[
  {
    "path": ".github/dependabot.yml",
    "content": "---\nversion: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n"
  },
  {
    "path": ".github/workflows/go.yml",
    "content": "---\nname: Go\n\non:\n  push:\n    branches: [master]\n  pull_request:\n\njobs:\n  build:\n    name: Build\n\n    strategy:\n      fail-fast: false\n      matrix:\n        go: [1.16.x]\n        may-fail: [false]\n        include:\n          - go: tip\n            may-fail: true\n\n    runs-on: ubuntu-20.04\n    continue-on-error: ${{ matrix.may-fail }}\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Setup Go v${{ matrix.go }}\n        if: ${{ matrix.go != 'tip' }}\n        uses: actions/setup-go@v2\n        with:\n          go-version: ${{ matrix.go }}\n\n      - name: Setup Go tip\n        if: ${{ matrix.go == 'tip' }}\n        run: |\n          curl -OL https://github.com/AlekSi/golang-tip/releases/download/tip/master.linux-amd64.tar.gz\n          sudo rm -rf /usr/local/go\n          sudo tar -C /usr/local -xzf master.linux-amd64.tar.gz\n          sudo ln -vsf /usr/local/go/bin/* /usr/bin/\n          sudo ln -vsf /usr/local/go/bin/* /bin/\n\n      - name: Run debug commands\n        run: |\n          env\n          which -a go\n          go version\n          go env\n\n      - name: Install tools\n        run: make init\n\n      - name: Test with race detector\n        run: make race\n\n      - name: Gather test coverage\n        run: make cover\n\n      - name: Upload test coverage report to coveralls.io\n        uses: shogo82148/actions-goveralls@v1.5.1\n        with:\n          path-to-profile: profile.cov\n"
  },
  {
    "path": ".gitignore",
    "content": "*.osm\n*.osm.bz2\n*.osm.pbf\n*.md5\n*.out\n*.test\n*.txt\n*.cov\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## v1.2.0 (tagged 2021-05-10)\n\n* Converted to Go module.\n* Updated .proto files ([#35](https://github.com/qedus/osmpbf/pull/35) by Lucas).\n* Updated protobuf dependency.\n* Migrated CI to GitHub Actions.\n\n## v1.1.0 (tagged 2018-03-29)\n\n* Added [`Decoder.Header()` method](https://pkg.go.dev/github.com/qedus/osmpbf#Decoder.Header)\n([#24](https://github.com/qedus/osmpbf/pull/24) by Karsten Klompmaker).\n* Added support for non-dense Nodes\n([#30](https://github.com/qedus/osmpbf/pull/30) by Clyde D'Cruz).\n* Minor optimizations.\n\n## v1.0.0 (tagged 2017-03-15)\n\n* First release with stable public API.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 qedus\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "export GORACE := halt_on_error=1\n\nall: cover\n\ninit:\n\tgo install -v golang.org/x/perf/cmd/benchstat@latest\n\nrace:\n\tgo install -v -race\n\tgo test -v -race\n\ncover:\n\tgo install -v\n\tgo test -v -coverprofile=profile.cov\n\nbench:\n\tenv OSMPBF_BENCHMARK_BUFFER=1048576  go test -v -run=NONE -bench=. -benchmem -benchtime=10s -count=5 | tee 01.txt\n\tenv OSMPBF_BENCHMARK_BUFFER=33554432 go test -v -run=NONE -bench=. -benchmem -benchtime=10s -count=5 | tee 32.txt\n\tbenchstat 01.txt 32.txt\n"
  },
  {
    "path": "OSMPBF/Makefile",
    "content": "all:\n\t# sync version with ../go.mod\n\tgo install -v google.golang.org/protobuf/cmd/protoc-gen-go@v1.26.0\n\n\trm *.go\n\tprotoc --go_out=. \\\n\t\t--go_opt=paths=source_relative \\\n\t\t--go_opt=Mfileformat.proto=github.com/qedus/osmpbf/OSMPBF \\\n\t\t--go_opt=Mosmformat.proto=github.com/qedus/osmpbf/OSMPBF \\\n\t\t*.proto\n"
  },
  {
    "path": "OSMPBF/README.md",
    "content": "# Proto Files\n\n`*.proto` files were downloaded from https://github.com/scrosby/OSM-binary/tree/master/src and changed in following ways:\n\n## Changes\n\n### StringTable\n\n- **File**: `osmformat.proto`\n- **Reason**: To eliminate continuous conversions from `[]byte` to `string`\n- **Old code**:\n\n```protobuf\nmessage StringTable {\n   repeated bytes s = 1;\n}\n```\n\n- **New code**:\n\n```protobuf\nmessage StringTable {\n   repeated string s = 1;\n}\n```\n\n- **Comptatibility**: This change is expected to be fully compatible with all PBF files.\n"
  },
  {
    "path": "OSMPBF/fileformat.pb.go",
    "content": "//* Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>\n//\n//Permission is hereby granted, free of charge, to any person obtaining a copy of\n//this software and associated documentation files (the \"Software\"), to deal in\n//the Software without restriction, including without limitation the rights to\n//use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n//of the Software, and to permit persons to whom the Software is furnished to do\n//so, subject to the following conditions:\n//\n//The above copyright notice and this permission notice shall be included in all\n//copies or substantial portions of the Software.\n//\n//THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n//SOFTWARE.\n//\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.15.8\n// source: fileformat.proto\n\npackage OSMPBF\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype Blob struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tRawSize *int32 `protobuf:\"varint,2,opt,name=raw_size,json=rawSize\" json:\"raw_size,omitempty\"` // When compressed, the uncompressed size\n\t// Types that are assignable to Data:\n\t//\t*Blob_Raw\n\t//\t*Blob_ZlibData\n\t//\t*Blob_LzmaData\n\t//\t*Blob_OBSOLETEBzip2Data\n\t//\t*Blob_Lz4Data\n\t//\t*Blob_ZstdData\n\tData isBlob_Data `protobuf_oneof:\"data\"`\n}\n\nfunc (x *Blob) Reset() {\n\t*x = Blob{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_fileformat_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Blob) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Blob) ProtoMessage() {}\n\nfunc (x *Blob) ProtoReflect() protoreflect.Message {\n\tmi := &file_fileformat_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Blob.ProtoReflect.Descriptor instead.\nfunc (*Blob) Descriptor() ([]byte, []int) {\n\treturn file_fileformat_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Blob) GetRawSize() int32 {\n\tif x != nil && x.RawSize != nil {\n\t\treturn *x.RawSize\n\t}\n\treturn 0\n}\n\nfunc (m *Blob) GetData() isBlob_Data {\n\tif m != nil {\n\t\treturn m.Data\n\t}\n\treturn nil\n}\n\nfunc (x *Blob) GetRaw() []byte {\n\tif x, ok := x.GetData().(*Blob_Raw); ok {\n\t\treturn x.Raw\n\t}\n\treturn nil\n}\n\nfunc (x *Blob) GetZlibData() []byte {\n\tif x, ok := x.GetData().(*Blob_ZlibData); ok {\n\t\treturn x.ZlibData\n\t}\n\treturn nil\n}\n\nfunc (x *Blob) GetLzmaData() []byte {\n\tif x, ok := x.GetData().(*Blob_LzmaData); ok {\n\t\treturn x.LzmaData\n\t}\n\treturn nil\n}\n\n// Deprecated: Do not use.\nfunc (x *Blob) GetOBSOLETEBzip2Data() []byte {\n\tif x, ok := x.GetData().(*Blob_OBSOLETEBzip2Data); ok {\n\t\treturn x.OBSOLETEBzip2Data\n\t}\n\treturn nil\n}\n\nfunc (x *Blob) GetLz4Data() []byte {\n\tif x, ok := x.GetData().(*Blob_Lz4Data); ok {\n\t\treturn x.Lz4Data\n\t}\n\treturn nil\n}\n\nfunc (x *Blob) GetZstdData() []byte {\n\tif x, ok := x.GetData().(*Blob_ZstdData); ok {\n\t\treturn x.ZstdData\n\t}\n\treturn nil\n}\n\ntype isBlob_Data interface {\n\tisBlob_Data()\n}\n\ntype Blob_Raw struct {\n\tRaw []byte `protobuf:\"bytes,1,opt,name=raw,oneof\"` // No compression\n}\n\ntype Blob_ZlibData struct {\n\t// Possible compressed versions of the data.\n\tZlibData []byte `protobuf:\"bytes,3,opt,name=zlib_data,json=zlibData,oneof\"`\n}\n\ntype Blob_LzmaData struct {\n\t// For LZMA compressed data (optional)\n\tLzmaData []byte `protobuf:\"bytes,4,opt,name=lzma_data,json=lzmaData,oneof\"`\n}\n\ntype Blob_OBSOLETEBzip2Data struct {\n\t// Formerly used for bzip2 compressed data. Deprecated in 2010.\n\t//\n\t// Deprecated: Do not use.\n\tOBSOLETEBzip2Data []byte `protobuf:\"bytes,5,opt,name=OBSOLETE_bzip2_data,json=OBSOLETEBzip2Data,oneof\"` // Don't reuse this tag number.\n}\n\ntype Blob_Lz4Data struct {\n\t// For LZ4 compressed data (optional)\n\tLz4Data []byte `protobuf:\"bytes,6,opt,name=lz4_data,json=lz4Data,oneof\"`\n}\n\ntype Blob_ZstdData struct {\n\t// For ZSTD compressed data (optional)\n\tZstdData []byte `protobuf:\"bytes,7,opt,name=zstd_data,json=zstdData,oneof\"`\n}\n\nfunc (*Blob_Raw) isBlob_Data() {}\n\nfunc (*Blob_ZlibData) isBlob_Data() {}\n\nfunc (*Blob_LzmaData) isBlob_Data() {}\n\nfunc (*Blob_OBSOLETEBzip2Data) isBlob_Data() {}\n\nfunc (*Blob_Lz4Data) isBlob_Data() {}\n\nfunc (*Blob_ZstdData) isBlob_Data() {}\n\ntype BlobHeader struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType      *string `protobuf:\"bytes,1,req,name=type\" json:\"type,omitempty\"`\n\tIndexdata []byte  `protobuf:\"bytes,2,opt,name=indexdata\" json:\"indexdata,omitempty\"`\n\tDatasize  *int32  `protobuf:\"varint,3,req,name=datasize\" json:\"datasize,omitempty\"`\n}\n\nfunc (x *BlobHeader) Reset() {\n\t*x = BlobHeader{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_fileformat_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *BlobHeader) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BlobHeader) ProtoMessage() {}\n\nfunc (x *BlobHeader) ProtoReflect() protoreflect.Message {\n\tmi := &file_fileformat_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use BlobHeader.ProtoReflect.Descriptor instead.\nfunc (*BlobHeader) Descriptor() ([]byte, []int) {\n\treturn file_fileformat_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *BlobHeader) GetType() string {\n\tif x != nil && x.Type != nil {\n\t\treturn *x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *BlobHeader) GetIndexdata() []byte {\n\tif x != nil {\n\t\treturn x.Indexdata\n\t}\n\treturn nil\n}\n\nfunc (x *BlobHeader) GetDatasize() int32 {\n\tif x != nil && x.Datasize != nil {\n\t\treturn *x.Datasize\n\t}\n\treturn 0\n}\n\nvar File_fileformat_proto protoreflect.FileDescriptor\n\nvar file_fileformat_proto_rawDesc = []byte{\n\t0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x12, 0x06, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x22, 0xed, 0x01, 0x0a, 0x04, 0x42,\n\t0x6c, 0x6f, 0x62, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x12,\n\t0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72,\n\t0x61, 0x77, 0x12, 0x1d, 0x0a, 0x09, 0x7a, 0x6c, 0x69, 0x62, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x7a, 0x6c, 0x69, 0x62, 0x44, 0x61, 0x74,\n\t0x61, 0x12, 0x1d, 0x0a, 0x09, 0x6c, 0x7a, 0x6d, 0x61, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04,\n\t0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x7a, 0x6d, 0x61, 0x44, 0x61, 0x74, 0x61,\n\t0x12, 0x34, 0x0a, 0x13, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x62, 0x7a, 0x69,\n\t0x70, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18,\n\t0x01, 0x48, 0x00, 0x52, 0x11, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x42, 0x7a, 0x69,\n\t0x70, 0x32, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x7a, 0x34, 0x5f, 0x64, 0x61,\n\t0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x7a, 0x34, 0x44,\n\t0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x09, 0x7a, 0x73, 0x74, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61,\n\t0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x7a, 0x73, 0x74, 0x64, 0x44, 0x61,\n\t0x74, 0x61, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5a, 0x0a, 0x0a, 0x42, 0x6c,\n\t0x6f, 0x62, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,\n\t0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09,\n\t0x69, 0x6e, 0x64, 0x65, 0x78, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,\n\t0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61,\n\t0x74, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x02, 0x28, 0x05, 0x52, 0x08, 0x64, 0x61,\n\t0x74, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x72, 0x6f, 0x73, 0x62, 0x79,\n\t0x2e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79,\n}\n\nvar (\n\tfile_fileformat_proto_rawDescOnce sync.Once\n\tfile_fileformat_proto_rawDescData = file_fileformat_proto_rawDesc\n)\n\nfunc file_fileformat_proto_rawDescGZIP() []byte {\n\tfile_fileformat_proto_rawDescOnce.Do(func() {\n\t\tfile_fileformat_proto_rawDescData = protoimpl.X.CompressGZIP(file_fileformat_proto_rawDescData)\n\t})\n\treturn file_fileformat_proto_rawDescData\n}\n\nvar file_fileformat_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_fileformat_proto_goTypes = []interface{}{\n\t(*Blob)(nil),       // 0: OSMPBF.Blob\n\t(*BlobHeader)(nil), // 1: OSMPBF.BlobHeader\n}\nvar file_fileformat_proto_depIdxs = []int32{\n\t0, // [0:0] is the sub-list for method output_type\n\t0, // [0:0] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_fileformat_proto_init() }\nfunc file_fileformat_proto_init() {\n\tif File_fileformat_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_fileformat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Blob); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_fileformat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*BlobHeader); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\tfile_fileformat_proto_msgTypes[0].OneofWrappers = []interface{}{\n\t\t(*Blob_Raw)(nil),\n\t\t(*Blob_ZlibData)(nil),\n\t\t(*Blob_LzmaData)(nil),\n\t\t(*Blob_OBSOLETEBzip2Data)(nil),\n\t\t(*Blob_Lz4Data)(nil),\n\t\t(*Blob_ZstdData)(nil),\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_fileformat_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_fileformat_proto_goTypes,\n\t\tDependencyIndexes: file_fileformat_proto_depIdxs,\n\t\tMessageInfos:      file_fileformat_proto_msgTypes,\n\t}.Build()\n\tFile_fileformat_proto = out.File\n\tfile_fileformat_proto_rawDesc = nil\n\tfile_fileformat_proto_goTypes = nil\n\tfile_fileformat_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "OSMPBF/fileformat.proto",
    "content": "/** Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n*/\n\nsyntax = \"proto2\";\n\noption java_package = \"crosby.binary\";\npackage OSMPBF;\n\n//protoc --java_out=../.. fileformat.proto\n\n\n//\n//  STORAGE LAYER: Storing primitives.\n//\n\nmessage Blob {\n  optional int32 raw_size = 2; // When compressed, the uncompressed size\n\n  oneof data {\n    bytes raw = 1; // No compression\n\n    // Possible compressed versions of the data.\n    bytes zlib_data = 3;\n\n    // For LZMA compressed data (optional)\n    bytes lzma_data = 4;\n\n    // Formerly used for bzip2 compressed data. Deprecated in 2010.\n    bytes OBSOLETE_bzip2_data = 5 [deprecated=true]; // Don't reuse this tag number.\n\n    // For LZ4 compressed data (optional)\n    bytes lz4_data = 6;\n\n    // For ZSTD compressed data (optional)\n    bytes zstd_data = 7;\n  }\n}\n\n/* A file contains an sequence of fileblock headers, each prefixed by\ntheir length in network byte order, followed by a data block\ncontaining the actual data. Types starting with a \"_\" are reserved.\n*/\n\nmessage BlobHeader {\n  required string type = 1;\n  optional bytes indexdata = 2;\n  required int32 datasize = 3;\n}\n"
  },
  {
    "path": "OSMPBF/osmformat.pb.go",
    "content": "//* Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>\n//\n//Permission is hereby granted, free of charge, to any person obtaining a copy of\n//this software and associated documentation files (the \"Software\"), to deal in\n//the Software without restriction, including without limitation the rights to\n//use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n//of the Software, and to permit persons to whom the Software is furnished to do\n//so, subject to the following conditions:\n//\n//The above copyright notice and this permission notice shall be included in all\n//copies or substantial portions of the Software.\n//\n//THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n//SOFTWARE.\n//\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.15.8\n// source: osmformat.proto\n\npackage OSMPBF\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype Relation_MemberType int32\n\nconst (\n\tRelation_NODE     Relation_MemberType = 0\n\tRelation_WAY      Relation_MemberType = 1\n\tRelation_RELATION Relation_MemberType = 2\n)\n\n// Enum value maps for Relation_MemberType.\nvar (\n\tRelation_MemberType_name = map[int32]string{\n\t\t0: \"NODE\",\n\t\t1: \"WAY\",\n\t\t2: \"RELATION\",\n\t}\n\tRelation_MemberType_value = map[string]int32{\n\t\t\"NODE\":     0,\n\t\t\"WAY\":      1,\n\t\t\"RELATION\": 2,\n\t}\n)\n\nfunc (x Relation_MemberType) Enum() *Relation_MemberType {\n\tp := new(Relation_MemberType)\n\t*p = x\n\treturn p\n}\n\nfunc (x Relation_MemberType) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Relation_MemberType) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_osmformat_proto_enumTypes[0].Descriptor()\n}\n\nfunc (Relation_MemberType) Type() protoreflect.EnumType {\n\treturn &file_osmformat_proto_enumTypes[0]\n}\n\nfunc (x Relation_MemberType) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Do not use.\nfunc (x *Relation_MemberType) UnmarshalJSON(b []byte) error {\n\tnum, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*x = Relation_MemberType(num)\n\treturn nil\n}\n\n// Deprecated: Use Relation_MemberType.Descriptor instead.\nfunc (Relation_MemberType) EnumDescriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{11, 0}\n}\n\ntype HeaderBlock struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tBbox *HeaderBBox `protobuf:\"bytes,1,opt,name=bbox\" json:\"bbox,omitempty\"`\n\t// Additional tags to aid in parsing this dataset\n\tRequiredFeatures []string `protobuf:\"bytes,4,rep,name=required_features,json=requiredFeatures\" json:\"required_features,omitempty\"`\n\tOptionalFeatures []string `protobuf:\"bytes,5,rep,name=optional_features,json=optionalFeatures\" json:\"optional_features,omitempty\"`\n\tWritingprogram   *string  `protobuf:\"bytes,16,opt,name=writingprogram\" json:\"writingprogram,omitempty\"`\n\tSource           *string  `protobuf:\"bytes,17,opt,name=source\" json:\"source,omitempty\"` // From the bbox field.\n\t// Replication timestamp, expressed in seconds since the epoch,\n\t// otherwise the same value as in the \"timestamp=...\" field\n\t// in the state.txt file used by Osmosis.\n\tOsmosisReplicationTimestamp *int64 `protobuf:\"varint,32,opt,name=osmosis_replication_timestamp,json=osmosisReplicationTimestamp\" json:\"osmosis_replication_timestamp,omitempty\"`\n\t// Replication sequence number (sequenceNumber in state.txt).\n\tOsmosisReplicationSequenceNumber *int64 `protobuf:\"varint,33,opt,name=osmosis_replication_sequence_number,json=osmosisReplicationSequenceNumber\" json:\"osmosis_replication_sequence_number,omitempty\"`\n\t// Replication base URL (from Osmosis' configuration.txt file).\n\tOsmosisReplicationBaseUrl *string `protobuf:\"bytes,34,opt,name=osmosis_replication_base_url,json=osmosisReplicationBaseUrl\" json:\"osmosis_replication_base_url,omitempty\"`\n}\n\nfunc (x *HeaderBlock) Reset() {\n\t*x = HeaderBlock{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HeaderBlock) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HeaderBlock) ProtoMessage() {}\n\nfunc (x *HeaderBlock) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HeaderBlock.ProtoReflect.Descriptor instead.\nfunc (*HeaderBlock) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *HeaderBlock) GetBbox() *HeaderBBox {\n\tif x != nil {\n\t\treturn x.Bbox\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderBlock) GetRequiredFeatures() []string {\n\tif x != nil {\n\t\treturn x.RequiredFeatures\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderBlock) GetOptionalFeatures() []string {\n\tif x != nil {\n\t\treturn x.OptionalFeatures\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderBlock) GetWritingprogram() string {\n\tif x != nil && x.Writingprogram != nil {\n\t\treturn *x.Writingprogram\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderBlock) GetSource() string {\n\tif x != nil && x.Source != nil {\n\t\treturn *x.Source\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderBlock) GetOsmosisReplicationTimestamp() int64 {\n\tif x != nil && x.OsmosisReplicationTimestamp != nil {\n\t\treturn *x.OsmosisReplicationTimestamp\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderBlock) GetOsmosisReplicationSequenceNumber() int64 {\n\tif x != nil && x.OsmosisReplicationSequenceNumber != nil {\n\t\treturn *x.OsmosisReplicationSequenceNumber\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderBlock) GetOsmosisReplicationBaseUrl() string {\n\tif x != nil && x.OsmosisReplicationBaseUrl != nil {\n\t\treturn *x.OsmosisReplicationBaseUrl\n\t}\n\treturn \"\"\n}\n\ntype HeaderBBox struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tLeft   *int64 `protobuf:\"zigzag64,1,req,name=left\" json:\"left,omitempty\"`\n\tRight  *int64 `protobuf:\"zigzag64,2,req,name=right\" json:\"right,omitempty\"`\n\tTop    *int64 `protobuf:\"zigzag64,3,req,name=top\" json:\"top,omitempty\"`\n\tBottom *int64 `protobuf:\"zigzag64,4,req,name=bottom\" json:\"bottom,omitempty\"`\n}\n\nfunc (x *HeaderBBox) Reset() {\n\t*x = HeaderBBox{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HeaderBBox) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HeaderBBox) ProtoMessage() {}\n\nfunc (x *HeaderBBox) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HeaderBBox.ProtoReflect.Descriptor instead.\nfunc (*HeaderBBox) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HeaderBBox) GetLeft() int64 {\n\tif x != nil && x.Left != nil {\n\t\treturn *x.Left\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderBBox) GetRight() int64 {\n\tif x != nil && x.Right != nil {\n\t\treturn *x.Right\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderBBox) GetTop() int64 {\n\tif x != nil && x.Top != nil {\n\t\treturn *x.Top\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderBBox) GetBottom() int64 {\n\tif x != nil && x.Bottom != nil {\n\t\treturn *x.Bottom\n\t}\n\treturn 0\n}\n\ntype PrimitiveBlock struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tStringtable    *StringTable      `protobuf:\"bytes,1,req,name=stringtable\" json:\"stringtable,omitempty\"`\n\tPrimitivegroup []*PrimitiveGroup `protobuf:\"bytes,2,rep,name=primitivegroup\" json:\"primitivegroup,omitempty\"`\n\t// Granularity, units of nanodegrees, used to store coordinates in this block.\n\tGranularity *int32 `protobuf:\"varint,17,opt,name=granularity,def=100\" json:\"granularity,omitempty\"`\n\t// Offset value between the output coordinates and the granularity grid in units of nanodegrees.\n\tLatOffset *int64 `protobuf:\"varint,19,opt,name=lat_offset,json=latOffset,def=0\" json:\"lat_offset,omitempty\"`\n\tLonOffset *int64 `protobuf:\"varint,20,opt,name=lon_offset,json=lonOffset,def=0\" json:\"lon_offset,omitempty\"`\n\t// Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.\n\tDateGranularity *int32 `protobuf:\"varint,18,opt,name=date_granularity,json=dateGranularity,def=1000\" json:\"date_granularity,omitempty\"`\n}\n\n// Default values for PrimitiveBlock fields.\nconst (\n\tDefault_PrimitiveBlock_Granularity     = int32(100)\n\tDefault_PrimitiveBlock_LatOffset       = int64(0)\n\tDefault_PrimitiveBlock_LonOffset       = int64(0)\n\tDefault_PrimitiveBlock_DateGranularity = int32(1000)\n)\n\nfunc (x *PrimitiveBlock) Reset() {\n\t*x = PrimitiveBlock{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *PrimitiveBlock) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PrimitiveBlock) ProtoMessage() {}\n\nfunc (x *PrimitiveBlock) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PrimitiveBlock.ProtoReflect.Descriptor instead.\nfunc (*PrimitiveBlock) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *PrimitiveBlock) GetStringtable() *StringTable {\n\tif x != nil {\n\t\treturn x.Stringtable\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitiveBlock) GetPrimitivegroup() []*PrimitiveGroup {\n\tif x != nil {\n\t\treturn x.Primitivegroup\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitiveBlock) GetGranularity() int32 {\n\tif x != nil && x.Granularity != nil {\n\t\treturn *x.Granularity\n\t}\n\treturn Default_PrimitiveBlock_Granularity\n}\n\nfunc (x *PrimitiveBlock) GetLatOffset() int64 {\n\tif x != nil && x.LatOffset != nil {\n\t\treturn *x.LatOffset\n\t}\n\treturn Default_PrimitiveBlock_LatOffset\n}\n\nfunc (x *PrimitiveBlock) GetLonOffset() int64 {\n\tif x != nil && x.LonOffset != nil {\n\t\treturn *x.LonOffset\n\t}\n\treturn Default_PrimitiveBlock_LonOffset\n}\n\nfunc (x *PrimitiveBlock) GetDateGranularity() int32 {\n\tif x != nil && x.DateGranularity != nil {\n\t\treturn *x.DateGranularity\n\t}\n\treturn Default_PrimitiveBlock_DateGranularity\n}\n\n// Group of OSMPrimitives. All primitives in a group must be the same type.\ntype PrimitiveGroup struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tNodes      []*Node      `protobuf:\"bytes,1,rep,name=nodes\" json:\"nodes,omitempty\"`\n\tDense      *DenseNodes  `protobuf:\"bytes,2,opt,name=dense\" json:\"dense,omitempty\"`\n\tWays       []*Way       `protobuf:\"bytes,3,rep,name=ways\" json:\"ways,omitempty\"`\n\tRelations  []*Relation  `protobuf:\"bytes,4,rep,name=relations\" json:\"relations,omitempty\"`\n\tChangesets []*ChangeSet `protobuf:\"bytes,5,rep,name=changesets\" json:\"changesets,omitempty\"`\n}\n\nfunc (x *PrimitiveGroup) Reset() {\n\t*x = PrimitiveGroup{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *PrimitiveGroup) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PrimitiveGroup) ProtoMessage() {}\n\nfunc (x *PrimitiveGroup) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[3]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use PrimitiveGroup.ProtoReflect.Descriptor instead.\nfunc (*PrimitiveGroup) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *PrimitiveGroup) GetNodes() []*Node {\n\tif x != nil {\n\t\treturn x.Nodes\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitiveGroup) GetDense() *DenseNodes {\n\tif x != nil {\n\t\treturn x.Dense\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitiveGroup) GetWays() []*Way {\n\tif x != nil {\n\t\treturn x.Ways\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitiveGroup) GetRelations() []*Relation {\n\tif x != nil {\n\t\treturn x.Relations\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitiveGroup) GetChangesets() []*ChangeSet {\n\tif x != nil {\n\t\treturn x.Changesets\n\t}\n\treturn nil\n}\n\n//* String table, contains the common strings in each block.\n//\n//Note that we reserve index '0' as a delimiter, so the entry at that\n//index in the table is ALWAYS blank and unused.\n//\ntype StringTable struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tS []string `protobuf:\"bytes,1,rep,name=s\" json:\"s,omitempty\"`\n}\n\nfunc (x *StringTable) Reset() {\n\t*x = StringTable{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *StringTable) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StringTable) ProtoMessage() {}\n\nfunc (x *StringTable) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[4]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use StringTable.ProtoReflect.Descriptor instead.\nfunc (*StringTable) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *StringTable) GetS() []string {\n\tif x != nil {\n\t\treturn x.S\n\t}\n\treturn nil\n}\n\n// Optional metadata that may be included into each primitive.\ntype Info struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tVersion   *int32  `protobuf:\"varint,1,opt,name=version,def=-1\" json:\"version,omitempty\"`\n\tTimestamp *int64  `protobuf:\"varint,2,opt,name=timestamp\" json:\"timestamp,omitempty\"`\n\tChangeset *int64  `protobuf:\"varint,3,opt,name=changeset\" json:\"changeset,omitempty\"`\n\tUid       *int32  `protobuf:\"varint,4,opt,name=uid\" json:\"uid,omitempty\"`\n\tUserSid   *uint32 `protobuf:\"varint,5,opt,name=user_sid,json=userSid\" json:\"user_sid,omitempty\"` // String IDs\n\t// The visible flag is used to store history information. It indicates that\n\t// the current object version has been created by a delete operation on the\n\t// OSM API.\n\t// When a writer sets this flag, it MUST add a required_features tag with\n\t// value \"HistoricalInformation\" to the HeaderBlock.\n\t// If this flag is not available for some object it MUST be assumed to be\n\t// true if the file has the required_features tag \"HistoricalInformation\"\n\t// set.\n\tVisible *bool `protobuf:\"varint,6,opt,name=visible\" json:\"visible,omitempty\"`\n}\n\n// Default values for Info fields.\nconst (\n\tDefault_Info_Version = int32(-1)\n)\n\nfunc (x *Info) Reset() {\n\t*x = Info{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[5]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Info) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Info) ProtoMessage() {}\n\nfunc (x *Info) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[5]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Info.ProtoReflect.Descriptor instead.\nfunc (*Info) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *Info) GetVersion() int32 {\n\tif x != nil && x.Version != nil {\n\t\treturn *x.Version\n\t}\n\treturn Default_Info_Version\n}\n\nfunc (x *Info) GetTimestamp() int64 {\n\tif x != nil && x.Timestamp != nil {\n\t\treturn *x.Timestamp\n\t}\n\treturn 0\n}\n\nfunc (x *Info) GetChangeset() int64 {\n\tif x != nil && x.Changeset != nil {\n\t\treturn *x.Changeset\n\t}\n\treturn 0\n}\n\nfunc (x *Info) GetUid() int32 {\n\tif x != nil && x.Uid != nil {\n\t\treturn *x.Uid\n\t}\n\treturn 0\n}\n\nfunc (x *Info) GetUserSid() uint32 {\n\tif x != nil && x.UserSid != nil {\n\t\treturn *x.UserSid\n\t}\n\treturn 0\n}\n\nfunc (x *Info) GetVisible() bool {\n\tif x != nil && x.Visible != nil {\n\t\treturn *x.Visible\n\t}\n\treturn false\n}\n\n//* Optional metadata that may be included into each primitive. Special dense format used in DenseNodes.\ntype DenseInfo struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tVersion   []int32 `protobuf:\"varint,1,rep,packed,name=version\" json:\"version,omitempty\"`\n\tTimestamp []int64 `protobuf:\"zigzag64,2,rep,packed,name=timestamp\" json:\"timestamp,omitempty\"`            // DELTA coded\n\tChangeset []int64 `protobuf:\"zigzag64,3,rep,packed,name=changeset\" json:\"changeset,omitempty\"`            // DELTA coded\n\tUid       []int32 `protobuf:\"zigzag32,4,rep,packed,name=uid\" json:\"uid,omitempty\"`                        // DELTA coded\n\tUserSid   []int32 `protobuf:\"zigzag32,5,rep,packed,name=user_sid,json=userSid\" json:\"user_sid,omitempty\"` // String IDs for usernames. DELTA coded\n\t// The visible flag is used to store history information. It indicates that\n\t// the current object version has been created by a delete operation on the\n\t// OSM API.\n\t// When a writer sets this flag, it MUST add a required_features tag with\n\t// value \"HistoricalInformation\" to the HeaderBlock.\n\t// If this flag is not available for some object it MUST be assumed to be\n\t// true if the file has the required_features tag \"HistoricalInformation\"\n\t// set.\n\tVisible []bool `protobuf:\"varint,6,rep,packed,name=visible\" json:\"visible,omitempty\"`\n}\n\nfunc (x *DenseInfo) Reset() {\n\t*x = DenseInfo{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[6]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *DenseInfo) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DenseInfo) ProtoMessage() {}\n\nfunc (x *DenseInfo) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[6]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use DenseInfo.ProtoReflect.Descriptor instead.\nfunc (*DenseInfo) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *DenseInfo) GetVersion() []int32 {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn nil\n}\n\nfunc (x *DenseInfo) GetTimestamp() []int64 {\n\tif x != nil {\n\t\treturn x.Timestamp\n\t}\n\treturn nil\n}\n\nfunc (x *DenseInfo) GetChangeset() []int64 {\n\tif x != nil {\n\t\treturn x.Changeset\n\t}\n\treturn nil\n}\n\nfunc (x *DenseInfo) GetUid() []int32 {\n\tif x != nil {\n\t\treturn x.Uid\n\t}\n\treturn nil\n}\n\nfunc (x *DenseInfo) GetUserSid() []int32 {\n\tif x != nil {\n\t\treturn x.UserSid\n\t}\n\treturn nil\n}\n\nfunc (x *DenseInfo) GetVisible() []bool {\n\tif x != nil {\n\t\treturn x.Visible\n\t}\n\treturn nil\n}\n\n// This is kept for backwards compatibility but not used anywhere.\ntype ChangeSet struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId *int64 `protobuf:\"varint,1,req,name=id\" json:\"id,omitempty\"`\n}\n\nfunc (x *ChangeSet) Reset() {\n\t*x = ChangeSet{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[7]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ChangeSet) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ChangeSet) ProtoMessage() {}\n\nfunc (x *ChangeSet) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[7]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use ChangeSet.ProtoReflect.Descriptor instead.\nfunc (*ChangeSet) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *ChangeSet) GetId() int64 {\n\tif x != nil && x.Id != nil {\n\t\treturn *x.Id\n\t}\n\treturn 0\n}\n\ntype Node struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId *int64 `protobuf:\"zigzag64,1,req,name=id\" json:\"id,omitempty\"`\n\t// Parallel arrays.\n\tKeys []uint32 `protobuf:\"varint,2,rep,packed,name=keys\" json:\"keys,omitempty\"` // String IDs.\n\tVals []uint32 `protobuf:\"varint,3,rep,packed,name=vals\" json:\"vals,omitempty\"` // String IDs.\n\tInfo *Info    `protobuf:\"bytes,4,opt,name=info\" json:\"info,omitempty\"`         // May be omitted in omitmeta\n\tLat  *int64   `protobuf:\"zigzag64,8,req,name=lat\" json:\"lat,omitempty\"`\n\tLon  *int64   `protobuf:\"zigzag64,9,req,name=lon\" json:\"lon,omitempty\"`\n}\n\nfunc (x *Node) Reset() {\n\t*x = Node{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[8]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Node) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Node) ProtoMessage() {}\n\nfunc (x *Node) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[8]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Node.ProtoReflect.Descriptor instead.\nfunc (*Node) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *Node) GetId() int64 {\n\tif x != nil && x.Id != nil {\n\t\treturn *x.Id\n\t}\n\treturn 0\n}\n\nfunc (x *Node) GetKeys() []uint32 {\n\tif x != nil {\n\t\treturn x.Keys\n\t}\n\treturn nil\n}\n\nfunc (x *Node) GetVals() []uint32 {\n\tif x != nil {\n\t\treturn x.Vals\n\t}\n\treturn nil\n}\n\nfunc (x *Node) GetInfo() *Info {\n\tif x != nil {\n\t\treturn x.Info\n\t}\n\treturn nil\n}\n\nfunc (x *Node) GetLat() int64 {\n\tif x != nil && x.Lat != nil {\n\t\treturn *x.Lat\n\t}\n\treturn 0\n}\n\nfunc (x *Node) GetLon() int64 {\n\tif x != nil && x.Lon != nil {\n\t\treturn *x.Lon\n\t}\n\treturn 0\n}\n\ntype DenseNodes struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId        []int64    `protobuf:\"zigzag64,1,rep,packed,name=id\" json:\"id,omitempty\"` // DELTA coded\n\tDenseinfo *DenseInfo `protobuf:\"bytes,5,opt,name=denseinfo\" json:\"denseinfo,omitempty\"`\n\tLat       []int64    `protobuf:\"zigzag64,8,rep,packed,name=lat\" json:\"lat,omitempty\"` // DELTA coded\n\tLon       []int64    `protobuf:\"zigzag64,9,rep,packed,name=lon\" json:\"lon,omitempty\"` // DELTA coded\n\t// Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.\n\tKeysVals []int32 `protobuf:\"varint,10,rep,packed,name=keys_vals,json=keysVals\" json:\"keys_vals,omitempty\"`\n}\n\nfunc (x *DenseNodes) Reset() {\n\t*x = DenseNodes{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[9]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *DenseNodes) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DenseNodes) ProtoMessage() {}\n\nfunc (x *DenseNodes) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[9]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use DenseNodes.ProtoReflect.Descriptor instead.\nfunc (*DenseNodes) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *DenseNodes) GetId() []int64 {\n\tif x != nil {\n\t\treturn x.Id\n\t}\n\treturn nil\n}\n\nfunc (x *DenseNodes) GetDenseinfo() *DenseInfo {\n\tif x != nil {\n\t\treturn x.Denseinfo\n\t}\n\treturn nil\n}\n\nfunc (x *DenseNodes) GetLat() []int64 {\n\tif x != nil {\n\t\treturn x.Lat\n\t}\n\treturn nil\n}\n\nfunc (x *DenseNodes) GetLon() []int64 {\n\tif x != nil {\n\t\treturn x.Lon\n\t}\n\treturn nil\n}\n\nfunc (x *DenseNodes) GetKeysVals() []int32 {\n\tif x != nil {\n\t\treturn x.KeysVals\n\t}\n\treturn nil\n}\n\ntype Way struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId *int64 `protobuf:\"varint,1,req,name=id\" json:\"id,omitempty\"`\n\t// Parallel arrays.\n\tKeys []uint32 `protobuf:\"varint,2,rep,packed,name=keys\" json:\"keys,omitempty\"`\n\tVals []uint32 `protobuf:\"varint,3,rep,packed,name=vals\" json:\"vals,omitempty\"`\n\tInfo *Info    `protobuf:\"bytes,4,opt,name=info\" json:\"info,omitempty\"`\n\tRefs []int64  `protobuf:\"zigzag64,8,rep,packed,name=refs\" json:\"refs,omitempty\"` // DELTA coded\n\t// The following two fields are optional. They are only used in a special\n\t// format where node locations are also added to the ways. This makes the\n\t// files larger, but allows creating way geometries directly.\n\t//\n\t// If this is used, you MUST set the optional_features tag \"LocationsOnWays\"\n\t// and the number of values in refs, lat, and lon MUST be the same.\n\tLat []int64 `protobuf:\"zigzag64,9,rep,packed,name=lat\" json:\"lat,omitempty\"`  // DELTA coded, optional\n\tLon []int64 `protobuf:\"zigzag64,10,rep,packed,name=lon\" json:\"lon,omitempty\"` // DELTA coded, optional\n}\n\nfunc (x *Way) Reset() {\n\t*x = Way{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[10]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Way) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Way) ProtoMessage() {}\n\nfunc (x *Way) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[10]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Way.ProtoReflect.Descriptor instead.\nfunc (*Way) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *Way) GetId() int64 {\n\tif x != nil && x.Id != nil {\n\t\treturn *x.Id\n\t}\n\treturn 0\n}\n\nfunc (x *Way) GetKeys() []uint32 {\n\tif x != nil {\n\t\treturn x.Keys\n\t}\n\treturn nil\n}\n\nfunc (x *Way) GetVals() []uint32 {\n\tif x != nil {\n\t\treturn x.Vals\n\t}\n\treturn nil\n}\n\nfunc (x *Way) GetInfo() *Info {\n\tif x != nil {\n\t\treturn x.Info\n\t}\n\treturn nil\n}\n\nfunc (x *Way) GetRefs() []int64 {\n\tif x != nil {\n\t\treturn x.Refs\n\t}\n\treturn nil\n}\n\nfunc (x *Way) GetLat() []int64 {\n\tif x != nil {\n\t\treturn x.Lat\n\t}\n\treturn nil\n}\n\nfunc (x *Way) GetLon() []int64 {\n\tif x != nil {\n\t\treturn x.Lon\n\t}\n\treturn nil\n}\n\ntype Relation struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tId *int64 `protobuf:\"varint,1,req,name=id\" json:\"id,omitempty\"`\n\t// Parallel arrays.\n\tKeys []uint32 `protobuf:\"varint,2,rep,packed,name=keys\" json:\"keys,omitempty\"`\n\tVals []uint32 `protobuf:\"varint,3,rep,packed,name=vals\" json:\"vals,omitempty\"`\n\tInfo *Info    `protobuf:\"bytes,4,opt,name=info\" json:\"info,omitempty\"`\n\t// Parallel arrays\n\tRolesSid []int32               `protobuf:\"varint,8,rep,packed,name=roles_sid,json=rolesSid\" json:\"roles_sid,omitempty\"` // This should have been defined as uint32 for consistency, but it is now too late to change it\n\tMemids   []int64               `protobuf:\"zigzag64,9,rep,packed,name=memids\" json:\"memids,omitempty\"`                   // DELTA encoded\n\tTypes    []Relation_MemberType `protobuf:\"varint,10,rep,packed,name=types,enum=OSMPBF.Relation_MemberType\" json:\"types,omitempty\"`\n}\n\nfunc (x *Relation) Reset() {\n\t*x = Relation{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_osmformat_proto_msgTypes[11]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Relation) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Relation) ProtoMessage() {}\n\nfunc (x *Relation) ProtoReflect() protoreflect.Message {\n\tmi := &file_osmformat_proto_msgTypes[11]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Relation.ProtoReflect.Descriptor instead.\nfunc (*Relation) Descriptor() ([]byte, []int) {\n\treturn file_osmformat_proto_rawDescGZIP(), []int{11}\n}\n\nfunc (x *Relation) GetId() int64 {\n\tif x != nil && x.Id != nil {\n\t\treturn *x.Id\n\t}\n\treturn 0\n}\n\nfunc (x *Relation) GetKeys() []uint32 {\n\tif x != nil {\n\t\treturn x.Keys\n\t}\n\treturn nil\n}\n\nfunc (x *Relation) GetVals() []uint32 {\n\tif x != nil {\n\t\treturn x.Vals\n\t}\n\treturn nil\n}\n\nfunc (x *Relation) GetInfo() *Info {\n\tif x != nil {\n\t\treturn x.Info\n\t}\n\treturn nil\n}\n\nfunc (x *Relation) GetRolesSid() []int32 {\n\tif x != nil {\n\t\treturn x.RolesSid\n\t}\n\treturn nil\n}\n\nfunc (x *Relation) GetMemids() []int64 {\n\tif x != nil {\n\t\treturn x.Memids\n\t}\n\treturn nil\n}\n\nfunc (x *Relation) GetTypes() []Relation_MemberType {\n\tif x != nil {\n\t\treturn x.Types\n\t}\n\treturn nil\n}\n\nvar File_osmformat_proto protoreflect.FileDescriptor\n\nvar file_osmformat_proto_rawDesc = []byte{\n\t0x0a, 0x0f, 0x6f, 0x73, 0x6d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x12, 0x06, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x22, 0xa3, 0x03, 0x0a, 0x0b, 0x48, 0x65,\n\t0x61, 0x64, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x26, 0x0a, 0x04, 0x62, 0x62, 0x6f,\n\t0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46,\n\t0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x42, 0x6f, 0x78, 0x52, 0x04, 0x62, 0x62, 0x6f,\n\t0x78, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x65,\n\t0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65,\n\t0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x2b,\n\t0x0a, 0x11, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75,\n\t0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x61, 0x6c, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x77,\n\t0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x10, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x67,\n\t0x72, 0x61, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x11, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x42, 0x0a, 0x1d, 0x6f,\n\t0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,\n\t0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x20, 0x20, 0x01,\n\t0x28, 0x03, 0x52, 0x1b, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,\n\t0x4d, 0x0a, 0x23, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f,\n\t0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x52, 0x20, 0x6f, 0x73,\n\t0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3f,\n\t0x0a, 0x1c, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x22,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70,\n\t0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x22,\n\t0x60, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x42, 0x6f, 0x78, 0x12, 0x12, 0x0a,\n\t0x04, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x12, 0x52, 0x04, 0x6c, 0x65, 0x66,\n\t0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x12,\n\t0x52, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x6f, 0x70, 0x18, 0x03,\n\t0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x74, 0x6f, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6f, 0x74,\n\t0x74, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x02, 0x28, 0x12, 0x52, 0x06, 0x62, 0x6f, 0x74, 0x74, 0x6f,\n\t0x6d, 0x22, 0xa3, 0x02, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x42,\n\t0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x61,\n\t0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x4f, 0x53, 0x4d, 0x50,\n\t0x42, 0x46, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x0b,\n\t0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x3e, 0x0a, 0x0e, 0x70,\n\t0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x50, 0x72, 0x69,\n\t0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, 0x70, 0x72, 0x69,\n\t0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x25, 0x0a, 0x0b, 0x67,\n\t0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05,\n\t0x3a, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69,\n\t0x74, 0x79, 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x61, 0x74, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74,\n\t0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x61, 0x74, 0x4f, 0x66,\n\t0x66, 0x73, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x6f, 0x6e, 0x5f, 0x6f, 0x66, 0x66, 0x73,\n\t0x65, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x6f, 0x6e,\n\t0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x10, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x67,\n\t0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05,\n\t0x3a, 0x04, 0x31, 0x30, 0x30, 0x30, 0x52, 0x0f, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e,\n\t0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6d,\n\t0x69, 0x74, 0x69, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f,\n\t0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50,\n\t0x42, 0x46, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x28,\n\t0x0a, 0x05, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,\n\t0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65,\n\t0x73, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x77, 0x61, 0x79, 0x73,\n\t0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e,\n\t0x57, 0x61, 0x79, 0x52, 0x04, 0x77, 0x61, 0x79, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x6c,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x4f,\n\t0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09,\n\t0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x68, 0x61,\n\t0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e,\n\t0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74,\n\t0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x73, 0x22, 0x1b, 0x0a, 0x0b,\n\t0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x73,\n\t0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x01, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x04, 0x49, 0x6e,\n\t0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x05, 0x3a, 0x02, 0x2d, 0x31, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,\n\t0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20,\n\t0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c,\n\t0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,\n\t0x03, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03,\n\t0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x19,\n\t0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d,\n\t0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x53, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x69, 0x73,\n\t0x69, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x69, 0x73, 0x69,\n\t0x62, 0x6c, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x09, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x49, 0x6e, 0x66,\n\t0x6f, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03,\n\t0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,\n\t0x20, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x03,\n\t0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,\n\t0x70, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x18, 0x03,\n\t0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65,\n\t0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x11,\n\t0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x08, 0x75, 0x73, 0x65,\n\t0x72, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x11, 0x42, 0x02, 0x10, 0x01, 0x52,\n\t0x07, 0x75, 0x73, 0x65, 0x72, 0x53, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x69, 0x73, 0x69,\n\t0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x08, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76,\n\t0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x1b, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65,\n\t0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52,\n\t0x02, 0x69, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02,\n\t0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x12, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04,\n\t0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04,\n\t0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03,\n\t0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04,\n\t0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d,\n\t0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x10,\n\t0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x08, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x6c, 0x61, 0x74,\n\t0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x6c,\n\t0x6f, 0x6e, 0x22, 0x9e, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65,\n\t0x73, 0x12, 0x12, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10,\n\t0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x69, 0x6e,\n\t0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42,\n\t0x46, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x64, 0x65, 0x6e,\n\t0x73, 0x65, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x08, 0x20,\n\t0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x03,\n\t0x6c, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c,\n\t0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x73, 0x18,\n\t0x0a, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x56,\n\t0x61, 0x6c, 0x73, 0x22, 0xab, 0x01, 0x0a, 0x03, 0x57, 0x61, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69,\n\t0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x6b,\n\t0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b,\n\t0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,\n\t0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x69,\n\t0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50,\n\t0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a,\n\t0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52,\n\t0x04, 0x72, 0x65, 0x66, 0x73, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x09, 0x20, 0x03,\n\t0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x6c,\n\t0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x6f,\n\t0x6e, 0x22, 0x8f, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e,\n\t0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16,\n\t0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01,\n\t0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03,\n\t0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20,\n\t0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f,\n\t0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f,\n\t0x12, 0x1f, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x08, 0x20,\n\t0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x53, 0x69,\n\t0x64, 0x12, 0x1a, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28,\n\t0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x69, 0x64, 0x73, 0x12, 0x35, 0x0a,\n\t0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x4f,\n\t0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d,\n\t0x65, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x02, 0x10, 0x01, 0x52, 0x05, 0x74,\n\t0x79, 0x70, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x79,\n\t0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03,\n\t0x57, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x4f,\n\t0x4e, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x72, 0x6f, 0x73, 0x62, 0x79, 0x2e, 0x62, 0x69,\n\t0x6e, 0x61, 0x72, 0x79,\n}\n\nvar (\n\tfile_osmformat_proto_rawDescOnce sync.Once\n\tfile_osmformat_proto_rawDescData = file_osmformat_proto_rawDesc\n)\n\nfunc file_osmformat_proto_rawDescGZIP() []byte {\n\tfile_osmformat_proto_rawDescOnce.Do(func() {\n\t\tfile_osmformat_proto_rawDescData = protoimpl.X.CompressGZIP(file_osmformat_proto_rawDescData)\n\t})\n\treturn file_osmformat_proto_rawDescData\n}\n\nvar file_osmformat_proto_enumTypes = make([]protoimpl.EnumInfo, 1)\nvar file_osmformat_proto_msgTypes = make([]protoimpl.MessageInfo, 12)\nvar file_osmformat_proto_goTypes = []interface{}{\n\t(Relation_MemberType)(0), // 0: OSMPBF.Relation.MemberType\n\t(*HeaderBlock)(nil),      // 1: OSMPBF.HeaderBlock\n\t(*HeaderBBox)(nil),       // 2: OSMPBF.HeaderBBox\n\t(*PrimitiveBlock)(nil),   // 3: OSMPBF.PrimitiveBlock\n\t(*PrimitiveGroup)(nil),   // 4: OSMPBF.PrimitiveGroup\n\t(*StringTable)(nil),      // 5: OSMPBF.StringTable\n\t(*Info)(nil),             // 6: OSMPBF.Info\n\t(*DenseInfo)(nil),        // 7: OSMPBF.DenseInfo\n\t(*ChangeSet)(nil),        // 8: OSMPBF.ChangeSet\n\t(*Node)(nil),             // 9: OSMPBF.Node\n\t(*DenseNodes)(nil),       // 10: OSMPBF.DenseNodes\n\t(*Way)(nil),              // 11: OSMPBF.Way\n\t(*Relation)(nil),         // 12: OSMPBF.Relation\n}\nvar file_osmformat_proto_depIdxs = []int32{\n\t2,  // 0: OSMPBF.HeaderBlock.bbox:type_name -> OSMPBF.HeaderBBox\n\t5,  // 1: OSMPBF.PrimitiveBlock.stringtable:type_name -> OSMPBF.StringTable\n\t4,  // 2: OSMPBF.PrimitiveBlock.primitivegroup:type_name -> OSMPBF.PrimitiveGroup\n\t9,  // 3: OSMPBF.PrimitiveGroup.nodes:type_name -> OSMPBF.Node\n\t10, // 4: OSMPBF.PrimitiveGroup.dense:type_name -> OSMPBF.DenseNodes\n\t11, // 5: OSMPBF.PrimitiveGroup.ways:type_name -> OSMPBF.Way\n\t12, // 6: OSMPBF.PrimitiveGroup.relations:type_name -> OSMPBF.Relation\n\t8,  // 7: OSMPBF.PrimitiveGroup.changesets:type_name -> OSMPBF.ChangeSet\n\t6,  // 8: OSMPBF.Node.info:type_name -> OSMPBF.Info\n\t7,  // 9: OSMPBF.DenseNodes.denseinfo:type_name -> OSMPBF.DenseInfo\n\t6,  // 10: OSMPBF.Way.info:type_name -> OSMPBF.Info\n\t6,  // 11: OSMPBF.Relation.info:type_name -> OSMPBF.Info\n\t0,  // 12: OSMPBF.Relation.types:type_name -> OSMPBF.Relation.MemberType\n\t13, // [13:13] is the sub-list for method output_type\n\t13, // [13:13] is the sub-list for method input_type\n\t13, // [13:13] is the sub-list for extension type_name\n\t13, // [13:13] is the sub-list for extension extendee\n\t0,  // [0:13] is the sub-list for field type_name\n}\n\nfunc init() { file_osmformat_proto_init() }\nfunc file_osmformat_proto_init() {\n\tif File_osmformat_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_osmformat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HeaderBlock); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HeaderBBox); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*PrimitiveBlock); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*PrimitiveGroup); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*StringTable); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Info); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*DenseInfo); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ChangeSet); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Node); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*DenseNodes); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Way); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_osmformat_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Relation); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_osmformat_proto_rawDesc,\n\t\t\tNumEnums:      1,\n\t\t\tNumMessages:   12,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_osmformat_proto_goTypes,\n\t\tDependencyIndexes: file_osmformat_proto_depIdxs,\n\t\tEnumInfos:         file_osmformat_proto_enumTypes,\n\t\tMessageInfos:      file_osmformat_proto_msgTypes,\n\t}.Build()\n\tFile_osmformat_proto = out.File\n\tfile_osmformat_proto_rawDesc = nil\n\tfile_osmformat_proto_goTypes = nil\n\tfile_osmformat_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "OSMPBF/osmformat.proto",
    "content": "/** Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n*/\n\nsyntax = \"proto2\";\n\noption java_package = \"crosby.binary\";\npackage OSMPBF;\n\n/* OSM Binary file format\n\nThis is the master schema file of the OSM binary file format. This\nfile is designed to support limited random-access and future\nextendability.\n\nA binary OSM file consists of a sequence of FileBlocks (please see\nfileformat.proto). The first fileblock contains a serialized instance\nof HeaderBlock, followed by a sequence of PrimitiveBlock blocks that\ncontain the primitives.\n\nEach primitiveblock is designed to be independently parsable. It\ncontains a string table storing all strings in that block (keys and\nvalues in tags, roles in relations, usernames, etc.) as well as\nmetadata containing the precision of coordinates or timestamps in that\nblock.\n\nA primitiveblock contains a sequence of primitive groups, each\ncontaining primitives of the same type (nodes, densenodes, ways,\nrelations). Coordinates are stored in signed 64-bit integers. Lat&lon\nare measured in units <granularity> nanodegrees. The default of\ngranularity of 100 nanodegrees corresponds to about 1cm on the ground,\nand a full lat or lon fits into 32 bits.\n\nConverting an integer to a latitude or longitude uses the formula:\n$OUT = IN * granularity / 10**9$. Many encoding schemes use delta\ncoding when representing nodes and relations.\n\n*/\n\n//////////////////////////////////////////////////////////////////////////\n//////////////////////////////////////////////////////////////////////////\n\n/* Contains the file header. */\n\nmessage HeaderBlock {\n  optional HeaderBBox bbox = 1;\n\n  /* Additional tags to aid in parsing this dataset */\n  repeated string required_features = 4;\n  repeated string optional_features = 5;\n\n  optional string writingprogram = 16;\n  optional string source = 17; // From the bbox field.\n\n  /* Tags that allow continuing an Osmosis replication */\n\n  // Replication timestamp, expressed in seconds since the epoch,\n  // otherwise the same value as in the \"timestamp=...\" field\n  // in the state.txt file used by Osmosis.\n  optional int64 osmosis_replication_timestamp = 32;\n\n  // Replication sequence number (sequenceNumber in state.txt).\n  optional int64 osmosis_replication_sequence_number = 33;\n\n  // Replication base URL (from Osmosis' configuration.txt file).\n  optional string osmosis_replication_base_url = 34;\n}\n\n\n/** The bounding box field in the OSM header. BBOX, as used in the OSM\nheader. Units are always in nanodegrees -- they do not obey\ngranularity rules. */\n\nmessage HeaderBBox {\n  required sint64 left = 1;\n  required sint64 right = 2;\n  required sint64 top = 3;\n  required sint64 bottom = 4;\n}\n\n\n///////////////////////////////////////////////////////////////////////\n///////////////////////////////////////////////////////////////////////\n\n\nmessage PrimitiveBlock {\n  required StringTable stringtable = 1;\n  repeated PrimitiveGroup primitivegroup = 2;\n\n  // Granularity, units of nanodegrees, used to store coordinates in this block.\n  optional int32 granularity = 17 [default=100];\n\n  // Offset value between the output coordinates and the granularity grid in units of nanodegrees.\n  optional int64 lat_offset = 19 [default=0];\n  optional int64 lon_offset = 20 [default=0];\n\n  // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.\n  optional int32 date_granularity = 18 [default=1000];\n}\n\n// Group of OSMPrimitives. All primitives in a group must be the same type.\nmessage PrimitiveGroup {\n  repeated Node nodes = 1;\n  optional DenseNodes dense = 2;\n  repeated Way ways = 3;\n  repeated Relation relations = 4;\n  repeated ChangeSet changesets = 5;\n}\n\n\n/** String table, contains the common strings in each block.\n\n Note that we reserve index '0' as a delimiter, so the entry at that\n index in the table is ALWAYS blank and unused.\n\n */\nmessage StringTable {\n  repeated string s = 1;\n}\n\n/* Optional metadata that may be included into each primitive. */\nmessage Info {\n  optional int32 version = 1 [default = -1];\n  optional int64 timestamp = 2;\n  optional int64 changeset = 3;\n  optional int32 uid = 4;\n  optional uint32 user_sid = 5; // String IDs\n\n  // The visible flag is used to store history information. It indicates that\n  // the current object version has been created by a delete operation on the\n  // OSM API.\n  // When a writer sets this flag, it MUST add a required_features tag with\n  // value \"HistoricalInformation\" to the HeaderBlock.\n  // If this flag is not available for some object it MUST be assumed to be\n  // true if the file has the required_features tag \"HistoricalInformation\"\n  // set.\n  optional bool visible = 6;\n}\n\n/** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. */\nmessage DenseInfo {\n  repeated int32 version = 1 [packed = true];\n  repeated sint64 timestamp = 2 [packed = true]; // DELTA coded\n  repeated sint64 changeset = 3 [packed = true]; // DELTA coded\n  repeated sint32 uid = 4 [packed = true]; // DELTA coded\n  repeated sint32 user_sid = 5 [packed = true]; // String IDs for usernames. DELTA coded\n\n  // The visible flag is used to store history information. It indicates that\n  // the current object version has been created by a delete operation on the\n  // OSM API.\n  // When a writer sets this flag, it MUST add a required_features tag with\n  // value \"HistoricalInformation\" to the HeaderBlock.\n  // If this flag is not available for some object it MUST be assumed to be\n  // true if the file has the required_features tag \"HistoricalInformation\"\n  // set.\n  repeated bool visible = 6 [packed = true];\n}\n\n\n// This is kept for backwards compatibility but not used anywhere.\nmessage ChangeSet {\n  required int64 id = 1;\n}\n\n\nmessage Node {\n  required sint64 id = 1;\n\n  // Parallel arrays.\n  repeated uint32 keys = 2 [packed = true]; // String IDs.\n  repeated uint32 vals = 3 [packed = true]; // String IDs.\n\n  optional Info info = 4; // May be omitted in omitmeta\n\n  required sint64 lat = 8;\n  required sint64 lon = 9;\n}\n\n/* Used to densly represent a sequence of nodes that do not have any tags.\n\nWe represent these nodes columnwise as five columns: ID's, lats, and\nlons, all delta coded. When metadata is not omitted,\n\nWe encode keys & vals for all nodes as a single array of integers\ncontaining key-stringid and val-stringid, using a stringid of 0 as a\ndelimiter between nodes.\n\n   ( (<keyid> <valid>)* '0' )*\n */\n\nmessage DenseNodes {\n  repeated sint64 id = 1 [packed = true]; // DELTA coded\n\n  optional DenseInfo denseinfo = 5;\n\n  repeated sint64 lat = 8 [packed = true]; // DELTA coded\n  repeated sint64 lon = 9 [packed = true]; // DELTA coded\n\n  // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.\n  repeated int32 keys_vals = 10 [packed = true];\n}\n\n\nmessage Way {\n  required int64 id = 1;\n\n  // Parallel arrays.\n  repeated uint32 keys = 2 [packed = true];\n  repeated uint32 vals = 3 [packed = true];\n\n  optional Info info = 4;\n\n  repeated sint64 refs = 8 [packed = true]; // DELTA coded\n\n  // The following two fields are optional. They are only used in a special\n  // format where node locations are also added to the ways. This makes the\n  // files larger, but allows creating way geometries directly.\n  //\n  // If this is used, you MUST set the optional_features tag \"LocationsOnWays\"\n  // and the number of values in refs, lat, and lon MUST be the same.\n  repeated sint64 lat = 9 [packed = true]; // DELTA coded, optional\n  repeated sint64 lon = 10 [packed = true]; // DELTA coded, optional\n}\n\nmessage Relation {\n  enum MemberType {\n    NODE = 0;\n    WAY = 1;\n    RELATION = 2;\n  }\n\n  required int64 id = 1;\n\n  // Parallel arrays.\n  repeated uint32 keys = 2 [packed = true];\n  repeated uint32 vals = 3 [packed = true];\n\n  optional Info info = 4;\n\n  // Parallel arrays\n  repeated int32 roles_sid = 8 [packed = true]; // This should have been defined as uint32 for consistency, but it is now too late to change it\n  repeated sint64 memids = 9 [packed = true]; // DELTA encoded\n  repeated MemberType types = 10 [packed = true];\n}\n"
  },
  {
    "path": "README.md",
    "content": "# osmpbf\n\n[![Build Status](https://github.com/qedus/osmpbf/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/qedus/osmpbf/actions/workflows/go.yml)\n[![Coverage Status](https://coveralls.io/repos/github/qedus/osmpbf/badge.svg?branch=master)](https://coveralls.io/github/qedus/osmpbf?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/qedus/osmpbf)](https://goreportcard.com/report/github.com/qedus/osmpbf)\n[![Go Reference](https://pkg.go.dev/badge/github.com/qedus/osmpbf.svg)](https://pkg.go.dev/github.com/qedus/osmpbf)\n\nPackage osmpbf is used to decode OpenStreetMap pbf files.\n\n## Installation\n\n```bash\n$ go get github.com/qedus/osmpbf\n```\n\n## Usage\n\nUsage is similar to `json.Decoder`.\n\n```Go\n\tf, err := os.Open(\"greater-london-140324.osm.pbf\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\td := osmpbf.NewDecoder(f)\n\n\t// use more memory from the start, it is faster\n\td.SetBufferSize(osmpbf.MaxBlobSize)\n\n\t// start decoding with several goroutines, it is faster\n\terr = d.Start(runtime.GOMAXPROCS(-1))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tvar nc, wc, rc uint64\n\tfor {\n\t\tif v, err := d.Decode(); err == io.EOF {\n\t\t\tbreak\n\t\t} else if err != nil {\n\t\t\tlog.Fatal(err)\n\t\t} else {\n\t\t\tswitch v := v.(type) {\n\t\t\tcase *osmpbf.Node:\n\t\t\t\t// Process Node v.\n\t\t\t\tnc++\n\t\t\tcase *osmpbf.Way:\n\t\t\t\t// Process Way v.\n\t\t\t\twc++\n\t\t\tcase *osmpbf.Relation:\n\t\t\t\t// Process Relation v.\n\t\t\t\trc++\n\t\t\tdefault:\n\t\t\t\tlog.Fatalf(\"unknown type %T\\n\", v)\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Printf(\"Nodes: %d, Ways: %d, Relations: %d\\n\", nc, wc, rc)\n```\n\n## Documentation\n\nhttps://pkg.go.dev/github.com/qedus/osmpbf\n\n## To Do\n\nThe parseNodes code has not been tested as I can only find PBF files with DenseNode format.\n\nAn Encoder still needs to be created to reverse the process.\n"
  },
  {
    "path": "decode.go",
    "content": "// Package osmpbf decodes OpenStreetMap (OSM) PBF files.\n// Use this package by creating a NewDecoder and passing it a PBF file.\n// Use Start to start decoding process.\n// Use Decode to return Node, Way and Relation structs.\npackage osmpbf // import \"github.com/qedus/osmpbf\"\n\nimport (\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/qedus/osmpbf/OSMPBF\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nconst (\n\tmaxBlobHeaderSize = 64 * 1024\n\n\tinitialBlobBufSize = 1 * 1024 * 1024\n\n\t// MaxBlobSize is maximum supported blob size.\n\tMaxBlobSize = 32 * 1024 * 1024\n)\n\nvar (\n\tparseCapabilities = map[string]bool{\n\t\t\"OsmSchema-V0.6\": true,\n\t\t\"DenseNodes\":     true,\n\t}\n)\n\ntype BoundingBox struct {\n\tLeft   float64\n\tRight  float64\n\tTop    float64\n\tBottom float64\n}\n\ntype Header struct {\n\tBoundingBox                      *BoundingBox\n\tRequiredFeatures                 []string\n\tOptionalFeatures                 []string\n\tWritingProgram                   string\n\tSource                           string\n\tOsmosisReplicationTimestamp      time.Time\n\tOsmosisReplicationSequenceNumber int64\n\tOsmosisReplicationBaseUrl        string\n}\n\ntype Info struct {\n\tVersion   int32\n\tUid       int32\n\tTimestamp time.Time\n\tChangeset int64\n\tUser      string\n\tVisible   bool\n}\n\ntype Node struct {\n\tID   int64\n\tLat  float64\n\tLon  float64\n\tTags map[string]string\n\tInfo Info\n}\n\ntype Way struct {\n\tID      int64\n\tTags    map[string]string\n\tNodeIDs []int64\n\tInfo    Info\n}\n\ntype Relation struct {\n\tID      int64\n\tTags    map[string]string\n\tMembers []Member\n\tInfo    Info\n}\n\ntype MemberType int\n\nconst (\n\tNodeType MemberType = iota\n\tWayType\n\tRelationType\n)\n\ntype Member struct {\n\tID   int64\n\tType MemberType\n\tRole string\n}\n\ntype pair struct {\n\ti interface{}\n\te error\n}\n\n// A Decoder reads and decodes OpenStreetMap PBF data from an input stream.\ntype Decoder struct {\n\tr          io.Reader\n\tserializer chan pair\n\n\tbuf *bytes.Buffer\n\n\t// store header block\n\theader *Header\n\t// synchronize header deserialization\n\theaderOnce sync.Once\n\n\t// for data decoders\n\tinputs  []chan<- pair\n\toutputs []<-chan pair\n}\n\n// NewDecoder returns a new decoder that reads from r.\nfunc NewDecoder(r io.Reader) *Decoder {\n\td := &Decoder{\n\t\tr:          r,\n\t\tserializer: make(chan pair, 8000), // typical PrimitiveBlock contains 8k OSM entities\n\t}\n\td.SetBufferSize(initialBlobBufSize)\n\treturn d\n}\n\n// SetBufferSize sets initial size of decoding buffer. Default value is 1MB, you can set higher value\n// (for example, MaxBlobSize) for (probably) faster decoding, or lower value for reduced memory consumption.\n// Any value will produce valid results; buffer will grow automatically if required.\nfunc (dec *Decoder) SetBufferSize(n int) {\n\tdec.buf = bytes.NewBuffer(make([]byte, 0, n))\n}\n\n// Header returns file header.\nfunc (dec *Decoder) Header() (*Header, error) {\n\t// deserialize the file header\n\treturn dec.header, dec.readOSMHeader()\n}\n\n// Start decoding process using n goroutines.\nfunc (dec *Decoder) Start(n int) error {\n\tif n < 1 {\n\t\tn = 1\n\t}\n\n\tif err := dec.readOSMHeader(); err != nil {\n\t\treturn err\n\t}\n\n\t// start data decoders\n\tfor i := 0; i < n; i++ {\n\t\tinput := make(chan pair)\n\t\toutput := make(chan pair)\n\t\tgo func() {\n\t\t\tdd := new(dataDecoder)\n\t\t\tfor p := range input {\n\t\t\t\tif p.e == nil {\n\t\t\t\t\t// send decoded objects or decoding error\n\t\t\t\t\tobjects, err := dd.Decode(p.i.(*OSMPBF.Blob))\n\t\t\t\t\toutput <- pair{objects, err}\n\t\t\t\t} else {\n\t\t\t\t\t// send input error as is\n\t\t\t\t\toutput <- pair{nil, p.e}\n\t\t\t\t}\n\t\t\t}\n\t\t\tclose(output)\n\t\t}()\n\n\t\tdec.inputs = append(dec.inputs, input)\n\t\tdec.outputs = append(dec.outputs, output)\n\t}\n\n\t// start reading OSMData\n\tgo func() {\n\t\tvar inputIndex int\n\t\tfor {\n\t\t\tinput := dec.inputs[inputIndex]\n\t\t\tinputIndex = (inputIndex + 1) % n\n\n\t\t\tblobHeader, blob, err := dec.readFileBlock()\n\t\t\tif err == nil && blobHeader.GetType() != \"OSMData\" {\n\t\t\t\terr = fmt.Errorf(\"unexpected fileblock of type %s\", blobHeader.GetType())\n\t\t\t}\n\t\t\tif err == nil {\n\t\t\t\t// send blob for decoding\n\t\t\t\tinput <- pair{blob, nil}\n\t\t\t} else {\n\t\t\t\t// send input error as is\n\t\t\t\tinput <- pair{nil, err}\n\t\t\t\tfor _, input := range dec.inputs {\n\t\t\t\t\tclose(input)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\tgo func() {\n\t\tvar outputIndex int\n\t\tfor {\n\t\t\toutput := dec.outputs[outputIndex]\n\t\t\toutputIndex = (outputIndex + 1) % n\n\n\t\t\tp := <-output\n\t\t\tif p.i != nil {\n\t\t\t\t// send decoded objects one by one\n\t\t\t\tfor _, o := range p.i.([]interface{}) {\n\t\t\t\t\tdec.serializer <- pair{o, nil}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif p.e != nil {\n\t\t\t\t// send input or decoding error\n\t\t\t\tdec.serializer <- pair{nil, p.e}\n\t\t\t\tclose(dec.serializer)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn nil\n}\n\n// Decode reads the next object from the input stream and returns either a\n// pointer to Node, Way or Relation struct representing the underlying OpenStreetMap PBF\n// data, or error encountered. The end of the input stream is reported by an io.EOF error.\n//\n// Decode is safe for parallel execution. Only first error encountered will be returned,\n// subsequent invocations will return io.EOF.\nfunc (dec *Decoder) Decode() (interface{}, error) {\n\tp, ok := <-dec.serializer\n\tif !ok {\n\t\treturn nil, io.EOF\n\t}\n\treturn p.i, p.e\n}\n\nfunc (dec *Decoder) readFileBlock() (*OSMPBF.BlobHeader, *OSMPBF.Blob, error) {\n\tblobHeaderSize, err := dec.readBlobHeaderSize()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tblobHeader, err := dec.readBlobHeader(blobHeaderSize)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tblob, err := dec.readBlob(blobHeader)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn blobHeader, blob, err\n}\n\nfunc (dec *Decoder) readBlobHeaderSize() (uint32, error) {\n\tdec.buf.Reset()\n\tif _, err := io.CopyN(dec.buf, dec.r, 4); err != nil {\n\t\treturn 0, err\n\t}\n\n\tsize := binary.BigEndian.Uint32(dec.buf.Bytes())\n\n\tif size >= maxBlobHeaderSize {\n\t\treturn 0, errors.New(\"BlobHeader size >= 64Kb\")\n\t}\n\treturn size, nil\n}\n\nfunc (dec *Decoder) readBlobHeader(size uint32) (*OSMPBF.BlobHeader, error) {\n\tdec.buf.Reset()\n\tif _, err := io.CopyN(dec.buf, dec.r, int64(size)); err != nil {\n\t\treturn nil, err\n\t}\n\n\tblobHeader := new(OSMPBF.BlobHeader)\n\tif err := proto.Unmarshal(dec.buf.Bytes(), blobHeader); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif blobHeader.GetDatasize() >= MaxBlobSize {\n\t\treturn nil, errors.New(\"Blob size >= 32Mb\")\n\t}\n\treturn blobHeader, nil\n}\n\nfunc (dec *Decoder) readBlob(blobHeader *OSMPBF.BlobHeader) (*OSMPBF.Blob, error) {\n\tdec.buf.Reset()\n\tif _, err := io.CopyN(dec.buf, dec.r, int64(blobHeader.GetDatasize())); err != nil {\n\t\treturn nil, err\n\t}\n\n\tblob := new(OSMPBF.Blob)\n\tif err := proto.Unmarshal(dec.buf.Bytes(), blob); err != nil {\n\t\treturn nil, err\n\t}\n\treturn blob, nil\n}\n\nfunc getData(blob *OSMPBF.Blob) ([]byte, error) {\n\tswitch blob.Data.(type) {\n\tcase *OSMPBF.Blob_Raw:\n\t\treturn blob.GetRaw(), nil\n\n\tcase *OSMPBF.Blob_ZlibData:\n\t\tr, err := zlib.NewReader(bytes.NewReader(blob.GetZlibData()))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbuf := bytes.NewBuffer(make([]byte, 0, blob.GetRawSize()+bytes.MinRead))\n\t\t_, err = buf.ReadFrom(r)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif buf.Len() != int(blob.GetRawSize()) {\n\t\t\terr = fmt.Errorf(\"raw blob data size %d but expected %d\", buf.Len(), blob.GetRawSize())\n\t\t\treturn nil, err\n\t\t}\n\t\treturn buf.Bytes(), nil\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unhandled blob data type %T\", blob.Data)\n\t}\n}\n\nfunc (dec *Decoder) readOSMHeader() error {\n\tvar err error\n\tdec.headerOnce.Do(func() {\n\t\tvar blobHeader *OSMPBF.BlobHeader\n\t\tvar blob *OSMPBF.Blob\n\t\tblobHeader, blob, err = dec.readFileBlock()\n\t\tif err == nil {\n\t\t\tif blobHeader.GetType() == \"OSMHeader\" {\n\t\t\t\terr = dec.decodeOSMHeader(blob)\n\t\t\t} else {\n\t\t\t\terr = fmt.Errorf(\"unexpected first fileblock of type %s\", blobHeader.GetType())\n\t\t\t}\n\t\t}\n\t})\n\n\treturn err\n}\n\nfunc (dec *Decoder) decodeOSMHeader(blob *OSMPBF.Blob) error {\n\tdata, err := getData(blob)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\theaderBlock := new(OSMPBF.HeaderBlock)\n\tif err := proto.Unmarshal(data, headerBlock); err != nil {\n\t\treturn err\n\t}\n\n\t// Check we have the parse capabilities\n\trequiredFeatures := headerBlock.GetRequiredFeatures()\n\tfor _, feature := range requiredFeatures {\n\t\tif !parseCapabilities[feature] {\n\t\t\treturn fmt.Errorf(\"parser does not have %s capability\", feature)\n\t\t}\n\t}\n\n\t// Read properties to header struct\n\theader := &Header{\n\t\tRequiredFeatures:                 headerBlock.GetRequiredFeatures(),\n\t\tOptionalFeatures:                 headerBlock.GetOptionalFeatures(),\n\t\tWritingProgram:                   headerBlock.GetWritingprogram(),\n\t\tSource:                           headerBlock.GetSource(),\n\t\tOsmosisReplicationBaseUrl:        headerBlock.GetOsmosisReplicationBaseUrl(),\n\t\tOsmosisReplicationSequenceNumber: headerBlock.GetOsmosisReplicationSequenceNumber(),\n\t}\n\n\t// convert timestamp epoch seconds to golang time structure if it exists\n\tif headerBlock.OsmosisReplicationTimestamp != nil {\n\t\theader.OsmosisReplicationTimestamp = time.Unix(*headerBlock.OsmosisReplicationTimestamp, 0)\n\t}\n\t// read bounding box if it exists\n\tif headerBlock.Bbox != nil {\n\t\t// Units are always in nanodegree and do not obey granularity rules. See osmformat.proto\n\t\theader.BoundingBox = &BoundingBox{\n\t\t\tLeft:   1e-9 * float64(*headerBlock.Bbox.Left),\n\t\t\tRight:  1e-9 * float64(*headerBlock.Bbox.Right),\n\t\t\tBottom: 1e-9 * float64(*headerBlock.Bbox.Bottom),\n\t\t\tTop:    1e-9 * float64(*headerBlock.Bbox.Top),\n\t\t}\n\t}\n\n\tdec.header = header\n\n\treturn nil\n}\n"
  },
  {
    "path": "decode_data.go",
    "content": "package osmpbf\n\nimport (\n\t\"time\"\n\n\t\"github.com/qedus/osmpbf/OSMPBF\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\n// Decoder for Blob with OSMData (PrimitiveBlock)\ntype dataDecoder struct {\n\tq []interface{}\n}\n\nfunc (dec *dataDecoder) Decode(blob *OSMPBF.Blob) ([]interface{}, error) {\n\tdec.q = make([]interface{}, 0, 8000) // typical PrimitiveBlock contains 8k OSM entities\n\n\tdata, err := getData(blob)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tprimitiveBlock := &OSMPBF.PrimitiveBlock{}\n\tif err := proto.Unmarshal(data, primitiveBlock); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdec.parsePrimitiveBlock(primitiveBlock)\n\treturn dec.q, nil\n}\n\nfunc (dec *dataDecoder) parsePrimitiveBlock(pb *OSMPBF.PrimitiveBlock) {\n\tfor _, pg := range pb.GetPrimitivegroup() {\n\t\tdec.parsePrimitiveGroup(pb, pg)\n\t}\n}\n\nfunc (dec *dataDecoder) parsePrimitiveGroup(pb *OSMPBF.PrimitiveBlock, pg *OSMPBF.PrimitiveGroup) {\n\tdec.parseNodes(pb, pg.GetNodes())\n\tdec.parseDenseNodes(pb, pg.GetDense())\n\tdec.parseWays(pb, pg.GetWays())\n\tdec.parseRelations(pb, pg.GetRelations())\n}\n\nfunc (dec *dataDecoder) parseNodes(pb *OSMPBF.PrimitiveBlock, nodes []*OSMPBF.Node) {\n\tst := pb.GetStringtable().GetS()\n\tgranularity := int64(pb.GetGranularity())\n\tdateGranularity := int64(pb.GetDateGranularity())\n\n\tlatOffset := pb.GetLatOffset()\n\tlonOffset := pb.GetLonOffset()\n\n\tfor _, node := range nodes {\n\t\tid := node.GetId()\n\t\tlat := node.GetLat()\n\t\tlon := node.GetLon()\n\n\t\tlatitude := 1e-9 * float64((latOffset + (granularity * lat)))\n\t\tlongitude := 1e-9 * float64((lonOffset + (granularity * lon)))\n\n\t\ttags := extractTags(st, node.GetKeys(), node.GetVals())\n\t\tinfo := extractInfo(st, node.GetInfo(), dateGranularity)\n\n\t\tdec.q = append(dec.q, &Node{id, latitude, longitude, tags, info})\n\t}\n\n}\n\nfunc (dec *dataDecoder) parseDenseNodes(pb *OSMPBF.PrimitiveBlock, dn *OSMPBF.DenseNodes) {\n\tst := pb.GetStringtable().GetS()\n\tgranularity := int64(pb.GetGranularity())\n\tlatOffset := pb.GetLatOffset()\n\tlonOffset := pb.GetLonOffset()\n\tdateGranularity := int64(pb.GetDateGranularity())\n\tids := dn.GetId()\n\tlats := dn.GetLat()\n\tlons := dn.GetLon()\n\tdi := dn.GetDenseinfo()\n\n\ttu := tagUnpacker{st, dn.GetKeysVals(), 0}\n\tvar id, lat, lon int64\n\tvar state denseInfoState\n\tfor index := range ids {\n\t\tid = ids[index] + id\n\t\tlat = lats[index] + lat\n\t\tlon = lons[index] + lon\n\t\tlatitude := 1e-9 * float64((latOffset + (granularity * lat)))\n\t\tlongitude := 1e-9 * float64((lonOffset + (granularity * lon)))\n\t\ttags := tu.next()\n\t\tinfo := extractDenseInfo(st, &state, di, index, dateGranularity)\n\n\t\tdec.q = append(dec.q, &Node{id, latitude, longitude, tags, info})\n\t}\n}\n\nfunc (dec *dataDecoder) parseWays(pb *OSMPBF.PrimitiveBlock, ways []*OSMPBF.Way) {\n\tst := pb.GetStringtable().GetS()\n\tdateGranularity := int64(pb.GetDateGranularity())\n\n\tfor _, way := range ways {\n\t\tid := way.GetId()\n\n\t\ttags := extractTags(st, way.GetKeys(), way.GetVals())\n\n\t\trefs := way.GetRefs()\n\t\tvar nodeID int64\n\t\tnodeIDs := make([]int64, len(refs))\n\t\tfor index := range refs {\n\t\t\tnodeID = refs[index] + nodeID // delta encoding\n\t\t\tnodeIDs[index] = nodeID\n\t\t}\n\n\t\tinfo := extractInfo(st, way.GetInfo(), dateGranularity)\n\n\t\tdec.q = append(dec.q, &Way{id, tags, nodeIDs, info})\n\t}\n}\n\n// Make relation members from stringtable and three parallel arrays of IDs.\nfunc extractMembers(stringTable []string, rel *OSMPBF.Relation) []Member {\n\tmemIDs := rel.GetMemids()\n\ttypes := rel.GetTypes()\n\troleIDs := rel.GetRolesSid()\n\n\tvar memID int64\n\tmembers := make([]Member, len(memIDs))\n\tfor index := range memIDs {\n\t\tmemID = memIDs[index] + memID // delta encoding\n\n\t\tvar memType MemberType\n\t\tswitch types[index] {\n\t\tcase OSMPBF.Relation_NODE:\n\t\t\tmemType = NodeType\n\t\tcase OSMPBF.Relation_WAY:\n\t\t\tmemType = WayType\n\t\tcase OSMPBF.Relation_RELATION:\n\t\t\tmemType = RelationType\n\t\t}\n\n\t\trole := stringTable[roleIDs[index]]\n\n\t\tmembers[index] = Member{memID, memType, role}\n\t}\n\n\treturn members\n}\n\nfunc (dec *dataDecoder) parseRelations(pb *OSMPBF.PrimitiveBlock, relations []*OSMPBF.Relation) {\n\tst := pb.GetStringtable().GetS()\n\tdateGranularity := int64(pb.GetDateGranularity())\n\n\tfor _, rel := range relations {\n\t\tid := rel.GetId()\n\t\ttags := extractTags(st, rel.GetKeys(), rel.GetVals())\n\t\tmembers := extractMembers(st, rel)\n\t\tinfo := extractInfo(st, rel.GetInfo(), dateGranularity)\n\n\t\tdec.q = append(dec.q, &Relation{id, tags, members, info})\n\t}\n}\n\nfunc extractInfo(stringTable []string, i *OSMPBF.Info, dateGranularity int64) Info {\n\tinfo := Info{Visible: true}\n\n\tif i != nil {\n\t\tinfo.Version = i.GetVersion()\n\n\t\tmillisec := time.Duration(i.GetTimestamp()*dateGranularity) * time.Millisecond\n\t\tinfo.Timestamp = time.Unix(0, millisec.Nanoseconds()).UTC()\n\n\t\tinfo.Changeset = i.GetChangeset()\n\n\t\tinfo.Uid = i.GetUid()\n\n\t\tinfo.User = stringTable[i.GetUserSid()]\n\n\t\tif i.Visible != nil {\n\t\t\tinfo.Visible = i.GetVisible()\n\t\t}\n\t}\n\n\treturn info\n}\n\ntype denseInfoState struct {\n\ttimestamp int64\n\tchangeset int64\n\tuid       int32\n\tuserSid   int32\n}\n\nfunc extractDenseInfo(stringTable []string, state *denseInfoState, di *OSMPBF.DenseInfo, index int, dateGranularity int64) Info {\n\tinfo := Info{Visible: true}\n\n\tversions := di.GetVersion()\n\tif len(versions) > 0 {\n\t\tinfo.Version = versions[index]\n\t}\n\n\ttimestamps := di.GetTimestamp()\n\tif len(timestamps) > 0 {\n\t\tstate.timestamp = timestamps[index] + state.timestamp\n\t\tmillisec := time.Duration(state.timestamp*dateGranularity) * time.Millisecond\n\t\tinfo.Timestamp = time.Unix(0, millisec.Nanoseconds()).UTC()\n\t}\n\n\tchangesets := di.GetChangeset()\n\tif len(changesets) > 0 {\n\t\tstate.changeset = changesets[index] + state.changeset\n\t\tinfo.Changeset = state.changeset\n\t}\n\n\tuids := di.GetUid()\n\tif len(uids) > 0 {\n\t\tstate.uid = uids[index] + state.uid\n\t\tinfo.Uid = state.uid\n\t}\n\n\tusersids := di.GetUserSid()\n\tif len(usersids) > 0 {\n\t\tstate.userSid = usersids[index] + state.userSid\n\t\tinfo.User = stringTable[state.userSid]\n\t}\n\n\tvisibleArray := di.GetVisible()\n\tif len(visibleArray) > 0 {\n\t\tinfo.Visible = visibleArray[index]\n\t}\n\n\treturn info\n}\n"
  },
  {
    "path": "decode_tag.go",
    "content": "package osmpbf\n\n// Make tags map from stringtable and two parallel arrays of IDs.\nfunc extractTags(stringTable []string, keyIDs, valueIDs []uint32) map[string]string {\n\ttags := make(map[string]string, len(keyIDs))\n\tfor index, keyID := range keyIDs {\n\t\tkey := stringTable[keyID]\n\t\tval := stringTable[valueIDs[index]]\n\t\ttags[key] = val\n\t}\n\treturn tags\n}\n\ntype tagUnpacker struct {\n\tstringTable []string\n\tkeysVals    []int32\n\tindex       int\n}\n\n// Make tags map from stringtable and array of IDs (used in DenseNodes encoding).\nfunc (tu *tagUnpacker) next() map[string]string {\n\ttags := make(map[string]string)\n\tfor tu.index < len(tu.keysVals) {\n\t\tkeyID := tu.keysVals[tu.index]\n\t\ttu.index++\n\t\tif keyID == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\tvalID := tu.keysVals[tu.index]\n\t\ttu.index++\n\n\t\tkey := tu.stringTable[keyID]\n\t\tval := tu.stringTable[valID]\n\t\ttags[key] = val\n\t}\n\treturn tags\n}\n"
  },
  {
    "path": "decode_test.go",
    "content": "package osmpbf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"time\"\n)\n\nconst (\n\t// Test files are stored at https://gist.github.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b\n\t// 8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d is the latest commit.\n\tGistURL = \"https://gist.githubusercontent.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b/raw/8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d/\"\n\n\t// Originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html\n\tLondon = \"greater-london-140324.osm.pbf\"\n\n\t// Same file as above, but without 'DenseNodes'. This has been generated using the below command (using osmium-tool http://osmcode.org/osmium-tool/)\n\t// \"osmium cat -o  greater-london-140324-nondense.osm.pbf greater-london-140324.osm.pbf -f osm.pbf,pbf_dense_nodes=false\"\n\tLondonNonDense = \"greater-london-140324-nondense.osm.pbf\"\n)\n\nfunc parseTime(s string) time.Time {\n\tt, err := time.Parse(time.RFC3339, s)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn t\n}\n\nvar (\n\tIDsExpectedOrder = []string{\n\t\t// Start of dense nodes.\n\t\t\"node/44\", \"node/47\", \"node/52\", \"node/58\", \"node/60\",\n\t\t\"node/79\", // Just because way/79 is already there\n\t\t\"node/2740703694\", \"node/2740703695\", \"node/2740703697\",\n\t\t\"node/2740703699\", \"node/2740703701\",\n\t\t// End of dense nodes.\n\n\t\t// Start of ways.\n\t\t\"way/73\", \"way/74\", \"way/75\", \"way/79\", \"way/482\",\n\t\t\"way/268745428\", \"way/268745431\", \"way/268745434\", \"way/268745436\",\n\t\t\"way/268745439\",\n\t\t// End of ways.\n\n\t\t// Start of relations.\n\t\t\"relation/69\", \"relation/94\", \"relation/152\", \"relation/245\",\n\t\t\"relation/332\", \"relation/3593436\", \"relation/3595575\",\n\t\t\"relation/3595798\", \"relation/3599126\", \"relation/3599127\",\n\t\t// End of relations\n\t}\n\n\tIDs map[string]bool\n\n\tenc uint64 = 2729006\n\tewc uint64 = 459055\n\terc uint64 = 12833\n\n\teh = &Header{\n\t\tBoundingBox: &BoundingBox{\n\t\t\tRight:  0.335437,\n\t\t\tLeft:   -0.511482,\n\t\t\tBottom: 51.28554,\n\t\t\tTop:    51.69344,\n\t\t},\n\t\tOsmosisReplicationTimestamp: time.Date(2014, 3, 24, 22, 55, 2, 0, time.FixedZone(\"test\", 3600)),\n\t\tRequiredFeatures: []string{\n\t\t\t\"OsmSchema-V0.6\",\n\t\t\t\"DenseNodes\",\n\t\t},\n\t\tWritingProgram: `Osmium (http:\\/\\/wiki.openstreetmap.org\\/wiki\\/Osmium)`,\n\t}\n\n\ten = &Node{\n\t\tID:  18088578,\n\t\tLat: 51.5442632,\n\t\tLon: -0.2010027,\n\t\tTags: map[string]string{\n\t\t\t\"alt_name\":   \"The King's Head\",\n\t\t\t\"amenity\":    \"pub\",\n\t\t\t\"created_by\": \"JOSM\",\n\t\t\t\"name\":       \"The Luminaire\",\n\t\t\t\"note\":       \"Live music venue too\",\n\t\t},\n\t\tInfo: Info{\n\t\t\tVersion:   2,\n\t\t\tTimestamp: parseTime(\"2009-05-20T10:28:54Z\"),\n\t\t\tChangeset: 1260468,\n\t\t\tUid:       508,\n\t\t\tUser:      \"Welshie\",\n\t\t\tVisible:   true,\n\t\t},\n\t}\n\n\tew = &Way{\n\t\tID: 4257116,\n\t\tNodeIDs: []int64{\n\t\t\t21544864, 333731851, 333731852, 333731850, 333731855,\n\t\t\t333731858, 333731854, 108047, 769984352, 21544864},\n\t\tTags: map[string]string{\n\t\t\t\"area\":    \"yes\",\n\t\t\t\"highway\": \"pedestrian\",\n\t\t\t\"name\":    \"Fitzroy Square\",\n\t\t},\n\t\tInfo: Info{\n\t\t\tVersion:   7,\n\t\t\tTimestamp: parseTime(\"2013-08-07T12:08:39Z\"),\n\t\t\tChangeset: 17253164,\n\t\t\tUid:       1016290,\n\t\t\tUser:      \"Amaroussi\",\n\t\t\tVisible:   true,\n\t\t},\n\t}\n\n\ter = &Relation{\n\t\tID: 7677,\n\t\tMembers: []Member{\n\t\t\t{ID: 4875932, Type: WayType, Role: \"outer\"},\n\t\t\t{ID: 4894305, Type: WayType, Role: \"inner\"},\n\t\t},\n\t\tTags: map[string]string{\n\t\t\t\"created_by\": \"Potlatch 0.9c\",\n\t\t\t\"type\":       \"multipolygon\",\n\t\t},\n\t\tInfo: Info{\n\t\t\tVersion:   4,\n\t\t\tTimestamp: parseTime(\"2008-07-19T15:04:03Z\"),\n\t\t\tChangeset: 540201,\n\t\t\tUid:       3876,\n\t\t\tUser:      \"Edgemaster\",\n\t\t\tVisible:   true,\n\t\t},\n\t}\n)\n\nfunc init() {\n\tIDs = make(map[string]bool)\n\tfor _, id := range IDsExpectedOrder {\n\t\tIDs[id] = false\n\t}\n}\n\nfunc downloadTestOSMFile(fileName string, t *testing.T) {\n\t_, err := os.Stat(fileName)\n\tif err == nil {\n\t\treturn\n\t}\n\tif !os.IsNotExist(err) {\n\t\tt.Fatal(err)\n\t}\n\n\tresp, err := http.Get(GistURL + fileName)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != 200 {\n\t\tt.Fatalf(\"expected 200, got %d\", resp.StatusCode)\n\t}\n\n\tout, err := os.Create(fileName)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer out.Close()\n\n\tif _, err = io.Copy(out, resp.Body); err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc checkHeader(a *Header) bool {\n\tif a == nil || a.BoundingBox == nil || a.RequiredFeatures == nil {\n\t\treturn false\n\t}\n\n\t// check bbox\n\tif a.BoundingBox.Right != eh.BoundingBox.Right || a.BoundingBox.Left != eh.BoundingBox.Left || a.BoundingBox.Top != eh.BoundingBox.Top || a.BoundingBox.Bottom != eh.BoundingBox.Bottom {\n\t\treturn false\n\t}\n\n\t// check timestamp\n\tif !a.OsmosisReplicationTimestamp.Equal(eh.OsmosisReplicationTimestamp) {\n\t\treturn false\n\t}\n\n\t// check writing program\n\tif a.WritingProgram != eh.WritingProgram {\n\t\treturn false\n\t}\n\n\t// check features\n\tif len(a.RequiredFeatures) != len(eh.RequiredFeatures) || a.RequiredFeatures[0] != eh.RequiredFeatures[0] || a.RequiredFeatures[1] != eh.RequiredFeatures[1] {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunc decodePBF(PBFfileName string, t *testing.T) {\n\tdownloadTestOSMFile(PBFfileName, t)\n\n\tf, err := os.Open(PBFfileName)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\td := NewDecoder(f)\n\td.SetBufferSize(1)\n\n\theader, err := d.Header()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif checkHeader(header) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", eh, header)\n\t}\n\n\terr = d.Start(runtime.GOMAXPROCS(-1))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tvar n *Node\n\tvar w *Way\n\tvar r *Relation\n\tvar nc, wc, rc uint64\n\tvar id string\n\tidsOrder := make([]string, 0, len(IDsExpectedOrder))\n\tfor {\n\t\tif v, err := d.Decode(); err == io.EOF {\n\t\t\tbreak\n\t\t} else if err != nil {\n\t\t\tt.Fatal(err)\n\t\t} else {\n\t\t\tswitch v := v.(type) {\n\t\t\tcase *Node:\n\t\t\t\tnc++\n\t\t\t\tif v.ID == en.ID {\n\t\t\t\t\tn = v\n\t\t\t\t}\n\t\t\t\tid = fmt.Sprintf(\"node/%d\", v.ID)\n\t\t\t\tif _, ok := IDs[id]; ok {\n\t\t\t\t\tidsOrder = append(idsOrder, id)\n\t\t\t\t}\n\t\t\tcase *Way:\n\t\t\t\twc++\n\t\t\t\tif v.ID == ew.ID {\n\t\t\t\t\tw = v\n\t\t\t\t}\n\t\t\t\tid = fmt.Sprintf(\"way/%d\", v.ID)\n\t\t\t\tif _, ok := IDs[id]; ok {\n\t\t\t\t\tidsOrder = append(idsOrder, id)\n\t\t\t\t}\n\t\t\tcase *Relation:\n\t\t\t\trc++\n\t\t\t\tif v.ID == er.ID {\n\t\t\t\t\tr = v\n\t\t\t\t}\n\t\t\t\tid = fmt.Sprintf(\"relation/%d\", v.ID)\n\t\t\t\tif _, ok := IDs[id]; ok {\n\t\t\t\t\tidsOrder = append(idsOrder, id)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tt.Fatalf(\"unknown type %T\", v)\n\t\t\t}\n\t\t}\n\t}\n\n\tif !reflect.DeepEqual(en, n) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", en, n)\n\t}\n\tif !reflect.DeepEqual(ew, w) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", ew, w)\n\t}\n\tif !reflect.DeepEqual(er, r) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", er, r)\n\t}\n\tif enc != nc || ewc != wc || erc != rc {\n\t\tt.Errorf(\"\\nExpected %7d nodes, %7d ways, %7d relations\\nGot %7d nodes, %7d ways, %7d relations.\",\n\t\t\tenc, ewc, erc, nc, wc, rc)\n\t}\n\tif !reflect.DeepEqual(IDsExpectedOrder, idsOrder) {\n\t\tt.Errorf(\"\\nExpected: %v\\nGot:      %v\", IDsExpectedOrder, idsOrder)\n\t}\n}\n\nfunc TestDecodePBFWithDenseNodes(t *testing.T) {\n\tdecodePBF(London, t)\n}\n\nfunc TestDecodePBFWithNodes(t *testing.T) {\n\tdecodePBF(LondonNonDense, t)\n}\n\nfunc TestDecodeConcurrent(t *testing.T) {\n\tdownloadTestOSMFile(London, t)\n\n\tf, err := os.Open(London)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\td := NewDecoder(f)\n\td.SetBufferSize(1)\n\terr = d.Start(runtime.GOMAXPROCS(-1))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\theader, err := d.Header()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif checkHeader(header) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", eh, header)\n\t}\n\n\tvar n *Node\n\tvar w *Way\n\tvar r *Relation\n\tvar nc, wc, rc uint64\n\tvar wg sync.WaitGroup\n\tfor i := 0; i < 4; i++ {\n\t\twg.Add(1)\n\n\t\tgo func() {\n\t\t\tdefer wg.Done()\n\n\t\t\tfor {\n\t\t\t\tif v, err := d.Decode(); err == io.EOF {\n\t\t\t\t\treturn\n\t\t\t\t} else if err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tswitch v := v.(type) {\n\t\t\t\t\tcase *Node:\n\t\t\t\t\t\tatomic.AddUint64(&nc, 1)\n\t\t\t\t\t\tif v.ID == en.ID {\n\t\t\t\t\t\t\tn = v\n\t\t\t\t\t\t}\n\t\t\t\t\tcase *Way:\n\t\t\t\t\t\tatomic.AddUint64(&wc, 1)\n\t\t\t\t\t\tif v.ID == ew.ID {\n\t\t\t\t\t\t\tw = v\n\t\t\t\t\t\t}\n\t\t\t\t\tcase *Relation:\n\t\t\t\t\t\tatomic.AddUint64(&rc, 1)\n\t\t\t\t\t\tif v.ID == er.ID {\n\t\t\t\t\t\t\tr = v\n\t\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tt.Errorf(\"unknown type %T\", v)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}()\n\t}\n\twg.Wait()\n\n\tif !reflect.DeepEqual(en, n) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", en, n)\n\t}\n\tif !reflect.DeepEqual(ew, w) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", ew, w)\n\t}\n\tif !reflect.DeepEqual(er, r) {\n\t\tt.Errorf(\"\\nExpected: %#v\\nActual:   %#v\", er, r)\n\t}\n\tif enc != nc || ewc != wc || erc != rc {\n\t\tt.Errorf(\"\\nExpected %7d nodes, %7d ways, %7d relations\\nGot %7d nodes, %7d ways, %7d relations\",\n\t\t\tenc, ewc, erc, nc, wc, rc)\n\t}\n}\n\nfunc BenchmarkDecode(b *testing.B) {\n\tfile := os.Getenv(\"OSMPBF_BENCHMARK_FILE\")\n\tif file == \"\" {\n\t\tfile = London\n\t}\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\tdefer f.Close()\n\tfileInfo, err := f.Stat()\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\n\tblobBufferSize, _ := strconv.Atoi(os.Getenv(\"OSMPBF_BENCHMARK_BUFFER\"))\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tif _, err = f.Seek(0, 0); err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\n\t\td := NewDecoder(f)\n\t\tif blobBufferSize > 0 {\n\t\t\td.SetBufferSize(blobBufferSize)\n\t\t}\n\t\terr = d.Start(runtime.GOMAXPROCS(-1))\n\t\tif err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\n\t\tvar nc, wc, rc uint64\n\t\tstart := time.Now()\n\t\tfor {\n\t\t\tif v, err := d.Decode(); err == io.EOF {\n\t\t\t\tbreak\n\t\t\t} else if err != nil {\n\t\t\t\tb.Fatal(err)\n\t\t\t} else {\n\t\t\t\tswitch v := v.(type) {\n\t\t\t\tcase *Node:\n\t\t\t\t\tnc++\n\t\t\t\tcase *Way:\n\t\t\t\t\twc++\n\t\t\t\tcase *Relation:\n\t\t\t\t\trc++\n\t\t\t\tdefault:\n\t\t\t\t\tb.Fatalf(\"unknown type %T\", v)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tb.Logf(\"Done in %.3f seconds. Nodes: %d, Ways: %d, Relations: %d\\n\",\n\t\t\ttime.Since(start).Seconds(), nc, wc, rc)\n\t\tb.SetBytes(fileInfo.Size())\n\t}\n}\n\nfunc BenchmarkDecodeConcurrent(b *testing.B) {\n\tfile := os.Getenv(\"OSMPBF_BENCHMARK_FILE\")\n\tif file == \"\" {\n\t\tfile = London\n\t}\n\tf, err := os.Open(file)\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\tdefer f.Close()\n\tfileInfo, err := f.Stat()\n\tif err != nil {\n\t\tb.Fatal(err)\n\t}\n\n\tblobBufferSize, _ := strconv.Atoi(os.Getenv(\"OSMPBF_BENCHMARK_BUFFER\"))\n\n\tb.ResetTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tif _, err = f.Seek(0, 0); err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\n\t\td := NewDecoder(f)\n\t\tif blobBufferSize > 0 {\n\t\t\td.SetBufferSize(blobBufferSize)\n\t\t}\n\t\terr = d.Start(runtime.GOMAXPROCS(-1))\n\t\tif err != nil {\n\t\t\tb.Fatal(err)\n\t\t}\n\n\t\tvar nc, wc, rc uint64\n\t\tstart := time.Now()\n\t\tvar wg sync.WaitGroup\n\t\tfor i := 0; i < 4; i++ {\n\t\t\twg.Add(1)\n\n\t\t\tgo func() {\n\t\t\t\tdefer wg.Done()\n\n\t\t\t\tfor {\n\t\t\t\t\tif v, err := d.Decode(); err == io.EOF {\n\t\t\t\t\t\treturn\n\t\t\t\t\t} else if err != nil {\n\t\t\t\t\t\tb.Error(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t} else {\n\t\t\t\t\t\tswitch v := v.(type) {\n\t\t\t\t\t\tcase *Node:\n\t\t\t\t\t\t\tatomic.AddUint64(&nc, 1)\n\t\t\t\t\t\tcase *Way:\n\t\t\t\t\t\t\tatomic.AddUint64(&wc, 1)\n\t\t\t\t\t\tcase *Relation:\n\t\t\t\t\t\t\tatomic.AddUint64(&rc, 1)\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tb.Errorf(\"unknown type %T\", v)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\t\t}\n\t\twg.Wait()\n\n\t\tb.Logf(\"Done in %.3f seconds. Nodes: %d, Ways: %d, Relations: %d\\n\",\n\t\t\ttime.Since(start).Seconds(), nc, wc, rc)\n\t\tb.SetBytes(fileInfo.Size())\n\t}\n}\n"
  },
  {
    "path": "example_test.go",
    "content": "package osmpbf_test\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"runtime\"\n\n\t\"github.com/qedus/osmpbf\"\n)\n\n// Don't forget to sync with README.md\n\nfunc Example() {\n\tf, err := os.Open(\"greater-london-140324.osm.pbf\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer f.Close()\n\n\td := osmpbf.NewDecoder(f)\n\n\t// use more memory from the start, it is faster\n\td.SetBufferSize(osmpbf.MaxBlobSize)\n\n\t// start decoding with several goroutines, it is faster\n\terr = d.Start(runtime.GOMAXPROCS(-1))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tvar nc, wc, rc uint64\n\tfor {\n\t\tif v, err := d.Decode(); err == io.EOF {\n\t\t\tbreak\n\t\t} else if err != nil {\n\t\t\tlog.Fatal(err)\n\t\t} else {\n\t\t\tswitch v := v.(type) {\n\t\t\tcase *osmpbf.Node:\n\t\t\t\t// Process Node v.\n\t\t\t\tnc++\n\t\t\tcase *osmpbf.Way:\n\t\t\t\t// Process Way v.\n\t\t\t\twc++\n\t\t\tcase *osmpbf.Relation:\n\t\t\t\t// Process Relation v.\n\t\t\t\trc++\n\t\t\tdefault:\n\t\t\t\tlog.Fatalf(\"unknown type %T\\n\", v)\n\t\t\t}\n\t\t}\n\t}\n\n\tfmt.Printf(\"Nodes: %d, Ways: %d, Relations: %d\\n\", nc, wc, rc)\n\t// Output:\n\t// Nodes: 2729006, Ways: 459055, Relations: 12833\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/qedus/osmpbf\n\ngo 1.16\n\nrequire google.golang.org/protobuf v1.27.1 // sync version with OSMPBF/Makefile\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\n"
  }
]