diff --git a/.github/staging_fake.yml b/.github/staging_fake.yml new file mode 100644 index 0000000000..e1a9e7072e --- /dev/null +++ b/.github/staging_fake.yml @@ -0,0 +1,30 @@ +networkId: N9DU6hLkTAbvcpji3TCKPPd3UQWKGyzUxGmgJEyvhByqAjfD +nodes: + - peerId: FAKE_PEER_ID1 + addresses: + - lol1-any-sync-node1.somefakesite.com:6666 + - lol1-any-sync-node1.somefakesite.com:6667 + - quic://lol1.somefakesite.com:8888 + types: + - tree + - peerId: FAKE_PEER_ID2 + addresses: + - lol1-file13.somefakesite.com:6666 + - lol1-file13.somefakesite.com:6667 + - quic://lol1-file13.somefakesite.com:8888 + types: + - file + - peerId: FAKE_PEER_ID3 + addresses: + - lol1-coord1.somefakesite.com:6666 + - lol1-coord1.somefakesite.com:6667 + - quic://lol1-coord1.somefakesite.com:8888 + types: + - coordinator + - peerId: FAKE_PEER_ID4 + addresses: + - lol1-cons1.somefakesite.com:6666 + - lol1-cons1.somefakesite.com:6667 + - quic://lol1-cons1.somefakesite.com:8888 + types: + - consensus diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b46813da78..d75b3af69f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: - name: Install Go uses: actions/setup-go@v1 with: - go-version: 1.22 + go-version: 1.22.8 if: github.event.inputs.run-on-runner != 'ARM64' && github.event_name != 'schedule' - name: Setup GO run: | @@ -109,7 +109,6 @@ jobs: which gomobile - name: Cross-compile library mac/win/linux run: | - make download-tantivy-all echo $FLAGS mkdir -p .release echo $SDKROOT @@ -123,7 +122,6 @@ jobs: - name: run perf tests run: | echo "Running perf tests" - make download-tantivy-all RUN_COUNT=${{ github.event.inputs.perf-test }} if [[ "${{ github.event_name }}" == "schedule" ]]; then RUN_COUNT=10 diff --git a/.github/workflows/perftests.yml b/.github/workflows/perftests.yml index 69bba967e8..19dd951628 100644 --- a/.github/workflows/perftests.yml +++ b/.github/workflows/perftests.yml @@ -1,3 +1,4 @@ +#https://linear.app/anytype/issue/GO-3985/make-performance-report-on-the-stand on: workflow_dispatch: inputs: @@ -8,13 +9,13 @@ on: perf-test: description: 'Run perf test times' required: true - default: '0' + default: '10' schedule: - - cron: '0 0 * * *' # every day at midnight + - cron: '0 1 * * *' # every day at 1am filters: branches: include: - - 'feature/chat' + - 'main' permissions: @@ -22,9 +23,10 @@ permissions: contents: 'write' -name: Build +name: Perf tests jobs: build: + timeout-minutes: 60 runs-on: 'ARM64' steps: - name: Setup GO @@ -35,13 +37,6 @@ jobs: echo $(go env GOPATH)/bin >> $GITHUB_PATH - name: Checkout uses: actions/checkout@v3 - - uses: actions/cache@v3 - with: - path: | - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go-${{ matrix.go-version }}- - name: Set env vars env: UNSPLASH_KEY: ${{ secrets.UNSPLASH_KEY }} @@ -78,24 +73,30 @@ jobs: - name: run perf tests run: | echo "Running perf tests" - make download-tantivy-all RUN_COUNT=${{ github.event.inputs.perf-test }} if [[ "${{ github.event_name }}" == "schedule" ]]; then RUN_COUNT=100 fi + echo $PERF_CONFIG_STAGING > config.json + mv .github/staging_fake.yml staging_fake.yml + PERF_CONFIG=$PWD/config.json + cd cmd/perfstand/account_create + CGO_ENABLED="1" go run main.go $PERF_CONFIG $RUN_COUNT + cd ../account_select + CGO_ENABLED="1" go run main.go $PERF_CONFIG $RUN_COUNT + cd ../../.. + echo $PERF_CONFIG_LOCAL > ./config.json cd cmd/perfstand/account_create - CGO_ENABLED="1" go run main.go $RUN_COUNT + CGO_ENABLED="1" go run main.go $PERF_CONFIG $RUN_COUNT cd ../account_select - CGO_ENABLED="1" go run main.go $RUN_COUNT + CGO_ENABLED="1" go run main.go $PERF_CONFIG $RUN_COUNT env: - TEST_MNEMONIC: ${{ secrets.TEST_MNEMONIC_30000 }} - CH_API_KEY: ${{ secrets.CH_API_KEY }} - ACCOUNT_HASH: ${{ secrets.ACCOUNT_HASH_30000 }} - ACCOUNT_SPACE: ${{ secrets.ACCOUNT_SPACE_30000 }} - ROOT_FOLDER: ${{ secrets.ROOT_FOLDER }} + PERF_CONFIG_STAGING: ${{ secrets.PERF_CONFIG_STAGING }} + PERF_CONFIG_LOCAL: ${{ secrets.PERF_CONFIG_LOCAL }} + CH_API_KEY: ${{ secrets.CH_PERF_API_KEY }} - name: Archive perf tests results uses: actions/upload-artifact@v4 with: - name: pprofs + name: traces path: | - *.pprof \ No newline at end of file + *.log \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dec49e1ac5..693f490f9c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: - main pull_request: branches: - - '*' + - '**' concurrency: group: ${{ github.workflow }}-${{ github.ref || github.run_id }} diff --git a/.mockery.yaml b/.mockery.yaml index dbc4a0124d..d406386133 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -37,19 +37,12 @@ packages: dir: "{{.InterfaceDir}}" outpkg: "{{.PackageName}}" inpackage: true + github.com/anyproto/anytype-heart/core/block/editor/lastused: + interfaces: + ObjectUsageUpdater: github.com/anyproto/anytype-heart/core/block/import/common: interfaces: Converter: - github.com/anyproto/anytype-heart/pkg/lib/database: - interfaces: - ObjectStore: - config: - dir: "{{.InterfaceDir}}" - outpkg: "{{.PackageName}}" - inpackage: true - github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore: - interfaces: - ObjectStore: github.com/anyproto/anytype-heart/core/block/restriction: interfaces: Service: @@ -102,6 +95,7 @@ packages: interfaces: TechSpace: SpaceView: + AccountObject: github.com/anyproto/anytype-heart/space/spacefactory: interfaces: SpaceFactory: @@ -112,6 +106,9 @@ packages: github.com/anyproto/anytype-heart/space/internal/components/spaceloader: interfaces: SpaceLoader: + github.com/anyproto/anytype-heart/space/internal/components/personalmigration: + interfaces: + fileObjectGetter: github.com/anyproto/anytype-heart/space/internal/components/participantwatcher: interfaces: ParticipantWatcher: @@ -132,6 +129,8 @@ packages: github.com/anyproto/anytype-heart/space: interfaces: Service: + coordinatorStatusUpdater: + NotificationSender: github.com/anyproto/anytype-heart/space/clientspace: interfaces: Space: @@ -165,6 +164,7 @@ packages: github.com/anyproto/anytype-heart/core/block/source: interfaces: Service: + Store: github.com/anyproto/anytype-heart/core/block/object/idresolver: interfaces: Resolver: @@ -218,4 +218,7 @@ packages: Downloader: github.com/anyproto/anytype-heart/core/block/detailservice: interfaces: - Service: \ No newline at end of file + Service: + github.com/anyproto/anytype-heart/core/kanban: + interfaces: + Service: diff --git a/.run/Run.run.xml b/.run/Run.run.xml index bb5187a59a..0595d2c209 100644 --- a/.run/Run.run.xml +++ b/.run/Run.run.xml @@ -2,14 +2,26 @@ - + + + + + diff --git a/Makefile b/Makefile index 386c670c02..e1b6c69061 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ CLIENT_ANDROID_PATH ?= ../anytype-kotlin CLIENT_IOS_PATH ?= ../anytype-swift TANTIVY_GO_PATH ?= ../tantivy-go BUILD_FLAGS ?= +TANTIVY_VERSION := $(shell cat go.mod | grep github.com/anyproto/tantivy-go | cut -d' ' -f2) export GOLANGCI_LINT_VERSION=1.58.1 export CGO_CFLAGS=-Wno-deprecated-non-prototype -Wno-unknown-warning-option -Wno-deprecated-declarations -Wno-xor-used-as-pow -Wno-single-bit-bitfield-constant-conversion @@ -46,7 +47,7 @@ endif cp $$ANY_SYNC_NETWORK $(CUSTOM_NETWORK_FILE); \ fi -setup-go: setup-network-config +setup-go: setup-network-config check-tantivy-version @echo 'Setting up go modules...' @go mod download @go install github.com/ahmetb/govvv@v0.2.0 @@ -280,10 +281,10 @@ protos-java: @echo 'Generating protobuf packages (Java)...' @protoc -I ./ --java_out=./dist/android/pb pb/protos/*.proto pkg/lib/pb/model/protos/*.proto -build-server: setup-network-config +build-server: setup-network-config check-tantivy-version @echo 'Building anytype-heart server...' @$(eval FLAGS += $$(shell govvv -flags -pkg github.com/anyproto/anytype-heart/util/vcs)) - @$(eval TAGS := nosigar nowatchdog) + @$(eval TAGS := $(TAGS) nosigar nowatchdog) ifdef ANY_SYNC_NETWORK @$(eval TAGS := $(TAGS) envnetworkcustom) endif @@ -339,7 +340,6 @@ endif ### Tantivy Section REPO := anyproto/tantivy-go -VERSION := v0.1.0 OUTPUT_DIR := deps/libs SHA_FILE = tantivity_sha256.txt @@ -356,7 +356,7 @@ TANTIVY_LIBS := android-386.tar.gz \ windows-amd64.tar.gz define download_tantivy_lib - curl -L -o $(OUTPUT_DIR)/$(1) https://github.com/$(REPO)/releases/download/$(VERSION)/$(1) + curl -L -o $(OUTPUT_DIR)/$(1) https://github.com/$(REPO)/releases/download/$(TANTIVY_VERSION)/$(1) endef define remove_arch @@ -366,6 +366,9 @@ endef remove-libs: @rm -rf deps/libs/* +write-tantivy-version: + @echo "$(TANTIVY_VERSION)" > $(OUTPUT_DIR)/.verified + download-tantivy: remove-libs $(TANTIVY_LIBS) $(TANTIVY_LIBS): @@ -381,13 +384,21 @@ download-tantivy-all-force: download-tantivy done @rm -rf deps/libs/*.tar.gz @echo "SHA256 checksums generated." + $(MAKE) write-tantivy-version download-tantivy-all: download-tantivy @echo "Validating SHA256 checksums..." - @shasum -a 256 -c $(SHA_FILE) --status || { echo "Hash mismatch detected."; exit 1; } + @shasum -a 256 -c $(SHA_FILE) --status || { echo "Hash mismatch detected. Call make download-tantivy-all-force"; exit 1; } @echo "All files are valid." @rm -rf deps/libs/*.tar.gz + $(MAKE) write-tantivy-version download-tantivy-local: remove-libs @mkdir -p $(OUTPUT_DIR) @cp -r $(TANTIVY_GO_PATH)/libs/* $(OUTPUT_DIR) + +check-tantivy-version: + $(eval OLD_VERSION := $(shell [ -f $(OUTPUT_DIR)/.verified ] && cat $(OUTPUT_DIR)/.verified || echo "")) + @if [ "$(TANTIVY_VERSION)" != "$(OLD_VERSION)" ]; then \ + $(MAKE) download-tantivy-all; \ + fi \ No newline at end of file diff --git a/clientlibrary/service/service.pb.go b/clientlibrary/service/service.pb.go index b11f187b6a..431b00fc9d 100644 --- a/clientlibrary/service/service.pb.go +++ b/clientlibrary/service/service.pb.go @@ -25,326 +25,330 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) } var fileDescriptor_93a29dc403579097 = []byte{ - // 5097 bytes of a gzipped FileDescriptorProto + // 5164 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0x5b, 0x6f, 0x24, 0x49, - 0x56, 0xf8, 0xa7, 0x5e, 0xfe, 0xf3, 0x27, 0x97, 0x1d, 0xa0, 0x06, 0x86, 0xd9, 0x61, 0xb7, 0xef, - 0xdd, 0xee, 0x6e, 0xdb, 0xe5, 0x9e, 0xee, 0xb9, 0xac, 0x76, 0x91, 0x90, 0xdb, 0x6e, 0x7b, 0xcc, - 0xda, 0x6e, 0xe3, 0x2a, 0x77, 0x4b, 0x23, 0x21, 0x11, 0xce, 0x3a, 0x2e, 0x27, 0xce, 0xca, 0xc8, - 0xcd, 0x8c, 0x2a, 0x77, 0x2d, 0x02, 0x81, 0x40, 0x20, 0x10, 0x88, 0x15, 0xb7, 0x57, 0x24, 0x3e, - 0x0d, 0x8f, 0xfb, 0xc8, 0xe3, 0x6a, 0xe6, 0x4b, 0xf0, 0x88, 0x32, 0x32, 0x32, 0x2e, 0x27, 0xe3, - 0x44, 0xa6, 0xf7, 0xa9, 0x5b, 0x75, 0x7e, 0xe7, 0x9c, 0x88, 0x8c, 0x13, 0x11, 0x27, 0x2e, 0x99, - 0x8e, 0x6e, 0xe7, 0xe7, 0x5b, 0x79, 0xc1, 0x05, 0x2f, 0xb7, 0x4a, 0x28, 0x96, 0x49, 0x0c, 0xcd, - 0xbf, 0x23, 0xf9, 0xf3, 0xf0, 0x7d, 0x96, 0xad, 0xc4, 0x2a, 0x87, 0x4f, 0x3e, 0x36, 0x64, 0xcc, - 0xe7, 0x73, 0x96, 0x4d, 0xcb, 0x1a, 0xf9, 0xe4, 0x23, 0x23, 0x81, 0x25, 0x64, 0x42, 0xfd, 0xfe, - 0xfc, 0x7f, 0x7f, 0x39, 0x88, 0x3e, 0xd8, 0x49, 0x13, 0xc8, 0xc4, 0x8e, 0xd2, 0x18, 0x7e, 0x1d, - 0x7d, 0x77, 0x3b, 0xcf, 0xf7, 0x41, 0xbc, 0x81, 0xa2, 0x4c, 0x78, 0x36, 0xbc, 0x3f, 0x52, 0x0e, - 0x46, 0xa7, 0x79, 0x3c, 0xda, 0xce, 0xf3, 0x91, 0x11, 0x8e, 0x4e, 0xe1, 0xa7, 0x0b, 0x28, 0xc5, - 0x27, 0x0f, 0xc2, 0x50, 0x99, 0xf3, 0xac, 0x84, 0xe1, 0x45, 0xf4, 0x5b, 0xdb, 0x79, 0x3e, 0x06, - 0xb1, 0x0b, 0x55, 0x05, 0xc6, 0x82, 0x09, 0x18, 0xae, 0xb5, 0x54, 0x5d, 0x40, 0xfb, 0x78, 0xdc, - 0x0d, 0x2a, 0x3f, 0x93, 0xe8, 0x3b, 0x95, 0x9f, 0xcb, 0x85, 0x98, 0xf2, 0xeb, 0x6c, 0x78, 0xb7, - 0xad, 0xa8, 0x44, 0xda, 0xf6, 0xbd, 0x10, 0xa2, 0xac, 0xbe, 0x8d, 0x7e, 0xfd, 0x2d, 0x4b, 0x53, - 0x10, 0x3b, 0x05, 0x54, 0x05, 0x77, 0x75, 0x6a, 0xd1, 0xa8, 0x96, 0x69, 0xbb, 0xf7, 0x83, 0x8c, - 0x32, 0xfc, 0x75, 0xf4, 0xdd, 0x5a, 0x72, 0x0a, 0x31, 0x5f, 0x42, 0x31, 0xf4, 0x6a, 0x29, 0x21, - 0xf1, 0xc8, 0x5b, 0x10, 0xb6, 0xbd, 0xc3, 0xb3, 0x25, 0x14, 0xc2, 0x6f, 0x5b, 0x09, 0xc3, 0xb6, - 0x0d, 0xa4, 0x6c, 0xff, 0xfd, 0x20, 0xfa, 0xfe, 0x76, 0x1c, 0xf3, 0x45, 0x26, 0x0e, 0x79, 0xcc, - 0xd2, 0xc3, 0x24, 0xbb, 0x3a, 0x86, 0xeb, 0x9d, 0xcb, 0x8a, 0xcf, 0x66, 0x30, 0x7c, 0xe1, 0x3e, - 0xd5, 0x1a, 0x1d, 0x69, 0x76, 0x64, 0xc3, 0xda, 0xf7, 0x67, 0x37, 0x53, 0x52, 0x65, 0xf9, 0xe7, - 0x41, 0x74, 0x0b, 0x97, 0x65, 0xcc, 0xd3, 0x25, 0x98, 0xd2, 0x7c, 0xde, 0x61, 0xd8, 0xc5, 0x75, - 0x79, 0xbe, 0xb8, 0xa9, 0x9a, 0x2a, 0x51, 0x1a, 0x7d, 0x68, 0x87, 0xcb, 0x18, 0x4a, 0xd9, 0x9d, - 0x9e, 0xd0, 0x11, 0xa1, 0x10, 0xed, 0xf9, 0x69, 0x1f, 0x54, 0x79, 0x4b, 0xa2, 0xa1, 0xf2, 0x96, - 0xf2, 0x52, 0x3b, 0x7b, 0xec, 0xb5, 0x60, 0x11, 0xda, 0xd7, 0x93, 0x1e, 0xa4, 0x72, 0xf5, 0x27, - 0xd1, 0x6f, 0xbc, 0xe5, 0xc5, 0x55, 0x99, 0xb3, 0x18, 0x54, 0x57, 0x78, 0xe8, 0x6a, 0x37, 0x52, - 0xdc, 0x1b, 0x1e, 0x75, 0x61, 0x56, 0xd0, 0x36, 0xc2, 0xd7, 0x39, 0xe0, 0x31, 0xc8, 0x28, 0x56, - 0x42, 0x2a, 0x68, 0x31, 0xa4, 0x6c, 0x5f, 0x45, 0x43, 0x63, 0xfb, 0xfc, 0x4f, 0x21, 0x16, 0xdb, - 0xd3, 0x29, 0x6e, 0x15, 0xa3, 0x2b, 0x89, 0xd1, 0xf6, 0x74, 0x4a, 0xb5, 0x8a, 0x1f, 0x55, 0xce, - 0xae, 0xa3, 0x8f, 0x90, 0xb3, 0xc3, 0xa4, 0x94, 0x0e, 0x37, 0xc3, 0x56, 0x14, 0xa6, 0x9d, 0x8e, - 0xfa, 0xe2, 0xca, 0xf1, 0x5f, 0x0e, 0xa2, 0xef, 0x79, 0x3c, 0x9f, 0xc2, 0x9c, 0x2f, 0x61, 0xf8, - 0xac, 0xdb, 0x5a, 0x4d, 0x6a, 0xff, 0x9f, 0xde, 0x40, 0xc3, 0x13, 0x26, 0x63, 0x48, 0x21, 0x16, - 0x64, 0x98, 0xd4, 0xe2, 0xce, 0x30, 0xd1, 0x98, 0xd5, 0xc3, 0x1a, 0xe1, 0x3e, 0x88, 0x9d, 0x45, - 0x51, 0x40, 0x26, 0xc8, 0xb6, 0x34, 0x48, 0x67, 0x5b, 0x3a, 0xa8, 0xa7, 0x3e, 0xfb, 0x20, 0xb6, - 0xd3, 0x94, 0xac, 0x4f, 0x2d, 0xee, 0xac, 0x8f, 0xc6, 0x94, 0x87, 0x38, 0xfa, 0x4d, 0xeb, 0x89, - 0x89, 0x83, 0xec, 0x82, 0x0f, 0xe9, 0x67, 0x21, 0xe5, 0xda, 0xc7, 0x5a, 0x27, 0xe7, 0xa9, 0xc6, - 0xab, 0x77, 0x39, 0x2f, 0xe8, 0x66, 0xa9, 0xc5, 0x9d, 0xd5, 0xd0, 0x98, 0xf2, 0xf0, 0xc7, 0xd1, - 0x07, 0x6a, 0x94, 0x6c, 0xe6, 0xb3, 0x07, 0xde, 0x21, 0x14, 0x4f, 0x68, 0x0f, 0x3b, 0x28, 0x33, - 0x38, 0x28, 0x99, 0x1a, 0x7c, 0xee, 0x7b, 0xf5, 0xd0, 0xd0, 0xf3, 0x20, 0x0c, 0xb5, 0x6c, 0xef, - 0x42, 0x0a, 0xa4, 0xed, 0x5a, 0xd8, 0x61, 0x5b, 0x43, 0xca, 0x76, 0x11, 0xfd, 0x8e, 0x7e, 0x2c, - 0xd5, 0x3c, 0x2a, 0xe5, 0xd5, 0x20, 0xbd, 0x4e, 0xd4, 0xdb, 0x86, 0xb4, 0xaf, 0x8d, 0x7e, 0x70, - 0xab, 0x3e, 0xaa, 0x07, 0xfa, 0xeb, 0x83, 0xfa, 0xdf, 0x83, 0x30, 0xa4, 0x6c, 0xff, 0xc3, 0x20, - 0xfa, 0x81, 0x92, 0xbd, 0xca, 0xd8, 0x79, 0x0a, 0x72, 0x4a, 0x3c, 0x06, 0x71, 0xcd, 0x8b, 0xab, - 0xf1, 0x2a, 0x8b, 0x89, 0xe9, 0xdf, 0x0f, 0x77, 0x4c, 0xff, 0xa4, 0x92, 0x95, 0xf1, 0xa9, 0x8a, - 0x0a, 0x9e, 0xe3, 0x8c, 0xaf, 0xa9, 0x81, 0xe0, 0x39, 0x95, 0xf1, 0xb9, 0x48, 0xcb, 0xea, 0x51, - 0x35, 0x6c, 0xfa, 0xad, 0x1e, 0xd9, 0xe3, 0xe4, 0xbd, 0x10, 0x62, 0x86, 0xad, 0x26, 0x80, 0x79, - 0x76, 0x91, 0xcc, 0xce, 0xf2, 0x69, 0x15, 0xc6, 0x4f, 0xfc, 0x11, 0x6a, 0x21, 0xc4, 0xb0, 0x45, - 0xa0, 0xca, 0xdb, 0x3f, 0x99, 0xc4, 0x48, 0x75, 0xa5, 0xbd, 0x82, 0xcf, 0x0f, 0x61, 0xc6, 0xe2, - 0x95, 0xea, 0xff, 0x9f, 0x85, 0x3a, 0x1e, 0xa6, 0x75, 0x21, 0x3e, 0xbf, 0xa1, 0x96, 0x2a, 0xcf, - 0x7f, 0x0e, 0xa2, 0x07, 0x4d, 0xf5, 0x2f, 0x59, 0x36, 0x03, 0xd5, 0x9e, 0x75, 0xe9, 0xb7, 0xb3, - 0xe9, 0x29, 0x94, 0x82, 0x15, 0x62, 0xf8, 0x23, 0x7f, 0x25, 0x43, 0x3a, 0xba, 0x6c, 0x3f, 0xfe, - 0x95, 0x74, 0x4d, 0xab, 0x8f, 0xab, 0x81, 0x4d, 0x0d, 0x01, 0x6e, 0xab, 0x4b, 0x09, 0x1e, 0x00, - 0xee, 0x85, 0x10, 0xd3, 0xea, 0x52, 0x70, 0x90, 0x2d, 0x13, 0x01, 0xfb, 0x90, 0x41, 0xd1, 0x6e, - 0xf5, 0x5a, 0xd5, 0x45, 0x88, 0x56, 0x27, 0x50, 0x33, 0xd8, 0x38, 0xde, 0xf4, 0xe4, 0xb8, 0x1e, - 0x30, 0xd2, 0x9a, 0x1e, 0x37, 0xfa, 0xc1, 0x66, 0x75, 0x67, 0xf9, 0x3c, 0x85, 0x25, 0xbf, 0xc2, - 0xab, 0x3b, 0xdb, 0x44, 0x0d, 0x10, 0xab, 0x3b, 0x2f, 0x68, 0x66, 0x30, 0xcb, 0xcf, 0x9b, 0x04, - 0xae, 0xd1, 0x0c, 0x66, 0x2b, 0x57, 0x62, 0x62, 0x06, 0xf3, 0x60, 0xca, 0xc3, 0x71, 0xf4, 0x6b, - 0x52, 0xf8, 0x87, 0x3c, 0xc9, 0x86, 0xb7, 0x3d, 0x4a, 0x95, 0x40, 0x5b, 0xbd, 0x43, 0x03, 0xa8, - 0xc4, 0xd5, 0xaf, 0x3b, 0x2c, 0x8b, 0x21, 0xf5, 0x96, 0xd8, 0x88, 0x83, 0x25, 0x76, 0x30, 0x93, - 0x3a, 0x48, 0x61, 0x35, 0x7e, 0x8d, 0x2f, 0x59, 0x91, 0x64, 0xb3, 0xa1, 0x4f, 0xd7, 0x92, 0x13, - 0xa9, 0x83, 0x8f, 0x43, 0x21, 0xac, 0x14, 0xb7, 0xf3, 0xbc, 0xa8, 0x86, 0x45, 0x5f, 0x08, 0xbb, - 0x48, 0x30, 0x84, 0x5b, 0xa8, 0xdf, 0xdb, 0x2e, 0xc4, 0x69, 0x92, 0x05, 0xbd, 0x29, 0xa4, 0x8f, - 0x37, 0x83, 0xa2, 0xe0, 0x3d, 0x04, 0xb6, 0x84, 0xa6, 0x66, 0xbe, 0x27, 0x63, 0x03, 0xc1, 0xe0, - 0x45, 0xa0, 0x59, 0xa7, 0x49, 0xf1, 0x11, 0xbb, 0x82, 0xea, 0x01, 0x43, 0x35, 0xaf, 0x0d, 0x7d, - 0xfa, 0x0e, 0x41, 0xac, 0xd3, 0xfc, 0xa4, 0x72, 0xb5, 0x88, 0x3e, 0x92, 0xf2, 0x13, 0x56, 0x88, - 0x24, 0x4e, 0x72, 0x96, 0x35, 0xf9, 0xbf, 0xaf, 0x5f, 0xb7, 0x28, 0xed, 0x72, 0xb3, 0x27, 0xad, - 0xdc, 0xfe, 0xc7, 0x20, 0xba, 0x8b, 0xfd, 0x9e, 0x40, 0x31, 0x4f, 0xe4, 0x32, 0xb2, 0xac, 0x07, - 0xe1, 0xe1, 0x97, 0x61, 0xa3, 0x2d, 0x05, 0x5d, 0x9a, 0x1f, 0xde, 0x5c, 0x51, 0x15, 0xec, 0x8f, - 0xa2, 0xa8, 0x5e, 0xae, 0xc8, 0x25, 0xa5, 0xdb, 0x6b, 0xd5, 0x3a, 0xc6, 0x59, 0x4f, 0xde, 0x0d, - 0x10, 0x66, 0xaa, 0xa8, 0x7f, 0x97, 0x2b, 0xe5, 0xa1, 0x57, 0x43, 0x8a, 0x88, 0xa9, 0x02, 0x21, - 0xb8, 0xa0, 0xe3, 0x4b, 0x7e, 0xed, 0x2f, 0x68, 0x25, 0x09, 0x17, 0x54, 0x11, 0x66, 0xef, 0x4a, - 0x15, 0xd4, 0xb7, 0x77, 0xd5, 0x14, 0x23, 0xb4, 0x77, 0x85, 0x19, 0x65, 0x98, 0x47, 0xbf, 0x6d, - 0x1b, 0x7e, 0xc9, 0xf9, 0xd5, 0x9c, 0x15, 0x57, 0xc3, 0xa7, 0xb4, 0x72, 0xc3, 0x68, 0x47, 0xeb, - 0xbd, 0x58, 0x33, 0x2c, 0xd8, 0x0e, 0xab, 0x44, 0xe3, 0xac, 0x48, 0xd1, 0xb0, 0xe0, 0xd8, 0x50, - 0x08, 0x31, 0x2c, 0x10, 0xa8, 0x49, 0xa0, 0x95, 0xb7, 0x4b, 0x26, 0xd7, 0xed, 0xfe, 0x87, 0x52, - 0x0b, 0x89, 0x04, 0xba, 0x05, 0x99, 0x59, 0xc1, 0xae, 0xc9, 0x18, 0xf0, 0x4a, 0xcc, 0x29, 0xda, - 0x18, 0xa8, 0x95, 0x98, 0x07, 0xc3, 0xe1, 0xb9, 0x5f, 0xb0, 0xfc, 0xd2, 0x1f, 0x9e, 0x52, 0x14, - 0x0e, 0xcf, 0x06, 0xc1, 0xb1, 0x34, 0x06, 0x56, 0xc4, 0x97, 0xfe, 0x58, 0xaa, 0x65, 0xe1, 0x58, - 0xd2, 0x0c, 0x8e, 0xa5, 0x5a, 0xf0, 0x36, 0x11, 0x97, 0x47, 0x20, 0x98, 0x3f, 0x96, 0x5c, 0x26, - 0x1c, 0x4b, 0x2d, 0xd6, 0x64, 0x49, 0xb6, 0xc3, 0xf1, 0xe2, 0xbc, 0x8c, 0x8b, 0xe4, 0x1c, 0x86, - 0x01, 0x2b, 0x1a, 0x22, 0xb2, 0x24, 0x12, 0x36, 0x13, 0x80, 0xf2, 0xd9, 0xc8, 0x0e, 0xa6, 0x25, - 0x9a, 0x00, 0x1a, 0x1b, 0x16, 0x41, 0x4c, 0x00, 0x7e, 0x12, 0x57, 0x6f, 0xbf, 0xe0, 0x8b, 0xbc, - 0xec, 0xa8, 0x1e, 0x82, 0xc2, 0xd5, 0x6b, 0xc3, 0xca, 0xe7, 0xbb, 0xe8, 0x77, 0xed, 0x47, 0x7a, - 0x96, 0x95, 0xda, 0xeb, 0x26, 0xfd, 0x9c, 0x2c, 0x8c, 0xd8, 0xf2, 0x0a, 0xe0, 0x26, 0x05, 0x6a, - 0x3c, 0x8b, 0x5d, 0x10, 0x2c, 0x49, 0xcb, 0xe1, 0x23, 0xbf, 0x8d, 0x46, 0x4e, 0xa4, 0x40, 0x3e, - 0x0e, 0xf7, 0xd9, 0xdd, 0x45, 0x9e, 0x26, 0x71, 0x7b, 0xef, 0x53, 0xe9, 0x6a, 0x71, 0xb8, 0xcf, - 0xda, 0x18, 0x1e, 0xdf, 0xc6, 0x20, 0xea, 0xff, 0x4c, 0x56, 0x39, 0xf8, 0xc7, 0x37, 0x07, 0x09, - 0x8f, 0x6f, 0x18, 0xc5, 0xf5, 0x19, 0x83, 0x38, 0x64, 0x2b, 0xbe, 0x20, 0xc6, 0x20, 0x2d, 0x0e, - 0xd7, 0xc7, 0xc6, 0x4c, 0x16, 0xa2, 0x3d, 0x1c, 0x64, 0x02, 0x8a, 0x8c, 0xa5, 0x7b, 0x29, 0x9b, - 0x95, 0x43, 0xa2, 0xdf, 0xb8, 0x14, 0x91, 0x85, 0xd0, 0xb4, 0xe7, 0x31, 0x1e, 0x94, 0x7b, 0x6c, - 0xc9, 0x8b, 0x44, 0xd0, 0x8f, 0xd1, 0x20, 0x9d, 0x8f, 0xd1, 0x41, 0xbd, 0xde, 0xb6, 0x8b, 0xf8, - 0x32, 0x59, 0xc2, 0x34, 0xe0, 0xad, 0x41, 0x7a, 0x78, 0xb3, 0x50, 0x4f, 0xa3, 0x8d, 0xf9, 0xa2, - 0x88, 0x81, 0x6c, 0xb4, 0x5a, 0xdc, 0xd9, 0x68, 0x1a, 0x53, 0x1e, 0xfe, 0x66, 0x10, 0xfd, 0x5e, - 0x2d, 0xb5, 0x37, 0x24, 0x77, 0x59, 0x79, 0x79, 0xce, 0x59, 0x31, 0x1d, 0x7e, 0xea, 0xb3, 0xe3, - 0x45, 0xb5, 0xeb, 0xe7, 0x37, 0x51, 0xc1, 0x8f, 0xf5, 0x30, 0x29, 0xad, 0x1e, 0xe7, 0x7d, 0xac, - 0x0e, 0x12, 0x7e, 0xac, 0x18, 0xc5, 0x03, 0x88, 0x94, 0xd7, 0x8b, 0xff, 0x47, 0xa4, 0xbe, 0xbb, - 0x03, 0xb0, 0xd6, 0xc9, 0xe1, 0xf1, 0xb1, 0x12, 0xba, 0xd1, 0xb2, 0x49, 0xd9, 0xf0, 0x47, 0xcc, - 0xa8, 0x2f, 0x4e, 0x7a, 0xd6, 0xbd, 0x22, 0xec, 0xb9, 0xd5, 0x33, 0x46, 0x7d, 0x71, 0xc2, 0xb3, - 0x35, 0xac, 0x85, 0x3c, 0x7b, 0x86, 0xb6, 0x51, 0x5f, 0x1c, 0x67, 0x14, 0x8a, 0x69, 0xe6, 0x85, - 0xa7, 0x01, 0x3b, 0x78, 0x6e, 0x58, 0xef, 0xc5, 0x2a, 0x87, 0x7f, 0x37, 0x88, 0xbe, 0x6f, 0x3c, - 0x1e, 0xf1, 0x69, 0x72, 0xb1, 0xaa, 0xa1, 0x37, 0x2c, 0x5d, 0x40, 0x39, 0x7c, 0x4e, 0x59, 0x6b, - 0xb3, 0xba, 0x04, 0x2f, 0x6e, 0xa4, 0x83, 0xfb, 0xce, 0x76, 0x9e, 0xa7, 0xab, 0x09, 0xcc, 0xf3, - 0x94, 0xec, 0x3b, 0x0e, 0x12, 0xee, 0x3b, 0x18, 0xc5, 0x99, 0xe6, 0x84, 0x57, 0x79, 0xac, 0x37, - 0xd3, 0x94, 0xa2, 0x70, 0xa6, 0xd9, 0x20, 0x38, 0x57, 0x9a, 0xf0, 0x1d, 0x9e, 0xa6, 0x10, 0x8b, - 0xf6, 0xa1, 0xa6, 0xd6, 0x34, 0x44, 0x38, 0x57, 0x42, 0xa4, 0x59, 0xff, 0x37, 0x6b, 0x2e, 0x56, - 0xc0, 0xcb, 0xd5, 0x61, 0x92, 0x5d, 0x0d, 0xfd, 0x69, 0x81, 0x01, 0x88, 0xf5, 0xbf, 0x17, 0xc4, - 0x6b, 0xbb, 0xb3, 0x6c, 0xca, 0xfd, 0x6b, 0xbb, 0x4a, 0x12, 0x5e, 0xdb, 0x29, 0x02, 0x9b, 0x3c, - 0x05, 0xca, 0x64, 0x25, 0x09, 0x9b, 0x54, 0x84, 0x6f, 0x28, 0x54, 0xbb, 0xc4, 0xe4, 0x50, 0x88, - 0xf6, 0x85, 0xd7, 0x3a, 0x39, 0x1c, 0xa1, 0xcd, 0x22, 0x6f, 0x0f, 0x44, 0x7c, 0xe9, 0x8f, 0x50, - 0x07, 0x09, 0x47, 0x28, 0x46, 0x71, 0x95, 0x26, 0x5c, 0x2f, 0x52, 0x1f, 0xf9, 0xe3, 0xa3, 0xb5, - 0x40, 0x5d, 0xeb, 0xe4, 0xf0, 0xd2, 0xe8, 0x60, 0x2e, 0x9f, 0x99, 0x37, 0xc8, 0x6b, 0x59, 0x78, - 0x69, 0xa4, 0x19, 0x5c, 0xfa, 0x5a, 0x50, 0x3d, 0x4e, 0x7f, 0xe9, 0x8d, 0x3c, 0x5c, 0x7a, 0x87, - 0x53, 0x4e, 0xfe, 0x6d, 0x10, 0xdd, 0xb6, 0xbd, 0x1c, 0xf3, 0xaa, 0x8f, 0xbc, 0x61, 0x69, 0x32, - 0x65, 0x02, 0x26, 0xfc, 0x0a, 0x32, 0xb4, 0x6f, 0xe3, 0x96, 0xb6, 0xe6, 0x47, 0x8e, 0x02, 0xb1, - 0x6f, 0xd3, 0x4b, 0x11, 0xc7, 0x49, 0x4d, 0x9f, 0x95, 0xb0, 0xc3, 0x4a, 0x62, 0x24, 0x73, 0x90, - 0x70, 0x9c, 0x60, 0x14, 0xe7, 0xab, 0xb5, 0xfc, 0xd5, 0xbb, 0x1c, 0x8a, 0x04, 0xb2, 0x18, 0xfc, - 0xf9, 0x2a, 0xa6, 0xc2, 0xf9, 0xaa, 0x87, 0x6e, 0x6d, 0x6b, 0xe8, 0xc1, 0xa9, 0x7d, 0x2f, 0x01, - 0x13, 0x81, 0x7b, 0x09, 0x04, 0x8a, 0x2b, 0x69, 0x00, 0xef, 0xd6, 0x60, 0xcb, 0x4a, 0x70, 0x6b, - 0x90, 0xa6, 0x5b, 0x9b, 0x45, 0x9a, 0x19, 0x57, 0xdd, 0xa4, 0xa3, 0xe8, 0x63, 0xbb, 0xbb, 0xac, - 0xf7, 0x62, 0xfd, 0xbb, 0x53, 0xa7, 0x90, 0x32, 0x39, 0x85, 0x04, 0xb6, 0x80, 0x1a, 0xa6, 0xcf, - 0xee, 0x94, 0xc5, 0x2a, 0x87, 0x7f, 0x35, 0x88, 0x3e, 0xf1, 0x79, 0x7c, 0x9d, 0x4b, 0xbf, 0xcf, - 0xba, 0x6d, 0xd5, 0x24, 0x71, 0xf1, 0x22, 0xac, 0xa1, 0xca, 0xf0, 0x67, 0xd1, 0xc7, 0x8d, 0xc8, - 0xdc, 0xcb, 0x50, 0x05, 0x70, 0x13, 0x28, 0x5d, 0x7e, 0xcc, 0x69, 0xf7, 0x5b, 0xbd, 0x79, 0xb3, - 0x36, 0x71, 0xcb, 0x55, 0xa2, 0xb5, 0x89, 0xb6, 0xa1, 0xc4, 0xc4, 0xda, 0xc4, 0x83, 0x99, 0x5d, - 0x0d, 0xbb, 0x7a, 0x6f, 0x13, 0x71, 0x29, 0x73, 0x1f, 0xb4, 0xab, 0xe1, 0x94, 0x55, 0x43, 0xc4, - 0xae, 0x06, 0x09, 0xe3, 0xec, 0xa0, 0x01, 0xab, 0xbe, 0xe9, 0x1b, 0x57, 0xb5, 0x21, 0xbb, 0x67, - 0x3e, 0xee, 0x06, 0x71, 0xbc, 0x36, 0x62, 0xb5, 0x0c, 0x79, 0x1a, 0xb2, 0x80, 0x96, 0x22, 0xeb, - 0xbd, 0x58, 0xe5, 0xf0, 0x2f, 0xa2, 0xef, 0xb5, 0x2a, 0xb6, 0x07, 0x4c, 0x2c, 0x0a, 0x98, 0x0e, - 0xb7, 0x3a, 0xca, 0xdd, 0x80, 0xda, 0xf5, 0xb3, 0xfe, 0x0a, 0xad, 0x7c, 0xb9, 0xe1, 0xea, 0xb0, - 0xd2, 0x65, 0x78, 0x1e, 0x32, 0xe9, 0xb2, 0xc1, 0x7c, 0x99, 0xd6, 0x69, 0x2d, 0x79, 0xed, 0xe8, - 0xda, 0x5e, 0xb2, 0x24, 0x95, 0x47, 0x34, 0x9f, 0x86, 0x8c, 0x3a, 0x68, 0x70, 0xc9, 0x4b, 0xaa, - 0xb4, 0x46, 0x66, 0xd9, 0xc7, 0xad, 0xa5, 0xd2, 0x06, 0x3d, 0x12, 0x78, 0x56, 0x4a, 0x9b, 0x3d, - 0x69, 0xe5, 0x56, 0x34, 0x5b, 0x85, 0xd5, 0xcf, 0x76, 0x90, 0xfb, 0xbc, 0x2a, 0x55, 0x4f, 0xa4, - 0x6f, 0xf6, 0xa4, 0x95, 0xd7, 0x3f, 0x8f, 0x3e, 0x6e, 0x7b, 0x55, 0x13, 0xd1, 0x56, 0xa7, 0x29, - 0x34, 0x17, 0x3d, 0xeb, 0xaf, 0x60, 0x96, 0x17, 0x5f, 0x25, 0xa5, 0xe0, 0xc5, 0x6a, 0x7c, 0xc9, - 0xaf, 0x9b, 0xfb, 0xce, 0x6e, 0x6f, 0x55, 0xc0, 0xc8, 0x22, 0x88, 0xe5, 0x85, 0x9f, 0x6c, 0xb9, - 0x32, 0xf7, 0xa2, 0x4b, 0xc2, 0x95, 0x45, 0x74, 0xb8, 0x72, 0x49, 0x33, 0x56, 0x35, 0xb5, 0x32, - 0x97, 0xb8, 0xd7, 0xfc, 0x45, 0x6d, 0x5f, 0xe4, 0x7e, 0xdc, 0x0d, 0x9a, 0x8c, 0x45, 0x89, 0x77, - 0x93, 0x8b, 0x0b, 0x5d, 0x27, 0x7f, 0x49, 0x6d, 0x84, 0xc8, 0x58, 0x08, 0xd4, 0x24, 0xc0, 0x7b, - 0x49, 0x0a, 0xf2, 0xbc, 0xef, 0xf5, 0xc5, 0x45, 0xca, 0xd9, 0x14, 0x25, 0xc0, 0x95, 0x78, 0x64, - 0xcb, 0x89, 0x04, 0xd8, 0xc7, 0x99, 0xd3, 0x9e, 0x4a, 0x7a, 0x0a, 0x31, 0xcf, 0xe2, 0x24, 0xc5, - 0xd7, 0xbf, 0xa4, 0xa6, 0x16, 0x12, 0xa7, 0x3d, 0x2d, 0xc8, 0x4c, 0x8c, 0x95, 0xa8, 0xea, 0xf6, - 0x4d, 0xf9, 0x1f, 0xb6, 0x15, 0x2d, 0x31, 0x31, 0x31, 0x7a, 0x30, 0xb3, 0x0e, 0xac, 0x84, 0x67, - 0xb9, 0x34, 0x7e, 0xa7, 0xad, 0x55, 0x4b, 0x88, 0x75, 0xa0, 0x4b, 0x98, 0xf5, 0x4c, 0xf5, 0xfb, - 0x2e, 0xbf, 0xce, 0xa4, 0xd1, 0x7b, 0x6d, 0x95, 0x46, 0x46, 0xac, 0x67, 0x30, 0xa3, 0x0c, 0xff, - 0x24, 0xfa, 0xff, 0xd2, 0x70, 0xc1, 0xf3, 0xe1, 0x2d, 0x8f, 0x42, 0x61, 0xdd, 0xd4, 0xba, 0x4d, - 0xca, 0xcd, 0x85, 0x43, 0x1d, 0x1b, 0x67, 0x25, 0x9b, 0xc1, 0xf0, 0x01, 0xd1, 0xe2, 0x52, 0x4a, - 0x5c, 0x38, 0x6c, 0x53, 0x6e, 0x54, 0x1c, 0xf3, 0xa9, 0xb2, 0xee, 0xa9, 0xa1, 0x16, 0x86, 0xa2, - 0xc2, 0x86, 0x4c, 0x32, 0x73, 0xcc, 0x96, 0xc9, 0x4c, 0x4f, 0x38, 0xf5, 0xb8, 0x55, 0xa2, 0x64, - 0xc6, 0x30, 0x23, 0x0b, 0x22, 0x92, 0x19, 0x12, 0x56, 0x3e, 0xff, 0x75, 0x10, 0xdd, 0x31, 0xcc, - 0x7e, 0xb3, 0x73, 0x76, 0x90, 0x5d, 0xf0, 0x2a, 0xf5, 0x39, 0x4c, 0xb2, 0xab, 0x72, 0xf8, 0x05, - 0x65, 0xd2, 0xcf, 0xeb, 0xa2, 0x7c, 0x79, 0x63, 0x3d, 0x93, 0xb5, 0x36, 0xdb, 0x4a, 0xe6, 0x2c, - 0xb6, 0xd6, 0x40, 0x59, 0xab, 0xde, 0x7d, 0xc2, 0x1c, 0x91, 0xb5, 0x86, 0x78, 0xd3, 0xc4, 0xda, - 0x79, 0xca, 0x33, 0xdc, 0xc4, 0xc6, 0x42, 0x25, 0x24, 0x9a, 0xb8, 0x05, 0x99, 0xf1, 0xb8, 0x11, - 0xd5, 0x3b, 0x20, 0xdb, 0x69, 0x8a, 0xc6, 0x63, 0xad, 0xaa, 0x01, 0x62, 0x3c, 0xf6, 0x82, 0xca, - 0xcf, 0x69, 0xf4, 0x9d, 0xea, 0x91, 0x9e, 0x14, 0xb0, 0x4c, 0x00, 0x5f, 0x1b, 0xb0, 0x24, 0x44, - 0xff, 0x77, 0x09, 0xd3, 0xb3, 0xce, 0xb2, 0x32, 0x4f, 0x59, 0x79, 0xa9, 0x0e, 0x7b, 0xdd, 0x3a, - 0x37, 0x42, 0x7c, 0xdc, 0xfb, 0xb0, 0x83, 0x32, 0x83, 0x7a, 0x23, 0xd3, 0x43, 0xcc, 0x23, 0xbf, - 0x6a, 0x6b, 0x98, 0x59, 0xeb, 0xe4, 0xcc, 0xee, 0xf3, 0x3e, 0x4b, 0x53, 0x28, 0x56, 0x8d, 0xec, - 0x88, 0x65, 0xc9, 0x05, 0x94, 0x02, 0xed, 0x3e, 0x2b, 0x6a, 0x84, 0x31, 0x62, 0xf7, 0x39, 0x80, - 0x9b, 0x6c, 0x1e, 0x79, 0x3e, 0xc8, 0xa6, 0xf0, 0x0e, 0x65, 0xf3, 0xd8, 0x8e, 0x64, 0x88, 0x6c, - 0x9e, 0x62, 0xcd, 0x2e, 0xec, 0xcb, 0x94, 0xc7, 0x57, 0x6a, 0x0a, 0x70, 0x1b, 0x58, 0x4a, 0xf0, - 0x1c, 0x70, 0x2f, 0x84, 0x98, 0x49, 0x40, 0x0a, 0x4e, 0x21, 0x4f, 0x59, 0x8c, 0xef, 0x8e, 0xd4, - 0x3a, 0x4a, 0x46, 0x4c, 0x02, 0x98, 0x41, 0xc5, 0x55, 0x77, 0x52, 0x7c, 0xc5, 0x45, 0x57, 0x52, - 0xee, 0x85, 0x10, 0x33, 0x0d, 0x4a, 0xc1, 0x38, 0x4f, 0x13, 0x81, 0xba, 0x41, 0xad, 0x21, 0x25, - 0x44, 0x37, 0x70, 0x09, 0x64, 0xf2, 0x08, 0x8a, 0x19, 0x78, 0x4d, 0x4a, 0x49, 0xd0, 0x64, 0x43, - 0x98, 0x2b, 0x86, 0x75, 0xdd, 0x79, 0xbe, 0x42, 0x57, 0x0c, 0x55, 0xb5, 0x78, 0xbe, 0x22, 0xae, - 0x18, 0x3a, 0x00, 0x2a, 0xe2, 0x09, 0x2b, 0x85, 0xbf, 0x88, 0x52, 0x12, 0x2c, 0x62, 0x43, 0x98, - 0x39, 0xba, 0x2e, 0xe2, 0x42, 0xa0, 0x39, 0x5a, 0x15, 0xc0, 0x3a, 0x0d, 0xbe, 0x4d, 0xca, 0xcd, - 0x48, 0x52, 0xb7, 0x0a, 0x88, 0xbd, 0x04, 0xd2, 0x69, 0x89, 0x46, 0x12, 0xf5, 0xdc, 0x1b, 0x29, - 0x31, 0x92, 0xb4, 0x29, 0x14, 0x4a, 0x6a, 0xaf, 0xda, 0x57, 0x3b, 0xb4, 0x4d, 0x7d, 0x2f, 0x84, - 0x98, 0xf1, 0xa9, 0x29, 0xf4, 0x0e, 0x2b, 0x8a, 0xa4, 0x9a, 0xfc, 0x1f, 0xf9, 0x0b, 0xd4, 0xc8, - 0x89, 0xf1, 0xc9, 0xc7, 0xa1, 0xee, 0xd5, 0x0c, 0xdc, 0xbe, 0x82, 0xe1, 0xa1, 0xfb, 0x7e, 0x90, - 0x31, 0x19, 0xa7, 0x94, 0x58, 0xc7, 0x99, 0xbe, 0xa7, 0xe9, 0x39, 0xcd, 0x7c, 0xd4, 0x85, 0x59, - 0xaf, 0x00, 0x68, 0x17, 0x47, 0x7c, 0x09, 0x13, 0xfe, 0xea, 0x5d, 0x52, 0x8a, 0x24, 0x9b, 0xa9, - 0x99, 0xfb, 0x05, 0x61, 0xc9, 0x07, 0x13, 0xaf, 0x00, 0x74, 0x2a, 0x99, 0x04, 0x02, 0x95, 0xe5, - 0x18, 0xae, 0xbd, 0x09, 0x04, 0xb6, 0xa8, 0x39, 0x22, 0x81, 0x08, 0xf1, 0x66, 0x1f, 0x45, 0x3b, - 0x57, 0xef, 0x49, 0x4e, 0x78, 0x93, 0xcb, 0x51, 0xd6, 0x30, 0x48, 0x2c, 0x65, 0x83, 0x0a, 0x66, - 0x7d, 0xa9, 0xfd, 0x9b, 0x2e, 0xf6, 0x98, 0xb0, 0xd3, 0xee, 0x66, 0x4f, 0x7a, 0x90, 0x1e, 0x57, - 0xe6, 0x4c, 0x9e, 0x72, 0xd5, 0x3e, 0x92, 0x7f, 0xd2, 0x83, 0xb4, 0xf6, 0x64, 0xec, 0x6a, 0xbd, - 0x64, 0xf1, 0xd5, 0xac, 0xe0, 0x8b, 0x6c, 0xba, 0xc3, 0x53, 0x5e, 0xa0, 0x3d, 0x19, 0xa7, 0xd4, - 0x08, 0x25, 0xf6, 0x64, 0x3a, 0x54, 0x4c, 0x06, 0x67, 0x97, 0x62, 0x3b, 0x4d, 0x66, 0x78, 0x45, - 0xed, 0x18, 0x92, 0x00, 0x91, 0xc1, 0x79, 0x41, 0x4f, 0x10, 0xd5, 0x2b, 0x6e, 0x91, 0xc4, 0x2c, - 0xad, 0xfd, 0x6d, 0xd1, 0x66, 0x1c, 0xb0, 0x33, 0x88, 0x3c, 0x0a, 0x9e, 0x7a, 0x4e, 0x16, 0x45, - 0x76, 0x90, 0x09, 0x4e, 0xd6, 0xb3, 0x01, 0x3a, 0xeb, 0x69, 0x81, 0x68, 0x58, 0x9d, 0xc0, 0xbb, - 0xaa, 0x34, 0xd5, 0x3f, 0xbe, 0x61, 0xb5, 0xfa, 0x7d, 0xa4, 0xe4, 0xa1, 0x61, 0x15, 0x71, 0xa8, - 0x32, 0xca, 0x49, 0x1d, 0x30, 0x01, 0x6d, 0x37, 0x4c, 0x1e, 0x77, 0x83, 0x7e, 0x3f, 0x63, 0xb1, - 0x4a, 0x21, 0xe4, 0x47, 0x02, 0x7d, 0xfc, 0x34, 0xa0, 0xd9, 0x6e, 0x71, 0xea, 0x73, 0x09, 0xf1, - 0x55, 0xeb, 0x8a, 0x91, 0x5b, 0xd0, 0x1a, 0x21, 0xb6, 0x5b, 0x08, 0xd4, 0xdf, 0x44, 0x07, 0x31, - 0xcf, 0x42, 0x4d, 0x54, 0xc9, 0xfb, 0x34, 0x91, 0xe2, 0xcc, 0xe2, 0x57, 0x4b, 0x55, 0x64, 0xd6, - 0xcd, 0xb4, 0x4e, 0x58, 0xb0, 0x21, 0x62, 0xf1, 0x4b, 0xc2, 0x26, 0x27, 0xc7, 0x3e, 0x8f, 0xda, - 0xf7, 0x95, 0x5b, 0x56, 0x8e, 0xe8, 0xfb, 0xca, 0x14, 0x4b, 0x57, 0xb2, 0x8e, 0x91, 0x0e, 0x2b, - 0x6e, 0x9c, 0x6c, 0xf4, 0x83, 0xcd, 0x92, 0xc7, 0xf1, 0xb9, 0x93, 0x02, 0x2b, 0x6a, 0xaf, 0x9b, - 0x01, 0x43, 0x06, 0x23, 0x96, 0x3c, 0x01, 0x1c, 0x0d, 0x61, 0x8e, 0xe7, 0x1d, 0x9e, 0x09, 0xc8, - 0x84, 0x6f, 0x08, 0x73, 0x8d, 0x29, 0x30, 0x34, 0x84, 0x51, 0x0a, 0x28, 0x6e, 0xe5, 0x7e, 0x10, - 0x88, 0x63, 0x36, 0xf7, 0x66, 0x6c, 0xf5, 0x5e, 0x4f, 0x2d, 0x0f, 0xc5, 0x2d, 0xe2, 0xac, 0x43, - 0x3e, 0xdb, 0xcb, 0x84, 0x15, 0x33, 0xbd, 0xbb, 0x31, 0x1d, 0x3e, 0xa3, 0xed, 0xb8, 0x24, 0x71, - 0xc8, 0x17, 0xd6, 0x40, 0xc3, 0xce, 0xc1, 0x9c, 0xcd, 0x74, 0x4d, 0x3d, 0x35, 0x90, 0xf2, 0x56, - 0x55, 0x1f, 0x77, 0x83, 0xc8, 0xcf, 0x9b, 0x64, 0x0a, 0x3c, 0xe0, 0x47, 0xca, 0xfb, 0xf8, 0xc1, - 0x20, 0xca, 0xde, 0xaa, 0x7a, 0xd7, 0x2b, 0xba, 0xed, 0x6c, 0xaa, 0xd6, 0xb1, 0x23, 0xe2, 0xf1, - 0x20, 0x2e, 0x94, 0xbd, 0x11, 0x3c, 0xea, 0xa3, 0xcd, 0x06, 0x6d, 0xa8, 0x8f, 0xea, 0xfd, 0xd7, - 0x3e, 0x7d, 0xd4, 0x07, 0x2b, 0x9f, 0x3f, 0x53, 0x7d, 0x74, 0x97, 0x09, 0x56, 0xe5, 0xed, 0x6f, - 0x12, 0xb8, 0x56, 0x0b, 0x61, 0x4f, 0x7d, 0x1b, 0x6a, 0x24, 0x5f, 0x54, 0x43, 0xab, 0xe2, 0xad, - 0xde, 0x7c, 0xc0, 0xb7, 0x5a, 0x21, 0x74, 0xfa, 0x46, 0x4b, 0x85, 0xad, 0xde, 0x7c, 0xc0, 0xb7, - 0x7a, 0x03, 0xb6, 0xd3, 0x37, 0x7a, 0x0d, 0x76, 0xab, 0x37, 0xaf, 0x7c, 0xff, 0x75, 0xd3, 0x71, - 0x6d, 0xe7, 0x55, 0x1e, 0x16, 0x8b, 0x64, 0x09, 0xbe, 0x74, 0xd2, 0xb5, 0xa7, 0xd1, 0x50, 0x3a, - 0x49, 0xab, 0x58, 0x9f, 0x4d, 0xf1, 0x95, 0xe2, 0x84, 0x97, 0x89, 0x3c, 0xa4, 0x7f, 0xd1, 0xc3, - 0x68, 0x03, 0x87, 0x16, 0x4d, 0x21, 0x25, 0x73, 0xdc, 0xe8, 0xa0, 0xe6, 0x46, 0xf1, 0x46, 0xc0, - 0x5e, 0xfb, 0x62, 0xf1, 0x66, 0x4f, 0xda, 0x1c, 0xfc, 0x39, 0x8c, 0x7d, 0xe2, 0x18, 0x6a, 0x55, - 0xef, 0xa1, 0xe3, 0xb3, 0xfe, 0x0a, 0xca, 0xfd, 0xdf, 0x36, 0xeb, 0x0a, 0xec, 0x5f, 0x75, 0x82, - 0xe7, 0x7d, 0x2c, 0xa2, 0x8e, 0xf0, 0xe2, 0x46, 0x3a, 0xaa, 0x20, 0xff, 0xd8, 0x2c, 0xa0, 0x1b, - 0x54, 0xbe, 0x57, 0xf1, 0xba, 0x98, 0x42, 0xa1, 0xfa, 0x44, 0xa8, 0x59, 0x0d, 0x8c, 0x7b, 0xc6, - 0xe7, 0x37, 0xd4, 0xb2, 0x3e, 0xa2, 0xe3, 0xc0, 0xea, 0x7d, 0x39, 0xab, 0x3c, 0x21, 0xcb, 0x16, - 0x8d, 0x0b, 0xf4, 0xc5, 0x4d, 0xd5, 0xa8, 0xbe, 0x62, 0xc1, 0xf2, 0x9d, 0xfc, 0x17, 0x3d, 0x0d, - 0x3b, 0x6f, 0xe9, 0x7f, 0x76, 0x33, 0x25, 0x55, 0x96, 0xff, 0x1a, 0x44, 0x0f, 0x1d, 0xd6, 0x9c, - 0x27, 0xa0, 0x5d, 0x8f, 0x1f, 0x07, 0xec, 0x53, 0x4a, 0xba, 0x70, 0xbf, 0xff, 0xab, 0x29, 0x9b, - 0x2f, 0xce, 0x38, 0x2a, 0x7b, 0x49, 0x2a, 0xa0, 0x68, 0x7f, 0x71, 0xc6, 0xb5, 0x5b, 0x53, 0x23, - 0xfa, 0x8b, 0x33, 0x01, 0xdc, 0xfa, 0xe2, 0x8c, 0xc7, 0xb3, 0xf7, 0x8b, 0x33, 0x5e, 0x6b, 0xc1, - 0x2f, 0xce, 0x84, 0x35, 0xa8, 0xe1, 0xbd, 0x29, 0x42, 0xbd, 0x6f, 0xdd, 0xcb, 0xa2, 0xbb, 0x8d, - 0xfd, 0xfc, 0x26, 0x2a, 0xc4, 0x04, 0x57, 0x73, 0xf2, 0x9e, 0x5b, 0x8f, 0x67, 0xea, 0xdc, 0x75, - 0xdb, 0xea, 0xcd, 0x2b, 0xdf, 0x3f, 0x55, 0xab, 0x1b, 0x3d, 0x9c, 0xf3, 0x42, 0xbe, 0xb5, 0xb8, - 0x1e, 0x1a, 0x9e, 0x2b, 0x0b, 0x76, 0xcb, 0x6f, 0xf4, 0x83, 0x89, 0xea, 0x56, 0x84, 0x6a, 0xf4, - 0x51, 0x97, 0x21, 0xd4, 0xe4, 0x5b, 0xbd, 0x79, 0x62, 0x1a, 0xa9, 0x7d, 0xd7, 0xad, 0xdd, 0xc3, - 0x98, 0xdb, 0xd6, 0xcf, 0xfa, 0x2b, 0x28, 0xf7, 0x4b, 0x95, 0x36, 0xda, 0xee, 0x65, 0x3b, 0x6f, - 0x76, 0x99, 0x1a, 0x3b, 0xcd, 0x3c, 0xea, 0x8b, 0x87, 0x12, 0x08, 0x7b, 0x0a, 0xed, 0x4a, 0x20, - 0xbc, 0xd3, 0xe8, 0x67, 0x37, 0x53, 0x52, 0x65, 0xf9, 0x97, 0x41, 0x74, 0x9b, 0x2c, 0x8b, 0x8a, - 0x83, 0x2f, 0xfa, 0x5a, 0x46, 0xf1, 0xf0, 0xe5, 0x8d, 0xf5, 0x54, 0xa1, 0xfe, 0x7d, 0x10, 0xdd, - 0x09, 0x14, 0xaa, 0x0e, 0x90, 0x1b, 0x58, 0x77, 0x03, 0xe5, 0x87, 0x37, 0x57, 0xa4, 0xa6, 0x7b, - 0x1b, 0x1f, 0xb7, 0x3f, 0xc5, 0x12, 0xb0, 0x3d, 0xa6, 0x3f, 0xc5, 0xd2, 0xad, 0x85, 0x37, 0x79, - 0xd8, 0x79, 0xb3, 0xe8, 0xf2, 0x6e, 0xf2, 0xc8, 0x1b, 0x6a, 0x68, 0xcd, 0xb1, 0xd6, 0xc9, 0xf9, - 0x9c, 0xbc, 0x7a, 0x97, 0xb3, 0x6c, 0x4a, 0x3b, 0xa9, 0xe5, 0xdd, 0x4e, 0x34, 0x87, 0x37, 0xc7, - 0x2a, 0xe9, 0x29, 0x6f, 0x16, 0x52, 0x4f, 0x28, 0x7d, 0x8d, 0x04, 0x37, 0xc7, 0x5a, 0x28, 0xe1, - 0x4d, 0x65, 0x8d, 0x21, 0x6f, 0x28, 0x59, 0x7c, 0xda, 0x07, 0x45, 0x29, 0xba, 0xf6, 0xa6, 0xf7, - 0xdc, 0x37, 0x42, 0x56, 0x5a, 0xfb, 0xee, 0x9b, 0x3d, 0x69, 0xc2, 0xed, 0x18, 0xc4, 0x57, 0xc0, - 0xa6, 0x50, 0x04, 0xdd, 0x6a, 0xaa, 0x97, 0x5b, 0x9b, 0xf6, 0xb9, 0xdd, 0xe1, 0xe9, 0x62, 0x9e, - 0xa9, 0xc6, 0x24, 0xdd, 0xda, 0x54, 0xb7, 0x5b, 0x44, 0xe3, 0x6d, 0x41, 0xe3, 0x56, 0xa6, 0x97, - 0x4f, 0xc3, 0x66, 0x9c, 0xac, 0x72, 0xbd, 0x17, 0x4b, 0xd7, 0x53, 0x85, 0x51, 0x47, 0x3d, 0x51, - 0x24, 0x6d, 0xf6, 0xa4, 0xf1, 0xfe, 0x9c, 0xe5, 0x56, 0xc7, 0xd3, 0x56, 0x87, 0xad, 0x56, 0x48, - 0x3d, 0xeb, 0xaf, 0x80, 0x77, 0x43, 0x55, 0x54, 0x1d, 0x26, 0xa5, 0xd8, 0x4b, 0xd2, 0x74, 0xb8, - 0x1e, 0x08, 0x93, 0x06, 0x0a, 0xee, 0x86, 0x7a, 0x60, 0x22, 0x92, 0x9b, 0xdd, 0xc3, 0x6c, 0xd8, - 0x65, 0x47, 0x52, 0xbd, 0x22, 0xd9, 0xa6, 0xd1, 0x8e, 0x96, 0xf5, 0xa8, 0x75, 0x6d, 0x47, 0xe1, - 0x07, 0xd7, 0xaa, 0xf0, 0x56, 0x6f, 0x1e, 0x1d, 0xb7, 0x4b, 0x4a, 0xce, 0x2c, 0x0f, 0x28, 0x13, - 0xce, 0x4c, 0xf2, 0xb0, 0x83, 0x42, 0xbb, 0x82, 0x75, 0x37, 0x7a, 0x9b, 0x4c, 0x67, 0x20, 0xbc, - 0x27, 0x45, 0x36, 0x10, 0x3c, 0x29, 0x42, 0x20, 0x6a, 0xba, 0xfa, 0x77, 0xbd, 0x1d, 0x7a, 0x30, - 0xf5, 0x35, 0x9d, 0x52, 0xb6, 0xa8, 0x50, 0xd3, 0x79, 0x69, 0x34, 0x1a, 0x68, 0xb7, 0xea, 0xd5, - 0xf8, 0xa7, 0x21, 0x33, 0xe8, 0xfd, 0xf8, 0xf5, 0x5e, 0x2c, 0x9a, 0x51, 0x8c, 0xc3, 0x64, 0x9e, - 0x08, 0xdf, 0x8c, 0x62, 0xd9, 0xa8, 0x90, 0xd0, 0x8c, 0xd2, 0x46, 0xa9, 0xea, 0x55, 0x39, 0xc2, - 0xc1, 0x34, 0x5c, 0xbd, 0x9a, 0xe9, 0x57, 0x3d, 0xcd, 0xb6, 0x0e, 0x36, 0x33, 0x1d, 0x32, 0xe2, - 0x52, 0x2d, 0x96, 0x3d, 0xb1, 0x2d, 0x5f, 0x99, 0xc4, 0x60, 0x68, 0xd4, 0xa1, 0x14, 0xf0, 0x86, - 0x7d, 0xc5, 0x35, 0x67, 0xaf, 0x79, 0x0e, 0xac, 0x60, 0x59, 0xec, 0x5d, 0x9c, 0x4a, 0x83, 0x2d, - 0x32, 0xb4, 0x38, 0x25, 0x35, 0xd0, 0xb1, 0xb9, 0xfb, 0xb2, 0xa3, 0xa7, 0x2b, 0xe8, 0xb7, 0x0a, - 0xdd, 0x77, 0x1d, 0x9f, 0xf4, 0x20, 0xf1, 0xb1, 0x79, 0x03, 0xe8, 0x8d, 0xef, 0xda, 0xe9, 0xa7, - 0x01, 0x53, 0x2e, 0x1a, 0x5a, 0x08, 0xd3, 0x2a, 0x28, 0xa8, 0x75, 0x82, 0x0b, 0xe2, 0x27, 0xb0, - 0xf2, 0x05, 0xb5, 0xc9, 0x4f, 0x25, 0x12, 0x0a, 0xea, 0x36, 0x8a, 0xf2, 0x4c, 0x7b, 0x1d, 0xf4, - 0x28, 0xa0, 0x6f, 0x2f, 0x7d, 0xd6, 0x3a, 0x39, 0xd4, 0x73, 0x76, 0x93, 0xa5, 0x73, 0x4e, 0xe0, - 0x29, 0xe8, 0x6e, 0xb2, 0xf4, 0x1f, 0x13, 0xac, 0xf7, 0x62, 0xf1, 0x91, 0x3c, 0x13, 0xf0, 0xae, - 0x39, 0x2b, 0xf7, 0x14, 0x57, 0xca, 0x5b, 0x87, 0xe5, 0x8f, 0xbb, 0x41, 0x73, 0x01, 0xf6, 0xa4, - 0xe0, 0x31, 0x94, 0xa5, 0xfa, 0x3e, 0x9d, 0x7b, 0xc3, 0x48, 0xc9, 0x46, 0xe8, 0xeb, 0x74, 0x0f, - 0xc2, 0x90, 0xb2, 0xfd, 0x55, 0xf4, 0xfe, 0x21, 0x9f, 0x8d, 0x21, 0x9b, 0x0e, 0x7f, 0xe0, 0x5e, - 0x39, 0xe5, 0xb3, 0x51, 0xf5, 0xb3, 0xb6, 0x77, 0x8b, 0x12, 0x9b, 0x4b, 0x73, 0xbb, 0x70, 0xbe, - 0x98, 0x8d, 0x05, 0x13, 0xe8, 0xd2, 0x9c, 0xfc, 0x7d, 0x54, 0x09, 0x88, 0x4b, 0x73, 0x0e, 0x80, - 0xec, 0x4d, 0x0a, 0x00, 0xaf, 0xbd, 0x4a, 0x10, 0xb4, 0xa7, 0x00, 0x33, 0xeb, 0x6a, 0x7b, 0x55, - 0x62, 0x8b, 0x2f, 0xb9, 0x19, 0x1d, 0x29, 0x25, 0x66, 0xdd, 0x36, 0x65, 0x82, 0xa1, 0xae, 0xbe, - 0xfc, 0x62, 0xc6, 0x62, 0x3e, 0x67, 0xc5, 0x0a, 0x05, 0x83, 0xaa, 0xa5, 0x05, 0x10, 0xc1, 0xe0, - 0x05, 0x4d, 0x94, 0x37, 0x8f, 0x39, 0xbe, 0xda, 0xe7, 0x05, 0x5f, 0x88, 0x24, 0x03, 0xfc, 0xd5, - 0x04, 0xfd, 0x40, 0x6d, 0x86, 0x88, 0x72, 0x8a, 0x35, 0x59, 0xa1, 0x24, 0xea, 0xfb, 0x77, 0xf2, - 0x2b, 0xaf, 0xa5, 0xe0, 0x05, 0x3e, 0x7f, 0xab, 0xad, 0x60, 0x88, 0xc8, 0x0a, 0x49, 0x18, 0xb5, - 0xfd, 0x49, 0x92, 0xcd, 0xbc, 0x6d, 0x7f, 0x62, 0x7f, 0x23, 0xf1, 0x0e, 0x0d, 0x98, 0xf1, 0xbd, - 0x7e, 0x68, 0xf5, 0x97, 0x89, 0xd4, 0xbb, 0x8f, 0xde, 0x87, 0x6e, 0x13, 0xc4, 0xf8, 0xee, 0x27, - 0x91, 0xab, 0xd7, 0x39, 0x64, 0x30, 0x6d, 0x6e, 0x99, 0xf9, 0x5c, 0x39, 0x44, 0xd0, 0x15, 0x26, - 0xcd, 0xa8, 0x2a, 0xe5, 0xa7, 0x8b, 0xec, 0xa4, 0xe0, 0x17, 0x49, 0x0a, 0x05, 0x1a, 0x55, 0x6b, - 0x75, 0x4b, 0x4e, 0x8c, 0xaa, 0x3e, 0xce, 0x5c, 0x57, 0x90, 0x52, 0xe7, 0x53, 0xc5, 0x93, 0x82, - 0xc5, 0xf8, 0xba, 0x42, 0x6d, 0xa3, 0x8d, 0x11, 0x3b, 0x69, 0x01, 0xdc, 0x44, 0xfa, 0x11, 0x88, - 0x22, 0x89, 0xcb, 0x31, 0x88, 0x13, 0x56, 0xb0, 0x39, 0x08, 0x28, 0x70, 0xa4, 0x2b, 0x64, 0xe4, - 0x30, 0x44, 0xa4, 0x53, 0xac, 0x72, 0xf8, 0x07, 0xd1, 0x87, 0xd5, 0x40, 0x0f, 0x99, 0xfa, 0xaa, - 0xfe, 0x2b, 0xf9, 0xe7, 0x38, 0x86, 0x1f, 0x69, 0x1b, 0x63, 0x51, 0x00, 0x9b, 0x37, 0xb6, 0x3f, - 0xd0, 0xbf, 0x4b, 0xf0, 0xd9, 0xa0, 0x6a, 0x90, 0x63, 0x2e, 0x92, 0x8b, 0x6a, 0x5d, 0xa5, 0x5e, - 0x19, 0x41, 0x0d, 0x62, 0x8b, 0x47, 0x81, 0x0f, 0x01, 0xf8, 0x38, 0x33, 0xd0, 0xd8, 0xd2, 0x53, - 0xc8, 0x53, 0x3c, 0xd0, 0x38, 0xda, 0x12, 0x20, 0x06, 0x1a, 0x2f, 0x68, 0xa2, 0xcb, 0x16, 0x4f, - 0x20, 0x5c, 0x99, 0x09, 0xf4, 0xab, 0xcc, 0xc4, 0xb9, 0x85, 0x9f, 0x46, 0x1f, 0x1e, 0xc1, 0xfc, - 0x1c, 0x8a, 0xf2, 0x32, 0xc9, 0xf7, 0xab, 0x19, 0x96, 0x89, 0x05, 0x7e, 0x4f, 0xcd, 0x10, 0x23, - 0x8d, 0x10, 0x69, 0x08, 0x81, 0x9a, 0xa1, 0xcc, 0x00, 0x07, 0xe5, 0x31, 0x9b, 0x83, 0xfc, 0xac, - 0xc1, 0x70, 0x9d, 0x32, 0x62, 0x41, 0xc4, 0x50, 0x46, 0xc2, 0xd6, 0x0b, 0x3d, 0x86, 0x39, 0x85, - 0x59, 0x15, 0x61, 0xc5, 0x09, 0x5b, 0xcd, 0x21, 0x13, 0xca, 0x24, 0xda, 0x84, 0xb5, 0x4c, 0xfa, - 0x79, 0x62, 0x13, 0xb6, 0x8f, 0x9e, 0x95, 0x74, 0x3b, 0x0f, 0xfe, 0x84, 0x17, 0xa2, 0xfe, 0x9b, - 0x19, 0x67, 0x45, 0x8a, 0x92, 0x6e, 0xf7, 0xa1, 0x3a, 0x24, 0x91, 0x74, 0x87, 0x35, 0xac, 0x8f, - 0x4d, 0x3b, 0x65, 0x78, 0x03, 0x85, 0x8e, 0x93, 0x57, 0x73, 0x96, 0xa4, 0x2a, 0x1a, 0x7e, 0x14, - 0xb0, 0x4d, 0xe8, 0x10, 0x1f, 0x9b, 0xee, 0xab, 0x6b, 0x7d, 0x9e, 0x3b, 0x5c, 0x42, 0xb4, 0x27, - 0xdc, 0x61, 0x9f, 0xd8, 0x13, 0xee, 0xd6, 0x32, 0x4b, 0x35, 0xc3, 0x4a, 0x6e, 0x25, 0x89, 0x1d, - 0x3e, 0xc5, 0x1b, 0x44, 0x96, 0x4d, 0x04, 0x12, 0x4b, 0xb5, 0xa0, 0x82, 0x99, 0xdb, 0x0c, 0xb6, - 0x97, 0x64, 0x2c, 0x4d, 0x7e, 0x86, 0x6f, 0x17, 0x5b, 0x76, 0x1a, 0x82, 0x98, 0xdb, 0xfc, 0xa4, - 0xcf, 0xd5, 0x3e, 0x88, 0x49, 0x52, 0x0d, 0xfd, 0x8f, 0x03, 0xcf, 0x4d, 0x12, 0xdd, 0xae, 0x2c, - 0x52, 0xb9, 0xfa, 0xf9, 0x20, 0xba, 0x8d, 0x1f, 0xeb, 0x76, 0x9e, 0x8f, 0xab, 0x94, 0xe4, 0x14, - 0x62, 0x48, 0x72, 0x31, 0xfc, 0x3c, 0xfc, 0xac, 0x10, 0x4e, 0x9c, 0xac, 0xf7, 0x50, 0xb3, 0xce, - 0x6b, 0xab, 0xb1, 0x64, 0x5c, 0xff, 0x31, 0xa9, 0xb3, 0x12, 0x0a, 0x35, 0x53, 0xee, 0x83, 0x40, - 0xbd, 0xd3, 0xe2, 0x46, 0x16, 0x58, 0x55, 0x94, 0xe8, 0x9d, 0x61, 0x0d, 0xb3, 0xbb, 0x63, 0x71, - 0xa7, 0x50, 0xf2, 0x74, 0x09, 0xf2, 0x82, 0xd9, 0x06, 0x69, 0xcc, 0xa2, 0x88, 0xdd, 0x1d, 0x9a, - 0x36, 0xe9, 0x46, 0xdb, 0xed, 0x76, 0xb6, 0x3a, 0xc0, 0x67, 0xe4, 0x1e, 0x4b, 0x12, 0x23, 0xd2, - 0x8d, 0x00, 0x6e, 0xed, 0x7e, 0x16, 0x9c, 0x4d, 0x63, 0x56, 0x8a, 0x13, 0xb6, 0x4a, 0x39, 0x9b, - 0xca, 0x79, 0x1d, 0xef, 0x7e, 0x36, 0xcc, 0xc8, 0x86, 0xa8, 0xdd, 0x4f, 0x0a, 0x36, 0x2b, 0x3b, - 0xf5, 0x37, 0xb2, 0xd4, 0xe5, 0xbd, 0xfb, 0x28, 0x47, 0x92, 0xe5, 0xc5, 0x17, 0xf7, 0x1e, 0x84, - 0x21, 0xf3, 0xd2, 0x51, 0x2d, 0x92, 0x69, 0xc8, 0x1d, 0x9f, 0x8e, 0x93, 0x80, 0xdc, 0x0d, 0x10, - 0xe6, 0x43, 0x04, 0xf5, 0xef, 0xcd, 0x9f, 0x79, 0x10, 0xea, 0xd3, 0xb8, 0x1b, 0x3e, 0x5d, 0x1b, - 0x1a, 0xd9, 0x5f, 0x17, 0xdb, 0xec, 0x49, 0x9b, 0x85, 0x9b, 0xfa, 0x3c, 0xef, 0x11, 0x94, 0x9e, - 0x37, 0x88, 0x2b, 0xe1, 0xc8, 0x48, 0x89, 0x85, 0x5b, 0x9b, 0x32, 0x81, 0x5e, 0xc9, 0x5e, 0x4d, - 0x13, 0xa1, 0x64, 0xcd, 0x95, 0xd8, 0x8d, 0xb6, 0x81, 0x36, 0x45, 0xd4, 0x8a, 0xa6, 0xcd, 0x58, - 0x5e, 0x31, 0x13, 0x3e, 0x9b, 0xa5, 0xa0, 0xa0, 0x53, 0x60, 0xf5, 0x57, 0xd4, 0xb6, 0xda, 0xb6, - 0xbc, 0x20, 0x31, 0x96, 0x07, 0x15, 0x4c, 0x1a, 0x59, 0x61, 0xf5, 0x19, 0x44, 0xf3, 0x60, 0xd7, - 0xda, 0x66, 0x1c, 0x80, 0x48, 0x23, 0xbd, 0xa0, 0x79, 0xd1, 0xa9, 0x12, 0xef, 0x43, 0xf3, 0x24, - 0xf0, 0x37, 0x67, 0xa4, 0xb2, 0x25, 0x26, 0x5e, 0x74, 0xf2, 0x60, 0x66, 0x9d, 0x80, 0x3c, 0xbc, - 0x5c, 0x1d, 0x4c, 0xf1, 0x3a, 0x01, 0xeb, 0x4b, 0x86, 0x58, 0x27, 0x50, 0xac, 0xdb, 0x74, 0xfa, - 0x03, 0xbb, 0x87, 0xac, 0x34, 0x95, 0xf3, 0x34, 0x9d, 0x17, 0x0c, 0x35, 0x1d, 0xa5, 0xe0, 0x3e, - 0x52, 0xfb, 0xf3, 0xbd, 0x9e, 0x47, 0xea, 0xfb, 0x6c, 0xef, 0xa3, 0x2e, 0xac, 0xf6, 0xf0, 0xf2, - 0xee, 0x7f, 0x7f, 0x73, 0x6b, 0xf0, 0x8b, 0x6f, 0x6e, 0x0d, 0x7e, 0xf9, 0xcd, 0xad, 0xc1, 0xcf, - 0xbf, 0xbd, 0xf5, 0xde, 0x2f, 0xbe, 0xbd, 0xf5, 0xde, 0xff, 0x7c, 0x7b, 0xeb, 0xbd, 0xaf, 0xdf, - 0x57, 0x7f, 0xdf, 0xf0, 0xfc, 0xff, 0xc9, 0xbf, 0x52, 0xf8, 0xe2, 0xff, 0x02, 0x00, 0x00, 0xff, - 0xff, 0x06, 0x0c, 0x0e, 0xc0, 0x03, 0x71, 0x00, 0x00, + 0x56, 0xf8, 0xa7, 0x5e, 0xfe, 0xf3, 0x27, 0x97, 0x1d, 0xa0, 0x06, 0x86, 0xd9, 0x61, 0xb7, 0xbb, + 0xa7, 0x6f, 0xee, 0x6e, 0xdb, 0xe9, 0x9e, 0xee, 0xe9, 0x99, 0xd5, 0x2e, 0x12, 0x72, 0xdb, 0x6d, + 0x8f, 0x59, 0xdb, 0x6d, 0x5c, 0xe5, 0x6e, 0x69, 0x24, 0x24, 0xc2, 0x99, 0xe1, 0x72, 0xe2, 0xac, + 0x8c, 0xdc, 0xcc, 0xa8, 0x72, 0xd7, 0x22, 0x10, 0x08, 0x04, 0x02, 0x81, 0x58, 0x71, 0x7b, 0x45, + 0xe2, 0x89, 0x8f, 0xc2, 0xe3, 0x3e, 0xf2, 0x88, 0x66, 0xf8, 0x20, 0x28, 0x23, 0x22, 0xe3, 0x72, + 0x32, 0x4e, 0x64, 0x7a, 0x9f, 0xba, 0x55, 0xe7, 0x77, 0xce, 0x89, 0xeb, 0x89, 0x13, 0x91, 0x91, + 0xe9, 0xe8, 0x76, 0x79, 0xbe, 0x55, 0x56, 0x8c, 0xb3, 0x7a, 0xab, 0xa6, 0xd5, 0x32, 0x4b, 0x68, + 0xfb, 0x6f, 0x2c, 0x7e, 0x1e, 0xbf, 0x4f, 0x8a, 0x15, 0x5f, 0x95, 0xf4, 0x93, 0x8f, 0x0d, 0x99, + 0xb0, 0xf9, 0x9c, 0x14, 0x69, 0x2d, 0x91, 0x4f, 0x3e, 0x32, 0x12, 0xba, 0xa4, 0x05, 0x57, 0xbf, + 0x3f, 0xfb, 0xcf, 0xff, 0x1d, 0x45, 0x1f, 0xec, 0xe4, 0x19, 0x2d, 0xf8, 0x8e, 0xd2, 0x18, 0x7f, + 0x1d, 0x7d, 0x77, 0xbb, 0x2c, 0xf7, 0x29, 0x7f, 0x43, 0xab, 0x3a, 0x63, 0xc5, 0xf8, 0x5e, 0xac, + 0x1c, 0xc4, 0xa7, 0x65, 0x12, 0x6f, 0x97, 0x65, 0x6c, 0x84, 0xf1, 0x29, 0xfd, 0xe9, 0x82, 0xd6, + 0xfc, 0x93, 0xfb, 0x61, 0xa8, 0x2e, 0x59, 0x51, 0xd3, 0xf1, 0x45, 0xf4, 0x1b, 0xdb, 0x65, 0x39, + 0xa1, 0x7c, 0x97, 0x36, 0x15, 0x98, 0x70, 0xc2, 0xe9, 0x78, 0xad, 0xa3, 0xea, 0x02, 0xda, 0xc7, + 0xa3, 0x7e, 0x50, 0xf9, 0x99, 0x46, 0xdf, 0x69, 0xfc, 0x5c, 0x2e, 0x78, 0xca, 0xae, 0x8b, 0xf1, + 0xa7, 0x5d, 0x45, 0x25, 0xd2, 0xb6, 0xef, 0x86, 0x10, 0x65, 0xf5, 0x6d, 0xf4, 0xab, 0x6f, 0x49, + 0x9e, 0x53, 0xbe, 0x53, 0xd1, 0xa6, 0xe0, 0xae, 0x8e, 0x14, 0xc5, 0x52, 0xa6, 0xed, 0xde, 0x0b, + 0x32, 0xca, 0xf0, 0xd7, 0xd1, 0x77, 0xa5, 0xe4, 0x94, 0x26, 0x6c, 0x49, 0xab, 0xb1, 0x57, 0x4b, + 0x09, 0x91, 0x26, 0xef, 0x40, 0xd0, 0xf6, 0x0e, 0x2b, 0x96, 0xb4, 0xe2, 0x7e, 0xdb, 0x4a, 0x18, + 0xb6, 0x6d, 0x20, 0x65, 0xfb, 0x6f, 0x47, 0xd1, 0xf7, 0xb7, 0x93, 0x84, 0x2d, 0x0a, 0x7e, 0xc8, + 0x12, 0x92, 0x1f, 0x66, 0xc5, 0xd5, 0x31, 0xbd, 0xde, 0xb9, 0x6c, 0xf8, 0x62, 0x46, 0xc7, 0xcf, + 0xdd, 0x56, 0x95, 0x68, 0xac, 0xd9, 0xd8, 0x86, 0xb5, 0xef, 0xcf, 0x6f, 0xa6, 0xa4, 0xca, 0xf2, + 0x8f, 0xa3, 0xe8, 0x16, 0x2c, 0xcb, 0x84, 0xe5, 0x4b, 0x6a, 0x4a, 0xf3, 0xa2, 0xc7, 0xb0, 0x8b, + 0xeb, 0xf2, 0x7c, 0x71, 0x53, 0x35, 0x55, 0xa2, 0x3c, 0xfa, 0xd0, 0x1e, 0x2e, 0x13, 0x5a, 0x8b, + 0xe9, 0xf4, 0x18, 0x1f, 0x11, 0x0a, 0xd1, 0x9e, 0x9f, 0x0c, 0x41, 0x95, 0xb7, 0x2c, 0x1a, 0x2b, + 0x6f, 0x39, 0xab, 0xb5, 0xb3, 0x47, 0x5e, 0x0b, 0x16, 0xa1, 0x7d, 0x3d, 0x1e, 0x40, 0x2a, 0x57, + 0x7f, 0x14, 0xfd, 0xda, 0x5b, 0x56, 0x5d, 0xd5, 0x25, 0x49, 0xa8, 0x9a, 0x0a, 0x0f, 0x5c, 0xed, + 0x56, 0x0a, 0x67, 0xc3, 0xc3, 0x3e, 0xcc, 0x1a, 0xb4, 0xad, 0xf0, 0x75, 0x49, 0x61, 0x0c, 0x32, + 0x8a, 0x8d, 0x10, 0x1b, 0xb4, 0x10, 0x52, 0xb6, 0xaf, 0xa2, 0xb1, 0xb1, 0x7d, 0xfe, 0xc7, 0x34, + 0xe1, 0xdb, 0x69, 0x0a, 0x7b, 0xc5, 0xe8, 0x0a, 0x22, 0xde, 0x4e, 0x53, 0xac, 0x57, 0xfc, 0xa8, + 0x72, 0x76, 0x1d, 0x7d, 0x04, 0x9c, 0x1d, 0x66, 0xb5, 0x70, 0xb8, 0x19, 0xb6, 0xa2, 0x30, 0xed, + 0x34, 0x1e, 0x8a, 0x2b, 0xc7, 0x7f, 0x3e, 0x8a, 0xbe, 0xe7, 0xf1, 0x7c, 0x4a, 0xe7, 0x6c, 0x49, + 0xc7, 0x4f, 0xfb, 0xad, 0x49, 0x52, 0xfb, 0xff, 0xec, 0x06, 0x1a, 0x9e, 0x61, 0x32, 0xa1, 0x39, + 0x4d, 0x38, 0x3a, 0x4c, 0xa4, 0xb8, 0x77, 0x98, 0x68, 0xcc, 0x9a, 0x61, 0xad, 0x70, 0x9f, 0xf2, + 0x9d, 0x45, 0x55, 0xd1, 0x82, 0xa3, 0x7d, 0x69, 0x90, 0xde, 0xbe, 0x74, 0x50, 0x4f, 0x7d, 0xf6, + 0x29, 0xdf, 0xce, 0x73, 0xb4, 0x3e, 0x52, 0xdc, 0x5b, 0x1f, 0x8d, 0x29, 0x0f, 0x49, 0xf4, 0xeb, + 0x56, 0x8b, 0xf1, 0x83, 0xe2, 0x82, 0x8d, 0xf1, 0xb6, 0x10, 0x72, 0xed, 0x63, 0xad, 0x97, 0xf3, + 0x54, 0xe3, 0xd5, 0xbb, 0x92, 0x55, 0x78, 0xb7, 0x48, 0x71, 0x6f, 0x35, 0x34, 0xa6, 0x3c, 0xfc, + 0x61, 0xf4, 0x81, 0x8a, 0x92, 0xed, 0x7a, 0x76, 0xdf, 0x1b, 0x42, 0xe1, 0x82, 0xf6, 0xa0, 0x87, + 0x32, 0xc1, 0x41, 0xc9, 0x54, 0xf0, 0xb9, 0xe7, 0xd5, 0x03, 0xa1, 0xe7, 0x7e, 0x18, 0xea, 0xd8, + 0xde, 0xa5, 0x39, 0x45, 0x6d, 0x4b, 0x61, 0x8f, 0x6d, 0x0d, 0x29, 0xdb, 0x55, 0xf4, 0x5b, 0xba, + 0x59, 0x9a, 0x75, 0x54, 0xc8, 0x9b, 0x20, 0xbd, 0x8e, 0xd4, 0xdb, 0x86, 0xb4, 0xaf, 0x8d, 0x61, + 0x70, 0xa7, 0x3e, 0x6a, 0x06, 0xfa, 0xeb, 0x03, 0xe6, 0xdf, 0xfd, 0x30, 0xa4, 0x6c, 0xff, 0xdd, + 0x28, 0xfa, 0x81, 0x92, 0xbd, 0x2a, 0xc8, 0x79, 0x4e, 0xc5, 0x92, 0x78, 0x4c, 0xf9, 0x35, 0xab, + 0xae, 0x26, 0xab, 0x22, 0x41, 0x96, 0x7f, 0x3f, 0xdc, 0xb3, 0xfc, 0xa3, 0x4a, 0x56, 0xc6, 0xa7, + 0x2a, 0xca, 0x59, 0x09, 0x33, 0xbe, 0xb6, 0x06, 0x9c, 0x95, 0x58, 0xc6, 0xe7, 0x22, 0x1d, 0xab, + 0x47, 0x4d, 0xd8, 0xf4, 0x5b, 0x3d, 0xb2, 0xe3, 0xe4, 0xdd, 0x10, 0x62, 0xc2, 0x56, 0x3b, 0x80, + 0x59, 0x71, 0x91, 0xcd, 0xce, 0xca, 0xb4, 0x19, 0xc6, 0x8f, 0xfd, 0x23, 0xd4, 0x42, 0x90, 0xb0, + 0x85, 0xa0, 0xca, 0xdb, 0x3f, 0x98, 0xc4, 0x48, 0x4d, 0xa5, 0xbd, 0x8a, 0xcd, 0x0f, 0xe9, 0x8c, + 0x24, 0x2b, 0x35, 0xff, 0x3f, 0x0f, 0x4d, 0x3c, 0x48, 0xeb, 0x42, 0xbc, 0xb8, 0xa1, 0x96, 0x2a, + 0xcf, 0xbf, 0x8f, 0xa2, 0xfb, 0x6d, 0xf5, 0x2f, 0x49, 0x31, 0xa3, 0xaa, 0x3f, 0x65, 0xe9, 0xb7, + 0x8b, 0xf4, 0x94, 0xd6, 0x9c, 0x54, 0x7c, 0xfc, 0x23, 0x7f, 0x25, 0x43, 0x3a, 0xba, 0x6c, 0x3f, + 0xfe, 0xa5, 0x74, 0x4d, 0xaf, 0x4f, 0x9a, 0xc0, 0xa6, 0x42, 0x80, 0xdb, 0xeb, 0x42, 0x02, 0x03, + 0xc0, 0xdd, 0x10, 0x62, 0x7a, 0x5d, 0x08, 0x0e, 0x8a, 0x65, 0xc6, 0xe9, 0x3e, 0x2d, 0x68, 0xd5, + 0xed, 0x75, 0xa9, 0xea, 0x22, 0x48, 0xaf, 0x23, 0xa8, 0x09, 0x36, 0x8e, 0x37, 0xbd, 0x38, 0xae, + 0x07, 0x8c, 0x74, 0x96, 0xc7, 0x8d, 0x61, 0xb0, 0xd9, 0xdd, 0x59, 0x3e, 0x4f, 0xe9, 0x92, 0x5d, + 0xc1, 0xdd, 0x9d, 0x6d, 0x42, 0x02, 0xc8, 0xee, 0xce, 0x0b, 0x9a, 0x15, 0xcc, 0xf2, 0xf3, 0x26, + 0xa3, 0xd7, 0x60, 0x05, 0xb3, 0x95, 0x1b, 0x31, 0xb2, 0x82, 0x79, 0x30, 0xe5, 0xe1, 0x38, 0xfa, + 0x15, 0x21, 0xfc, 0x7d, 0x96, 0x15, 0xe3, 0xdb, 0x1e, 0xa5, 0x46, 0xa0, 0xad, 0xde, 0xc1, 0x01, + 0x50, 0xe2, 0xe6, 0xd7, 0x1d, 0x52, 0x24, 0x34, 0xf7, 0x96, 0xd8, 0x88, 0x83, 0x25, 0x76, 0x30, + 0x93, 0x3a, 0x08, 0x61, 0x13, 0xbf, 0x26, 0x97, 0xa4, 0xca, 0x8a, 0xd9, 0xd8, 0xa7, 0x6b, 0xc9, + 0x91, 0xd4, 0xc1, 0xc7, 0x81, 0x21, 0xac, 0x14, 0xb7, 0xcb, 0xb2, 0x6a, 0xc2, 0xa2, 0x6f, 0x08, + 0xbb, 0x48, 0x70, 0x08, 0x77, 0x50, 0xbf, 0xb7, 0x5d, 0x9a, 0xe4, 0x59, 0x11, 0xf4, 0xa6, 0x90, + 0x21, 0xde, 0x0c, 0x0a, 0x06, 0xef, 0x21, 0x25, 0x4b, 0xda, 0xd6, 0xcc, 0xd7, 0x32, 0x36, 0x10, + 0x1c, 0xbc, 0x00, 0x34, 0xfb, 0x34, 0x21, 0x3e, 0x22, 0x57, 0xb4, 0x69, 0x60, 0xda, 0xac, 0x6b, + 0x63, 0x9f, 0xbe, 0x43, 0x20, 0xfb, 0x34, 0x3f, 0xa9, 0x5c, 0x2d, 0xa2, 0x8f, 0x84, 0xfc, 0x84, + 0x54, 0x3c, 0x4b, 0xb2, 0x92, 0x14, 0x6d, 0xfe, 0xef, 0x9b, 0xd7, 0x1d, 0x4a, 0xbb, 0xdc, 0x1c, + 0x48, 0x2b, 0xb7, 0xff, 0x36, 0x8a, 0x3e, 0x85, 0x7e, 0x4f, 0x68, 0x35, 0xcf, 0xc4, 0x36, 0xb2, + 0x96, 0x41, 0x78, 0xfc, 0x65, 0xd8, 0x68, 0x47, 0x41, 0x97, 0xe6, 0x87, 0x37, 0x57, 0x54, 0x05, + 0xfb, 0x83, 0x28, 0x92, 0xdb, 0x15, 0xb1, 0xa5, 0x74, 0x67, 0xad, 0xda, 0xc7, 0x38, 0xfb, 0xc9, + 0x4f, 0x03, 0x84, 0x59, 0x2a, 0xe4, 0xef, 0x62, 0xa7, 0x3c, 0xf6, 0x6a, 0x08, 0x11, 0xb2, 0x54, + 0x00, 0x04, 0x16, 0x74, 0x72, 0xc9, 0xae, 0xfd, 0x05, 0x6d, 0x24, 0xe1, 0x82, 0x2a, 0xc2, 0x9c, + 0x5d, 0xa9, 0x82, 0xfa, 0xce, 0xae, 0xda, 0x62, 0x84, 0xce, 0xae, 0x20, 0xa3, 0x0c, 0xb3, 0xe8, + 0x37, 0x6d, 0xc3, 0x2f, 0x19, 0xbb, 0x9a, 0x93, 0xea, 0x6a, 0xfc, 0x04, 0x57, 0x6e, 0x19, 0xed, + 0x68, 0x7d, 0x10, 0x6b, 0xc2, 0x82, 0xed, 0xb0, 0x49, 0x34, 0xce, 0xaa, 0x1c, 0x84, 0x05, 0xc7, + 0x86, 0x42, 0x90, 0xb0, 0x80, 0xa0, 0x26, 0x72, 0xdb, 0xde, 0x26, 0x14, 0xee, 0x96, 0x1c, 0xf5, + 0x09, 0xc5, 0x76, 0x4b, 0x1e, 0x0c, 0x0e, 0xa1, 0xfd, 0x8a, 0x94, 0x97, 0xfe, 0x21, 0x24, 0x44, + 0xe1, 0x21, 0xd4, 0x22, 0xb0, 0xbf, 0x27, 0x94, 0x54, 0xc9, 0xa5, 0xbf, 0xbf, 0xa5, 0x2c, 0xdc, + 0xdf, 0x9a, 0x81, 0xfd, 0x2d, 0x05, 0x6f, 0x33, 0x7e, 0x79, 0x44, 0x39, 0xf1, 0xf7, 0xb7, 0xcb, + 0x84, 0xfb, 0xbb, 0xc3, 0x9a, 0x4c, 0xc6, 0x76, 0x38, 0x59, 0x9c, 0xd7, 0x49, 0x95, 0x9d, 0xd3, + 0x71, 0xc0, 0x8a, 0x86, 0x90, 0x4c, 0x06, 0x85, 0x95, 0xcf, 0x9f, 0x8f, 0xa2, 0xdb, 0x6d, 0xb7, + 0xb3, 0xba, 0x96, 0x2b, 0x2b, 0x70, 0xff, 0xc2, 0xdf, 0xbf, 0x08, 0x8e, 0x9c, 0x26, 0x0e, 0x50, + 0xb3, 0xa2, 0xaa, 0xbf, 0x48, 0x67, 0x45, 0xad, 0x0b, 0xf5, 0xe5, 0x10, 0xeb, 0x96, 0x02, 0x12, + 0x55, 0x07, 0x29, 0x9a, 0x05, 0x4d, 0xf5, 0x4f, 0x2b, 0x3b, 0x48, 0x6b, 0xb0, 0xa0, 0xb5, 0xed, + 0x6d, 0x11, 0xc8, 0x82, 0xe6, 0x27, 0xe1, 0x50, 0xd8, 0xaf, 0xd8, 0xa2, 0xac, 0x7b, 0x86, 0x02, + 0x80, 0xc2, 0x43, 0xa1, 0x0b, 0x2b, 0x9f, 0xef, 0xa2, 0xdf, 0xb6, 0x87, 0x9f, 0xdd, 0xd8, 0x9b, + 0xf8, 0x98, 0xf2, 0x35, 0x71, 0x3c, 0x14, 0x37, 0x29, 0x5d, 0xeb, 0x99, 0xef, 0x52, 0x4e, 0xb2, + 0xbc, 0x1e, 0x3f, 0xf4, 0xdb, 0x68, 0xe5, 0x48, 0x4a, 0xe7, 0xe3, 0x60, 0x7c, 0xdb, 0x5d, 0x94, + 0x79, 0x96, 0x74, 0xcf, 0x72, 0x95, 0xae, 0x16, 0x87, 0xe3, 0x9b, 0x8d, 0xc1, 0x78, 0x3d, 0xa1, + 0x5c, 0xfe, 0x67, 0xba, 0x2a, 0xa9, 0x3f, 0x5e, 0x3b, 0x48, 0x38, 0x5e, 0x43, 0x14, 0xd6, 0x67, + 0x42, 0xf9, 0x21, 0x59, 0xb1, 0x05, 0x12, 0xaf, 0xb5, 0x38, 0x5c, 0x1f, 0x1b, 0x33, 0x59, 0x95, + 0xf6, 0x70, 0x50, 0x70, 0x5a, 0x15, 0x24, 0xdf, 0xcb, 0xc9, 0xac, 0x1e, 0x23, 0x31, 0xc6, 0xa5, + 0x90, 0xac, 0x0a, 0xa7, 0x3d, 0xcd, 0x78, 0x50, 0xef, 0x91, 0x25, 0xab, 0x32, 0x8e, 0x37, 0xa3, + 0x41, 0x7a, 0x9b, 0xd1, 0x41, 0xbd, 0xde, 0xb6, 0xab, 0xe4, 0x32, 0x5b, 0xd2, 0x34, 0xe0, 0xad, + 0x45, 0x06, 0x78, 0xb3, 0x50, 0x4f, 0xa7, 0x4d, 0xd8, 0xa2, 0x4a, 0x28, 0xda, 0x69, 0x52, 0xdc, + 0xdb, 0x69, 0x1a, 0x53, 0x1e, 0xfe, 0x6a, 0x14, 0xfd, 0x8e, 0x94, 0xda, 0x07, 0xac, 0xbb, 0xa4, + 0xbe, 0x3c, 0x67, 0xa4, 0x4a, 0xc7, 0x9f, 0xf9, 0xec, 0x78, 0x51, 0xed, 0xfa, 0xd9, 0x4d, 0x54, + 0x60, 0xb3, 0x1e, 0x66, 0xb5, 0x35, 0xe3, 0xbc, 0xcd, 0xea, 0x20, 0xe1, 0x66, 0x85, 0x28, 0x0c, + 0x20, 0x42, 0x2e, 0x0f, 0x33, 0x1e, 0xa2, 0xfa, 0xee, 0x89, 0xc6, 0x5a, 0x2f, 0x07, 0xe3, 0x63, + 0x23, 0x74, 0x47, 0xcb, 0x26, 0x66, 0xc3, 0x3f, 0x62, 0xe2, 0xa1, 0x38, 0xea, 0x59, 0xcf, 0x8a, + 0xb0, 0xe7, 0xce, 0xcc, 0x88, 0x87, 0xe2, 0x88, 0x67, 0x2b, 0xac, 0x85, 0x3c, 0x7b, 0x42, 0x5b, + 0x3c, 0x14, 0x87, 0xd9, 0x97, 0x62, 0xda, 0x75, 0xe1, 0x49, 0xc0, 0x0e, 0x5c, 0x1b, 0xd6, 0x07, + 0xb1, 0xca, 0xe1, 0xdf, 0x8c, 0xa2, 0xef, 0x1b, 0x8f, 0x47, 0x2c, 0xcd, 0x2e, 0x56, 0x12, 0x7a, + 0x43, 0xf2, 0x05, 0xad, 0xc7, 0xcf, 0x30, 0x6b, 0x5d, 0x56, 0x97, 0xe0, 0xf9, 0x8d, 0x74, 0xe0, + 0xdc, 0xd9, 0x2e, 0xcb, 0x7c, 0x35, 0xa5, 0xf3, 0x32, 0x47, 0xe7, 0x8e, 0x83, 0x84, 0xe7, 0x0e, + 0x44, 0x61, 0x56, 0x3e, 0x65, 0x4d, 0xce, 0xef, 0xcd, 0xca, 0x85, 0x28, 0x9c, 0x95, 0xb7, 0x08, + 0xcc, 0x95, 0xa6, 0x6c, 0x87, 0xe5, 0x39, 0x4d, 0x78, 0xf7, 0x21, 0xad, 0xd6, 0x34, 0x44, 0x38, + 0x57, 0x02, 0xa4, 0x39, 0xcf, 0x68, 0xf7, 0x90, 0xa4, 0xa2, 0x2f, 0x57, 0x87, 0x59, 0x71, 0x35, + 0xf6, 0xa7, 0x05, 0x06, 0x40, 0xce, 0x33, 0xbc, 0x20, 0xdc, 0xab, 0x9e, 0x15, 0x29, 0xf3, 0xef, + 0x55, 0x1b, 0x49, 0x78, 0xaf, 0xaa, 0x08, 0x68, 0xf2, 0x94, 0x62, 0x26, 0x1b, 0x49, 0xd8, 0xa4, + 0x22, 0x7c, 0xa1, 0x50, 0x9d, 0x7a, 0xa3, 0xa1, 0x10, 0x9c, 0x73, 0xaf, 0xf5, 0x72, 0x70, 0x84, + 0xb6, 0x9b, 0xd6, 0x3d, 0xca, 0x93, 0x4b, 0xff, 0x08, 0x75, 0x90, 0xf0, 0x08, 0x85, 0x28, 0xac, + 0xd2, 0x94, 0xe9, 0x4d, 0xf7, 0x43, 0xff, 0xf8, 0xe8, 0x6c, 0xb8, 0xd7, 0x7a, 0x39, 0xb8, 0x8d, + 0x3c, 0x98, 0x8b, 0x36, 0xf3, 0x0e, 0x72, 0x29, 0x0b, 0x6f, 0x23, 0x35, 0x03, 0x4b, 0x2f, 0x05, + 0x4d, 0x73, 0xfa, 0x4b, 0x6f, 0xe4, 0xe1, 0xd2, 0x3b, 0x9c, 0x72, 0xf2, 0x2f, 0x7a, 0x1b, 0x27, + 0xa5, 0xc7, 0xac, 0x99, 0x23, 0x6f, 0x48, 0x9e, 0xa5, 0x84, 0xd3, 0x29, 0xbb, 0xa2, 0x85, 0x7f, + 0xc7, 0xa4, 0x4a, 0x2b, 0xf9, 0xd8, 0x51, 0x08, 0xef, 0x98, 0xc2, 0x8a, 0x70, 0x9c, 0x48, 0xfa, + 0xac, 0xa6, 0x3b, 0xa4, 0x46, 0x22, 0x99, 0x83, 0x84, 0xc7, 0x09, 0x44, 0x61, 0xbe, 0x2a, 0xe5, + 0xaf, 0xde, 0x95, 0xb4, 0xca, 0x68, 0x91, 0x50, 0x7f, 0xbe, 0x0a, 0xa9, 0x70, 0xbe, 0xea, 0xa1, + 0x3b, 0xc7, 0x34, 0x3a, 0x38, 0x75, 0xef, 0x59, 0x40, 0x22, 0x70, 0xcf, 0x02, 0x41, 0x61, 0x25, + 0x0d, 0xe0, 0x3d, 0xea, 0xec, 0x58, 0x09, 0x1e, 0x75, 0xe2, 0x74, 0xe7, 0xf0, 0x4b, 0x33, 0x93, + 0x66, 0x9a, 0xf4, 0x14, 0x7d, 0x62, 0x4f, 0x97, 0xf5, 0x41, 0xac, 0xff, 0xb4, 0xed, 0x94, 0xe6, + 0x44, 0x2c, 0x21, 0x81, 0x23, 0xad, 0x96, 0x19, 0x72, 0xda, 0x66, 0xb1, 0xca, 0xe1, 0x5f, 0x8c, + 0xa2, 0x4f, 0x7c, 0x1e, 0x5f, 0x97, 0xc2, 0xef, 0xd3, 0x7e, 0x5b, 0x92, 0x44, 0x2e, 0x92, 0x84, + 0x35, 0x54, 0x19, 0xfe, 0x24, 0xfa, 0xb8, 0x15, 0x99, 0x7b, 0x26, 0xaa, 0x00, 0x6e, 0x02, 0xa5, + 0xcb, 0x0f, 0x39, 0xed, 0x7e, 0x6b, 0x30, 0x6f, 0xf6, 0x26, 0x6e, 0xb9, 0x6a, 0xb0, 0x37, 0xd1, + 0x36, 0x94, 0x18, 0xd9, 0x9b, 0x78, 0x30, 0x73, 0xaa, 0x61, 0x57, 0xef, 0x6d, 0xc6, 0x2f, 0x45, + 0xee, 0x03, 0x4e, 0x35, 0x9c, 0xb2, 0x6a, 0x08, 0x39, 0xd5, 0x40, 0x61, 0x98, 0x1d, 0xb4, 0x60, + 0x33, 0x37, 0x7d, 0x71, 0x55, 0x1b, 0xb2, 0x67, 0xe6, 0xa3, 0x7e, 0x10, 0x8e, 0xd7, 0x56, 0xac, + 0xb6, 0x21, 0x4f, 0x42, 0x16, 0xc0, 0x56, 0x64, 0x7d, 0x10, 0xab, 0x1c, 0xfe, 0x59, 0xf4, 0xbd, + 0x4e, 0xc5, 0xf6, 0x28, 0xe1, 0x8b, 0x8a, 0xa6, 0xe3, 0xad, 0x9e, 0x72, 0xb7, 0xa0, 0x76, 0xfd, + 0x74, 0xb8, 0x42, 0x27, 0x5f, 0x6e, 0x39, 0x39, 0xac, 0x74, 0x19, 0x9e, 0x85, 0x4c, 0xba, 0x6c, + 0x30, 0x5f, 0xc6, 0x75, 0x3a, 0x5b, 0x5e, 0x7b, 0x74, 0x6d, 0x2f, 0x49, 0x96, 0x8b, 0x47, 0x4e, + 0x9f, 0x85, 0x8c, 0x3a, 0x68, 0x70, 0xcb, 0x8b, 0xaa, 0x74, 0x22, 0xb3, 0x98, 0xe3, 0xd6, 0x56, + 0x69, 0x03, 0x8f, 0x04, 0x9e, 0x9d, 0xd2, 0xe6, 0x40, 0x5a, 0xb9, 0xe5, 0xed, 0x51, 0x61, 0xf3, + 0xb3, 0x3d, 0xc8, 0x7d, 0x5e, 0x95, 0xaa, 0x67, 0xa4, 0x6f, 0x0e, 0xa4, 0x95, 0xd7, 0x3f, 0x8d, + 0x3e, 0xee, 0x7a, 0x55, 0x0b, 0xd1, 0x56, 0xaf, 0x29, 0xb0, 0x16, 0x3d, 0x1d, 0xae, 0x60, 0xb6, + 0x17, 0x5f, 0x65, 0x35, 0x67, 0xd5, 0x6a, 0x72, 0xc9, 0xae, 0xdb, 0xfb, 0xdb, 0xee, 0x6c, 0x55, + 0x40, 0x6c, 0x11, 0xc8, 0xf6, 0xc2, 0x4f, 0x76, 0x5c, 0x99, 0x7b, 0xde, 0x35, 0xe2, 0xca, 0x22, + 0x7a, 0x5c, 0xb9, 0xa4, 0x89, 0x55, 0x6d, 0xad, 0xcc, 0xa5, 0xf4, 0x35, 0x7f, 0x51, 0xbb, 0x17, + 0xd3, 0x1f, 0xf5, 0x83, 0x26, 0x63, 0x51, 0xe2, 0xdd, 0xec, 0xe2, 0x42, 0xd7, 0xc9, 0x5f, 0x52, + 0x1b, 0x41, 0x32, 0x16, 0x04, 0x35, 0x09, 0xf0, 0x5e, 0x96, 0x53, 0x71, 0xba, 0xfe, 0xfa, 0xe2, + 0x22, 0x67, 0x24, 0x05, 0x09, 0x70, 0x23, 0x8e, 0x6d, 0x39, 0x92, 0x00, 0xfb, 0x38, 0x73, 0xfd, + 0xab, 0x91, 0x9e, 0xd2, 0x84, 0x15, 0x49, 0x96, 0xc3, 0xeb, 0x6c, 0x42, 0x53, 0x0b, 0x91, 0xeb, + 0x5f, 0x1d, 0xc8, 0x2c, 0x8c, 0x8d, 0xa8, 0x99, 0xf6, 0x6d, 0xf9, 0x1f, 0x74, 0x15, 0x2d, 0x31, + 0xb2, 0x30, 0x7a, 0x30, 0xb3, 0x0f, 0x6c, 0x84, 0x67, 0xa5, 0x30, 0x7e, 0xa7, 0xab, 0x25, 0x25, + 0xc8, 0x3e, 0xd0, 0x25, 0xcc, 0x7e, 0xa6, 0xf9, 0x7d, 0x97, 0x5d, 0x17, 0xc2, 0xe8, 0xdd, 0xae, + 0x4a, 0x2b, 0x43, 0xf6, 0x33, 0x90, 0x51, 0x86, 0x7f, 0x12, 0xfd, 0x7f, 0x61, 0xb8, 0x62, 0xe5, + 0xf8, 0x96, 0x47, 0xa1, 0xb2, 0x6e, 0x9e, 0xdd, 0x46, 0xe5, 0xe6, 0x02, 0xa5, 0x1e, 0x1b, 0x67, + 0x35, 0x99, 0xd1, 0xf1, 0x7d, 0xa4, 0xc7, 0x85, 0x14, 0xb9, 0x40, 0xd9, 0xa5, 0xdc, 0x51, 0x71, + 0xcc, 0x52, 0x65, 0xdd, 0x53, 0x43, 0x2d, 0x0c, 0x8d, 0x0a, 0x1b, 0x32, 0xc9, 0xcc, 0x31, 0x59, + 0x66, 0x33, 0xbd, 0xe0, 0xc8, 0xb8, 0x55, 0x83, 0x64, 0xc6, 0x30, 0xb1, 0x05, 0x21, 0xc9, 0x0c, + 0x0a, 0x2b, 0x9f, 0xff, 0x3c, 0x8a, 0xee, 0x18, 0x66, 0xbf, 0x3d, 0x39, 0x3b, 0x28, 0x2e, 0x58, + 0x93, 0xfa, 0x1c, 0x66, 0xc5, 0x55, 0x3d, 0xfe, 0x02, 0x33, 0xe9, 0xe7, 0x75, 0x51, 0xbe, 0xbc, + 0xb1, 0x9e, 0xc9, 0x5a, 0xdb, 0x63, 0x25, 0xf3, 0x6c, 0x59, 0x6a, 0x80, 0xac, 0x55, 0x9f, 0x3e, + 0x41, 0x0e, 0xc9, 0x5a, 0x43, 0xbc, 0xe9, 0x62, 0xed, 0x3c, 0x67, 0x05, 0xec, 0x62, 0x63, 0xa1, + 0x11, 0x22, 0x5d, 0xdc, 0x81, 0x4c, 0x3c, 0x6e, 0x45, 0xf2, 0x04, 0x64, 0x3b, 0xcf, 0x41, 0x3c, + 0xd6, 0xaa, 0x1a, 0x40, 0xe2, 0xb1, 0x17, 0x54, 0x7e, 0x4e, 0xa3, 0xef, 0x34, 0x4d, 0x7a, 0x52, + 0xd1, 0x65, 0x46, 0xe1, 0x35, 0x08, 0x4b, 0x82, 0xcc, 0x7f, 0x97, 0x30, 0x33, 0xeb, 0xac, 0xa8, + 0xcb, 0x9c, 0xd4, 0x97, 0xea, 0xc1, 0xb8, 0x5b, 0xe7, 0x56, 0x08, 0x1f, 0x8d, 0x3f, 0xe8, 0xa1, + 0x4c, 0x50, 0x6f, 0x65, 0x3a, 0xc4, 0x3c, 0xf4, 0xab, 0x76, 0xc2, 0xcc, 0x5a, 0x2f, 0x67, 0x4e, + 0x9f, 0xf7, 0x49, 0x9e, 0xd3, 0x6a, 0xd5, 0xca, 0x8e, 0x48, 0x91, 0x5d, 0xd0, 0x9a, 0x83, 0xd3, + 0x67, 0x45, 0xc5, 0x10, 0x43, 0x4e, 0x9f, 0x03, 0xb8, 0xc9, 0xe6, 0x81, 0xe7, 0x83, 0x22, 0xa5, + 0xef, 0x40, 0x36, 0x0f, 0xed, 0x08, 0x06, 0xc9, 0xe6, 0x31, 0xd6, 0x9c, 0xc2, 0xbe, 0xcc, 0x59, + 0x72, 0xa5, 0x96, 0x00, 0xb7, 0x83, 0x85, 0x04, 0xae, 0x01, 0x77, 0x43, 0x88, 0x59, 0x04, 0x84, + 0xe0, 0x94, 0x96, 0x39, 0x49, 0xe0, 0x5d, 0x18, 0xa9, 0xa3, 0x64, 0xc8, 0x22, 0x00, 0x19, 0x50, + 0x5c, 0x75, 0xc7, 0xc6, 0x57, 0x5c, 0x70, 0xc5, 0xe6, 0x6e, 0x08, 0x31, 0xcb, 0xa0, 0x10, 0x4c, + 0xca, 0x3c, 0xe3, 0x60, 0x1a, 0x48, 0x0d, 0x21, 0x41, 0xa6, 0x81, 0x4b, 0x00, 0x93, 0x47, 0xb4, + 0x9a, 0x51, 0xaf, 0x49, 0x21, 0x09, 0x9a, 0x6c, 0x09, 0x73, 0x65, 0x52, 0xd6, 0x9d, 0x95, 0x2b, + 0x70, 0x65, 0x52, 0x55, 0x8b, 0x95, 0x2b, 0xe4, 0xca, 0xa4, 0x03, 0x80, 0x22, 0x9e, 0x90, 0x9a, + 0xfb, 0x8b, 0x28, 0x24, 0xc1, 0x22, 0xb6, 0x84, 0x59, 0xa3, 0x65, 0x11, 0x17, 0x1c, 0xac, 0xd1, + 0xaa, 0x00, 0xd6, 0xd3, 0xe0, 0xdb, 0xa8, 0xdc, 0x44, 0x12, 0xd9, 0x2b, 0x94, 0xef, 0x65, 0x34, + 0x4f, 0x6b, 0x10, 0x49, 0x54, 0xbb, 0xb7, 0x52, 0x24, 0x92, 0x74, 0x29, 0x30, 0x94, 0xd4, 0x59, + 0xb5, 0xaf, 0x76, 0xe0, 0x98, 0xfa, 0x6e, 0x08, 0x31, 0xf1, 0xa9, 0x2d, 0xf4, 0x0e, 0xa9, 0xaa, + 0xac, 0x59, 0xfc, 0x1f, 0xfa, 0x0b, 0xd4, 0xca, 0x91, 0xf8, 0xe4, 0xe3, 0xc0, 0xf4, 0x6a, 0x03, + 0xb7, 0xaf, 0x60, 0x30, 0x74, 0xdf, 0x0b, 0x32, 0x26, 0xe3, 0x14, 0x12, 0xeb, 0x71, 0xa6, 0xaf, + 0x35, 0x3d, 0x4f, 0x33, 0x1f, 0xf6, 0x61, 0xd6, 0x2b, 0x0d, 0xda, 0xc5, 0x11, 0x5b, 0xd2, 0x29, + 0x7b, 0xf5, 0x2e, 0xab, 0x79, 0x56, 0xcc, 0xd4, 0xca, 0xfd, 0x1c, 0xb1, 0xe4, 0x83, 0x91, 0x57, + 0x1a, 0x7a, 0x95, 0x4c, 0x02, 0x01, 0xca, 0x72, 0x4c, 0xaf, 0xbd, 0x09, 0x04, 0xb4, 0xa8, 0x39, + 0x24, 0x81, 0x08, 0xf1, 0xe6, 0x1c, 0x45, 0x3b, 0x57, 0xef, 0x7d, 0x4e, 0x59, 0x9b, 0xcb, 0x61, + 0xd6, 0x20, 0x88, 0x6c, 0x65, 0x83, 0x0a, 0x66, 0x7f, 0xa9, 0xfd, 0x9b, 0x29, 0xf6, 0x08, 0xb1, + 0xd3, 0x9d, 0x66, 0x8f, 0x07, 0x90, 0x1e, 0x57, 0xe6, 0x99, 0x3c, 0xe6, 0xaa, 0xfb, 0x48, 0xfe, + 0xf1, 0x00, 0xd2, 0x3a, 0x93, 0xb1, 0xab, 0xf5, 0x92, 0x24, 0x57, 0xb3, 0x8a, 0x2d, 0x8a, 0x74, + 0x87, 0xe5, 0xac, 0x02, 0x67, 0x32, 0x4e, 0xa9, 0x01, 0x8a, 0x9c, 0xc9, 0xf4, 0xa8, 0x98, 0x0c, + 0xce, 0x2e, 0xc5, 0x76, 0x9e, 0xcd, 0xe0, 0x8e, 0xda, 0x31, 0x24, 0x00, 0x24, 0x83, 0xf3, 0x82, + 0x9e, 0x41, 0x24, 0x77, 0xdc, 0x3c, 0x4b, 0x48, 0x2e, 0xfd, 0x6d, 0xe1, 0x66, 0x1c, 0xb0, 0x77, + 0x10, 0x79, 0x14, 0x3c, 0xf5, 0x9c, 0x2e, 0xaa, 0xe2, 0xa0, 0xe0, 0x0c, 0xad, 0x67, 0x0b, 0xf4, + 0xd6, 0xd3, 0x02, 0x41, 0x58, 0x9d, 0xd2, 0x77, 0x4d, 0x69, 0x9a, 0x7f, 0x7c, 0x61, 0xb5, 0xf9, + 0x3d, 0x56, 0xf2, 0x50, 0x58, 0x05, 0x1c, 0xa8, 0x8c, 0x72, 0x22, 0x07, 0x4c, 0x40, 0xdb, 0x1d, + 0x26, 0x8f, 0xfa, 0x41, 0xbf, 0x9f, 0x09, 0x5f, 0xe5, 0x34, 0xe4, 0x47, 0x00, 0x43, 0xfc, 0xb4, + 0xa0, 0x39, 0x6e, 0x71, 0xea, 0x73, 0x49, 0x93, 0xab, 0xce, 0x15, 0x23, 0xb7, 0xa0, 0x12, 0x41, + 0x8e, 0x5b, 0x10, 0xd4, 0xdf, 0x45, 0x07, 0x09, 0x2b, 0x42, 0x5d, 0xd4, 0xc8, 0x87, 0x74, 0x91, + 0xe2, 0xcc, 0xe6, 0x57, 0x4b, 0xd5, 0xc8, 0x94, 0xdd, 0xb4, 0x8e, 0x58, 0xb0, 0x21, 0x64, 0xf3, + 0x8b, 0xc2, 0x26, 0x27, 0x87, 0x3e, 0x8f, 0xba, 0xf7, 0xaf, 0x3b, 0x56, 0x8e, 0xf0, 0xfb, 0xd7, + 0x18, 0x8b, 0x57, 0x52, 0x8e, 0x91, 0x1e, 0x2b, 0xee, 0x38, 0xd9, 0x18, 0x06, 0x9b, 0x2d, 0x8f, + 0xe3, 0x73, 0x27, 0xa7, 0xa4, 0x92, 0x5e, 0x37, 0x03, 0x86, 0x0c, 0x86, 0x6c, 0x79, 0x02, 0x38, + 0x08, 0x61, 0x8e, 0xe7, 0x1d, 0x56, 0x70, 0x5a, 0x70, 0x5f, 0x08, 0x73, 0x8d, 0x29, 0x30, 0x14, + 0xc2, 0x30, 0x05, 0x30, 0x6e, 0xc5, 0x79, 0x10, 0xe5, 0xc7, 0x64, 0xee, 0xcd, 0xd8, 0xe4, 0x59, + 0x8f, 0x94, 0x87, 0xc6, 0x2d, 0xe0, 0xac, 0x87, 0x7c, 0xb6, 0x97, 0x29, 0xa9, 0x66, 0xfa, 0x74, + 0x23, 0x1d, 0x3f, 0xc5, 0xed, 0xb8, 0x24, 0xf2, 0x90, 0x2f, 0xac, 0x01, 0xc2, 0xce, 0xc1, 0x9c, + 0xcc, 0x74, 0x4d, 0x3d, 0x35, 0x10, 0xf2, 0x4e, 0x55, 0x1f, 0xf5, 0x83, 0xc0, 0xcf, 0x9b, 0x2c, + 0xa5, 0x2c, 0xe0, 0x47, 0xc8, 0x87, 0xf8, 0x81, 0x20, 0xc8, 0xde, 0x9a, 0x7a, 0xcb, 0x1d, 0xdd, + 0x76, 0x91, 0xaa, 0x7d, 0x6c, 0x8c, 0x34, 0x0f, 0xe0, 0x42, 0xd9, 0x1b, 0xc2, 0x83, 0x39, 0xda, + 0x1e, 0xd0, 0x86, 0xe6, 0xa8, 0x3e, 0x7f, 0x1d, 0x32, 0x47, 0x7d, 0xb0, 0xf2, 0xf9, 0x33, 0x35, + 0x47, 0x77, 0x09, 0x27, 0x4d, 0xde, 0xfe, 0x26, 0xa3, 0xd7, 0x6a, 0x23, 0xec, 0xa9, 0x6f, 0x4b, + 0xc5, 0xe2, 0xc5, 0x3b, 0xb0, 0x2b, 0xde, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x1d, 0x42, 0xaf, 0x6f, + 0xb0, 0x55, 0xd8, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x37, 0x7a, 0x7b, 0x7d, 0x83, 0xd7, 0x7a, 0xb7, + 0x06, 0xf3, 0xca, 0xf7, 0x5f, 0xb6, 0x13, 0xd7, 0x76, 0xde, 0xe4, 0x61, 0x09, 0xcf, 0x96, 0xd4, + 0x97, 0x4e, 0xba, 0xf6, 0x34, 0x1a, 0x4a, 0x27, 0x71, 0x15, 0xeb, 0x33, 0x30, 0xbe, 0x52, 0x9c, + 0xb0, 0x3a, 0x13, 0x0f, 0xe9, 0x9f, 0x0f, 0x30, 0xda, 0xc2, 0xa1, 0x4d, 0x53, 0x48, 0xc9, 0x3c, + 0x6e, 0x74, 0x50, 0x73, 0xa3, 0x78, 0x23, 0x60, 0xaf, 0x7b, 0xb1, 0x78, 0x73, 0x20, 0x6d, 0x1e, + 0xfc, 0x39, 0x8c, 0xfd, 0xc4, 0x31, 0xd4, 0xab, 0xde, 0x87, 0x8e, 0x4f, 0x87, 0x2b, 0x28, 0xf7, + 0x7f, 0xdd, 0xee, 0x2b, 0xa0, 0x7f, 0x35, 0x09, 0x9e, 0x0d, 0xb1, 0x08, 0x26, 0xc2, 0xf3, 0x1b, + 0xe9, 0xa8, 0x82, 0xfc, 0x7d, 0xbb, 0x81, 0x6e, 0x51, 0xf1, 0x5e, 0xc5, 0xeb, 0x2a, 0xa5, 0x95, + 0x9a, 0x13, 0xa1, 0x6e, 0x35, 0x30, 0x9c, 0x19, 0x2f, 0x6e, 0xa8, 0x65, 0x7d, 0x14, 0xc8, 0x81, + 0xd5, 0xfb, 0x7f, 0x56, 0x79, 0x42, 0x96, 0x2d, 0x1a, 0x16, 0xe8, 0x8b, 0x9b, 0xaa, 0x61, 0x73, + 0xc5, 0x82, 0xc5, 0x37, 0x06, 0x9e, 0x0f, 0x34, 0xec, 0x7c, 0x75, 0xe0, 0xf3, 0x9b, 0x29, 0xa9, + 0xb2, 0xfc, 0xc7, 0x28, 0x7a, 0xe0, 0xb0, 0xe6, 0x79, 0x02, 0x38, 0xf5, 0xf8, 0x71, 0xc0, 0x3e, + 0xa6, 0xa4, 0x0b, 0xf7, 0xbb, 0xbf, 0x9c, 0xb2, 0xf9, 0x82, 0x8e, 0xa3, 0xb2, 0x97, 0xe5, 0x9c, + 0x56, 0xdd, 0x2f, 0xe8, 0xb8, 0x76, 0x25, 0x15, 0xe3, 0x5f, 0xd0, 0x09, 0xe0, 0xd6, 0x17, 0x74, + 0x3c, 0x9e, 0xbd, 0x5f, 0xd0, 0xf1, 0x5a, 0x0b, 0x7e, 0x41, 0x27, 0xac, 0x81, 0x85, 0xf7, 0xb6, + 0x08, 0xf2, 0xdc, 0x7a, 0x90, 0x45, 0xf7, 0x18, 0xfb, 0xd9, 0x4d, 0x54, 0x90, 0x05, 0x4e, 0x72, + 0xe2, 0x9e, 0xdb, 0x80, 0x36, 0x75, 0xee, 0xba, 0x6d, 0x0d, 0xe6, 0x95, 0xef, 0x9f, 0xaa, 0xdd, + 0x8d, 0x0e, 0xe7, 0xac, 0x12, 0x5f, 0x4f, 0x5a, 0x0f, 0x85, 0xe7, 0xc6, 0x82, 0xdd, 0xf3, 0x1b, + 0xc3, 0x60, 0xa4, 0xba, 0x0d, 0xa1, 0x3a, 0x3d, 0xee, 0x33, 0x04, 0xba, 0x7c, 0x6b, 0x30, 0x8f, + 0x2c, 0x23, 0xd2, 0xb7, 0xec, 0xed, 0x01, 0xc6, 0xdc, 0xbe, 0x7e, 0x3a, 0x5c, 0x41, 0xb9, 0x5f, + 0xaa, 0xb4, 0xd1, 0x76, 0x2f, 0xfa, 0x79, 0xb3, 0xcf, 0xd4, 0xc4, 0xe9, 0xe6, 0x78, 0x28, 0x1e, + 0x4a, 0x20, 0xec, 0x25, 0xb4, 0x2f, 0x81, 0xf0, 0x2e, 0xa3, 0x9f, 0xdf, 0x4c, 0x49, 0x95, 0xe5, + 0x9f, 0x46, 0xd1, 0x6d, 0xb4, 0x2c, 0x6a, 0x1c, 0x7c, 0x31, 0xd4, 0x32, 0x18, 0x0f, 0x5f, 0xde, + 0x58, 0x4f, 0x15, 0xea, 0x5f, 0x47, 0xd1, 0x9d, 0x40, 0xa1, 0xe4, 0x00, 0xb9, 0x81, 0x75, 0x77, + 0xa0, 0xfc, 0xf0, 0xe6, 0x8a, 0xd8, 0x72, 0x6f, 0xe3, 0x93, 0xee, 0xa7, 0x65, 0x02, 0xb6, 0x27, + 0xf8, 0xa7, 0x65, 0xfa, 0xb5, 0xe0, 0x21, 0x0f, 0x39, 0x6f, 0x37, 0x5d, 0xde, 0x43, 0x1e, 0x71, + 0x43, 0x0d, 0xec, 0x39, 0xd6, 0x7a, 0x39, 0x9f, 0x93, 0x57, 0xef, 0x4a, 0x52, 0xa4, 0xb8, 0x13, + 0x29, 0xef, 0x77, 0xa2, 0x39, 0x78, 0x38, 0xd6, 0x48, 0x4f, 0x59, 0xbb, 0x91, 0x7a, 0x8c, 0xe9, + 0x6b, 0x24, 0x78, 0x38, 0xd6, 0x41, 0x11, 0x6f, 0x2a, 0x6b, 0x0c, 0x79, 0x03, 0xc9, 0xe2, 0x93, + 0x21, 0x28, 0x48, 0xd1, 0xb5, 0x37, 0x7d, 0xe6, 0xbe, 0x11, 0xb2, 0xd2, 0x39, 0x77, 0xdf, 0x1c, + 0x48, 0x23, 0x6e, 0x27, 0x94, 0x7f, 0x45, 0x49, 0x4a, 0xab, 0xa0, 0x5b, 0x4d, 0x0d, 0x72, 0x6b, + 0xd3, 0x3e, 0xb7, 0x3b, 0x2c, 0x5f, 0xcc, 0x0b, 0xd5, 0x99, 0xa8, 0x5b, 0x9b, 0xea, 0x77, 0x0b, + 0x68, 0x78, 0x2c, 0x68, 0xdc, 0x8a, 0xf4, 0xf2, 0x49, 0xd8, 0x8c, 0x93, 0x55, 0xae, 0x0f, 0x62, + 0xf1, 0x7a, 0xaa, 0x61, 0xd4, 0x53, 0x4f, 0x30, 0x92, 0x36, 0x07, 0xd2, 0xf0, 0x7c, 0xce, 0x72, + 0xab, 0xc7, 0xd3, 0x56, 0x8f, 0xad, 0xce, 0x90, 0x7a, 0x3a, 0x5c, 0x01, 0x9e, 0x86, 0xaa, 0x51, + 0x75, 0x98, 0xd5, 0x7c, 0x2f, 0xcb, 0xf3, 0xf1, 0x7a, 0x60, 0x98, 0xb4, 0x50, 0xf0, 0x34, 0xd4, + 0x03, 0x23, 0x23, 0xb9, 0x3d, 0x3d, 0x2c, 0xc6, 0x7d, 0x76, 0x04, 0x35, 0x68, 0x24, 0xdb, 0x34, + 0x38, 0xd1, 0xb2, 0x9a, 0x5a, 0xd7, 0x36, 0x0e, 0x37, 0x5c, 0xa7, 0xc2, 0x5b, 0x83, 0x79, 0xf0, + 0xb8, 0x5d, 0x50, 0x62, 0x65, 0xb9, 0x8f, 0x99, 0x70, 0x56, 0x92, 0x07, 0x3d, 0x14, 0x38, 0x15, + 0x94, 0xd3, 0xe8, 0x6d, 0x96, 0xce, 0x28, 0xf7, 0x3e, 0x29, 0xb2, 0x81, 0xe0, 0x93, 0x22, 0x00, + 0x82, 0xae, 0x93, 0xbf, 0xeb, 0xe3, 0xd0, 0x83, 0xd4, 0xd7, 0x75, 0x4a, 0xd9, 0xa2, 0x42, 0x5d, + 0xe7, 0xa5, 0x41, 0x34, 0xd0, 0x6e, 0xd5, 0xab, 0xf1, 0x4f, 0x42, 0x66, 0xc0, 0xfb, 0xf1, 0xeb, + 0x83, 0x58, 0xb0, 0xa2, 0x18, 0x87, 0xd9, 0x3c, 0xe3, 0xbe, 0x15, 0xc5, 0xb2, 0xd1, 0x20, 0xa1, + 0x15, 0xa5, 0x8b, 0x62, 0xd5, 0x6b, 0x72, 0x84, 0x83, 0x34, 0x5c, 0x3d, 0xc9, 0x0c, 0xab, 0x9e, + 0x66, 0x3b, 0x0f, 0x36, 0x0b, 0x3d, 0x64, 0xf8, 0xa5, 0xda, 0x2c, 0x7b, 0xc6, 0xb6, 0x78, 0x65, + 0x12, 0x82, 0xa1, 0xa8, 0x83, 0x29, 0xc0, 0x03, 0xfb, 0x86, 0x6b, 0x9f, 0xbd, 0x96, 0x25, 0x25, + 0x15, 0x29, 0x12, 0xef, 0xe6, 0x54, 0x18, 0xec, 0x90, 0xa1, 0xcd, 0x29, 0xaa, 0x01, 0x1e, 0x9b, + 0xbb, 0x2f, 0x3b, 0x7a, 0xa6, 0x82, 0x7e, 0xab, 0xd0, 0x7d, 0xd7, 0xf1, 0xf1, 0x00, 0x12, 0x3e, + 0x36, 0x6f, 0x01, 0x7d, 0xf0, 0x2d, 0x9d, 0x7e, 0x16, 0x30, 0xe5, 0xa2, 0xa1, 0x8d, 0x30, 0xae, + 0x02, 0x06, 0xb5, 0x4e, 0x70, 0x29, 0xff, 0x09, 0x5d, 0xf9, 0x06, 0xb5, 0xc9, 0x4f, 0x05, 0x12, + 0x1a, 0xd4, 0x5d, 0x14, 0xe4, 0x99, 0xf6, 0x3e, 0xe8, 0x61, 0x40, 0xdf, 0xde, 0xfa, 0xac, 0xf5, + 0x72, 0x60, 0xe6, 0xec, 0x66, 0x4b, 0xe7, 0x39, 0x81, 0xa7, 0xa0, 0xbb, 0xd9, 0xd2, 0xff, 0x98, + 0x60, 0x7d, 0x10, 0x0b, 0x1f, 0xc9, 0x13, 0x4e, 0xdf, 0xb5, 0xcf, 0xca, 0x3d, 0xc5, 0x15, 0xf2, + 0xce, 0xc3, 0xf2, 0x47, 0xfd, 0xa0, 0xb9, 0x00, 0x7b, 0x52, 0xb1, 0x84, 0xd6, 0xb5, 0xfa, 0xde, + 0x9e, 0x7b, 0xc3, 0x48, 0xc9, 0x62, 0xf0, 0xb5, 0xbd, 0xfb, 0x61, 0x48, 0xd9, 0xfe, 0x2a, 0x7a, + 0xff, 0x90, 0xcd, 0x26, 0xb4, 0x48, 0xc7, 0x3f, 0x70, 0xaf, 0x9c, 0xb2, 0x59, 0xdc, 0xfc, 0xac, + 0xed, 0xdd, 0xc2, 0xc4, 0xe6, 0xd2, 0xdc, 0x2e, 0x3d, 0x5f, 0xcc, 0x26, 0x9c, 0x70, 0x70, 0x69, + 0x4e, 0xfc, 0x1e, 0x37, 0x02, 0xe4, 0xd2, 0x9c, 0x03, 0x00, 0x7b, 0xd3, 0x8a, 0x52, 0xaf, 0xbd, + 0x46, 0x10, 0xb4, 0xa7, 0x00, 0xb3, 0xea, 0x6a, 0x7b, 0x4d, 0x62, 0x0b, 0x2f, 0xb9, 0x19, 0x1d, + 0x21, 0x45, 0x56, 0xdd, 0x2e, 0x65, 0x06, 0x83, 0xac, 0xbe, 0xf8, 0x62, 0xc6, 0x62, 0x3e, 0x27, + 0xd5, 0x0a, 0x0c, 0x06, 0x55, 0x4b, 0x0b, 0x40, 0x06, 0x83, 0x17, 0x34, 0xa3, 0xbc, 0x6d, 0xe6, + 0xe4, 0x6a, 0x9f, 0x55, 0x6c, 0xc1, 0xb3, 0x82, 0xc2, 0xaf, 0x26, 0xe8, 0x06, 0xb5, 0x19, 0x64, + 0x94, 0x63, 0xac, 0xc9, 0x0a, 0x05, 0x21, 0xef, 0xdf, 0x89, 0xaf, 0xd6, 0xd6, 0x9c, 0x55, 0xf0, + 0xf9, 0x9b, 0xb4, 0x02, 0x21, 0x24, 0x2b, 0x44, 0x61, 0xd0, 0xf7, 0x27, 0x59, 0x31, 0xf3, 0xf6, + 0xfd, 0x89, 0xfd, 0xcd, 0xc7, 0x3b, 0x38, 0x60, 0xe2, 0xbb, 0x6c, 0x34, 0xf9, 0x65, 0x22, 0xf5, + 0xee, 0xa3, 0xb7, 0xd1, 0x6d, 0x02, 0x89, 0xef, 0x7e, 0x12, 0xb8, 0x7a, 0x5d, 0xd2, 0x82, 0xa6, + 0xed, 0x2d, 0x33, 0x9f, 0x2b, 0x87, 0x08, 0xba, 0x82, 0xa4, 0x89, 0xaa, 0x42, 0x7e, 0xba, 0x28, + 0x4e, 0x2a, 0x76, 0x91, 0xe5, 0xb4, 0x02, 0x51, 0x55, 0xaa, 0x5b, 0x72, 0x24, 0xaa, 0xfa, 0x38, + 0x73, 0x5d, 0x41, 0x48, 0x9d, 0x4f, 0x2f, 0x4f, 0x2b, 0x92, 0xc0, 0xeb, 0x0a, 0xd2, 0x46, 0x17, + 0x43, 0x4e, 0xd2, 0x02, 0xb8, 0x95, 0x18, 0x48, 0xd7, 0xc5, 0x4a, 0x8c, 0x0f, 0xf5, 0xee, 0x9d, + 0xf8, 0x12, 0x62, 0x0d, 0x12, 0x03, 0x65, 0xce, 0x47, 0x22, 0x89, 0x41, 0x58, 0xc3, 0xcc, 0xb6, + 0x23, 0xca, 0xab, 0x2c, 0xa9, 0x27, 0x94, 0x9f, 0x90, 0x8a, 0xcc, 0x29, 0xa7, 0x15, 0x9c, 0x6d, + 0x0a, 0x89, 0x1d, 0x06, 0x99, 0x6d, 0x18, 0xab, 0x1c, 0xfe, 0x5e, 0xf4, 0x61, 0xb3, 0xd8, 0xd0, + 0x42, 0xfd, 0xa5, 0x82, 0x57, 0xe2, 0x4f, 0x9c, 0x8c, 0x3f, 0xd2, 0x36, 0x26, 0xbc, 0xa2, 0x64, + 0xde, 0xda, 0xfe, 0x40, 0xff, 0x2e, 0xc0, 0xa7, 0xa3, 0x66, 0x50, 0x1c, 0x33, 0x9e, 0x5d, 0x34, + 0x7b, 0x3b, 0xf5, 0xda, 0x0a, 0x18, 0x14, 0xb6, 0x38, 0x0e, 0x7c, 0x8c, 0xc0, 0xc7, 0x99, 0x60, + 0x67, 0x4b, 0x4f, 0x69, 0x99, 0xc3, 0x60, 0xe7, 0x68, 0x0b, 0x00, 0x09, 0x76, 0x5e, 0xd0, 0x8c, + 0x70, 0x5b, 0x3c, 0xa5, 0xe1, 0xca, 0x4c, 0xe9, 0xb0, 0xca, 0x4c, 0x9d, 0x37, 0x01, 0xf2, 0xe8, + 0xc3, 0x23, 0x3a, 0x3f, 0xa7, 0x55, 0x7d, 0x99, 0x95, 0xfb, 0xcd, 0x2a, 0x4f, 0xf8, 0x02, 0xbe, + 0x2b, 0x67, 0x88, 0x58, 0x23, 0x48, 0x2a, 0x84, 0xa0, 0x26, 0x9c, 0x1a, 0xe0, 0xa0, 0x3e, 0x26, + 0x73, 0x2a, 0x3e, 0xad, 0x30, 0x5e, 0xc7, 0x8c, 0x58, 0x10, 0x12, 0x4e, 0x51, 0xd8, 0x7a, 0xa9, + 0xc8, 0x30, 0xa7, 0x74, 0xd6, 0x8c, 0xb0, 0xea, 0x84, 0xac, 0xe6, 0xb4, 0xe0, 0xca, 0x24, 0x38, + 0x08, 0xb6, 0x4c, 0xfa, 0x79, 0xe4, 0x20, 0x78, 0x88, 0x9e, 0x35, 0xbf, 0x9d, 0x86, 0x3f, 0x61, + 0x15, 0x97, 0x7f, 0x87, 0xe4, 0xac, 0xca, 0xc1, 0xfc, 0x76, 0x1b, 0xd5, 0x21, 0x91, 0xf9, 0x1d, + 0xd6, 0xb0, 0x3e, 0xe0, 0xed, 0x94, 0xe1, 0x0d, 0xad, 0xf4, 0x38, 0x79, 0x35, 0x27, 0x59, 0xae, + 0x46, 0xc3, 0x8f, 0x02, 0xb6, 0x11, 0x1d, 0xe4, 0x03, 0xde, 0x43, 0x75, 0xad, 0x4f, 0x9e, 0x87, + 0x4b, 0x08, 0xce, 0xa5, 0x7b, 0xec, 0x23, 0xe7, 0xd2, 0xfd, 0x5a, 0x66, 0xbb, 0x68, 0x58, 0xc1, + 0xad, 0x04, 0xb1, 0xc3, 0x52, 0x78, 0x48, 0x65, 0xd9, 0x04, 0x20, 0xb2, 0x5d, 0x0c, 0x2a, 0x98, + 0xf5, 0xd5, 0x60, 0x7b, 0x59, 0x41, 0xf2, 0xec, 0x67, 0xf0, 0x86, 0xb3, 0x65, 0xa7, 0x25, 0x90, + 0xf5, 0xd5, 0x4f, 0xfa, 0x5c, 0xed, 0x53, 0x3e, 0xcd, 0x9a, 0xd0, 0xff, 0x28, 0xd0, 0x6e, 0x82, + 0xe8, 0x77, 0x65, 0x91, 0xd6, 0x47, 0x3a, 0x61, 0xb3, 0x6e, 0x97, 0xe5, 0xa4, 0x59, 0x9a, 0x4e, + 0x69, 0x42, 0xb3, 0x92, 0x8f, 0x5f, 0x84, 0xdb, 0x0a, 0xe0, 0xc8, 0xd3, 0xfd, 0x01, 0x6a, 0xd6, + 0x33, 0xe3, 0x26, 0x96, 0x4c, 0xe4, 0x1f, 0xe8, 0x3a, 0xab, 0x69, 0xa5, 0x56, 0xeb, 0x7d, 0xca, + 0xc1, 0xec, 0xb4, 0xb8, 0xd8, 0x02, 0x9b, 0x8a, 0x22, 0xb3, 0x33, 0xac, 0x61, 0x4e, 0x98, 0x2c, + 0xee, 0x94, 0xd6, 0x2c, 0x5f, 0x52, 0x71, 0xc9, 0x6d, 0x03, 0x35, 0x66, 0x51, 0xc8, 0x09, 0x13, + 0x4e, 0x9b, 0x94, 0xa7, 0xeb, 0x76, 0xbb, 0x58, 0x1d, 0xc0, 0xe7, 0xf4, 0x1e, 0x4b, 0x02, 0x43, + 0x52, 0x9e, 0x00, 0x6e, 0x9d, 0xc0, 0x56, 0x8c, 0xa4, 0x09, 0xa9, 0xf9, 0x09, 0x59, 0xe5, 0x8c, + 0xa4, 0x62, 0x5d, 0x87, 0x27, 0xb0, 0x2d, 0x13, 0xdb, 0x10, 0x76, 0x02, 0x8b, 0xc1, 0x66, 0x77, + 0xa9, 0xfe, 0xee, 0x98, 0xba, 0x40, 0x78, 0x0f, 0xa4, 0x49, 0xa2, 0xbc, 0xf0, 0xf2, 0xe0, 0xfd, + 0x30, 0x64, 0x5e, 0x7c, 0x92, 0x22, 0x91, 0x86, 0xdc, 0xf1, 0xe9, 0x38, 0x09, 0xc8, 0xa7, 0x01, + 0xc2, 0x7c, 0x0c, 0x41, 0xfe, 0xde, 0xfe, 0xe9, 0x0c, 0xae, 0x3e, 0x65, 0xbc, 0xe1, 0xd3, 0xb5, + 0xa1, 0xd8, 0xfe, 0xc2, 0xd9, 0xe6, 0x40, 0xda, 0x6c, 0x1e, 0x77, 0x2e, 0x09, 0xdf, 0x4e, 0xd3, + 0x23, 0x5a, 0x7b, 0xde, 0x62, 0x6e, 0x84, 0xb1, 0x91, 0x22, 0x9b, 0xc7, 0x2e, 0x65, 0x06, 0x7a, + 0x23, 0x7b, 0x95, 0x66, 0x5c, 0xc9, 0xda, 0x6b, 0xb9, 0x1b, 0x5d, 0x03, 0x5d, 0x0a, 0xa9, 0x15, + 0x4e, 0x9b, 0x58, 0xde, 0x30, 0x53, 0x36, 0x9b, 0xe5, 0x54, 0x41, 0xa7, 0x94, 0xc8, 0x2f, 0xb9, + 0x6d, 0x75, 0x6d, 0x79, 0x41, 0x24, 0x96, 0x07, 0x15, 0x4c, 0x1a, 0xd9, 0x60, 0xf2, 0x39, 0x48, + 0xdb, 0xb0, 0x6b, 0x5d, 0x33, 0x0e, 0x80, 0xa4, 0x91, 0x5e, 0xd0, 0xbc, 0x6c, 0xd5, 0x88, 0xf7, + 0x69, 0xdb, 0x12, 0xf0, 0xbb, 0x37, 0x42, 0xd9, 0x12, 0x23, 0x2f, 0x5b, 0x79, 0x30, 0xb3, 0x4f, + 0x00, 0x1e, 0x5e, 0xae, 0x0e, 0x52, 0xb8, 0x4f, 0x80, 0xfa, 0x82, 0x41, 0xf6, 0x09, 0x18, 0xeb, + 0x76, 0x9d, 0xfe, 0xc8, 0xef, 0x21, 0xa9, 0x4d, 0xe5, 0x3c, 0x5d, 0xe7, 0x05, 0x43, 0x5d, 0x87, + 0x29, 0xb8, 0x4d, 0x6a, 0x7f, 0x42, 0xd8, 0xd3, 0xa4, 0xbe, 0x4f, 0x07, 0x3f, 0xec, 0xc3, 0x4c, + 0x5c, 0xd2, 0x9b, 0x32, 0x71, 0x4f, 0xc6, 0xff, 0x09, 0x77, 0x29, 0x44, 0xe2, 0x52, 0x07, 0x92, + 0xb6, 0x5f, 0x7e, 0xfa, 0x5f, 0xdf, 0xdc, 0x1a, 0xfd, 0xe2, 0x9b, 0x5b, 0xa3, 0xff, 0xf9, 0xe6, + 0xd6, 0xe8, 0xe7, 0xdf, 0xde, 0x7a, 0xef, 0x17, 0xdf, 0xde, 0x7a, 0xef, 0xbf, 0xbf, 0xbd, 0xf5, + 0xde, 0xd7, 0xef, 0xab, 0xbf, 0x47, 0x79, 0xfe, 0xff, 0xc4, 0x5f, 0x95, 0x7c, 0xfe, 0x7f, 0x01, + 0x00, 0x00, 0xff, 0xff, 0xe5, 0xb3, 0x13, 0x72, 0xb3, 0x72, 0x00, 0x00, } // This is a compile-time assertion to ensure that this generated file @@ -416,13 +420,14 @@ type ClientCommandsHandler interface { ObjectCreate(context.Context, *pb.RpcObjectCreateRequest) *pb.RpcObjectCreateResponse ObjectCreateBookmark(context.Context, *pb.RpcObjectCreateBookmarkRequest) *pb.RpcObjectCreateBookmarkResponse ObjectCreateFromUrl(context.Context, *pb.RpcObjectCreateFromUrlRequest) *pb.RpcObjectCreateFromUrlResponse - ObjectChatAdd(context.Context, *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse // ObjectCreateSet just creates the new set, without adding the link to it from some other page ObjectCreateSet(context.Context, *pb.RpcObjectCreateSetRequest) *pb.RpcObjectCreateSetResponse ObjectGraph(context.Context, *pb.RpcObjectGraphRequest) *pb.RpcObjectGraphResponse ObjectSearch(context.Context, *pb.RpcObjectSearchRequest) *pb.RpcObjectSearchResponse ObjectSearchWithMeta(context.Context, *pb.RpcObjectSearchWithMetaRequest) *pb.RpcObjectSearchWithMetaResponse ObjectSearchSubscribe(context.Context, *pb.RpcObjectSearchSubscribeRequest) *pb.RpcObjectSearchSubscribeResponse + ObjectCrossSpaceSearchSubscribe(context.Context, *pb.RpcObjectCrossSpaceSearchSubscribeRequest) *pb.RpcObjectCrossSpaceSearchSubscribeResponse + ObjectCrossSpaceSearchUnsubscribe(context.Context, *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) *pb.RpcObjectCrossSpaceSearchUnsubscribeResponse ObjectSubscribeIds(context.Context, *pb.RpcObjectSubscribeIdsRequest) *pb.RpcObjectSubscribeIdsResponse ObjectGroupsSubscribe(context.Context, *pb.RpcObjectGroupsSubscribeRequest) *pb.RpcObjectGroupsSubscribeResponse ObjectSearchUnsubscribe(context.Context, *pb.RpcObjectSearchUnsubscribeRequest) *pb.RpcObjectSearchUnsubscribeResponse @@ -624,6 +629,7 @@ type ClientCommandsHandler interface { DebugOpenedObjects(context.Context, *pb.RpcDebugOpenedObjectsRequest) *pb.RpcDebugOpenedObjectsResponse DebugRunProfiler(context.Context, *pb.RpcDebugRunProfilerRequest) *pb.RpcDebugRunProfilerResponse DebugAccountSelectTrace(context.Context, *pb.RpcDebugAccountSelectTraceRequest) *pb.RpcDebugAccountSelectTraceResponse + DebugAnystoreObjectChanges(context.Context, *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse MetricsSetParameters(context.Context, *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse // used only for lib-server via grpc // Streams not supported ### ListenSessionEvents(context.Context, *pb.StreamRequest) @@ -666,7 +672,7 @@ type ClientCommandsHandler interface { DeviceSetName(context.Context, *pb.RpcDeviceSetNameRequest) *pb.RpcDeviceSetNameResponse DeviceList(context.Context, *pb.RpcDeviceListRequest) *pb.RpcDeviceListResponse DeviceNetworkStateSet(context.Context, *pb.RpcDeviceNetworkStateSetRequest) *pb.RpcDeviceNetworkStateSetResponse - // Chats dummy impl + // Chats ChatAddMessage(context.Context, *pb.RpcChatAddMessageRequest) *pb.RpcChatAddMessageResponse ChatEditMessageContent(context.Context, *pb.RpcChatEditMessageContentRequest) *pb.RpcChatEditMessageContentResponse ChatToggleMessageReaction(context.Context, *pb.RpcChatToggleMessageReactionRequest) *pb.RpcChatToggleMessageReactionResponse @@ -675,6 +681,7 @@ type ClientCommandsHandler interface { ChatGetMessagesByIds(context.Context, *pb.RpcChatGetMessagesByIdsRequest) *pb.RpcChatGetMessagesByIdsResponse ChatSubscribeLastMessages(context.Context, *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse ChatUnsubscribe(context.Context, *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse + ObjectChatAdd(context.Context, *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse } func registerClientCommandsHandler(srv ClientCommandsHandler) { @@ -1701,26 +1708,6 @@ func ObjectCreateFromUrl(b []byte) (resp []byte) { return resp } -func ObjectChatAdd(b []byte) (resp []byte) { - defer func() { - if PanicHandler != nil { - if r := recover(); r != nil { - resp, _ = (&pb.RpcObjectChatAddResponse{Error: &pb.RpcObjectChatAddResponseError{Code: pb.RpcObjectChatAddResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal() - PanicHandler(r) - } - } - }() - - in := new(pb.RpcObjectChatAddRequest) - if err := in.Unmarshal(b); err != nil { - resp, _ = (&pb.RpcObjectChatAddResponse{Error: &pb.RpcObjectChatAddResponseError{Code: pb.RpcObjectChatAddResponseError_BAD_INPUT, Description: err.Error()}}).Marshal() - return resp - } - - resp, _ = clientCommandsHandler.ObjectChatAdd(context.Background(), in).Marshal() - return resp -} - func ObjectCreateSet(b []byte) (resp []byte) { defer func() { if PanicHandler != nil { @@ -1821,6 +1808,46 @@ func ObjectSearchSubscribe(b []byte) (resp []byte) { return resp } +func ObjectCrossSpaceSearchSubscribe(b []byte) (resp []byte) { + defer func() { + if PanicHandler != nil { + if r := recover(); r != nil { + resp, _ = (&pb.RpcObjectCrossSpaceSearchSubscribeResponse{Error: &pb.RpcObjectCrossSpaceSearchSubscribeResponseError{Code: pb.RpcObjectCrossSpaceSearchSubscribeResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal() + PanicHandler(r) + } + } + }() + + in := new(pb.RpcObjectCrossSpaceSearchSubscribeRequest) + if err := in.Unmarshal(b); err != nil { + resp, _ = (&pb.RpcObjectCrossSpaceSearchSubscribeResponse{Error: &pb.RpcObjectCrossSpaceSearchSubscribeResponseError{Code: pb.RpcObjectCrossSpaceSearchSubscribeResponseError_BAD_INPUT, Description: err.Error()}}).Marshal() + return resp + } + + resp, _ = clientCommandsHandler.ObjectCrossSpaceSearchSubscribe(context.Background(), in).Marshal() + return resp +} + +func ObjectCrossSpaceSearchUnsubscribe(b []byte) (resp []byte) { + defer func() { + if PanicHandler != nil { + if r := recover(); r != nil { + resp, _ = (&pb.RpcObjectCrossSpaceSearchUnsubscribeResponse{Error: &pb.RpcObjectCrossSpaceSearchUnsubscribeResponseError{Code: pb.RpcObjectCrossSpaceSearchUnsubscribeResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal() + PanicHandler(r) + } + } + }() + + in := new(pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) + if err := in.Unmarshal(b); err != nil { + resp, _ = (&pb.RpcObjectCrossSpaceSearchUnsubscribeResponse{Error: &pb.RpcObjectCrossSpaceSearchUnsubscribeResponseError{Code: pb.RpcObjectCrossSpaceSearchUnsubscribeResponseError_BAD_INPUT, Description: err.Error()}}).Marshal() + return resp + } + + resp, _ = clientCommandsHandler.ObjectCrossSpaceSearchUnsubscribe(context.Background(), in).Marshal() + return resp +} + func ObjectSubscribeIds(b []byte) (resp []byte) { defer func() { if PanicHandler != nil { @@ -5281,6 +5308,26 @@ func DebugAccountSelectTrace(b []byte) (resp []byte) { return resp } +func DebugAnystoreObjectChanges(b []byte) (resp []byte) { + defer func() { + if PanicHandler != nil { + if r := recover(); r != nil { + resp, _ = (&pb.RpcDebugAnystoreObjectChangesResponse{Error: &pb.RpcDebugAnystoreObjectChangesResponseError{Code: pb.RpcDebugAnystoreObjectChangesResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal() + PanicHandler(r) + } + } + }() + + in := new(pb.RpcDebugAnystoreObjectChangesRequest) + if err := in.Unmarshal(b); err != nil { + resp, _ = (&pb.RpcDebugAnystoreObjectChangesResponse{Error: &pb.RpcDebugAnystoreObjectChangesResponseError{Code: pb.RpcDebugAnystoreObjectChangesResponseError_BAD_INPUT, Description: err.Error()}}).Marshal() + return resp + } + + resp, _ = clientCommandsHandler.DebugAnystoreObjectChanges(context.Background(), in).Marshal() + return resp +} + func MetricsSetParameters(b []byte) (resp []byte) { defer func() { if PanicHandler != nil { @@ -5861,6 +5908,26 @@ func ChatUnsubscribe(b []byte) (resp []byte) { return resp } +func ObjectChatAdd(b []byte) (resp []byte) { + defer func() { + if PanicHandler != nil { + if r := recover(); r != nil { + resp, _ = (&pb.RpcObjectChatAddResponse{Error: &pb.RpcObjectChatAddResponseError{Code: pb.RpcObjectChatAddResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal() + PanicHandler(r) + } + } + }() + + in := new(pb.RpcObjectChatAddRequest) + if err := in.Unmarshal(b); err != nil { + resp, _ = (&pb.RpcObjectChatAddResponse{Error: &pb.RpcObjectChatAddResponseError{Code: pb.RpcObjectChatAddResponseError_BAD_INPUT, Description: err.Error()}}).Marshal() + return resp + } + + resp, _ = clientCommandsHandler.ObjectChatAdd(context.Background(), in).Marshal() + return resp +} + var PanicHandler func(v interface{}) func CommandAsync(cmd string, data []byte, callback func(data []byte)) { @@ -5969,8 +6036,6 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) { cd = ObjectCreateBookmark(data) case "ObjectCreateFromUrl": cd = ObjectCreateFromUrl(data) - case "ObjectChatAdd": - cd = ObjectChatAdd(data) case "ObjectCreateSet": cd = ObjectCreateSet(data) case "ObjectGraph": @@ -5981,6 +6046,10 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) { cd = ObjectSearchWithMeta(data) case "ObjectSearchSubscribe": cd = ObjectSearchSubscribe(data) + case "ObjectCrossSpaceSearchSubscribe": + cd = ObjectCrossSpaceSearchSubscribe(data) + case "ObjectCrossSpaceSearchUnsubscribe": + cd = ObjectCrossSpaceSearchUnsubscribe(data) case "ObjectSubscribeIds": cd = ObjectSubscribeIds(data) case "ObjectGroupsSubscribe": @@ -6327,6 +6396,8 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) { cd = DebugRunProfiler(data) case "DebugAccountSelectTrace": cd = DebugAccountSelectTrace(data) + case "DebugAnystoreObjectChanges": + cd = DebugAnystoreObjectChanges(data) case "MetricsSetParameters": cd = MetricsSetParameters(data) case "NotificationList": @@ -6385,6 +6456,8 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) { cd = ChatSubscribeLastMessages(data) case "ChatUnsubscribe": cd = ChatUnsubscribe(data) + case "ObjectChatAdd": + cd = ObjectChatAdd(data) default: log.Errorf("unknown command type: %s\n", cmd) } @@ -7121,20 +7194,6 @@ func (h *ClientCommandsHandlerProxy) ObjectCreateFromUrl(ctx context.Context, re call, _ := actualCall(ctx, req) return call.(*pb.RpcObjectCreateFromUrlResponse) } -func (h *ClientCommandsHandlerProxy) ObjectChatAdd(ctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse { - actualCall := func(ctx context.Context, req any) (any, error) { - return h.client.ObjectChatAdd(ctx, req.(*pb.RpcObjectChatAddRequest)), nil - } - for _, interceptor := range h.interceptors { - toCall := actualCall - currentInterceptor := interceptor - actualCall = func(ctx context.Context, req any) (any, error) { - return currentInterceptor(ctx, req, "ObjectChatAdd", toCall) - } - } - call, _ := actualCall(ctx, req) - return call.(*pb.RpcObjectChatAddResponse) -} func (h *ClientCommandsHandlerProxy) ObjectCreateSet(ctx context.Context, req *pb.RpcObjectCreateSetRequest) *pb.RpcObjectCreateSetResponse { actualCall := func(ctx context.Context, req any) (any, error) { return h.client.ObjectCreateSet(ctx, req.(*pb.RpcObjectCreateSetRequest)), nil @@ -7205,6 +7264,34 @@ func (h *ClientCommandsHandlerProxy) ObjectSearchSubscribe(ctx context.Context, call, _ := actualCall(ctx, req) return call.(*pb.RpcObjectSearchSubscribeResponse) } +func (h *ClientCommandsHandlerProxy) ObjectCrossSpaceSearchSubscribe(ctx context.Context, req *pb.RpcObjectCrossSpaceSearchSubscribeRequest) *pb.RpcObjectCrossSpaceSearchSubscribeResponse { + actualCall := func(ctx context.Context, req any) (any, error) { + return h.client.ObjectCrossSpaceSearchSubscribe(ctx, req.(*pb.RpcObjectCrossSpaceSearchSubscribeRequest)), nil + } + for _, interceptor := range h.interceptors { + toCall := actualCall + currentInterceptor := interceptor + actualCall = func(ctx context.Context, req any) (any, error) { + return currentInterceptor(ctx, req, "ObjectCrossSpaceSearchSubscribe", toCall) + } + } + call, _ := actualCall(ctx, req) + return call.(*pb.RpcObjectCrossSpaceSearchSubscribeResponse) +} +func (h *ClientCommandsHandlerProxy) ObjectCrossSpaceSearchUnsubscribe(ctx context.Context, req *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) *pb.RpcObjectCrossSpaceSearchUnsubscribeResponse { + actualCall := func(ctx context.Context, req any) (any, error) { + return h.client.ObjectCrossSpaceSearchUnsubscribe(ctx, req.(*pb.RpcObjectCrossSpaceSearchUnsubscribeRequest)), nil + } + for _, interceptor := range h.interceptors { + toCall := actualCall + currentInterceptor := interceptor + actualCall = func(ctx context.Context, req any) (any, error) { + return currentInterceptor(ctx, req, "ObjectCrossSpaceSearchUnsubscribe", toCall) + } + } + call, _ := actualCall(ctx, req) + return call.(*pb.RpcObjectCrossSpaceSearchUnsubscribeResponse) +} func (h *ClientCommandsHandlerProxy) ObjectSubscribeIds(ctx context.Context, req *pb.RpcObjectSubscribeIdsRequest) *pb.RpcObjectSubscribeIdsResponse { actualCall := func(ctx context.Context, req any) (any, error) { return h.client.ObjectSubscribeIds(ctx, req.(*pb.RpcObjectSubscribeIdsRequest)), nil @@ -9627,6 +9714,20 @@ func (h *ClientCommandsHandlerProxy) DebugAccountSelectTrace(ctx context.Context call, _ := actualCall(ctx, req) return call.(*pb.RpcDebugAccountSelectTraceResponse) } +func (h *ClientCommandsHandlerProxy) DebugAnystoreObjectChanges(ctx context.Context, req *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse { + actualCall := func(ctx context.Context, req any) (any, error) { + return h.client.DebugAnystoreObjectChanges(ctx, req.(*pb.RpcDebugAnystoreObjectChangesRequest)), nil + } + for _, interceptor := range h.interceptors { + toCall := actualCall + currentInterceptor := interceptor + actualCall = func(ctx context.Context, req any) (any, error) { + return currentInterceptor(ctx, req, "DebugAnystoreObjectChanges", toCall) + } + } + call, _ := actualCall(ctx, req) + return call.(*pb.RpcDebugAnystoreObjectChangesResponse) +} func (h *ClientCommandsHandlerProxy) MetricsSetParameters(ctx context.Context, req *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse { actualCall := func(ctx context.Context, req any) (any, error) { return h.client.MetricsSetParameters(ctx, req.(*pb.RpcMetricsSetParametersRequest)), nil @@ -10033,3 +10134,17 @@ func (h *ClientCommandsHandlerProxy) ChatUnsubscribe(ctx context.Context, req *p call, _ := actualCall(ctx, req) return call.(*pb.RpcChatUnsubscribeResponse) } +func (h *ClientCommandsHandlerProxy) ObjectChatAdd(ctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse { + actualCall := func(ctx context.Context, req any) (any, error) { + return h.client.ObjectChatAdd(ctx, req.(*pb.RpcObjectChatAddRequest)), nil + } + for _, interceptor := range h.interceptors { + toCall := actualCall + currentInterceptor := interceptor + actualCall = func(ctx context.Context, req any) (any, error) { + return currentInterceptor(ctx, req, "ObjectChatAdd", toCall) + } + } + call, _ := actualCall(ctx, req) + return call.(*pb.RpcObjectChatAddResponse) +} diff --git a/cmd/perfstand/account_create/main.go b/cmd/perfstand/account_create/main.go new file mode 100644 index 0000000000..c82b4069e5 --- /dev/null +++ b/cmd/perfstand/account_create/main.go @@ -0,0 +1,110 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "os/exec" + + "go.uber.org/atomic" + + "github.com/anyproto/anytype-heart/cmd/perfstand/internal" +) + +const AccountCreate = "AccountCreate" + +type input struct { + *internal.BasicInput +} + +type wallet struct { + Mnemonic string `json:"mnemonic"` +} + +func NewInput() *input { + res := new(input) + res.BasicInput = new(internal.BasicInput) + return res +} + +func NewResults(networkMode string) internal.PerfResult { + return internal.PerfResult{ + AccountCreate: {MethodName: AccountCreate, NetworkMode: networkMode}, + } +} + +func main() { + prep := NewInput() + err := internal.Prepare(prep, nil) + if err != nil { + fmt.Println("Error preparing the environment:", err) + os.Exit(1) + } + + res := NewResults(prep.NetworkMode) + for i := 0; i < prep.Times; i++ { + err = iterate(prep, res) + if err != nil { + fmt.Println("Error making iteration:", err) + os.Exit(1) + } + } + err = internal.After(res) + if err != nil { + fmt.Println("Error after the test:", err) + os.Exit(1) + } +} + +func iterate(prep *input, result internal.PerfResult) error { + workspace, err := os.MkdirTemp("", "workspace") + prep.Workspace = workspace + if err != nil { + return err + } + defer os.RemoveAll(workspace) + fmt.Println("Created temporary directory:", workspace) + + var currentOperation atomic.String + done := make(chan struct{}) + wait := make(chan map[string][]byte) + + err = internal.StartWithTracing(¤tOperation, done, wait) + if err != nil { + return err + } + + err = internal.ExecuteCommand(internal.GrpcMetricsSetParameters()) + if err != nil { + return err + } + + walletStr, err := exec.Command("bash", "-c", internal.GrpcWalletCreate(workspace)).Output() + if err != nil { + return err + } + + var wallet wallet + err = json.Unmarshal(walletStr, &wallet) + if err != nil { + return err + } + + grpcurlCommands := []internal.Command{ + {internal.GrpcWalletCreateSession(wallet.Mnemonic), ""}, + accountCreate(prep), + } + + err = internal.CollectMeasurements(grpcurlCommands, ¤tOperation, result, done, wait) + if err != nil { + return err + } + return nil +} + +func accountCreate(prep *input) internal.Command { + if prep.NetworkMode != internal.NetworkLocal { + return internal.Command{Command: internal.GrpcAccountCreate(prep.Workspace, "2", prep.NodesConfig), Name: AccountCreate} + } + return internal.Command{Command: internal.GrpcAccountCreate(prep.Workspace, "1", ""), Name: AccountCreate} +} diff --git a/cmd/perfstand/account_select/main.go b/cmd/perfstand/account_select/main.go new file mode 100644 index 0000000000..092dcd6c50 --- /dev/null +++ b/cmd/perfstand/account_select/main.go @@ -0,0 +1,103 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + + "go.uber.org/atomic" + + "github.com/anyproto/anytype-heart/cmd/perfstand/internal" +) + +const AccountSelect = "AccountSelect" +const WorkspaceOpen = "WorkspaceOpen" +const WorkspaceCreate = "WorkspaceCreate" + +type input struct { + *internal.BasicInput + RootPath string `json:"root_path"` + AccHash string `json:"acc_hash"` + Mnemonic string `json:"mnemonic"` + Space string `json:"space"` +} + +func NewInput() *input { + res := new(input) + res.BasicInput = new(internal.BasicInput) + return res +} + +func NewResults(networkMode string) internal.PerfResult { + return internal.PerfResult{ + AccountSelect: {MethodName: AccountSelect, NetworkMode: networkMode}, + WorkspaceOpen: {MethodName: WorkspaceOpen, NetworkMode: networkMode}, + WorkspaceCreate: {MethodName: WorkspaceCreate, NetworkMode: networkMode}, + } +} + +func main() { + prep := NewInput() + err := internal.Prepare(prep, extractAcc) + if err != nil { + fmt.Println("Error preparing the environment:", err) + os.Exit(1) + } + defer os.RemoveAll(prep.Workspace) + + res := NewResults(prep.NetworkMode) + for i := 0; i < prep.Times; i++ { + err = iterate(prep, res) + if err != nil { + fmt.Println("Error making iteration:", err) + os.Exit(1) + } + } + err = internal.After(res) + if err != nil { + fmt.Println("Error after the test:", err) + os.Exit(1) + } +} + +func extractAcc(input *input) error { + err := internal.UnpackZip(filepath.Join(input.RootPath, input.AccHash+".zip"), input.Workspace) + if err != nil { + return err + } + fmt.Println("Unpacked files to:", input.Workspace) + return nil +} + +func iterate(prep *input, result internal.PerfResult) error { + var currentOperation atomic.String + done := make(chan struct{}) + wait := make(chan map[string][]byte) + + err := internal.StartWithTracing(¤tOperation, done, wait) + if err != nil { + return err + } + + grpcurlCommands := []internal.Command{ + {internal.GrpcMetricsSetParameters(), ""}, + {internal.GrpcWalletRecover(prep.Workspace, prep.Mnemonic), ""}, + {internal.GrpcWalletCreateSession(prep.Mnemonic), ""}, + accountSelect(prep), + {internal.GrpcWorkspaceOpen(prep.Space), WorkspaceOpen}, + {internal.GrpcWorkspaceCreate(), WorkspaceCreate}, + } + + err = internal.CollectMeasurements(grpcurlCommands, ¤tOperation, result, done, wait) + if err != nil { + return err + } + return nil +} + +func accountSelect(prep *input) internal.Command { + if prep.NetworkMode != internal.NetworkLocal { + return internal.Command{Command: internal.GrpcAccountSelect(prep.AccHash, prep.Workspace, "2", prep.NodesConfig), Name: AccountSelect} + } + return internal.Command{Command: internal.GrpcAccountSelect(prep.AccHash, prep.Workspace, "1", ""), Name: AccountSelect} +} diff --git a/cmd/perfstand/internal/util.go b/cmd/perfstand/internal/util.go new file mode 100644 index 0000000000..451c472ac4 --- /dev/null +++ b/cmd/perfstand/internal/util.go @@ -0,0 +1,512 @@ +package internal + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "time" + + "go.uber.org/atomic" +) + +const NetworkLocal = "local" +const NetworkStaging = "staging" + +type Event struct { + MethodName string `json:"method_name"` + Duration int64 `json:"duration"` + MiddlewareVersion string `json:"middleware_version"` + Network string `json:"network"` +} + +func GetMiddlewareVersion() (string, error) { + out, err := exec.Command("git", "describe", "--tags", "--always").Output() + if err != nil { + return "", err + } + middlewareVersion := strings.Trim(string(out), "\n") + return middlewareVersion, nil +} + +func SendResultsToHttp(apiKey string, events []Event) error { + payload := map[string]interface{}{ + "api_key": apiKey, + "events": events, + } + + jsonData, err := json.Marshal(payload) + if err != nil { + return fmt.Errorf("failed to marshal JSON: %w", err) + } + + req, err := http.NewRequest("POST", "https://telemetry.anytype.io/perfstand", bytes.NewBuffer(jsonData)) + if err != nil { + return fmt.Errorf("failed to create request: %w", err) + } + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{Timeout: 30 * time.Second} + resp, err := client.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + + fmt.Println("Results sent successfully!") + return nil +} + +func KillServer() error { + return ExecuteCommand("kill -9 $(lsof -i :31007 -t) ; echo \"Server killed\"") +} + +func ExecuteCommand(command string) error { + fmt.Println(command) + cmd := exec.Command("bash", "-c", command) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + return err + } + return nil +} + +func UnpackZip(path string, workspace string) error { + return ExecuteCommand("unzip -o " + path + " -d " + workspace) +} + +func BuildAnytype(err error) error { + buildServer := exec.Command("make", "build-server") + buildServer.Stdout = os.Stdout + buildServer.Stderr = os.Stderr + buildServer.Env = append(os.Environ(), "TAGS=noauth") + + err = buildServer.Run() + return err +} + +func LoadEnv(env string) (string, error) { + res := os.Getenv(env) + if res == "" { + return "", fmt.Errorf("environment variable %s is not set", env) + } + return res, nil +} + +func SetupWd() (string, error) { + err := os.Chdir("../../..") + if err != nil { + return "", err + } + + getwd, err := os.Getwd() + if err != nil { + return "", err + } + + fmt.Println("Current working directory:", getwd) + return getwd, nil +} + +func GrpcWorkspaceOpen(workspace string) string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "spaceId": "` + workspace + `" + }' localhost:31007 anytype.ClientCommands.WorkspaceOpen` +} + +func GrpcWorkspaceCreate() string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + }' localhost:31007 anytype.ClientCommands.WorkspaceCreate` +} + +func GrpcAccountSelect(accHash, workspace, networkMode, staging string) string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "id": "` + accHash + `", + "rootPath": "` + workspace + `", + "disableLocalNetworkSync": false, + "networkMode": ` + networkMode + `, + "networkCustomConfigFilePath": "` + staging + `" + }' localhost:31007 anytype.ClientCommands.AccountSelect` +} + +func GrpcWalletCreateSession(mnemonic string) string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "mnemonic": "` + mnemonic + `" + }' localhost:31007 anytype.ClientCommands.WalletCreateSession` +} + +func GrpcWalletRecover(workspace, mnemonic string) string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "rootPath": "` + workspace + `", + "mnemonic": "` + mnemonic + `" + }' localhost:31007 anytype.ClientCommands.WalletRecover` +} + +func GrpcWalletCreate(workspace string) string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "rootPath": "` + workspace + `" + }' localhost:31007 anytype.ClientCommands.WalletCreate` +} + +func GrpcAccountCreate(workspace, networkMode, staging string) string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "icon": 13, + "networkMode": ` + networkMode + `, + "storePath": "` + workspace + `", + "networkCustomConfigFilePath": "` + staging + `" + }' localhost:31007 anytype.ClientCommands.AccountCreate` +} + +func GrpcMetricsSetParameters() string { + return `grpcurl -import-path ../anytype-heart/ -proto pb/protos/service/service.proto -plaintext -d '{ + "platform": "test", + "version": "0.0.0-test" + }' localhost:31007 anytype.ClientCommands.MetricsSetParameters` +} + +func StartAnytypeBackground() error { + runServer := exec.Command("./dist/server") + runServer.Stdout = os.Stdout + runServer.Stderr = os.Stderr + runServer.Env = append(os.Environ(), `ANYPROF=:6060`) + err := runServer.Start() + if err != nil { + return err + } + + // Wait for the server to start + for { + err = ExecuteCommand(`pids=$(lsof -i :31007 -t) && [ -n "$pids" ] && echo "Found process: $pids" || { echo "No process found"; exit 1; }`) + if err == nil { + break + } else { + time.Sleep(10 * time.Second) + fmt.Println("Waiting for the server to start...", err) + } + } + return nil +} + +func CollectGoroutines() ([]byte, error) { + url := "http://localhost:6060/debug/pprof/goroutine?debug=1" + + resp, err := http.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return body, nil +} + +type Command struct { + Command string + Name string +} + +type MethodResult struct { + MethodName string + NetworkMode string + Measurements []int64 + CurrentMax int64 + CurrentMaxIndex int64 + MaxTrace []byte +} + +func (mr *MethodResult) TryUpdateTrace(trace []byte) { + mrLen := len(mr.Measurements) - 1 + if mr.CurrentMax < mr.Measurements[mrLen] { + mr.CurrentMax = mr.Measurements[mrLen] + mr.MaxTrace = trace + } +} + +func Convert(res map[string]*MethodResult) ([]Event, error) { + middlewareVersion, err := GetMiddlewareVersion() + if err != nil { + return nil, err + } + + var events []Event + for _, value := range res { + for _, duration := range value.Measurements { + events = append(events, Event{ + MethodName: value.MethodName, + Duration: duration, + MiddlewareVersion: middlewareVersion, + Network: value.NetworkMode, + }) + } + } + return events, nil +} + +type PerfResult = map[string]*MethodResult + +func SaveMaxTracesToFiles(perfResult PerfResult) error { + for key, result := range perfResult { + if result.CurrentMax > 0 { + fileName := fmt.Sprintf("goroutine_%s_%d_%d.log", result.MethodName, result.CurrentMax, result.CurrentMaxIndex) + err := os.WriteFile(fileName, result.MaxTrace, 0644) + if err != nil { + return err + } + fmt.Printf("Saved MaxTrace for method %s to file: %s\n", key, fileName) + } + } + return nil +} + +func AssertFileExists(filePath string) error { + _, err := os.Stat(filePath) + if err != nil { + return err + } + return nil +} + +func TraceServer(currentOperation *atomic.String, done chan struct{}, wait chan map[string][]byte) { + currentTraces := make(map[string][][]byte) + for { + select { + case <-done: + traces := make(map[string][]byte) + for key, value := range currentTraces { + if len(value) > 0 { + traces[key] = value[len(value)/2] + } else { + traces[key] = nil + } + } + wait <- traces + fmt.Println("Goroutine stopped") + default: + time.Sleep(1 * time.Second) + currentOperation := currentOperation.Load() + if currentOperation != "" { + bytes, err := CollectGoroutines() + if err != nil { + fmt.Println("Error collecting goroutines:", err) + } else { + if trace, ok := currentTraces[currentOperation]; ok { + currentTraces[currentOperation] = append(trace, bytes) + } else { + currentTraces[currentOperation] = [][]byte{bytes} + } + } + } + } + } +} + +func Measure(grpcurlCommands []Command, currentOperation *atomic.String, result PerfResult) error { + for _, cmd := range grpcurlCommands { + if cmd.Name != "" { + currentOperation.Store(cmd.Name) + } + start := time.Now().UnixMilli() + err := ExecuteCommand(cmd.Command) + if err != nil { + return err + } + if val, ok := result[cmd.Name]; ok { + val.Measurements = append(val.Measurements, time.Now().UnixMilli()-start) + } + currentOperation.Store("") + } + return nil +} + +func StartWithTracing(currentOperation *atomic.String, done chan struct{}, wait chan map[string][]byte) error { + go TraceServer(currentOperation, done, wait) + err := KillServer() + if err != nil { + return err + } + + err = StartAnytypeBackground() + if err != nil { + return err + } + return nil +} + +func CollectMeasurements( + grpcurlCommands []Command, + currentOperation *atomic.String, + result PerfResult, + done chan struct{}, + wait chan map[string][]byte, +) error { + err := Measure(grpcurlCommands, currentOperation, result) + if err != nil { + return err + } + + err = KillServer() + if err != nil { + return err + } + + fmt.Println("All commands executed successfully.") + close(done) + traces := <-wait + for key, value := range traces { + result[key].TryUpdateTrace(value) + } + return nil +} + +func ReadJson[T any](t *T, path string) error { + data, err := os.ReadFile(path) + if err != nil { + return err + } + err = json.Unmarshal(data, &t) + if err != nil { + return err + } + return nil +} + +type BasicInput struct { + NetworkMode string `json:"network_mode"` + NodesConfig string `json:"nodes_config"` + Times int `json:"times,omitempty"` + Workspace string `json:"workspace,omitempty"` +} + +type BasicInputtable interface { + ValidateNetwork() error + SetTimes(times int) + SetWorkspace(workspace string) +} + +func (bi *BasicInput) ValidateNetwork() error { + if bi.NetworkMode != NetworkLocal && bi.NetworkMode != NetworkStaging { + return fmt.Errorf("network mode should be either 'local' or 'staging', got: %s", bi.NetworkMode) + } + if bi.NetworkMode == NetworkStaging { + wd, err := os.Getwd() + if err != nil { + return err + } + bi.NodesConfig = filepath.Join(wd, bi.NodesConfig) + err = AssertFileExists(bi.NodesConfig) + if err != nil { + return err + } + } + return nil +} + +func (bi *BasicInput) SetTimes(times int) { + bi.Times = times +} + +func (bi *BasicInput) SetWorkspace(workspace string) { + bi.Workspace = workspace +} + +func Prepare[T BasicInputtable](prep T, f func(T) error) error { + configPath := os.Args[1] + err := AssertFileExists(configPath) + if err != nil { + return err + } + + times, err := strconv.Atoi(os.Args[2]) + if err != nil { + return err + } + if times <= 0 { + return fmt.Errorf("times should be greater than 0, got: %d", times) + } + prep.SetTimes(times) + + err = ReadJson(&prep, configPath) + if err != nil { + return err + } + + workspace, err := os.MkdirTemp("", "workspace") + if err != nil { + return err + } + fmt.Println("Created temporary directory:", workspace) + prep.SetWorkspace(workspace) + + _, err = SetupWd() + if err != nil { + return err + } + + err = prep.ValidateNetwork() + if err != nil { + return err + } + + if f != nil { + err = f(prep) + if err != nil { + return err + } + } + + err = BuildAnytype(err) + if err != nil { + return err + } + return nil +} + +func SendResults(res PerfResult) error { + apiKey, err := LoadEnv("CH_API_KEY") + if err != nil { + return err + } + + events, err := Convert(res) + if err != nil { + return err + } + + err = SendResultsToHttp(apiKey, events) + if err != nil { + return err + } + + for key, value := range res { + fmt.Printf("### Results::%s: %v\n", key, value.Measurements) + } + return nil +} + +func After(res PerfResult) error { + err := SendResults(res) + if err != nil { + return err + } + + err = SaveMaxTracesToFiles(res) + if err != nil { + return err + } + return nil +} diff --git a/core/acl/aclservice_test.go b/core/acl/aclservice_test.go index c04c8ad26f..f4e1c2d539 100644 --- a/core/acl/aclservice_test.go +++ b/core/acl/aclservice_test.go @@ -15,16 +15,20 @@ import ( "github.com/anyproto/any-sync/commonspace/object/acl/list/mock_list" "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/headupdater" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/sync/syncdeps" + "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/coordinator/coordinatorclient/mock_coordinatorclient" "github.com/anyproto/any-sync/coordinator/coordinatorproto" "github.com/anyproto/any-sync/net/peer" "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/util/cidutil" "github.com/anyproto/any-sync/util/crypto" + "github.com/anyproto/protobuf/proto" "github.com/ipfs/go-cid" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" + "storj.io/drpc" "github.com/anyproto/anytype-heart/core/anytype/account/mock_account" "github.com/anyproto/anytype-heart/core/domain" @@ -145,6 +149,23 @@ func (m mockSyncAcl) SetHeadUpdater(updater headupdater.HeadUpdater) { func (m mockSyncAcl) SetAclUpdater(updater headupdater.AclUpdater) { } +func (m mockSyncAcl) HandleHeadUpdate(ctx context.Context, statusUpdater syncstatus.StatusUpdater, headUpdate drpc.Message) (syncdeps.Request, error) { + return nil, nil +} +func (m mockSyncAcl) HandleStreamRequest(ctx context.Context, rq syncdeps.Request, updater syncdeps.QueueSizeUpdater, send func(resp proto.Message) error) (syncdeps.Request, error) { + return nil, nil +} +func (m mockSyncAcl) HandleDeprecatedRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + return nil, nil +} + +func (m mockSyncAcl) HandleResponse(ctx context.Context, peerId string, objectId string, resp syncdeps.Response) error { + return nil +} +func (m mockSyncAcl) ResponseCollector() syncdeps.ResponseCollector { + return nil +} + func TestService_MakeShareable(t *testing.T) { t.Run("ok", func(t *testing.T) { fx := newFixture(t) diff --git a/core/anytype/account/mock_account/mock_Service.go b/core/anytype/account/mock_account/mock_Service.go index e21056f7e3..24b35f12cb 100644 --- a/core/anytype/account/mock_account/mock_Service.go +++ b/core/anytype/account/mock_account/mock_Service.go @@ -129,9 +129,9 @@ func (_c *MockService_Delete_Call) RunAndReturn(run func(context.Context) (int64 return _c } -// GetInfo provides a mock function with given fields: ctx, spaceID -func (_m *MockService) GetInfo(ctx context.Context, spaceID string) (*model.AccountInfo, error) { - ret := _m.Called(ctx, spaceID) +// GetInfo provides a mock function with given fields: ctx +func (_m *MockService) GetInfo(ctx context.Context) (*model.AccountInfo, error) { + ret := _m.Called(ctx) if len(ret) == 0 { panic("no return value specified for GetInfo") @@ -139,19 +139,19 @@ func (_m *MockService) GetInfo(ctx context.Context, spaceID string) (*model.Acco var r0 *model.AccountInfo var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string) (*model.AccountInfo, error)); ok { - return rf(ctx, spaceID) + if rf, ok := ret.Get(0).(func(context.Context) (*model.AccountInfo, error)); ok { + return rf(ctx) } - if rf, ok := ret.Get(0).(func(context.Context, string) *model.AccountInfo); ok { - r0 = rf(ctx, spaceID) + if rf, ok := ret.Get(0).(func(context.Context) *model.AccountInfo); ok { + r0 = rf(ctx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*model.AccountInfo) } } - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(ctx, spaceID) + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) } else { r1 = ret.Error(1) } @@ -166,14 +166,13 @@ type MockService_GetInfo_Call struct { // GetInfo is a helper method to define mock.On call // - ctx context.Context -// - spaceID string -func (_e *MockService_Expecter) GetInfo(ctx interface{}, spaceID interface{}) *MockService_GetInfo_Call { - return &MockService_GetInfo_Call{Call: _e.mock.On("GetInfo", ctx, spaceID)} +func (_e *MockService_Expecter) GetInfo(ctx interface{}) *MockService_GetInfo_Call { + return &MockService_GetInfo_Call{Call: _e.mock.On("GetInfo", ctx)} } -func (_c *MockService_GetInfo_Call) Run(run func(ctx context.Context, spaceID string)) *MockService_GetInfo_Call { +func (_c *MockService_GetInfo_Call) Run(run func(ctx context.Context)) *MockService_GetInfo_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) + run(args[0].(context.Context)) }) return _c } @@ -183,7 +182,66 @@ func (_c *MockService_GetInfo_Call) Return(_a0 *model.AccountInfo, _a1 error) *M return _c } -func (_c *MockService_GetInfo_Call) RunAndReturn(run func(context.Context, string) (*model.AccountInfo, error)) *MockService_GetInfo_Call { +func (_c *MockService_GetInfo_Call) RunAndReturn(run func(context.Context) (*model.AccountInfo, error)) *MockService_GetInfo_Call { + _c.Call.Return(run) + return _c +} + +// GetSpaceInfo provides a mock function with given fields: ctx, spaceId +func (_m *MockService) GetSpaceInfo(ctx context.Context, spaceId string) (*model.AccountInfo, error) { + ret := _m.Called(ctx, spaceId) + + if len(ret) == 0 { + panic("no return value specified for GetSpaceInfo") + } + + var r0 *model.AccountInfo + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*model.AccountInfo, error)); ok { + return rf(ctx, spaceId) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *model.AccountInfo); ok { + r0 = rf(ctx, spaceId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.AccountInfo) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, spaceId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockService_GetSpaceInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSpaceInfo' +type MockService_GetSpaceInfo_Call struct { + *mock.Call +} + +// GetSpaceInfo is a helper method to define mock.On call +// - ctx context.Context +// - spaceId string +func (_e *MockService_Expecter) GetSpaceInfo(ctx interface{}, spaceId interface{}) *MockService_GetSpaceInfo_Call { + return &MockService_GetSpaceInfo_Call{Call: _e.mock.On("GetSpaceInfo", ctx, spaceId)} +} + +func (_c *MockService_GetSpaceInfo_Call) Run(run func(ctx context.Context, spaceId string)) *MockService_GetSpaceInfo_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *MockService_GetSpaceInfo_Call) Return(_a0 *model.AccountInfo, _a1 error) *MockService_GetSpaceInfo_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockService_GetSpaceInfo_Call) RunAndReturn(run func(context.Context, string) (*model.AccountInfo, error)) *MockService_GetSpaceInfo_Call { _c.Call.Return(run) return _c } diff --git a/core/anytype/account/profile.go b/core/anytype/account/profile.go index 9d05d29b49..d44c017263 100644 --- a/core/anytype/account/profile.go +++ b/core/anytype/account/profile.go @@ -1,7 +1,6 @@ package account import ( - "context" "fmt" "github.com/anyproto/anytype-heart/core/domain" @@ -20,11 +19,7 @@ func (s *service) MyParticipantId(spaceId string) string { } func (s *service) ProfileObjectId() (string, error) { - ids, err := s.getDerivedIds(context.Background(), s.personalSpaceId) - if err != nil { - return "", err - } - return ids.Profile, nil + return s.spaceService.TechSpace().AccountObjectId() } func (s *service) ProfileInfo() (Profile, error) { @@ -37,7 +32,7 @@ func (s *service) ProfileInfo() (Profile, error) { AccountId: s.AccountID(), } - profileDetails, err := s.objectStore.GetDetails(profile.Id) + profileDetails, err := s.objectStore.SpaceIndex(s.personalSpaceId).GetDetails(profile.Id) if err != nil { return profile, err } diff --git a/core/anytype/account/service.go b/core/anytype/account/service.go index 15d231d8f1..7867556c31 100644 --- a/core/anytype/account/service.go +++ b/core/anytype/account/service.go @@ -14,17 +14,15 @@ import ( "github.com/anyproto/anytype-heart/core/anytype/config" "github.com/anyproto/anytype-heart/core/block/cache" - "github.com/anyproto/anytype-heart/core/block/editor/smartblock" - "github.com/anyproto/anytype-heart/core/block/editor/state" "github.com/anyproto/anytype-heart/core/wallet" "github.com/anyproto/anytype-heart/pkg/lib/gateway" "github.com/anyproto/anytype-heart/pkg/lib/localstore/addr" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - "github.com/anyproto/anytype-heart/pkg/lib/threads" "github.com/anyproto/anytype-heart/space" "github.com/anyproto/anytype-heart/space/spacecore" + "github.com/anyproto/anytype-heart/space/techspace" ) const CName = "account" @@ -33,7 +31,8 @@ var log = logging.Logger(CName) type Service interface { app.Component - GetInfo(ctx context.Context, spaceID string) (*model.AccountInfo, error) + GetInfo(ctx context.Context) (*model.AccountInfo, error) + GetSpaceInfo(ctx context.Context, spaceId string) (*model.AccountInfo, error) Delete(ctx context.Context) (toBeDeleted int64, err error) RevertDeletion(ctx context.Context) error AccountID() string @@ -112,14 +111,17 @@ func (s *service) Name() (name string) { return CName } -func (s *service) GetInfo(ctx context.Context, spaceID string) (*model.AccountInfo, error) { - +func (s *service) GetInfo(ctx context.Context) (*model.AccountInfo, error) { + accountId, err := s.spaceService.TechSpace().AccountObjectId() + if err != nil { + return nil, fmt.Errorf("failed to get account id: %w", err) + } deviceKey := s.wallet.GetDevicePrivkey() deviceId := deviceKey.GetPublic().PeerId() - analyticsId, err := s.getAnalyticsID(ctx) + analyticsId, err := s.getAnalyticsId(ctx, s.spaceService.TechSpace()) if err != nil { - log.Errorf("failed to get analytics id: %s", err) + return nil, fmt.Errorf("failed to get analytics id: %w", err) } gwAddr := s.gateway.Addr() @@ -133,77 +135,66 @@ func (s *service) GetInfo(ctx context.Context, spaceID string) (*model.AccountIn cfg.CustomFileStorePath = s.wallet.RepoPath() } - profileSpace, err := s.spaceService.GetPersonalSpace(ctx) - if err != nil { - return nil, fmt.Errorf("get personal space: %w", err) - } - profileObjectId := profileSpace.DerivedIDs().Profile - - techSpaceId, err := s.spaceCore.DeriveID(ctx, spacecore.TechSpaceType) - if err != nil { - return nil, fmt.Errorf("failed to derive tech space id: %w", err) - } - - ids, err := s.getDerivedIds(ctx, spaceID) - if err != nil { - return nil, fmt.Errorf("failed to get derived ids: %w", err) - } - - var spaceViewId string - // Tech space doesn't have space view - if spaceID != techSpaceId { - spaceViewId, err = s.spaceService.SpaceViewId(spaceID) - if err != nil { - return nil, fmt.Errorf("failed to get spaceViewId: %w", err) - } - } - return &model.AccountInfo{ - HomeObjectId: ids.Home, - ArchiveObjectId: ids.Archive, - ProfileObjectId: profileObjectId, + ProfileObjectId: accountId, MarketplaceWorkspaceId: addr.AnytypeMarketplaceWorkspace, DeviceId: deviceId, - AccountSpaceId: spaceID, - WidgetsId: ids.Widgets, - SpaceViewId: spaceViewId, GatewayUrl: gwAddr, LocalStoragePath: cfg.CustomFileStorePath, AnalyticsId: analyticsId, - NetworkId: s.getNetworkID(), - TechSpaceId: techSpaceId, + NetworkId: s.getNetworkId(), + TechSpaceId: s.spaceService.TechSpaceId(), }, nil } -func (s *service) getDerivedIds(ctx context.Context, spaceID string) (ids threads.DerivedSmartblockIds, err error) { - spc, err := s.spaceService.Wait(ctx, spaceID) +func (s *service) GetSpaceInfo(ctx context.Context, spaceId string) (*model.AccountInfo, error) { + getInfo, err := s.GetInfo(ctx) + if err != nil { + return nil, err + } + spc, err := s.spaceService.Wait(ctx, spaceId) if err != nil { - return ids, fmt.Errorf("failed to get space: %w", err) + return nil, fmt.Errorf("failed to get space: %w", err) } - return spc.DeriveObjectIDs(ctx) + ids := spc.DerivedIDs() + spaceViewId, err := s.spaceService.SpaceViewId(spaceId) + if err != nil { + return nil, fmt.Errorf("failed to get spaceViewId: %w", err) + } + getInfo.AccountSpaceId = spaceId + getInfo.SpaceViewId = spaceViewId + getInfo.HomeObjectId = ids.Home + getInfo.WidgetsId = ids.Widgets + getInfo.ArchiveObjectId = ids.Archive + return getInfo, nil } -func (s *service) getAnalyticsID(ctx context.Context) (string, error) { +func (s *service) getAnalyticsId(ctx context.Context, techSpace techspace.TechSpace) (analyticsId string, err error) { if s.config.AnalyticsId != "" { return s.config.AnalyticsId, nil } - ids, err := s.getDerivedIds(ctx, s.personalSpaceId) - if err != nil { - return "", fmt.Errorf("failed to get derived ids: %w", err) - } - var analyticsID string - err = cache.Do(s.picker, ids.Workspace, func(sb smartblock.SmartBlock) error { - st := sb.NewState().GetSetting(state.SettingsAnalyticsId) - if st == nil { - log.Errorf("analytics id not found") - } else { - analyticsID = st.GetStringValue() + err = techSpace.DoAccountObject(ctx, func(accountObject techspace.AccountObject) error { + analyticsId, err = accountObject.GetAnalyticsId() + if err != nil { + log.Debug("failed to get analytics id: %s", err) } return nil }) - return analyticsID, err + if analyticsId == "" { + err = s.spaceService.WaitPersonalSpaceMigration(ctx) + if err != nil { + return + } + } else { + return analyticsId, nil + } + err = techSpace.DoAccountObject(ctx, func(accountObject techspace.AccountObject) error { + analyticsId, err = accountObject.GetAnalyticsId() + return err + }) + return } -func (s *service) getNetworkID() string { +func (s *service) getNetworkId() string { return s.config.GetNodeConf().NetworkId } diff --git a/core/anytype/bootstrap.go b/core/anytype/bootstrap.go index 02893fa34b..815de98976 100644 --- a/core/anytype/bootstrap.go +++ b/core/anytype/bootstrap.go @@ -25,6 +25,7 @@ import ( "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/nodeconf/nodeconfstore" "github.com/anyproto/any-sync/util/crypto" + "github.com/anyproto/any-sync/util/syncqueues" "go.uber.org/zap" "github.com/anyproto/any-sync/nameservice/nameserviceclient" @@ -37,6 +38,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/backlinks" "github.com/anyproto/anytype-heart/core/block/bookmark" decorator "github.com/anyproto/anytype-heart/core/block/bookmark/bookmarkimporter" + "github.com/anyproto/anytype-heart/core/block/chats" "github.com/anyproto/anytype-heart/core/block/collection" "github.com/anyproto/anytype-heart/core/block/dataviewservice" "github.com/anyproto/anytype-heart/core/block/detailservice" @@ -80,6 +82,7 @@ import ( "github.com/anyproto/anytype-heart/core/recordsbatcher" "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/core/subscription/crossspacesub" "github.com/anyproto/anytype-heart/core/syncstatus" "github.com/anyproto/anytype-heart/core/syncstatus/detailsupdater" "github.com/anyproto/anytype-heart/core/syncstatus/nodestatus" @@ -219,6 +222,7 @@ func Bootstrap(a *app.App, components ...app.Component) { Register(nodeconfsource.New()). Register(nodeconfstore.New()). Register(nodeconf.New()). + Register(syncqueues.New()). Register(peerstore.New()). Register(storage.New()). Register(secureservice.New()). @@ -230,10 +234,11 @@ func Bootstrap(a *app.App, components ...app.Component) { Register(yamux.New()). Register(quic.New()). Register(clientserver.New()). - Register(streampool.New()). Register(coordinatorclient.New()). Register(nodeclient.New()). Register(credentialprovider.New()). + Register(spacecore.NewStreamOpener()). + Register(streampool.New()). Register(commonspace.New()). Register(aclclient.NewAclJoiningClient()). Register(virtualspaceservice.New()). @@ -250,6 +255,7 @@ func Bootstrap(a *app.App, components ...app.Component) { Register(files.New()). Register(fileoffloader.New()). Register(fileacl.New()). + Register(chats.New()). Register(source.New()). Register(spacefactory.New()). Register(space.New()). @@ -286,6 +292,7 @@ func Bootstrap(a *app.App, components ...app.Component) { Register(debug.New()). Register(collection.New()). Register(subscription.New()). + Register(crossspacesub.New()). Register(syncsubscriptions.New()). Register(builtinobjects.New()). Register(bookmark.New()). diff --git a/core/anytype/config/config.go b/core/anytype/config/config.go index 76422e191f..ef8f1c726f 100644 --- a/core/anytype/config/config.go +++ b/core/anytype/config/config.go @@ -11,10 +11,11 @@ import ( anystore "github.com/anyproto/any-store" "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/net/streampool" + //nolint:misspell "github.com/anyproto/any-sync/commonspace/config" "github.com/anyproto/any-sync/metric" - "github.com/anyproto/any-sync/net/peerservice" "github.com/anyproto/any-sync/net/rpc" "github.com/anyproto/any-sync/net/rpc/debugserver" "github.com/anyproto/any-sync/net/transport/quic" @@ -154,13 +155,13 @@ func New(options ...func(*Config)) *Config { } func (c *Config) Init(a *app.App) (err error) { - repoPath := a.MustComponent(wallet.CName).(wallet.Wallet).RepoPath() + repoPath := app.MustComponent[wallet.Wallet](a).RepoPath() if err = c.initFromFileAndEnv(repoPath); err != nil { return } if !c.PeferYamuxTransport { // PeferYamuxTransport is false by default and used only in case client has some problems with QUIC - a.MustComponent(peerservice.CName).(quicPreferenceSetter).PreferQuic(true) + app.MustComponent[quicPreferenceSetter](a).PreferQuic(true) } // check if sqlite db exists if _, err2 := os.Stat(filepath.Join(repoPath, SpaceStoreSqlitePath)); err2 == nil { @@ -411,6 +412,14 @@ func (c *Config) GetNodeConfStorePath() string { return filepath.Join(c.RepoPath, "nodeconf") } +func (c *Config) GetStreamConfig() streampool.StreamConfig { + return streampool.StreamConfig{ + SendQueueSize: 300, + DialQueueWorkers: 4, + DialQueueSize: 300, + } +} + func (c *Config) GetYamux() yamux.Config { return yamux.Config{ ListenAddrs: []string{}, diff --git a/core/application/account_create.go b/core/application/account_create.go index 53c63b19b1..ee455bb1e4 100644 --- a/core/application/account_create.go +++ b/core/application/account_create.go @@ -3,7 +3,6 @@ package application import ( "context" "errors" - "fmt" "os" "path/filepath" @@ -105,12 +104,16 @@ func (s *Service) handleCustomStorageLocation(req *pb.RpcAccountCreateRequest, a } func (s *Service) setAccountAndProfileDetails(ctx context.Context, req *pb.RpcAccountCreateRequest, newAcc *model.Account) error { - personalSpaceId := app.MustComponent[account.Service](s.app).PersonalSpaceID() + spaceService := app.MustComponent[space.Service](s.app) + techSpaceId := spaceService.TechSpaceId() + personalSpaceId := spaceService.PersonalSpaceId() var err error - newAcc.Info, err = app.MustComponent[account.Service](s.app).GetInfo(ctx, personalSpaceId) + newAcc.Info, err = app.MustComponent[account.Service](s.app).GetInfo(ctx) if err != nil { return err } + // TODO: remove it release 8, this is need for client to set "My First Space" as space name + newAcc.Info.AccountSpaceId = personalSpaceId bs := s.app.MustComponent(block.CName).(*block.Service) commonDetails := []*model.Detail{ @@ -127,7 +130,7 @@ func (s *Service) setAccountAndProfileDetails(ctx context.Context, req *pb.RpcAc profileDetails = append(profileDetails, commonDetails...) if req.GetAvatarLocalPath() != "" { - hash, _, err := bs.UploadFile(context.Background(), personalSpaceId, block.FileUploadRequest{ + hash, _, err := bs.UploadFile(context.Background(), techSpaceId, block.FileUploadRequest{ RpcFileUploadRequest: pb.RpcFileUploadRequest{ LocalPath: req.GetAvatarLocalPath(), Type: model.BlockContentFile_Image, @@ -143,27 +146,16 @@ func (s *Service) setAccountAndProfileDetails(ctx context.Context, req *pb.RpcAc }) } } - - spaceService := app.MustComponent[space.Service](s.app) - spc, err := spaceService.Get(ctx, personalSpaceId) + accId, err := spaceService.TechSpace().AccountObjectId() if err != nil { - return fmt.Errorf("get personal space: %w", err) + return errors.Join(ErrSetDetails, err) } - accountObjects := spc.DerivedIDs() - ds := app.MustComponent[detailservice.Service](s.app) if err := ds.SetDetails(nil, - accountObjects.Profile, + accId, profileDetails, ); err != nil { return errors.Join(ErrSetDetails, err) } - - if err := ds.SetDetails(nil, - accountObjects.Workspace, - commonDetails, - ); err != nil { - return errors.Join(ErrSetDetails, err) - } return nil } diff --git a/core/application/account_select.go b/core/application/account_select.go index 05e0b70ccb..97c25fb7f2 100644 --- a/core/application/account_select.go +++ b/core/application/account_select.go @@ -57,10 +57,9 @@ func (s *Service) AccountSelect(ctx context.Context, req *pb.RpcAccountSelectReq // objectCache := app.MustComponent[objectcache.Cache](s.app) // objectCache.CloseBlocks() - spaceID := app.MustComponent[account.Service](s.app).PersonalSpaceID() acc := &model.Account{Id: req.Id} var err error - acc.Info, err = app.MustComponent[account.Service](s.app).GetInfo(ctx, spaceID) + acc.Info, err = app.MustComponent[account.Service](s.app).GetInfo(ctx) if err != nil { return nil, err } @@ -154,7 +153,6 @@ func (s *Service) start(ctx context.Context, id string, rootPath string, disable } acc := &model.Account{Id: id} - spaceID := app.MustComponent[account.Service](s.app).PersonalSpaceID() - acc.Info, err = app.MustComponent[account.Service](s.app).GetInfo(ctx, spaceID) + acc.Info, err = app.MustComponent[account.Service](s.app).GetInfo(ctx) return acc, err } diff --git a/core/block/backlinks/watcher.go b/core/block/backlinks/watcher.go index e1484403f4..83a4b20cbd 100644 --- a/core/block/backlinks/watcher.go +++ b/core/block/backlinks/watcher.go @@ -19,6 +19,7 @@ import ( "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/space" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -30,7 +31,7 @@ const CName = "backlinks-update-watcher" var log = logging.Logger(CName) type backlinksUpdater interface { - SubscribeLinksUpdate(callback func(info objectstore.LinksUpdateInfo)) + SubscribeLinksUpdate(callback func(info spaceindex.LinksUpdateInfo)) } type backLinksUpdate struct { @@ -75,7 +76,7 @@ func (uw *UpdateWatcher) Close(context.Context) error { } func (uw *UpdateWatcher) Run(context.Context) error { - uw.updater.SubscribeLinksUpdate(func(info objectstore.LinksUpdateInfo) { + uw.updater.SubscribeLinksUpdate(func(info spaceindex.LinksUpdateInfo) { if err := uw.infoBatch.Add(info); err != nil { log.With("objectId", info.LinksFromId).Errorf("failed to add backlinks update info to message batch: %v", err) } @@ -85,7 +86,7 @@ func (uw *UpdateWatcher) Run(context.Context) error { return nil } -func applyUpdates(m map[string]*backLinksUpdate, update objectstore.LinksUpdateInfo) { +func applyUpdates(m map[string]*backLinksUpdate, update spaceindex.LinksUpdateInfo) { if update.LinksFromId == "" { return } @@ -161,7 +162,7 @@ func (uw *UpdateWatcher) backlinksUpdateHandler() { l.Lock() for _, msg := range msgs { - info, ok := msg.(objectstore.LinksUpdateInfo) + info, ok := msg.(spaceindex.LinksUpdateInfo) if !ok || hasSelfLinks(info) { continue } @@ -206,7 +207,7 @@ func (uw *UpdateWatcher) updateBackLinksInObject(id string, backlinksUpdate *bac } err = spc.DoLockedIfNotExists(id, func() error { - return uw.store.ModifyObjectDetails(id, func(details *types.Struct) (*types.Struct, bool, error) { + return uw.store.SpaceIndex(spaceId).ModifyObjectDetails(id, func(details *types.Struct) (*types.Struct, bool, error) { return updateBacklinks(details, backlinksUpdate) }) }) @@ -232,7 +233,7 @@ func (uw *UpdateWatcher) updateBackLinksInObject(id string, backlinksUpdate *bac } -func hasSelfLinks(info objectstore.LinksUpdateInfo) bool { +func hasSelfLinks(info spaceindex.LinksUpdateInfo) bool { for _, link := range info.Added { if link == info.LinksFromId { return true diff --git a/core/block/bookmark/bookmark_service.go b/core/block/bookmark/bookmark_service.go index fea63b496d..0814edba19 100644 --- a/core/block/bookmark/bookmark_service.go +++ b/core/block/bookmark/bookmark_service.go @@ -127,7 +127,7 @@ func (s *service) CreateBookmarkObject( } url := pbtypes.GetString(details, bundle.RelationKeySource.String()) - records, err := s.store.Query(database.Query{ + records, err := s.store.SpaceIndex(spaceID).Query(database.Query{ Sorts: []*model.BlockContentDataviewSort{ { RelationKey: bundle.RelationKeyLastModifiedDate.String(), diff --git a/core/block/bookmark/bookmark_service_test.go b/core/block/bookmark/bookmark_service_test.go index b0571833c6..72c53b9f18 100644 --- a/core/block/bookmark/bookmark_service_test.go +++ b/core/block/bookmark/bookmark_service_test.go @@ -96,7 +96,7 @@ func TestService_CreateBookmarkObject(t *testing.T) { details := &types.Struct{Fields: map[string]*types.Value{ bundle.RelationKeySource.String(): pbtypes.String(url), }} - fx.store.AddObjects(t, []objectstore.TestObject{{ + fx.store.AddObjects(t, "space1", []objectstore.TestObject{{ bundle.RelationKeyId: pbtypes.String("bk"), bundle.RelationKeySource: pbtypes.String(url), bundle.RelationKeyType: pbtypes.String(bookmarkId), diff --git a/core/block/chats/service.go b/core/block/chats/service.go new file mode 100644 index 0000000000..a8c93e883d --- /dev/null +++ b/core/block/chats/service.go @@ -0,0 +1,123 @@ +package chats + +import ( + "context" + + "github.com/anyproto/any-sync/app" + + "github.com/anyproto/anytype-heart/core/block/cache" + "github.com/anyproto/anytype-heart/core/block/editor/chatobject" + "github.com/anyproto/anytype-heart/core/session" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +const CName = "core.block.chats" + +type Service interface { + AddMessage(ctx context.Context, sessionCtx session.Context, chatObjectId string, message *model.ChatMessage) (string, error) + EditMessage(ctx context.Context, chatObjectId string, messageId string, newMessage *model.ChatMessage) error + ToggleMessageReaction(ctx context.Context, chatObjectId string, messageId string, emoji string) error + DeleteMessage(ctx context.Context, chatObjectId string, messageId string) error + GetMessages(ctx context.Context, chatObjectId string, beforeOrderId string, limit int) ([]*model.ChatMessage, error) + GetMessagesByIds(ctx context.Context, chatObjectId string, messageIds []string) ([]*model.ChatMessage, error) + SubscribeLastMessages(ctx context.Context, chatObjectId string, limit int) ([]*model.ChatMessage, int, error) + Unsubscribe(chatObjectId string) error + + app.Component +} + +var _ Service = (*service)(nil) + +type service struct { + objectGetter cache.ObjectGetter +} + +func New() Service { + return &service{} +} + +func (s *service) Name() string { + return CName +} + +func (s *service) Init(a *app.App) error { + s.objectGetter = app.MustComponent[cache.ObjectGetter](a) + + return nil +} + +func (s *service) AddMessage(ctx context.Context, sessionCtx session.Context, chatObjectId string, message *model.ChatMessage) (string, error) { + var messageId string + err := cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + var err error + messageId, err = sb.AddMessage(ctx, sessionCtx, message) + return err + }) + return messageId, err +} + +func (s *service) EditMessage(ctx context.Context, chatObjectId string, messageId string, newMessage *model.ChatMessage) error { + return cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + return sb.EditMessage(ctx, messageId, newMessage) + }) +} + +func (s *service) ToggleMessageReaction(ctx context.Context, chatObjectId string, messageId string, emoji string) error { + return cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + return sb.ToggleMessageReaction(ctx, messageId, emoji) + }) +} + +func (s *service) DeleteMessage(ctx context.Context, chatObjectId string, messageId string) error { + return cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + return sb.DeleteMessage(ctx, messageId) + }) +} + +func (s *service) GetMessages(ctx context.Context, chatObjectId string, beforeOrderId string, limit int) ([]*model.ChatMessage, error) { + var res []*model.ChatMessage + err := cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + msgs, err := sb.GetMessages(ctx, beforeOrderId, limit) + if err != nil { + return err + } + res = msgs + return nil + }) + return res, err +} + +func (s *service) GetMessagesByIds(ctx context.Context, chatObjectId string, messageIds []string) ([]*model.ChatMessage, error) { + var res []*model.ChatMessage + err := cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + msg, err := sb.GetMessagesByIds(ctx, messageIds) + if err != nil { + return err + } + res = msg + return nil + }) + return res, err +} + +func (s *service) SubscribeLastMessages(ctx context.Context, chatObjectId string, limit int) ([]*model.ChatMessage, int, error) { + var ( + msgs []*model.ChatMessage + numBefore int + ) + err := cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + var err error + msgs, numBefore, err = sb.SubscribeLastMessages(ctx, limit) + if err != nil { + return err + } + return nil + }) + return msgs, numBefore, err +} + +func (s *service) Unsubscribe(chatObjectId string) error { + return cache.Do(s.objectGetter, chatObjectId, func(sb chatobject.StoreObject) error { + return sb.Unsubscribe() + }) +} diff --git a/core/block/collection/service.go b/core/block/collection/service.go index 1f557af071..a485940b56 100644 --- a/core/block/collection/service.go +++ b/core/block/collection/service.go @@ -203,12 +203,13 @@ func (s *Service) CreateCollection(details *types.Struct, flags []*model.Interna func (s *Service) ObjectToCollection(id string) error { return cache.DoState(s.picker, id, func(st *state.State, b basic.CommonOperations) error { - s.setDefaultObjectTypeToViews(st) + sb := b.(smartblock.SmartBlock) + s.setDefaultObjectTypeToViews(sb.SpaceID(), st) return b.SetObjectTypesInState(st, []domain.TypeKey{bundle.TypeKeyCollection}, true) }) } -func (s *Service) setDefaultObjectTypeToViews(st *state.State) { +func (s *Service) setDefaultObjectTypeToViews(spaceId string, st *state.State) { if !lo.Contains(st.ParentState().ObjectTypeKeys(), bundle.TypeKeySet) { return } @@ -218,7 +219,7 @@ func (s *Service) setDefaultObjectTypeToViews(st *state.State) { return } - if s.isNotCreatableType(setOfValue[0]) { + if s.isNotCreatableType(spaceId, setOfValue[0]) { return } @@ -236,8 +237,8 @@ func (s *Service) setDefaultObjectTypeToViews(st *state.State) { } } -func (s *Service) isNotCreatableType(id string) bool { - uk, err := s.objectStore.GetUniqueKeyById(id) +func (s *Service) isNotCreatableType(spaceId string, id string) bool { + uk, err := s.objectStore.SpaceIndex(spaceId).GetUniqueKeyById(id) if err != nil { return true } diff --git a/core/block/collection/service_test.go b/core/block/collection/service_test.go index 7719b092d7..8fa51699f1 100644 --- a/core/block/collection/service_test.go +++ b/core/block/collection/service_test.go @@ -17,7 +17,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -41,13 +41,13 @@ func (t *testPicker) Name() string { return "" } type fixture struct { picker *testPicker *Service + objectStore *objectstore.StoreFixture } func newFixture(t *testing.T) *fixture { picker := &testPicker{} a := &app.App{} - objectStore := mock_objectstore.NewMockObjectStore(t) - objectStore.EXPECT().Name().Return("objectStore") + objectStore := objectstore.NewStoreFixture(t) a.Register(picker) a.Register(objectStore) @@ -55,7 +55,7 @@ func newFixture(t *testing.T) *fixture { err := s.Init(a) require.NoError(t, err) - return &fixture{picker: picker, Service: s} + return &fixture{picker: picker, Service: s, objectStore: objectStore} } func TestBroadcast(t *testing.T) { @@ -157,7 +157,7 @@ func TestSetObjectTypeToViews(t *testing.T) { st := generateState(bundle.TypeKeyPage, setOfValue) // when - s.setDefaultObjectTypeToViews(st) + s.setDefaultObjectTypeToViews("space1", st) // then assertViews(st, "") @@ -175,13 +175,18 @@ func TestSetObjectTypeToViews(t *testing.T) { } { t.Run("object is a set by "+testCase.name, func(t *testing.T) { // given - store := mock_objectstore.NewMockObjectStore(t) - store.EXPECT().GetUniqueKeyById(setOfValue).Return(domain.NewUniqueKey(testCase.sbType, testCase.key)) - s := Service{objectStore: store} + s := newFixture(t) + s.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + { + bundle.RelationKeyId: pbtypes.String(setOfValue), + bundle.RelationKeyUniqueKey: pbtypes.String(domain.MustUniqueKey(testCase.sbType, testCase.key).Marshal()), + }, + }) + st := generateState(bundle.TypeKeySet, setOfValue) // when - s.setDefaultObjectTypeToViews(st) + s.setDefaultObjectTypeToViews("space1", st) // then assertViews(st, testCase.expected) diff --git a/core/block/debug.go b/core/block/debug.go index d701753179..ecfceba133 100644 --- a/core/block/debug.go +++ b/core/block/debug.go @@ -14,12 +14,9 @@ import ( "github.com/anyproto/anytype-heart/core/block/cache" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/source" - "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/tests/blockbuilder" "github.com/anyproto/anytype-heart/util/debug" - "github.com/anyproto/anytype-heart/util/pbtypes" ) func (s *Service) DebugRouter(r chi.Router) { @@ -51,14 +48,8 @@ type debugObject struct { func (s *Service) debugListObjectsPerSpace(req *http.Request) ([]debugObject, error) { spaceId := chi.URLParam(req, "spaceId") - ids, _, err := s.objectStore.QueryObjectIDs(database.Query{ - Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceId), - Condition: model.BlockContentDataviewFilter_Equal, - }, - }, + ids, _, err := s.objectStore.SpaceIndex(spaceId).QueryObjectIds(database.Query{ + Filters: nil, }) if err != nil { return nil, fmt.Errorf("list ids: %w", err) @@ -78,7 +69,7 @@ func (s *Service) debugListObjectsPerSpace(req *http.Request) ([]debugObject, er } func (s *Service) debugListObjects(req *http.Request) ([]debugObject, error) { - ids, err := s.objectStore.ListIds() + ids, err := s.objectStore.ListIdsCrossSpace() if err != nil { return nil, fmt.Errorf("list ids: %w", err) } diff --git a/core/block/delete.go b/core/block/delete.go index 20cfda5cf4..fd75e2777d 100644 --- a/core/block/delete.go +++ b/core/block/delete.go @@ -8,7 +8,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/event" - "github.com/anyproto/anytype-heart/core/files/fileobject" + "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" @@ -43,8 +43,8 @@ func (s *Service) DeleteObjectByFullID(id domain.FullID) error { case coresb.SmartBlockTypeSubObject: return fmt.Errorf("subobjects deprecated") case coresb.SmartBlockTypeFileObject: - err = s.fileObjectService.DeleteFileData(id.ObjectID) - if err != nil && !errors.Is(err, fileobject.ErrEmptyFileId) { + err = s.fileObjectService.DeleteFileData(id.SpaceID, id.ObjectID) + if err != nil && !errors.Is(err, filemodels.ErrEmptyFileId) { return fmt.Errorf("delete file data: %w", err) } err = spc.DeleteTree(context.Background(), id.ObjectID) @@ -84,7 +84,7 @@ func (s *Service) deleteDerivedObject(id domain.FullID, spc clientspace.Space) ( return fmt.Errorf("on delete: %w", err) } if sbType == coresb.SmartBlockTypeRelation { - err := s.deleteRelationOptions(relationKey) + err := s.deleteRelationOptions(id.SpaceID, relationKey) if err != nil { return fmt.Errorf("failed to delete relation options of deleted relation: %w", err) } @@ -92,8 +92,8 @@ func (s *Service) deleteDerivedObject(id domain.FullID, spc clientspace.Space) ( return nil } -func (s *Service) deleteRelationOptions(relationKey string) error { - relationOptions, _, err := s.objectStore.QueryObjectIDs(database.Query{ +func (s *Service) deleteRelationOptions(spaceId string, relationKey string) error { + relationOptions, _, err := s.objectStore.SpaceIndex(spaceId).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyLayout.String(), @@ -144,7 +144,7 @@ func (s *Service) OnDelete(id domain.FullID, workspaceRemove func() error) error if err != nil { log.With("error", err, "objectId", id.ObjectID).Error("failed to perform delete operation on object") } - if err := s.objectStore.DeleteObject(id); err != nil { + if err := s.objectStore.SpaceIndex(id.SpaceID).DeleteObject(id.ObjectID); err != nil { return fmt.Errorf("delete object from local store: %w", err) } diff --git a/core/block/detailservice/relations.go b/core/block/detailservice/relations.go index d693cd8604..97a1d27654 100644 --- a/core/block/detailservice/relations.go +++ b/core/block/detailservice/relations.go @@ -18,7 +18,6 @@ import ( coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/localstore/addr" - "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" @@ -70,11 +69,7 @@ func (s *service) ListRelationsWithValue(spaceId string, value *types.Value) (ke countersByKeys := make(map[string]int64) detailHandlesValue := generateFilter(value) - err = s.store.QueryIterate(database.Query{Filters: []*model.BlockContentDataviewFilter{{ - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }}}, func(details *types.Struct) { + err = s.store.SpaceIndex(spaceId).QueryIterate(database.Query{Filters: nil}, func(details *types.Struct) { for key, valueToCheck := range details.Fields { if detailHandlesValue(valueToCheck) { if counter, ok := countersByKeys[key]; ok { diff --git a/core/block/detailservice/relations_test.go b/core/block/detailservice/relations_test.go index ff9c071f7f..cfd9beb510 100644 --- a/core/block/detailservice/relations_test.go +++ b/core/block/detailservice/relations_test.go @@ -33,7 +33,7 @@ func relationObject(key domain.RelationKey, format model.RelationFormat) objects func TestService_ListRelationsWithValue(t *testing.T) { now := time.Now() store := objectstore.NewStoreFixture(t) - store.AddObjects(t, []objectstore.TestObject{ + store.AddObjects(t, spaceId, []objectstore.TestObject{ // relations relationObject(bundle.RelationKeyLastModifiedDate, model.RelationFormat_date), relationObject(bundle.RelationKeyAddedDate, model.RelationFormat_date), diff --git a/core/block/detailservice/service_test.go b/core/block/detailservice/service_test.go index 16167b9f54..b6c63feebd 100644 --- a/core/block/detailservice/service_test.go +++ b/core/block/detailservice/service_test.go @@ -281,7 +281,7 @@ func TestService_SetWorkspaceDashboardId(t *testing.T) { assert.Equal(t, wsObjectId, objectId) ws := &editor.Workspaces{ SmartBlock: sb, - AllOperations: basic.NewBasic(sb, fx.store, nil, nil, nil), + AllOperations: basic.NewBasic(sb, fx.store.SpaceIndex(spaceId), nil, nil, nil), } return ws, nil }) @@ -304,7 +304,7 @@ func TestService_SetWorkspaceDashboardId(t *testing.T) { assert.Equal(t, wsObjectId, objectId) ws := &editor.Workspaces{ SmartBlock: sb, - AllOperations: basic.NewBasic(sb, fx.store, nil, nil, nil), + AllOperations: basic.NewBasic(sb, fx.store.SpaceIndex(spaceId), nil, nil, nil), } return ws, nil }) @@ -333,11 +333,11 @@ func TestService_SetListIsFavorite(t *testing.T) { fx := newFixture(t) sb := smarttest.New(homeId) sb.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { require.Equal(t, homeId, objectId) - return editor.NewDashboard(sb, fx.store, nil), nil + return editor.NewDashboard(sb, fx.store.SpaceIndex(spaceId), nil), nil }) // when @@ -356,11 +356,11 @@ func TestService_SetListIsFavorite(t *testing.T) { sb.AddBlock(simple.New(&model.Block{Id: "obj1", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj1"}}})) sb.AddBlock(simple.New(&model.Block{Id: "obj2", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj2"}}})) sb.AddBlock(simple.New(&model.Block{Id: "obj3", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj3"}}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { require.Equal(t, homeId, objectId) - return editor.NewDashboard(sb, fx.store, nil), nil + return editor.NewDashboard(sb, fx.store.SpaceIndex(spaceId), nil), nil }) // when @@ -376,7 +376,7 @@ func TestService_SetListIsFavorite(t *testing.T) { fx := newFixture(t) sb := smarttest.New(homeId) sb.AddBlock(simple.New(&model.Block{Id: homeId, ChildrenIds: []string{}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId}) flag := false fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { @@ -385,7 +385,7 @@ func TestService_SetListIsFavorite(t *testing.T) { return nil, fmt.Errorf("unexpected error") } flag = true - return editor.NewDashboard(sb, fx.store, nil), nil + return editor.NewDashboard(sb, fx.store.SpaceIndex(spaceId), nil), nil }) // when @@ -399,7 +399,7 @@ func TestService_SetListIsFavorite(t *testing.T) { t.Run("all updates failed", func(t *testing.T) { // given fx := newFixture(t) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Home: homeId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { require.Equal(t, homeId, objectId) @@ -427,11 +427,11 @@ func TestService_SetIsArchived(t *testing.T) { fx := newFixture(t) sb := smarttest.New(binId) sb.AddBlock(simple.New(&model.Block{Id: binId, ChildrenIds: []string{}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Archive: binId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { if objectId == binId { - return editor.NewArchive(sb, fx.store), nil + return editor.NewArchive(sb, fx.store.SpaceIndex(spaceId)), nil } return smarttest.New(objectId), nil }) @@ -450,10 +450,10 @@ func TestService_SetIsArchived(t *testing.T) { fx := newFixture(t) sb := smarttest.New(binId) sb.AddBlock(simple.New(&model.Block{Id: binId, ChildrenIds: []string{}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { if objectId == binId { - return editor.NewArchive(sb, fx.store), nil + return editor.NewArchive(sb, fx.store.SpaceIndex(spaceId)), nil } return smarttest.New(objectId), nil }) @@ -483,11 +483,11 @@ func TestService_SetListIsArchived(t *testing.T) { fx := newFixture(t) sb := smarttest.New(binId) sb.AddBlock(simple.New(&model.Block{Id: binId, ChildrenIds: []string{}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Archive: binId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { if objectId == binId { - return editor.NewArchive(sb, fx.store), nil + return editor.NewArchive(sb, fx.store.SpaceIndex(spaceId)), nil } return smarttest.New(objectId), nil }) @@ -511,11 +511,11 @@ func TestService_SetListIsArchived(t *testing.T) { sb.AddBlock(simple.New(&model.Block{Id: "obj2", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj2"}}})) sb.AddBlock(simple.New(&model.Block{Id: "obj3", Content: &model.BlockContentOfLink{Link: &model.BlockContentLink{TargetBlockId: "obj3"}}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Archive: binId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { if objectId == binId { - return editor.NewArchive(sb, fx.store), nil + return editor.NewArchive(sb, fx.store.SpaceIndex(spaceId)), nil } return smarttest.New(objectId), nil }) @@ -533,11 +533,11 @@ func TestService_SetListIsArchived(t *testing.T) { fx := newFixture(t) sb := smarttest.New(binId) sb.AddBlock(simple.New(&model.Block{Id: binId, ChildrenIds: []string{}})) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Archive: binId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { if objectId == binId { - return editor.NewArchive(sb, fx.store), nil + return editor.NewArchive(sb, fx.store.SpaceIndex(spaceId)), nil } if objectId == "obj2" { return nil, fmt.Errorf("failed to get object") @@ -557,7 +557,7 @@ func TestService_SetListIsArchived(t *testing.T) { t.Run("all updates failed", func(t *testing.T) { // given fx := newFixture(t) - fx.store.AddObjects(t, objects) + fx.store.AddObjects(t, spaceId, objects) fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{Archive: binId}) fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) { return nil, fmt.Errorf("failed to get object") diff --git a/core/block/detailservice/set_details.go b/core/block/detailservice/set_details.go index 9c80baefa4..f20e133634 100644 --- a/core/block/detailservice/set_details.go +++ b/core/block/detailservice/set_details.go @@ -85,22 +85,32 @@ func (s *service) SetIsArchived(objectId string, isArchived bool) error { } func (s *service) SetListIsFavorite(objectIds []string, isFavorite bool) error { - ids, err := s.store.HasIDs(objectIds...) + objectIdsPerSpace, err := s.partitionObjectIdsBySpaceId(objectIds) if err != nil { - return err + return fmt.Errorf("partition object ids by spaces: %w", err) } + var ( anySucceed bool resultError error ) - for _, id := range ids { - err := s.SetIsFavorite(id, isFavorite) + for spaceId, objectIds := range objectIdsPerSpace { + ids, err := s.store.SpaceIndex(spaceId).HasIds(objectIds) if err != nil { - log.Error("failed to favorite object", zap.String("objectId", id), zap.Error(err)) - resultError = errors.Join(resultError, err) - } else { - anySucceed = true + return err + } + + for _, id := range ids { + // TODO Set list of ids at once + err := s.SetIsFavorite(id, isFavorite) + if err != nil { + log.Error("failed to favorite object", zap.String("objectId", id), zap.Error(err)) + resultError = errors.Join(resultError, err) + } else { + anySucceed = true + } } + } if resultError != nil { log.Warn("failed to set objects as favorite", zap.Error(resultError)) @@ -183,7 +193,7 @@ func (s *service) setIsArchivedForObjects(spaceId string, objectIds []string, is return fmt.Errorf("unexpected archive block type: %T", b) } - ids, err := s.store.HasIDs(objectIds...) + ids, err := s.store.SpaceIndex(spaceId).HasIds(objectIds) if err != nil { return err } diff --git a/core/block/editor/accountobject/accounthandler.go b/core/block/editor/accountobject/accounthandler.go new file mode 100644 index 0000000000..0f27c07f16 --- /dev/null +++ b/core/block/editor/accountobject/accounthandler.go @@ -0,0 +1,46 @@ +package accountobject + +import ( + "context" + "fmt" + + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" + + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/pb" +) + +type accountHandler struct { +} + +func (a accountHandler) CollectionName() string { + return collectionName +} + +func (a accountHandler) Init(ctx context.Context, s *storestate.StoreState) (err error) { + _, err = s.Collection(ctx, collectionName) + return +} + +func (a accountHandler) BeforeCreate(ctx context.Context, ch storestate.ChangeOp) (err error) { + return +} + +func (a accountHandler) BeforeModify(ctx context.Context, ch storestate.ChangeOp) (mode storestate.ModifyMode, err error) { + return storestate.ModifyModeUpsert, nil +} + +func (a accountHandler) BeforeDelete(ctx context.Context, ch storestate.ChangeOp) (mode storestate.DeleteMode, err error) { + _, err = ch.State.Collection(ctx, collectionName) + if err != nil { + return storestate.DeleteModeDelete, fmt.Errorf("get collection: %w", err) + } + return storestate.DeleteModeDelete, nil +} + +func (a accountHandler) UpgradeKeyModifier(ch storestate.ChangeOp, key *pb.KeyModify, mod query.Modifier) query.Modifier { + return query.ModifyFunc(func(a *anyenc.Arena, v *anyenc.Value) (result *anyenc.Value, modified bool, err error) { + return mod.Modify(a, v) + }) +} diff --git a/core/block/editor/accountobject/accountobject.go b/core/block/editor/accountobject/accountobject.go new file mode 100644 index 0000000000..87e7a17e81 --- /dev/null +++ b/core/block/editor/accountobject/accountobject.go @@ -0,0 +1,404 @@ +package accountobject + +import ( + "context" + "crypto/rand" + "errors" + "fmt" + "time" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/util/crypto" + "github.com/gogo/protobuf/types" + "go.uber.org/zap" + + "github.com/anyproto/anytype-heart/core/anytype/config" + "github.com/anyproto/anytype-heart/core/block/editor/anystoredebug" + "github.com/anyproto/anytype-heart/core/block/editor/basic" + "github.com/anyproto/anytype-heart/core/block/editor/converter" + "github.com/anyproto/anytype-heart/core/block/editor/lastused" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/core/block/editor/template" + "github.com/anyproto/anytype-heart/core/block/simple" + "github.com/anyproto/anytype-heart/core/block/source" + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/files/fileobject" + "github.com/anyproto/anytype-heart/core/session" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +var log = logger.NewNamedSugared("common.editor.accountobject") + +const ( + collectionName = "account" + accountDocumentId = "accountObject" + idKey = "id" + analyticsKey = "analyticsId" + iconMigrationKey = "iconMigration" + privateAnalyticsIdKey = "privateAnalyticsId" +) + +type ProfileDetails struct { + Name string + Description string + IconImage string +} + +type AccountObject interface { + smartblock.SmartBlock + anystoredebug.AnystoreDebug + + basic.DetailsSettable + SetSharedSpacesLimit(limit int) (err error) + SetProfileDetails(details *types.Struct) (err error) + MigrateIconImage(image string) (err error) + IsIconMigrated() (bool, error) + SetAnalyticsId(analyticsId string) (err error) + GetAnalyticsId() (string, error) + GetPrivateAnalyticsId() string +} + +type StoreDbProvider interface { + GetStoreDb() anystore.DB +} + +var _ AccountObject = (*accountObject)(nil) + +type accountObject struct { + anystoredebug.AnystoreDebug + smartblock.SmartBlock + bs basic.DetailsSettable + state *storestate.StoreState + storeSource source.Store + ctx context.Context + cancel context.CancelFunc + relMapper *relationsMapper + cfg *config.Config + crdtDb anystore.DB +} + +func (a *accountObject) SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error) { + return a.bs.SetDetails(ctx, details, showEvent) +} + +func (a *accountObject) SetDetailsAndUpdateLastUsed(ctx session.Context, details []*model.Detail, showEvent bool) (err error) { + return a.bs.SetDetailsAndUpdateLastUsed(ctx, details, showEvent) +} + +func New( + sb smartblock.SmartBlock, + spaceObjects spaceindex.Store, + layoutConverter converter.LayoutConverter, + fileObjectService fileobject.Service, + lastUsedUpdater lastused.ObjectUsageUpdater, + crdtDb anystore.DB, + cfg *config.Config) AccountObject { + return &accountObject{ + crdtDb: crdtDb, + bs: basic.NewBasic(sb, spaceObjects, layoutConverter, fileObjectService, lastUsedUpdater), + SmartBlock: sb, + cfg: cfg, + relMapper: newRelationsMapper(map[string]KeyType{ + bundle.RelationKeyName.String(): KeyTypeString, + bundle.RelationKeyDescription.String(): KeyTypeString, + bundle.RelationKeyIconImage.String(): KeyTypeString, + bundle.RelationKeyIconOption.String(): KeyTypeInt64, + }), + } +} + +func (a *accountObject) Init(ctx *smartblock.InitContext) error { + err := a.SmartBlock.Init(ctx) + if err != nil { + return err + } + stateStore, err := storestate.New(ctx.Ctx, a.Id(), a.crdtDb, accountHandler{}) + if err != nil { + return fmt.Errorf("create state store: %w", err) + } + a.state = stateStore + + a.AnystoreDebug = anystoredebug.New(a.SmartBlock, stateStore) + + storeSource, ok := ctx.Source.(source.Store) + if !ok { + return fmt.Errorf("source is not a store") + } + storeSource.SetPushChangeHook(a.OnPushChange) + a.storeSource = storeSource + err = storeSource.ReadStoreDoc(ctx.Ctx, stateStore, a.onUpdate) + if err != nil { + return fmt.Errorf("read store doc: %w", err) + } + coll, err := a.state.Collection(ctx.Ctx, collectionName) + if err != nil { + return fmt.Errorf("get collection: %w", err) + } + a.ctx, a.cancel = context.WithCancel(context.Background()) + _, err = coll.FindId(ctx.Ctx, accountDocumentId) + if err != nil && !errors.Is(err, anystore.ErrDocNotFound) { + return fmt.Errorf("find id: %w", err) + } + if errors.Is(err, anystore.ErrDocNotFound) { + var docToInsert string + docToInsert, err = a.genInitialDoc(true) + if err != nil { + return fmt.Errorf("generate initial doc: %w", err) + } + err = coll.Insert(ctx.Ctx, anyenc.MustParseJson(docToInsert)) + if err != nil { + return fmt.Errorf("insert account document: %w", err) + } + } + st := a.NewState() + err = a.update(a.ctx, st) + if err != nil { + return fmt.Errorf("update state: %w", err) + } + err = a.initState(st) + if err != nil { + return fmt.Errorf("init state: %w", err) + } + return a.SmartBlock.Apply(st, smartblock.NotPushChanges, smartblock.NoHistory, smartblock.SkipIfNoChanges) +} + +// GetPrivateAnalyticsId returns the private analytics id of the account object, should not be used directly +// only when hashing it with other data, e.g. hash(privateAnalyticsId + someData) +func (a *accountObject) GetPrivateAnalyticsId() string { + val, err := a.getValue() + if err != nil { + return "" + } + return string(val.GetStringBytes(privateAnalyticsIdKey)) +} + +func (a *accountObject) genInitialDoc(isNewAccount bool) (docToInsert string, err error) { + privateAnalytics, err := generatePrivateAnalyticsId() + if err != nil { + err = fmt.Errorf("generate private analytics id: %w", err) + } + if isNewAccount { + docToInsert = fmt.Sprintf( + `{"%s":"%s","%s":"%s","%s":"true","%s":"%s"}`, + idKey, accountDocumentId, + analyticsKey, a.cfg.AnalyticsId, + iconMigrationKey, + privateAnalyticsIdKey, privateAnalytics) + } else { + docToInsert = fmt.Sprintf(`{"%s":"%s"}`, idKey, accountDocumentId) + } + return +} + +func (a *accountObject) initState(st *state.State) error { + template.InitTemplate(st, + template.WithTitle, + template.WithForcedObjectTypes([]domain.TypeKey{bundle.TypeKeyProfile}), + template.WithForcedDetail(bundle.RelationKeyLayout, pbtypes.Float64(float64(model.ObjectType_profile))), + template.WithDetail(bundle.RelationKeyLayoutAlign, pbtypes.Float64(float64(model.Block_AlignCenter))), + ) + blockId := "identity" + st.Set(simple.New(&model.Block{ + Id: blockId, + Content: &model.BlockContentOfRelation{ + Relation: &model.BlockContentRelation{ + Key: bundle.RelationKeyProfileOwnerIdentity.String(), + }, + }, + Restrictions: &model.BlockRestrictions{ + Edit: true, + Remove: true, + Drag: true, + DropOn: true, + }, + })) + err := st.InsertTo(state.TitleBlockID, model.Block_Bottom, blockId) + if err != nil { + return fmt.Errorf("insert block: %w", err) + } + st.SetDetail(bundle.RelationKeyIsHidden.String(), pbtypes.Bool(true)) + return nil +} + +func (a *accountObject) OnPushChange(params source.PushChangeParams) (id string, err error) { + var ( + chs = params.Changes + builder = &storestate.Builder{} + ) + for _, ch := range chs { + set := ch.GetDetailsSet() + if set != nil && set.Key != "" { + val, ok := a.relMapper.GetStoreKey(set.Key, set.Value) + if !ok { + continue + } + err := builder.Modify(collectionName, accountDocumentId, []string{set.Key}, pb.ModifyOp_Set, val) + if err != nil { + return "", fmt.Errorf("modify content: %w", err) + } + } + } + if builder.StoreChange == nil { + return "", nil + } + return a.storeSource.PushStoreChange(a.ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: a.state, + Time: time.Now(), + }) +} + +func (a *accountObject) SetAnalyticsId(id string) error { + builder := &storestate.Builder{} + err := builder.Modify(collectionName, accountDocumentId, []string{analyticsKey}, pb.ModifyOp_Set, fmt.Sprintf(`"%s"`, id)) + if err != nil { + return nil + } + privateAnalyticsId, err := generatePrivateAnalyticsId() + if err != nil { + return fmt.Errorf("generate private analytics id: %w", err) + } + err = builder.Modify(collectionName, accountDocumentId, []string{privateAnalyticsIdKey}, pb.ModifyOp_Set, fmt.Sprintf(`"%s"`, privateAnalyticsId)) + if err != nil { + return nil + } + _, err = a.storeSource.PushStoreChange(a.ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: a.state, + Time: time.Now(), + }) + return err +} + +func (a *accountObject) onUpdate() { + st := a.NewState() + err := a.update(a.ctx, st) + if err != nil { + log.Warn("get profile details", zap.Error(err)) + return + } + err = a.SmartBlock.(source.ChangeReceiver).StateRebuild(st) + if err != nil { + log.Warn("state rebuild", zap.Error(err)) + return + } +} + +func (a *accountObject) setValue(key string, val any) error { + builder := &storestate.Builder{} + err := builder.Modify(collectionName, accountDocumentId, []string{key}, pb.ModifyOp_Set, val) + if err != nil { + return nil + } + _, err = a.storeSource.PushStoreChange(a.ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: a.state, + Time: time.Now(), + }) + return err +} + +func (a *accountObject) getValue() (val *anyenc.Value, err error) { + coll, err := a.state.Collection(a.ctx, collectionName) + if err != nil { + err = fmt.Errorf("get collection: %w", err) + return + } + obj, err := coll.FindId(a.ctx, accountDocumentId) + if err != nil { + err = fmt.Errorf("find id: %w", err) + return + } + return obj.Value(), nil +} + +func (a *accountObject) GetAnalyticsId() (id string, err error) { + val, err := a.getValue() + if err != nil { + return + } + return string(val.GetStringBytes(analyticsKey)), nil +} + +func (a *accountObject) TryClose(objectTTL time.Duration) (res bool, err error) { + return false, nil +} + +func (a *accountObject) Close() error { + a.cancel() + return a.SmartBlock.Close() +} + +func (a *accountObject) SetSharedSpacesLimit(limit int) (err error) { + st := a.NewState() + st.SetDetailAndBundledRelation(bundle.RelationKeySharedSpacesLimit, pbtypes.Int64(int64(limit))) + return a.Apply(st) +} + +func (a *accountObject) GetSharedSpacesLimit() (limit int) { + return int(pbtypes.GetInt64(a.CombinedDetails(), bundle.RelationKeySharedSpacesLimit.String())) +} + +func (a *accountObject) SetProfileDetails(details *types.Struct) (err error) { + st := a.NewState() + // we should set everything in local state, but not everything in the store (this should be filtered in OnPushChange) + for key, val := range details.Fields { + st.SetDetailAndBundledRelation(domain.RelationKey(key), val) + } + return a.Apply(st) +} + +func (a *accountObject) MigrateIconImage(image string) (err error) { + if image != "" { + st := a.NewState() + st.SetDetailAndBundledRelation(bundle.RelationKeyIconImage, pbtypes.String(image)) + err = a.Apply(st) + if err != nil { + return fmt.Errorf("set icon image: %w", err) + } + } + return a.setValue(iconMigrationKey, `"true"`) +} + +func (a *accountObject) IsIconMigrated() (res bool, err error) { + val, err := a.getValue() + if err != nil { + return + } + return string(val.GetStringBytes(iconMigrationKey)) != "", nil +} + +func (a *accountObject) update(ctx context.Context, st *state.State) (err error) { + coll, err := a.state.Collection(ctx, collectionName) + if err != nil { + return fmt.Errorf("get collection: %w", err) + } + obj, err := coll.FindId(ctx, accountDocumentId) + if err != nil { + return fmt.Errorf("find id: %w", err) + } + for key := range a.relMapper.keys { + pbVal, ok := a.relMapper.GetRelationKey(key, obj.Value()) + if !ok { + continue + } + st.SetDetailAndBundledRelation(domain.RelationKey(key), pbVal) + } + return +} + +func generatePrivateAnalyticsId() (string, error) { + raw := make([]byte, 64) + if _, err := rand.Read(raw); err != nil { + return "", err + } + return crypto.EncodeBytesToString(raw), nil +} diff --git a/core/block/editor/accountobject/accountobject_test.go b/core/block/editor/accountobject/accountobject_test.go new file mode 100644 index 0000000000..68ac639899 --- /dev/null +++ b/core/block/editor/accountobject/accountobject_test.go @@ -0,0 +1,236 @@ +package accountobject + +import ( + "context" + "errors" + "fmt" + "path/filepath" + "testing" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/globalsign/mgo/bson" + "github.com/gogo/protobuf/types" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/core/anytype/config" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/core/block/simple" + "github.com/anyproto/anytype-heart/core/block/source" + "github.com/anyproto/anytype-heart/core/block/source/mock_source" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +var ctx = context.Background() + +type fixture struct { + *accountObject + source *mock_source.MockStore + storeFx *objectstore.StoreFixture + db anystore.DB + events []*pb.EventMessage +} + +func newFixture(t *testing.T, isNewAccount bool, prepareDb func(db anystore.DB)) *fixture { + ctx := context.Background() + cfg := config.New(config.WithNewAccount(isNewAccount)) + cfg.AnalyticsId = "analyticsId" + db, err := anystore.Open(ctx, filepath.Join(t.TempDir(), "crdt.db"), nil) + require.NoError(t, err) + if prepareDb != nil { + prepareDb(db) + } + t.Cleanup(func() { + err := db.Close() + require.NoError(t, err) + }) + sb := smarttest.New("accountId1") + indexStore := objectstore.NewStoreFixture(t).SpaceIndex("spaceId") + object := New(sb, indexStore, nil, nil, nil, db, cfg) + + fx := &fixture{ + storeFx: objectstore.NewStoreFixture(t), + db: db, + accountObject: object.(*accountObject), + } + source := mock_source.NewMockStore(t) + source.EXPECT().ReadStoreDoc(ctx, mock.Anything, mock.Anything).Return(nil) + source.EXPECT().PushStoreChange(mock.Anything, mock.Anything).RunAndReturn(fx.applyToStore).Maybe() + source.EXPECT().SetPushChangeHook(mock.Anything) + fx.source = source + + err = object.Init(&smartblock.InitContext{ + Ctx: ctx, + Source: source, + }) + require.NoError(t, err) + + return fx +} + +func (fx *fixture) applyToStore(ctx context.Context, params source.PushStoreChangeParams) (string, error) { + changeId := bson.NewObjectId().Hex() + tx, err := params.State.NewTx(ctx) + if err != nil { + return "", fmt.Errorf("new tx: %w", err) + } + order := tx.NextOrder(tx.GetMaxOrder()) + err = tx.ApplyChangeSet(storestate.ChangeSet{ + Id: changeId, + Order: order, + Changes: params.Changes, + Creator: "creator", + Timestamp: params.Time.Unix(), + }) + if err != nil { + return "", errors.Join(tx.Rollback(), fmt.Errorf("apply change set: %w", err)) + } + err = tx.Commit() + if err != nil { + return "", err + } + fx.onUpdate() + return changeId, nil +} + +func assertBlock(t *testing.T, st state.Doc, id string) { + found := false + st.Iterate(func(b simple.Block) (isContinue bool) { + if b.Model().Id == id { + found = true + return false + } + return true + }) + require.True(t, found) +} + +func makeStoreContent(m map[string]any) source.PushChangeParams { + changes := make([]*pb.ChangeContent, 0, len(m)) + for k, v := range m { + changes = append(changes, &pb.ChangeContent{ + &pb.ChangeContentValueOfDetailsSet{DetailsSet: &pb.ChangeDetailsSet{ + Key: k, + Value: pbtypes.InterfaceToValue(v), + }, + }, + }) + } + return source.PushChangeParams{Changes: changes} +} + +func (fx *fixture) assertStoreValue(t *testing.T, test any, extract func(val *anyenc.Value) any) { + val, err := fx.getValue() + require.NoError(t, err) + require.Equal(t, test, extract(val)) +} + +func (fx *fixture) assertStateValue(t *testing.T, val any, extract func(str *types.Struct) any) { + require.Equal(t, val, extract(fx.SmartBlock.NewState().CombinedDetails())) +} + +func TestAccountNew(t *testing.T) { + fx := newFixture(t, true, nil) + st := fx.SmartBlock.NewState() + assertBlock(t, st, "accountId1") + assertBlock(t, st, "title") + assertBlock(t, st, "header") + assertBlock(t, st, "identity") + res, err := fx.IsIconMigrated() + require.NoError(t, err) + require.True(t, res) + id, err := fx.GetAnalyticsId() + require.NoError(t, err) + require.Equal(t, "analyticsId", id) +} + +func TestAccountOldInitWithData(t *testing.T) { + fx := newFixture(t, false, func(db anystore.DB) { + tx, err := db.WriteTx(ctx) + collName := "accountId1" + collectionName + coll, err := db.CreateCollection(tx.Context(), collName) + require.NoError(t, err) + err = coll.Insert(tx.Context(), anyenc.MustParseJson(fmt.Sprintf(`{"id":"%s","analyticsId":"%s","%s":"true","name":"Anna","description":"Molly"}`, accountDocumentId, "analyticsId", iconMigrationKey))) + require.NoError(t, err) + require.NoError(t, tx.Commit()) + }) + st := fx.SmartBlock.NewState() + assertBlock(t, st, "accountId1") + assertBlock(t, st, "title") + assertBlock(t, st, "header") + assertBlock(t, st, "identity") + res, err := fx.IsIconMigrated() + require.NoError(t, err) + require.True(t, res) + id, err := fx.GetAnalyticsId() + require.NoError(t, err) + require.Equal(t, "analyticsId", id) + fx.assertStateValue(t, "Anna", func(str *types.Struct) any { + return pbtypes.GetString(str, "name") + }) + fx.assertStateValue(t, "Molly", func(str *types.Struct) any { + return pbtypes.GetString(str, "description") + }) + require.NotNil(t, fx) +} + +func TestPushNewChanges(t *testing.T) { + // this tests both cases when we get changes from somewhere or we push our own changes + fx := newFixture(t, true, nil) + _, err := fx.OnPushChange(makeStoreContent(map[string]any{"name": "Anna", "description": "Molly"})) + require.NoError(t, err) + fx.assertStateValue(t, "Anna", func(str *types.Struct) any { + return pbtypes.GetString(str, "name") + }) + fx.assertStateValue(t, "Molly", func(str *types.Struct) any { + return pbtypes.GetString(str, "description") + }) + require.NotNil(t, fx) +} + +func TestIconMigrated(t *testing.T) { + fx := newFixture(t, false, nil) + err := fx.MigrateIconImage("image") + require.NoError(t, err) + res, err := fx.IsIconMigrated() + require.NoError(t, err) + require.True(t, res) +} + +func TestSetSharedSpacesLimit(t *testing.T) { + fx := newFixture(t, true, nil) + err := fx.SetSharedSpacesLimit(10) + require.NoError(t, err) + res := fx.GetSharedSpacesLimit() + require.Equal(t, 10, res) +} + +func TestAccountObject_GetPrivateAnalyticsId(t *testing.T) { + t.Run("new account", func(t *testing.T) { + fx := newFixture(t, true, nil) + res := fx.GetPrivateAnalyticsId() + require.NotEmpty(t, res) + }) + t.Run("old account", func(t *testing.T) { + fx := newFixture(t, false, nil) + err := fx.SetAnalyticsId("analyticsId") + require.NoError(t, err) + res := fx.GetPrivateAnalyticsId() + require.NotEmpty(t, res) + }) +} + +func TestAnalyticsId(t *testing.T) { + fx := newFixture(t, true, nil) + err := fx.SetAnalyticsId("analyticsId") + require.NoError(t, err) + res, err := fx.GetAnalyticsId() + require.NoError(t, err) + require.Equal(t, "analyticsId", res) +} diff --git a/core/block/editor/accountobject/relationsmapper.go b/core/block/editor/accountobject/relationsmapper.go new file mode 100644 index 0000000000..cfbb65a27e --- /dev/null +++ b/core/block/editor/accountobject/relationsmapper.go @@ -0,0 +1,70 @@ +package accountobject + +import ( + "fmt" + + "github.com/anyproto/any-store/anyenc" + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +type KeyType int + +const ( + KeyTypeString KeyType = iota + KeyTypeInt64 +) + +type relationsMapper struct { + keys map[string]KeyType +} + +func newRelationsMapper(keys map[string]KeyType) *relationsMapper { + return &relationsMapper{ + keys: keys, + } +} + +func (r *relationsMapper) GetRelationKey(key string, val *anyenc.Value) (*types.Value, bool) { + kt, ok := r.keys[key] + if !ok { + return nil, false + } + switch kt { + case KeyTypeString: + val := val.GetStringBytes(key) + if val == nil { + return nil, false + } + return pbtypes.String(string(val)), true + case KeyTypeInt64: + val := val.GetInt(key) + if val == 0 { + return nil, false + } + return pbtypes.Int64(int64(val)), true + } + return nil, false +} + +func (r *relationsMapper) GetStoreKey(key string, val *types.Value) (res any, ok bool) { + kt, ok := r.keys[key] + if !ok { + return nil, false + } + switch kt { + case KeyTypeString: + res = val.GetStringValue() + if res == "" { + return nil, false + } + res = fmt.Sprintf(`"%s"`, res) + case KeyTypeInt64: + res = int64(val.GetNumberValue()) + if res == 0 { + return nil, false + } + } + return res, true +} diff --git a/core/block/editor/anystoredebug/debug.go b/core/block/editor/anystoredebug/debug.go new file mode 100644 index 0000000000..e43e652d21 --- /dev/null +++ b/core/block/editor/anystoredebug/debug.go @@ -0,0 +1,98 @@ +package anystoredebug + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/objecttreebuilder" + "github.com/gogo/protobuf/jsonpb" + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/core/block/source" +) + +type DebugChange struct { + ChangeId string + OrderId string + Change *types.Struct + Error error +} + +type AnystoreDebug interface { + DebugChanges(ctx context.Context) ([]*DebugChange, error) +} + +type debugComponent struct { + smartblock.SmartBlock + store *storestate.StoreState +} + +func New(sb smartblock.SmartBlock, store *storestate.StoreState) AnystoreDebug { + return &debugComponent{ + SmartBlock: sb, + store: store, + } +} + +func (s *debugComponent) DebugChanges(ctx context.Context) ([]*DebugChange, error) { + historyTree, err := s.SmartBlock.Space().TreeBuilder().BuildHistoryTree(context.Background(), s.Id(), objecttreebuilder.HistoryTreeOpts{ + Heads: nil, + Include: true, + }) + if err != nil { + return nil, fmt.Errorf("build history tree: %w", err) + } + + tx, err := s.store.NewTx(ctx) + if err != nil { + return nil, fmt.Errorf("new tx: %w", err) + } + defer tx.Commit() + + var result []*DebugChange + err = historyTree.IterateFrom(historyTree.Root().Id, source.UnmarshalStoreChange, func(change *objecttree.Change) bool { + orderId, err := tx.GetOrder(change.Id) + if err != nil { + result = append(result, &DebugChange{ + ChangeId: change.Id, + Error: fmt.Errorf("get order: %w", err), + }) + } + + raw, err := json.Marshal(change.Model) + if err != nil { + result = append(result, &DebugChange{ + ChangeId: change.Id, + OrderId: orderId, + Error: fmt.Errorf("marshal json: %w", err), + }) + return true + } + changeStruct := &types.Struct{Fields: map[string]*types.Value{}} + err = jsonpb.UnmarshalString(string(raw), changeStruct) + if err != nil { + result = append(result, &DebugChange{ + ChangeId: change.Id, + OrderId: orderId, + Error: fmt.Errorf("unmarshal to struct: %w", err), + }) + return true + } + + result = append(result, &DebugChange{ + ChangeId: change.Id, + OrderId: orderId, + Change: changeStruct, + }) + return true + }) + if err != nil { + return nil, fmt.Errorf("iterate root: %w", err) + } + + return result, nil +} diff --git a/core/block/editor/archive.go b/core/block/editor/archive.go index 00b296dc88..0071b936a0 100644 --- a/core/block/editor/archive.go +++ b/core/block/editor/archive.go @@ -1,6 +1,9 @@ package editor import ( + "errors" + + "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/gogo/protobuf/types" "github.com/anyproto/anytype-heart/core/block/editor/collection" @@ -12,7 +15,7 @@ import ( "github.com/anyproto/anytype-heart/core/relationutils" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" @@ -24,12 +27,12 @@ var archiveRequiredRelations = []domain.RelationKey{} type Archive struct { smartblock.SmartBlock collection.Collection - objectStore objectstore.ObjectStore + objectStore spaceindex.Store } func NewArchive( sb smartblock.SmartBlock, - objectStore objectstore.ObjectStore, + objectStore spaceindex.Store, ) *Archive { return &Archive{ SmartBlock: sb, @@ -77,21 +80,25 @@ func (p *Archive) updateObjects(_ smartblock.ApplyInfo) (err error) { if err != nil { return } + go func() { + uErr := p.updateInStore(archivedIds) + if uErr != nil { + log.Errorf("archive: can't update in store: %v", uErr) + } + }() + return nil +} +func (p *Archive) updateInStore(archivedIds []string) error { records, err := p.objectStore.QueryRaw(&database.Filters{FilterObj: database.FiltersAnd{ database.FilterEq{ Key: bundle.RelationKeyIsArchived.String(), Cond: model.BlockContentDataviewFilter_Equal, Value: pbtypes.Bool(true), }, - database.FilterEq{ - Key: bundle.RelationKeySpaceId.String(), - Cond: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(p.SpaceID()), - }, }}, 0, 0) if err != nil { - return + return err } var storeArchivedIds = make([]string, 0, len(records)) @@ -111,7 +118,7 @@ func (p *Archive) updateObjects(_ smartblock.ApplyInfo) (err error) { current.Fields[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(false) return current, nil }); err != nil { - log.Errorf("archive: can't set detail to object: %v", err) + logArchiveError(err) } }(removedId) } @@ -126,9 +133,16 @@ func (p *Archive) updateObjects(_ smartblock.ApplyInfo) (err error) { current.Fields[bundle.RelationKeyIsArchived.String()] = pbtypes.Bool(true) return current, nil }); err != nil { - log.Errorf("archive: can't set detail to object: %v", err) + logArchiveError(err) } }(addedId) } - return + return nil +} + +func logArchiveError(err error) { + if errors.Is(err, spacestorage.ErrTreeStorageAlreadyDeleted) { + return + } + log.Errorf("archive: can't set detail to object: %v", err) } diff --git a/core/block/editor/archive_test.go b/core/block/editor/archive_test.go index 5a80c6d40a..5b911945d2 100644 --- a/core/block/editor/archive_test.go +++ b/core/block/editor/archive_test.go @@ -4,20 +4,17 @@ import ( "testing" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/anyproto/anytype-heart/core/block/editor/collection" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" "github.com/anyproto/anytype-heart/core/block/migration" - "github.com/anyproto/anytype-heart/util/testMock" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" ) -func NewArchiveTest(ctrl *gomock.Controller) (*Archive, error) { +func NewArchiveTest(t *testing.T) (*Archive, error) { sb := smarttest.New("root") - objectStore := testMock.NewMockObjectStore(ctrl) - objectStore.EXPECT().GetDetails(gomock.Any()).AnyTimes() - objectStore.EXPECT().QueryRaw(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + objectStore := spaceindex.NewStoreFixture(t) a := &Archive{ SmartBlock: sb, Collection: collection.NewCollection(sb, objectStore), @@ -38,11 +35,8 @@ func NewArchiveTest(ctrl *gomock.Controller) (*Archive, error) { } func TestArchive_Archive(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - t.Run("archive", func(t *testing.T) { - a, err := NewArchiveTest(ctrl) + a, err := NewArchiveTest(t) require.NoError(t, err) require.NoError(t, a.AddObject("1")) @@ -56,7 +50,7 @@ func TestArchive_Archive(t *testing.T) { }) t.Run("archive archived", func(t *testing.T) { - a, err := NewArchiveTest(ctrl) + a, err := NewArchiveTest(t) require.NoError(t, err) require.NoError(t, a.AddObject("1")) @@ -69,11 +63,8 @@ func TestArchive_Archive(t *testing.T) { } func TestArchive_UnArchive(t *testing.T) { - ctrl := gomock.NewController(t) - defer ctrl.Finish() - t.Run("unarchive", func(t *testing.T) { - a, err := NewArchiveTest(ctrl) + a, err := NewArchiveTest(t) require.NoError(t, err) require.NoError(t, a.AddObject("1")) @@ -85,7 +76,7 @@ func TestArchive_UnArchive(t *testing.T) { require.Len(t, chIds, 1) }) t.Run("unarchived", func(t *testing.T) { - a, err := NewArchiveTest(ctrl) + a, err := NewArchiveTest(t) require.NoError(t, err) require.NoError(t, a.AddObject("1")) diff --git a/core/block/editor/basic/basic.go b/core/block/editor/basic/basic.go index 991e5a848a..55aea4d9f0 100644 --- a/core/block/editor/basic/basic.go +++ b/core/block/editor/basic/basic.go @@ -25,7 +25,7 @@ import ( "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" @@ -104,7 +104,7 @@ type Updatable interface { func NewBasic( sb smartblock.SmartBlock, - objectStore objectstore.ObjectStore, + objectStore spaceindex.Store, layoutConverter converter.LayoutConverter, fileObjectService fileobject.Service, lastUsedUpdater lastused.ObjectUsageUpdater, @@ -121,8 +121,8 @@ func NewBasic( type basic struct { smartblock.SmartBlock - objectStore objectstore.ObjectStore - layoutConverter converter.LayoutConverter + objectStore spaceindex.Store + layoutConverter converter.LayoutConverter fileObjectService fileobject.Service lastUsedUpdater lastused.ObjectUsageUpdater } @@ -419,7 +419,7 @@ func (bs *basic) AddRelationAndSet(ctx session.Context, req pb.RpcBlockRelationA return smartblock.ErrSimpleBlockNotFound } - rel, err := bs.objectStore.FetchRelationByKey(bs.SpaceID(), req.RelationKey) + rel, err := bs.objectStore.FetchRelationByKey(req.RelationKey) if err != nil { return } diff --git a/core/block/editor/basic/details.go b/core/block/editor/basic/details.go index c0f1e6a2d8..df6f8f7f78 100644 --- a/core/block/editor/basic/details.go +++ b/core/block/editor/basic/details.go @@ -170,7 +170,7 @@ func (bs *basic) createDetailUpdate(st *state.State, detail *model.Detail) (*det } func (bs *basic) validateDetailFormat(spaceID string, key string, v *types.Value) error { - r, err := bs.objectStore.FetchRelationByKey(spaceID, key) + r, err := bs.objectStore.FetchRelationByKey(key) if err != nil { return err } @@ -313,7 +313,7 @@ func (bs *basic) setDetailSpecialCases(st *state.State, detail *model.Detail) er } func (bs *basic) addRelationLink(st *state.State, relationKey string) error { - relLink, err := bs.objectStore.GetRelationLink(bs.SpaceID(), relationKey) + relLink, err := bs.objectStore.GetRelationLink(relationKey) if err != nil || relLink == nil { return fmt.Errorf("failed to get relation: %w", err) } @@ -321,11 +321,14 @@ func (bs *basic) addRelationLink(st *state.State, relationKey string) error { return nil } +// addRelationLinks is deprecated and will be removed in release 7 func (bs *basic) addRelationLinks(st *state.State, relationKeys ...string) error { if len(relationKeys) == 0 { return nil } - relations, err := bs.objectStore.FetchRelationByKeys(bs.SpaceID(), relationKeys...) + // this code depends on the objectstore being indexed, but can be run on start with empty account + // todo: remove this code in release because we will no longer need relationLinks + relations, err := bs.objectStore.FetchRelationByKeys(relationKeys...) if err != nil || relations == nil { return fmt.Errorf("failed to get relations: %w", err) } @@ -403,7 +406,7 @@ func (bs *basic) getLayoutForType(objectTypeKey domain.TypeKey) (model.ObjectTyp if err != nil { return 0, fmt.Errorf("create unique key: %w", err) } - typeDetails, err := bs.objectStore.GetObjectByUniqueKey(bs.SpaceID(), uk) + typeDetails, err := bs.objectStore.GetObjectByUniqueKey(uk) if err != nil { return 0, fmt.Errorf("get object by unique key: %w", err) } diff --git a/core/block/editor/basic/details_test.go b/core/block/editor/basic/details_test.go index 2565eb5c49..b4e1caeebb 100644 --- a/core/block/editor/basic/details_test.go +++ b/core/block/editor/basic/details_test.go @@ -10,13 +10,14 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) type duFixture struct { sb *smarttest.SmartTest - store *objectstore.StoreFixture + store *spaceindex.StoreFixture basic DetailsUpdatable } @@ -30,7 +31,7 @@ func newDUFixture(t *testing.T) *duFixture { sb.SetDetails(nil, nil, false) sb.SetSpaceId(spaceId) - store := objectstore.NewStoreFixture(t) + store := spaceindex.NewStoreFixture(t) b := NewBasic(sb, store, converter.NewLayoutConverter(), nil, nil) diff --git a/core/block/editor/basic/extract_objects.go b/core/block/editor/basic/extract_objects.go index 9fbf099d30..cdf7095b69 100644 --- a/core/block/editor/basic/extract_objects.go +++ b/core/block/editor/basic/extract_objects.go @@ -95,7 +95,7 @@ func (bs *basic) prepareTargetObjectDetails( typeUniqueKey domain.UniqueKey, rootBlock simple.Block, ) (*types.Struct, error) { - objType, err := bs.objectStore.GetObjectByUniqueKey(spaceID, typeUniqueKey) + objType, err := bs.objectStore.GetObjectByUniqueKey(typeUniqueKey) if err != nil { return nil, err } diff --git a/core/block/editor/basic/extract_objects_test.go b/core/block/editor/basic/extract_objects_test.go index d32c5eda2e..45c7d115e7 100644 --- a/core/block/editor/basic/extract_objects_test.go +++ b/core/block/editor/basic/extract_objects_test.go @@ -8,7 +8,6 @@ import ( "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/anyproto/anytype-heart/core/block/editor/converter" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" @@ -22,10 +21,10 @@ import ( "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" - "github.com/anyproto/anytype-heart/util/testMock" ) type testCreator struct { @@ -297,7 +296,6 @@ func TestExtractObjects(t *testing.T) { } { t.Run(tc.name, func(t *testing.T) { fixture := newFixture(t) - defer fixture.cleanUp() creator := testCreator{objects: map[string]*smarttest.SmartTest{}} sb := makeTestObject() @@ -358,7 +356,7 @@ func TestExtractObjects(t *testing.T) { }) t.Run("add custom link block", func(t *testing.T) { fixture := newFixture(t) - defer fixture.cleanUp() + creator := testCreator{objects: map[string]*smarttest.SmartTest{}} sb := makeTestObject() creator.Add(sb) @@ -391,7 +389,7 @@ func TestExtractObjects(t *testing.T) { }) t.Run("add custom link block for multiple blocks", func(t *testing.T) { fixture := newFixture(t) - defer fixture.cleanUp() + creator := testCreator{objects: map[string]*smarttest.SmartTest{}} sb := makeTestObject() creator.Add(sb) @@ -615,39 +613,27 @@ func generateState(root string, blocks []simple.Block) *state.State { type fixture struct { t *testing.T - ctrl *gomock.Controller - store *testMock.MockObjectStore + store *spaceindex.StoreFixture } func newFixture(t *testing.T) *fixture { - ctrl := gomock.NewController(t) - objectStore := testMock.NewMockObjectStore(ctrl) - - objectStore.EXPECT().GetObjectByUniqueKey(gomock.Any(), gomock.Any()).DoAndReturn( - func(_ string, uk domain.UniqueKey) (*model.ObjectDetails, error) { - layout := pbtypes.Int64(int64(model.ObjectType_basic)) - switch uk.InternalKey() { - case "note": - layout = pbtypes.Int64(int64(model.ObjectType_note)) - case "task": - layout = pbtypes.Int64(int64(model.ObjectType_todo)) - } - return &model.ObjectDetails{ - Details: &types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyRecommendedLayout.String(): layout, - }, - }, - }, nil - }).AnyTimes() + objectStore := spaceindex.NewStoreFixture(t) + + objectStore.AddObjects(t, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("id1"), + bundle.RelationKeyUniqueKey: pbtypes.String("ot-note"), + bundle.RelationKeyRecommendedLayout: pbtypes.Int64(int64(model.ObjectType_note)), + }, + { + bundle.RelationKeyId: pbtypes.String("id2"), + bundle.RelationKeyUniqueKey: pbtypes.String("ot-task"), + bundle.RelationKeyRecommendedLayout: pbtypes.Int64(int64(model.ObjectType_todo)), + }, + }) return &fixture{ t: t, - ctrl: ctrl, store: objectStore, } } - -func (fx *fixture) cleanUp() { - fx.ctrl.Finish() -} diff --git a/core/block/editor/chatobject/chathandler.go b/core/block/editor/chatobject/chathandler.go new file mode 100644 index 0000000000..028301d13e --- /dev/null +++ b/core/block/editor/chatobject/chathandler.go @@ -0,0 +1,119 @@ +package chatobject + +import ( + "context" + "errors" + "fmt" + "strings" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" + + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/pb" +) + +type ChatHandler struct { + subscription *subscription +} + +func (d ChatHandler) CollectionName() string { + return collectionName +} + +func (d ChatHandler) Init(ctx context.Context, s *storestate.StoreState) (err error) { + coll, err := s.Collection(ctx, collectionName) + if err != nil { + return err + } + iErr := coll.EnsureIndex(ctx, anystore.IndexInfo{ + Fields: []string{"_o.id"}, + }) + if iErr != nil && !errors.Is(iErr, anystore.ErrIndexExists) { + return iErr + } + return +} + +func (d ChatHandler) BeforeCreate(ctx context.Context, ch storestate.ChangeOp) (err error) { + msg := newMessageWrapper(ch.Arena, ch.Value) + msg.setCreatedAt(ch.Change.Timestamp) + msg.setCreator(ch.Change.Creator) + + model := msg.toModel() + model.OrderId = ch.Change.Order + d.subscription.add(model) + + return +} + +func (d ChatHandler) BeforeModify(ctx context.Context, ch storestate.ChangeOp) (mode storestate.ModifyMode, err error) { + return storestate.ModifyModeUpsert, nil +} + +func (d ChatHandler) BeforeDelete(ctx context.Context, ch storestate.ChangeOp) (mode storestate.DeleteMode, err error) { + coll, err := ch.State.Collection(ctx, collectionName) + if err != nil { + return storestate.DeleteModeDelete, fmt.Errorf("get collection: %w", err) + } + + messageId := ch.Change.Change.GetDelete().GetDocumentId() + + doc, err := coll.FindId(ctx, messageId) + if err != nil { + return storestate.DeleteModeDelete, fmt.Errorf("get message: %w", err) + } + + message := newMessageWrapper(ch.Arena, doc.Value()) + if message.getCreator() != ch.Change.Creator { + return storestate.DeleteModeDelete, errors.New("can't delete not own message") + } + + d.subscription.delete(messageId) + return storestate.DeleteModeDelete, nil +} + +func (d ChatHandler) UpgradeKeyModifier(ch storestate.ChangeOp, key *pb.KeyModify, mod query.Modifier) query.Modifier { + return query.ModifyFunc(func(a *anyenc.Arena, v *anyenc.Value) (result *anyenc.Value, modified bool, err error) { + if len(key.KeyPath) == 0 { + return nil, false, fmt.Errorf("no key path") + } + + path := key.KeyPath[0] + + result, modified, err = mod.Modify(a, v) + if err != nil { + return nil, false, err + } + + if modified { + msg := newMessageWrapper(a, result) + model := msg.toModel() + + switch path { + case reactionsKey: + // Do not parse json, just trim " + identity := strings.Trim(key.ModifyValue, `"`) + if identity != ch.Change.Creator { + return v, false, errors.Join(storestate.ErrValidation, fmt.Errorf("can't toggle someone else's reactions")) + } + // TODO Count validation + + d.subscription.updateReactions(model) + case contentKey: + creator := model.Creator + if creator != ch.Change.Creator { + return v, false, errors.Join(storestate.ErrValidation, fmt.Errorf("can't modify someone else's message")) + } + result.Set(modifiedAtKey, a.NewNumberInt(int(ch.Change.Timestamp))) + model.ModifiedAt = ch.Change.Timestamp + d.subscription.updateFull(model) + default: + return nil, false, fmt.Errorf("invalid key path %s", key.KeyPath) + } + } + + return result, modified, nil + }) +} diff --git a/core/block/editor/chatobject/chatobject.go b/core/block/editor/chatobject/chatobject.go new file mode 100644 index 0000000000..a54c4e1e9f --- /dev/null +++ b/core/block/editor/chatobject/chatobject.go @@ -0,0 +1,349 @@ +package chatobject + +import ( + "context" + "errors" + "fmt" + "sort" + "time" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" + "golang.org/x/exp/slices" + + "github.com/anyproto/anytype-heart/core/block/editor/anystoredebug" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/core/block/source" + "github.com/anyproto/anytype-heart/core/event" + "github.com/anyproto/anytype-heart/core/session" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +const ( + collectionName = "chats" + descOrder = "-_o.id" +) + +type StoreObject interface { + smartblock.SmartBlock + anystoredebug.AnystoreDebug + + AddMessage(ctx context.Context, sessionCtx session.Context, message *model.ChatMessage) (string, error) + GetMessages(ctx context.Context, beforeOrderId string, limit int) ([]*model.ChatMessage, error) + GetMessagesByIds(ctx context.Context, messageIds []string) ([]*model.ChatMessage, error) + EditMessage(ctx context.Context, messageId string, newMessage *model.ChatMessage) error + ToggleMessageReaction(ctx context.Context, messageId string, emoji string) error + DeleteMessage(ctx context.Context, messageId string) error + SubscribeLastMessages(ctx context.Context, limit int) ([]*model.ChatMessage, int, error) + Unsubscribe() error +} + +type AccountService interface { + AccountID() string +} + +type storeObject struct { + anystoredebug.AnystoreDebug + smartblock.SmartBlock + locker smartblock.Locker + + accountService AccountService + storeSource source.Store + store *storestate.StoreState + eventSender event.Sender + subscription *subscription + crdtDb anystore.DB + + arenaPool *anyenc.ArenaPool +} + +func New(sb smartblock.SmartBlock, accountService AccountService, eventSender event.Sender, crdtDb anystore.DB) StoreObject { + return &storeObject{ + SmartBlock: sb, + locker: sb.(smartblock.Locker), + accountService: accountService, + arenaPool: &anyenc.ArenaPool{}, + eventSender: eventSender, + crdtDb: crdtDb, + } +} + +func (s *storeObject) Init(ctx *smartblock.InitContext) error { + err := s.SmartBlock.Init(ctx) + if err != nil { + return err + } + s.subscription = newSubscription(s.Id(), s.eventSender) + + stateStore, err := storestate.New(ctx.Ctx, s.Id(), s.crdtDb, ChatHandler{ + subscription: s.subscription, + }) + if err != nil { + return fmt.Errorf("create state store: %w", err) + } + s.store = stateStore + + storeSource, ok := ctx.Source.(source.Store) + if !ok { + return fmt.Errorf("source is not a store") + } + s.storeSource = storeSource + err = storeSource.ReadStoreDoc(ctx.Ctx, stateStore, s.onUpdate) + if err != nil { + return fmt.Errorf("read store doc: %w", err) + } + + s.AnystoreDebug = anystoredebug.New(s.SmartBlock, stateStore) + + return nil +} + +func (s *storeObject) onUpdate() { + s.subscription.flush() +} + +func (s *storeObject) GetMessagesByIds(ctx context.Context, messageIds []string) ([]*model.ChatMessage, error) { + coll, err := s.store.Collection(ctx, collectionName) + if err != nil { + return nil, fmt.Errorf("get collection: %w", err) + } + txn, err := coll.ReadTx(ctx) + if err != nil { + return nil, fmt.Errorf("start read tx: %w", err) + } + messages := make([]*model.ChatMessage, 0, len(messageIds)) + for _, messageId := range messageIds { + obj, err := coll.FindId(txn.Context(), messageId) + if errors.Is(err, anystore.ErrDocNotFound) { + continue + } + if err != nil { + return nil, errors.Join(txn.Commit(), fmt.Errorf("find id: %w", err)) + } + msg := newMessageWrapper(nil, obj.Value()) + messages = append(messages, msg.toModel()) + } + return messages, txn.Commit() +} + +func (s *storeObject) GetMessages(ctx context.Context, beforeOrderId string, limit int) ([]*model.ChatMessage, error) { + coll, err := s.store.Collection(ctx, collectionName) + if err != nil { + return nil, fmt.Errorf("get collection: %w", err) + } + var msgs []*model.ChatMessage + if beforeOrderId != "" { + qry := coll.Find(query.Key{Path: []string{orderKey, "id"}, Filter: query.NewComp(query.CompOpLt, beforeOrderId)}).Sort(descOrder).Limit(uint(limit)) + msgs, err = s.queryMessages(ctx, qry) + if err != nil { + return nil, fmt.Errorf("query messages: %w", err) + } + } else { + qry := coll.Find(nil).Sort(descOrder).Limit(uint(limit)) + msgs, err = s.queryMessages(ctx, qry) + if err != nil { + return nil, fmt.Errorf("query messages: %w", err) + } + } + sort.Slice(msgs, func(i, j int) bool { + return msgs[i].OrderId < msgs[j].OrderId + }) + return msgs, nil +} + +func (s *storeObject) queryMessages(ctx context.Context, query anystore.Query) ([]*model.ChatMessage, error) { + arena := s.arenaPool.Get() + defer func() { + arena.Reset() + s.arenaPool.Put(arena) + }() + + iter, err := query.Iter(ctx) + if err != nil { + return nil, fmt.Errorf("find iter: %w", err) + } + defer iter.Close() + + var res []*model.ChatMessage + for iter.Next() { + doc, err := iter.Doc() + if err != nil { + return nil, fmt.Errorf("get doc: %w", err) + } + + message := newMessageWrapper(arena, doc.Value()).toModel() + res = append(res, message) + } + return res, nil +} + +func (s *storeObject) AddMessage(ctx context.Context, sessionCtx session.Context, message *model.ChatMessage) (string, error) { + arena := s.arenaPool.Get() + defer func() { + arena.Reset() + s.arenaPool.Put(arena) + }() + obj := marshalModel(arena, message) + + builder := storestate.Builder{} + err := builder.Create(collectionName, storestate.IdFromChange, obj) + if err != nil { + return "", fmt.Errorf("create chat: %w", err) + } + + s.subscription.setSessionContext(sessionCtx) + messageId, err := s.storeSource.PushStoreChange(ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: s.store, + Time: time.Now(), + }) + if err != nil { + return "", fmt.Errorf("push change: %w", err) + } + return messageId, nil +} + +func (s *storeObject) DeleteMessage(ctx context.Context, messageId string) error { + builder := storestate.Builder{} + builder.Delete(collectionName, messageId) + _, err := s.storeSource.PushStoreChange(ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: s.store, + Time: time.Now(), + }) + if err != nil { + return fmt.Errorf("push change: %w", err) + } + return nil +} + +func (s *storeObject) EditMessage(ctx context.Context, messageId string, newMessage *model.ChatMessage) error { + arena := s.arenaPool.Get() + defer func() { + arena.Reset() + s.arenaPool.Put(arena) + }() + obj := marshalModel(arena, newMessage) + + builder := storestate.Builder{} + err := builder.Modify(collectionName, messageId, []string{contentKey}, pb.ModifyOp_Set, obj.Get(contentKey)) + if err != nil { + return fmt.Errorf("modify content: %w", err) + } + _, err = s.storeSource.PushStoreChange(ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: s.store, + Time: time.Now(), + }) + if err != nil { + return fmt.Errorf("push change: %w", err) + } + return nil +} + +func (s *storeObject) ToggleMessageReaction(ctx context.Context, messageId string, emoji string) error { + arena := s.arenaPool.Get() + defer func() { + arena.Reset() + s.arenaPool.Put(arena) + }() + + hasReaction, err := s.hasMyReaction(ctx, arena, messageId, emoji) + if err != nil { + return fmt.Errorf("check reaction: %w", err) + } + + builder := storestate.Builder{} + + if hasReaction { + err = builder.Modify(collectionName, messageId, []string{reactionsKey, emoji}, pb.ModifyOp_Pull, arena.NewString(s.accountService.AccountID())) + if err != nil { + return fmt.Errorf("modify content: %w", err) + } + } else { + err = builder.Modify(collectionName, messageId, []string{reactionsKey, emoji}, pb.ModifyOp_AddToSet, arena.NewString(s.accountService.AccountID())) + if err != nil { + return fmt.Errorf("modify content: %w", err) + } + } + + _, err = s.storeSource.PushStoreChange(ctx, source.PushStoreChangeParams{ + Changes: builder.ChangeSet, + State: s.store, + Time: time.Now(), + }) + if err != nil { + return fmt.Errorf("push change: %w", err) + } + return nil +} + +func (s *storeObject) hasMyReaction(ctx context.Context, arena *anyenc.Arena, messageId string, emoji string) (bool, error) { + coll, err := s.store.Collection(ctx, collectionName) + if err != nil { + return false, fmt.Errorf("get collection: %w", err) + } + doc, err := coll.FindId(ctx, messageId) + if err != nil { + return false, fmt.Errorf("find message: %w", err) + } + + myIdentity := s.accountService.AccountID() + msg := newMessageWrapper(arena, doc.Value()) + reactions := msg.reactionsToModel() + if v, ok := reactions.GetReactions()[emoji]; ok { + if slices.Contains(v.GetIds(), myIdentity) { + return true, nil + } + } + return false, nil +} + +func (s *storeObject) SubscribeLastMessages(ctx context.Context, limit int) ([]*model.ChatMessage, int, error) { + coll, err := s.store.Collection(ctx, collectionName) + if err != nil { + return nil, 0, fmt.Errorf("get collection: %w", err) + } + query := coll.Find(nil).Sort(descOrder).Limit(uint(limit)) + messages, err := s.queryMessages(ctx, query) + if err != nil { + return nil, 0, fmt.Errorf("query messages: %w", err) + } + // reverse + sort.Slice(messages, func(i, j int) bool { + return messages[i].OrderId < messages[j].OrderId + }) + + var firstOrderId string + if len(messages) > 0 { + firstOrderId = messages[0].OrderId + } + s.subscription.subscribe(firstOrderId) + + return messages, 0, nil +} + +func (s *storeObject) Unsubscribe() error { + s.subscription.close() + return nil +} + +func (s *storeObject) TryClose(objectTTL time.Duration) (res bool, err error) { + if !s.locker.TryLock() { + return false, nil + } + isActive := s.subscription.enabled + s.Unlock() + + if isActive { + return false, nil + } + return s.SmartBlock.TryClose(objectTTL) +} + +func (s *storeObject) Close() error { + return s.SmartBlock.Close() +} diff --git a/core/block/editor/chatobject/chatobject_test.go b/core/block/editor/chatobject/chatobject_test.go new file mode 100644 index 0000000000..dd384965ba --- /dev/null +++ b/core/block/editor/chatobject/chatobject_test.go @@ -0,0 +1,373 @@ +package chatobject + +import ( + "context" + "errors" + "fmt" + "path/filepath" + "testing" + + anystore "github.com/anyproto/any-store" + "github.com/globalsign/mgo/bson" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/core/block/source" + "github.com/anyproto/anytype-heart/core/block/source/mock_source" + "github.com/anyproto/anytype-heart/core/event/mock_event" + "github.com/anyproto/anytype-heart/core/session" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +type accountServiceStub struct { + accountId string +} + +func (a *accountServiceStub) AccountID() string { + return a.accountId +} + +type fixture struct { + *storeObject + source *mock_source.MockStore + accountServiceStub *accountServiceStub + sourceCreator string + events []*pb.EventMessage +} + +const testCreator = "accountId1" + +func newFixture(t *testing.T) *fixture { + ctx := context.Background() + db, err := anystore.Open(ctx, filepath.Join(t.TempDir(), "crdt.db"), nil) + require.NoError(t, err) + t.Cleanup(func() { + err := db.Close() + require.NoError(t, err) + }) + + accountService := &accountServiceStub{accountId: testCreator} + + eventSender := mock_event.NewMockSender(t) + + sb := smarttest.New("chatId1") + + object := New(sb, accountService, eventSender, db) + + fx := &fixture{ + storeObject: object.(*storeObject), + accountServiceStub: accountService, + sourceCreator: testCreator, + } + eventSender.EXPECT().Broadcast(mock.Anything).Run(func(event *pb.Event) { + for _, msg := range event.Messages { + fx.events = append(fx.events, msg) + } + }).Return().Maybe() + + source := mock_source.NewMockStore(t) + source.EXPECT().ReadStoreDoc(ctx, mock.Anything, mock.Anything).Return(nil) + source.EXPECT().PushStoreChange(mock.Anything, mock.Anything).RunAndReturn(fx.applyToStore).Maybe() + fx.source = source + + err = object.Init(&smartblock.InitContext{ + Ctx: ctx, + Source: source, + }) + require.NoError(t, err) + + return fx +} + +func TestAddMessage(t *testing.T) { + ctx := context.Background() + sessionCtx := session.NewContext() + + fx := newFixture(t) + + inputMessage := givenMessage() + messageId, err := fx.AddMessage(ctx, sessionCtx, inputMessage) + require.NoError(t, err) + assert.NotEmpty(t, messageId) + assert.NotEmpty(t, sessionCtx.GetMessages()) + + messages, err := fx.GetMessages(ctx, "", 0) + require.NoError(t, err) + + require.Len(t, messages, 1) + + want := givenMessage() + want.Id = messageId + want.Creator = testCreator + + got := messages[0] + assertMessagesEqual(t, want, got) +} + +func TestGetMessages(t *testing.T) { + ctx := context.Background() + fx := newFixture(t) + + for i := 0; i < 10; i++ { + inputMessage := givenMessage() + inputMessage.Message.Text = fmt.Sprintf("text %d", i+1) + messageId, err := fx.AddMessage(ctx, nil, inputMessage) + require.NoError(t, err) + assert.NotEmpty(t, messageId) + } + + messages, err := fx.GetMessages(ctx, "", 5) + require.NoError(t, err) + wantTexts := []string{"text 6", "text 7", "text 8", "text 9", "text 10"} + for i, msg := range messages { + assert.Equal(t, wantTexts[i], msg.Message.Text) + } + + lastOrderId := messages[0].OrderId + messages, err = fx.GetMessages(ctx, lastOrderId, 10) + require.NoError(t, err) + wantTexts = []string{"text 1", "text 2", "text 3", "text 4", "text 5"} + for i, msg := range messages { + assert.Equal(t, wantTexts[i], msg.Message.Text) + } +} + +func TestGetMessagesByIds(t *testing.T) { + ctx := context.Background() + sessionCtx := session.NewContext() + + fx := newFixture(t) + + inputMessage := givenMessage() + messageId, err := fx.AddMessage(ctx, sessionCtx, inputMessage) + require.NoError(t, err) + + messages, err := fx.GetMessagesByIds(ctx, []string{messageId, "wrongId"}) + require.NoError(t, err) + require.Len(t, messages, 1) + + want := givenMessage() + want.Id = messageId + want.Creator = testCreator + got := messages[0] + assertMessagesEqual(t, want, got) +} + +func TestEditMessage(t *testing.T) { + t.Run("edit own message", func(t *testing.T) { + ctx := context.Background() + fx := newFixture(t) + + // Add + inputMessage := givenMessage() + + messageId, err := fx.AddMessage(ctx, nil, inputMessage) + require.NoError(t, err) + assert.NotEmpty(t, messageId) + + // Edit + editedMessage := givenMessage() + editedMessage.Message.Text = "edited text!" + + err = fx.EditMessage(ctx, messageId, editedMessage) + require.NoError(t, err) + + messages, err := fx.GetMessages(ctx, "", 0) + require.NoError(t, err) + require.Len(t, messages, 1) + + want := editedMessage + want.Id = messageId + want.Creator = testCreator + + got := messages[0] + assert.True(t, got.ModifiedAt > 0) + got.ModifiedAt = 0 + assertMessagesEqual(t, want, got) + }) + + t.Run("edit other's message", func(t *testing.T) { + ctx := context.Background() + fx := newFixture(t) + + // Add + inputMessage := givenMessage() + + messageId, err := fx.AddMessage(ctx, nil, inputMessage) + require.NoError(t, err) + assert.NotEmpty(t, messageId) + + // Edit + editedMessage := givenMessage() + editedMessage.Message.Text = "edited text!" + + fx.sourceCreator = "maliciousPerson" + + err = fx.EditMessage(ctx, messageId, editedMessage) + require.Error(t, err) + + // Check that nothing is changed + messages, err := fx.GetMessages(ctx, "", 0) + require.NoError(t, err) + require.Len(t, messages, 1) + + want := inputMessage + want.Id = messageId + want.Creator = testCreator + + got := messages[0] + assertMessagesEqual(t, want, got) + }) + +} + +func TestToggleReaction(t *testing.T) { + ctx := context.Background() + fx := newFixture(t) + + // Add + inputMessage := givenMessage() + inputMessage.Reactions = nil + + messageId, err := fx.AddMessage(ctx, nil, inputMessage) + require.NoError(t, err) + assert.NotEmpty(t, messageId) + + // Edit + editedMessage := givenMessage() + editedMessage.Message.Text = "edited text!" + + t.Run("can toggle own reactions", func(t *testing.T) { + err = fx.ToggleMessageReaction(ctx, messageId, "👻") + require.NoError(t, err) + err = fx.ToggleMessageReaction(ctx, messageId, "🐻") + require.NoError(t, err) + err = fx.ToggleMessageReaction(ctx, messageId, "👺") + require.NoError(t, err) + err = fx.ToggleMessageReaction(ctx, messageId, "👺") + require.NoError(t, err) + }) + + anotherPerson := "anotherPerson" + + t.Run("can't toggle someone else's reactions", func(t *testing.T) { + fx.sourceCreator = testCreator + fx.accountServiceStub.accountId = anotherPerson + err = fx.ToggleMessageReaction(ctx, messageId, "🐻") + require.Error(t, err) + }) + t.Run("can toggle reactions on someone else's messages", func(t *testing.T) { + fx.sourceCreator = anotherPerson + fx.accountServiceStub.accountId = anotherPerson + err = fx.ToggleMessageReaction(ctx, messageId, "🐻") + require.NoError(t, err) + }) + + messages, err := fx.GetMessages(ctx, "", 0) + require.NoError(t, err) + require.Len(t, messages, 1) + + got := messages[0].Reactions + + want := &model.ChatMessageReactions{ + Reactions: map[string]*model.ChatMessageReactionsIdentityList{ + "👻": { + Ids: []string{testCreator}, + }, + "🐻": { + Ids: []string{testCreator, anotherPerson}, + }, + }, + } + assert.Equal(t, want, got) +} + +func (fx *fixture) applyToStore(ctx context.Context, params source.PushStoreChangeParams) (string, error) { + changeId := bson.NewObjectId().Hex() + tx, err := params.State.NewTx(ctx) + if err != nil { + return "", fmt.Errorf("new tx: %w", err) + } + order := tx.NextOrder(tx.GetMaxOrder()) + err = tx.ApplyChangeSet(storestate.ChangeSet{ + Id: changeId, + Order: order, + Changes: params.Changes, + Creator: fx.sourceCreator, + Timestamp: params.Time.Unix(), + }) + if err != nil { + return "", errors.Join(tx.Rollback(), fmt.Errorf("apply change set: %w", err)) + } + err = tx.Commit() + if err != nil { + return "", err + } + fx.onUpdate() + return changeId, nil +} + +func givenMessage() *model.ChatMessage { + return &model.ChatMessage{ + Id: "", + OrderId: "", + Creator: "", + ReplyToMessageId: "replyToMessageId1", + Message: &model.ChatMessageMessageContent{ + Text: "text!", + Style: model.BlockContentText_Quote, + Marks: []*model.BlockContentTextMark{ + { + Range: &model.Range{ + From: 0, + To: 1, + }, + Type: model.BlockContentTextMark_Link, + Param: "https://example.com", + }, + { + Range: &model.Range{ + From: 2, + To: 3, + }, + Type: model.BlockContentTextMark_Italic, + }, + }, + }, + Attachments: []*model.ChatMessageAttachment{ + { + Target: "attachmentId1", + Type: model.ChatMessageAttachment_IMAGE, + }, + { + Target: "attachmentId2", + Type: model.ChatMessageAttachment_LINK, + }, + }, + Reactions: &model.ChatMessageReactions{ + Reactions: map[string]*model.ChatMessageReactionsIdentityList{ + "🥰": { + Ids: []string{"identity1", "identity2"}, + }, + "🤔": { + Ids: []string{"identity3"}, + }, + }, + }, + } +} + +func assertMessagesEqual(t *testing.T, want, got *model.ChatMessage) { + // Cleanup order id + assert.NotEmpty(t, got.OrderId) + got.OrderId = "" + // Cleanup timestamp + assert.NotZero(t, got.CreatedAt) + got.CreatedAt = 0 + assert.Equal(t, want, got) +} diff --git a/core/block/editor/chatobject/message.go b/core/block/editor/chatobject/message.go new file mode 100644 index 0000000000..76f194e728 --- /dev/null +++ b/core/block/editor/chatobject/message.go @@ -0,0 +1,191 @@ +package chatobject + +import ( + "github.com/anyproto/any-store/anyenc" + + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +const ( + creatorKey = "creator" + createdAtKey = "createdAt" + modifiedAtKey = "modifiedAt" + reactionsKey = "reactions" + contentKey = "content" + orderKey = "_o" +) + +type messageWrapper struct { + val *anyenc.Value + arena *anyenc.Arena +} + +func newMessageWrapper(arena *anyenc.Arena, val *anyenc.Value) *messageWrapper { + return &messageWrapper{arena: arena, val: val} +} + +func (m *messageWrapper) getCreator() string { + return string(m.val.GetStringBytes(creatorKey)) +} + +func (m *messageWrapper) setCreator(v string) { + m.val.Set(creatorKey, m.arena.NewString(v)) +} + +func (m *messageWrapper) setCreatedAt(v int64) { + m.val.Set(createdAtKey, m.arena.NewNumberInt(int(v))) +} + +/* +{ + "id": "", // Unique message identifier + "creator": "", // Identifier for the message author + "replyToMessageId": "", + "dateCreated": "", // Date and time the message was created + "dateEdited": "", // Date and time the message was last updated; >> for beta + "wasEdited": false, // Flag indicating if the message was edited; Sets automatically when content was changed; >> for beta + "content": { // everything inside can be only edited by the creator + "message": { // [set]; set all fields at once + "text": "message text", // The text content of the message part + "kind": "", // The style/type of the message part (e.g., Paragraph, Quote, Code) + "marks": [ + { + "from": 0, // Starting position of the mark in the text + "to": 100, // Ending position of the mark in the text + "type": "" // Type of the mark (e.g., Bold, Italic, Link) + } + ] + }, + "attachments": { // [set], [unset]; + "": { // use object_id as attachment_id in the first iteration + "target": "", // Identifier for the attachment object. todo: we have target in the key, should we remove it from here? + "type": "" // Type of attachment (e.g., file, image, link) + } + }, + "reactions": { // [addToSet], [pull] to specify the emoji + "": ["", ""], // Users who reacted with this emoji + "": [""] // Users who reacted with this emoji + } +} + +*/ + +func marshalModel(arena *anyenc.Arena, msg *model.ChatMessage) *anyenc.Value { + message := arena.NewObject() + message.Set("text", arena.NewString(msg.Message.Text)) + message.Set("style", arena.NewNumberInt(int(msg.Message.Style))) + marks := arena.NewArray() + for i, inMark := range msg.Message.Marks { + mark := arena.NewObject() + mark.Set("from", arena.NewNumberInt(int(inMark.Range.From))) + mark.Set("to", arena.NewNumberInt(int(inMark.Range.To))) + mark.Set("type", arena.NewNumberInt(int(inMark.Type))) + if inMark.Param != "" { + mark.Set("param", arena.NewString(inMark.Param)) + } + marks.SetArrayItem(i, mark) + } + message.Set("marks", marks) + + attachments := arena.NewObject() + for i, inAttachment := range msg.Attachments { + attachment := arena.NewObject() + attachment.Set("type", arena.NewNumberInt(int(inAttachment.Type))) + attachments.Set(inAttachment.Target, attachment) + attachments.SetArrayItem(i, attachment) + } + + content := arena.NewObject() + content.Set("message", message) + content.Set("attachments", attachments) + + reactions := arena.NewObject() + for emoji, inReaction := range msg.GetReactions().GetReactions() { + identities := arena.NewArray() + for j, identity := range inReaction.Ids { + identities.SetArrayItem(j, arena.NewString(identity)) + } + reactions.Set(emoji, identities) + } + + root := arena.NewObject() + root.Set(creatorKey, arena.NewString(msg.Creator)) + root.Set(createdAtKey, arena.NewNumberInt(int(msg.CreatedAt))) + root.Set(modifiedAtKey, arena.NewNumberInt(int(msg.ModifiedAt))) + root.Set("replyToMessageId", arena.NewString(msg.ReplyToMessageId)) + root.Set(contentKey, content) + root.Set(reactionsKey, reactions) + return root +} + +func (m *messageWrapper) toModel() *model.ChatMessage { + return &model.ChatMessage{ + Id: string(m.val.GetStringBytes("id")), + Creator: string(m.val.GetStringBytes(creatorKey)), + CreatedAt: int64(m.val.GetInt(createdAtKey)), + ModifiedAt: int64(m.val.GetInt(modifiedAtKey)), + OrderId: string(m.val.GetStringBytes("_o", "id")), + ReplyToMessageId: string(m.val.GetStringBytes("replyToMessageId")), + Message: m.contentToModel(), + Attachments: m.attachmentsToModel(), + Reactions: m.reactionsToModel(), + } +} + +func (m *messageWrapper) contentToModel() *model.ChatMessageMessageContent { + inMarks := m.val.GetArray(contentKey, "message", "marks") + marks := make([]*model.BlockContentTextMark, 0, len(inMarks)) + for _, inMark := range inMarks { + mark := &model.BlockContentTextMark{ + Range: &model.Range{ + From: int32(inMark.GetInt("from")), + To: int32(inMark.GetInt("to")), + }, + Type: model.BlockContentTextMarkType(inMark.GetInt("type")), + Param: string(inMark.GetStringBytes("param")), + } + marks = append(marks, mark) + } + return &model.ChatMessageMessageContent{ + Text: string(m.val.GetStringBytes(contentKey, "message", "text")), + Style: model.BlockContentTextStyle(m.val.GetInt("content", "message", "style")), + Marks: marks, + } +} + +func (m *messageWrapper) attachmentsToModel() []*model.ChatMessageAttachment { + inAttachments := m.val.GetObject(contentKey, "attachments") + var attachments []*model.ChatMessageAttachment + if inAttachments != nil { + attachments = make([]*model.ChatMessageAttachment, 0, inAttachments.Len()) + inAttachments.Visit(func(targetObjectId []byte, inAttachment *anyenc.Value) { + attachments = append(attachments, &model.ChatMessageAttachment{ + Target: string(targetObjectId), + Type: model.ChatMessageAttachmentAttachmentType(inAttachment.GetInt("type")), + }) + }) + } + return attachments +} + +func (m *messageWrapper) reactionsToModel() *model.ChatMessageReactions { + inReactions := m.val.GetObject(reactionsKey) + reactions := &model.ChatMessageReactions{ + Reactions: map[string]*model.ChatMessageReactionsIdentityList{}, + } + if inReactions != nil { + inReactions.Visit(func(emoji []byte, inReaction *anyenc.Value) { + inReactionArr := inReaction.GetArray() + identities := make([]string, 0, len(inReactionArr)) + for _, identity := range inReactionArr { + identities = append(identities, string(identity.GetStringBytes())) + } + if len(identities) > 0 { + reactions.Reactions[string(emoji)] = &model.ChatMessageReactionsIdentityList{ + Ids: identities, + } + } + }) + } + return reactions +} diff --git a/core/block/editor/chatobject/subscription.go b/core/block/editor/chatobject/subscription.go new file mode 100644 index 0000000000..8c41dc09c5 --- /dev/null +++ b/core/block/editor/chatobject/subscription.go @@ -0,0 +1,133 @@ +package chatobject + +import ( + "slices" + + "github.com/anyproto/anytype-heart/core/event" + "github.com/anyproto/anytype-heart/core/session" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +type subscription struct { + chatId string + eventSender event.Sender + + sessionContext session.Context + + eventsBuffer []*pb.EventMessage + + firstOrderId string + enabled bool +} + +func newSubscription(chatId string, eventSender event.Sender) *subscription { + return &subscription{ + chatId: chatId, + eventSender: eventSender, + } +} + +func (s *subscription) subscribe(firstOrderId string) { + s.firstOrderId = firstOrderId + s.enabled = true +} + +func (s *subscription) close() { + s.enabled = false +} + +// setSessionContext sets the session context for the current operation +func (s *subscription) setSessionContext(ctx session.Context) { + s.sessionContext = ctx +} + +func (s *subscription) flush() { + defer func() { + s.eventsBuffer = s.eventsBuffer[:0] + }() + + if len(s.eventsBuffer) == 0 { + return + } + + if s.sessionContext != nil { + s.sessionContext.SetMessages(s.chatId, slices.Clone(s.eventsBuffer)) + s.sessionContext = nil + } else if s.enabled { + s.eventSender.Broadcast(&pb.Event{ + ContextId: s.chatId, + Messages: slices.Clone(s.eventsBuffer), + }) + } +} + +func (s *subscription) add(message *model.ChatMessage) { + if !s.canSend(message) { + return + } + ev := &pb.EventChatAdd{ + Id: message.Id, + Message: message, + OrderId: message.OrderId, + } + s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{ + Value: &pb.EventMessageValueOfChatAdd{ + ChatAdd: ev, + }, + }) +} + +func (s *subscription) delete(messageId string) { + ev := &pb.EventChatDelete{ + Id: messageId, + } + s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{ + Value: &pb.EventMessageValueOfChatDelete{ + ChatDelete: ev, + }, + }) +} + +func (s *subscription) updateFull(message *model.ChatMessage) { + if !s.canSend(message) { + return + } + ev := &pb.EventChatUpdate{ + Id: message.Id, + Message: message, + } + s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{ + Value: &pb.EventMessageValueOfChatUpdate{ + ChatUpdate: ev, + }, + }) +} + +func (s *subscription) updateReactions(message *model.ChatMessage) { + if !s.canSend(message) { + return + } + ev := &pb.EventChatUpdateReactions{ + Id: message.Id, + Reactions: message.Reactions, + } + s.eventsBuffer = append(s.eventsBuffer, &pb.EventMessage{ + Value: &pb.EventMessageValueOfChatUpdateReactions{ + ChatUpdateReactions: ev, + }, + }) +} + +func (s *subscription) canSend(message *model.ChatMessage) bool { + if s.sessionContext != nil { + return true + } + if !s.enabled { + return false + } + if s.firstOrderId > message.OrderId { + return false + } + return true +} diff --git a/core/block/editor/chatobject/subscription_test.go b/core/block/editor/chatobject/subscription_test.go new file mode 100644 index 0000000000..f3da28821e --- /dev/null +++ b/core/block/editor/chatobject/subscription_test.go @@ -0,0 +1,84 @@ +package chatobject + +import ( + "context" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSubscription(t *testing.T) { + ctx := context.Background() + fx := newFixture(t) + + for i := 0; i < 10; i++ { + inputMessage := givenMessage() + inputMessage.Message.Text = fmt.Sprintf("text %d", i+1) + messageId, err := fx.AddMessage(ctx, nil, inputMessage) + require.NoError(t, err) + assert.NotEmpty(t, messageId) + } + + messages, _, err := fx.SubscribeLastMessages(ctx, 5) + require.NoError(t, err) + wantTexts := []string{"text 6", "text 7", "text 8", "text 9", "text 10"} + for i, msg := range messages { + assert.Equal(t, wantTexts[i], msg.Message.Text) + } + + t.Run("add message", func(t *testing.T) { + messageId, err := fx.AddMessage(ctx, nil, givenMessage()) + require.NoError(t, err) + require.Len(t, fx.events, 1) + + ev := fx.events[0].GetChatAdd() + require.NotNil(t, ev) + assert.Equal(t, messageId, ev.Id) + + fx.events = nil + }) + + t.Run("edit message", func(t *testing.T) { + edited := givenMessage() + edited.Message.Text = "edited text" + + err = fx.EditMessage(ctx, messages[0].Id, edited) + require.NoError(t, err) + require.Len(t, fx.events, 1) + + ev := fx.events[0].GetChatUpdate() + require.NotNil(t, ev) + assert.Equal(t, messages[0].Id, ev.Id) + assert.Equal(t, edited.Message.Text, ev.Message.Message.Text) + + fx.events = nil + }) + + t.Run("toggle message reaction", func(t *testing.T) { + err = fx.ToggleMessageReaction(ctx, messages[0].Id, "👍") + require.NoError(t, err) + require.Len(t, fx.events, 1) + + ev := fx.events[0].GetChatUpdateReactions() + require.NotNil(t, ev) + assert.Equal(t, messages[0].Id, ev.Id) + _, ok := ev.Reactions.Reactions["👍"] + assert.True(t, ok) + + fx.events = nil + }) + + t.Run("delete message", func(t *testing.T) { + err = fx.DeleteMessage(ctx, messages[0].Id) + require.NoError(t, err) + require.Len(t, fx.events, 1) + + ev := fx.events[0].GetChatDelete() + require.NotNil(t, ev) + assert.Equal(t, messages[0].Id, ev.Id) + + fx.events = nil + }) +} diff --git a/core/block/editor/clipboard/clipboard.go b/core/block/editor/clipboard/clipboard.go index 100d234b59..67871afca1 100644 --- a/core/block/editor/clipboard/clipboard.go +++ b/core/block/editor/clipboard/clipboard.go @@ -26,7 +26,7 @@ import ( "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/core" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/slice" @@ -47,7 +47,7 @@ type Clipboard interface { Export(req pb.RpcBlockExportRequest) (path string, err error) } -func NewClipboard(sb smartblock.SmartBlock, file file.File, tempDirProvider core.TempDirProvider, objectStore objectstore.ObjectStore, fileService files.Service, fileObjectService fileobject.Service) Clipboard { +func NewClipboard(sb smartblock.SmartBlock, file file.File, tempDirProvider core.TempDirProvider, objectStore spaceindex.Store, fileService files.Service, fileObjectService fileobject.Service) Clipboard { return &clipboard{ SmartBlock: sb, file: file, @@ -61,9 +61,9 @@ func NewClipboard(sb smartblock.SmartBlock, file file.File, tempDirProvider core type clipboard struct { smartblock.SmartBlock file file.File - tempDirProvider core.TempDirProvider - objectStore objectstore.ObjectStore - fileService files.Service + tempDirProvider core.TempDirProvider + objectStore spaceindex.Store + fileService files.Service fileObjectService fileobject.Service } @@ -572,7 +572,7 @@ func (cb *clipboard) addRelationLinksToDataview(d *model.BlockContentDataview) ( for k := range relationKeys { relationKeysList = append(relationKeysList, k) } - relations, err := cb.objectStore.FetchRelationByKeys(cb.SpaceID(), relationKeysList...) + relations, err := cb.objectStore.FetchRelationByKeys(relationKeysList...) if err != nil { return fmt.Errorf("failed to fetch relation keys of dataview: %w", err) } diff --git a/core/block/editor/collection/collection.go b/core/block/editor/collection/collection.go index c6c105a1e7..dfd53f9a26 100644 --- a/core/block/editor/collection/collection.go +++ b/core/block/editor/collection/collection.go @@ -10,13 +10,13 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/simple" "github.com/anyproto/anytype-heart/core/block/source" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) var ErrObjectNotFound = fmt.Errorf("object not found") -func NewCollection(sb smartblock.SmartBlock, objectStore objectstore.ObjectStore) Collection { +func NewCollection(sb smartblock.SmartBlock, objectStore spaceindex.Store) Collection { return &objectLinksCollection{SmartBlock: sb, objectStore: objectStore} } @@ -33,7 +33,7 @@ type Collection interface { type objectLinksCollection struct { smartblock.SmartBlock - objectStore objectstore.ObjectStore + objectStore spaceindex.Store } func (p *objectLinksCollection) AddObject(id string) (err error) { diff --git a/core/block/editor/converter/layout.go b/core/block/editor/converter/layout.go index ccf2db36ba..b882c6c7f4 100644 --- a/core/block/editor/converter/layout.go +++ b/core/block/editor/converter/layout.go @@ -54,6 +54,13 @@ func (c *layoutConverter) Convert(space smartblock.Space, st *state.State, fromL return nil } + if fromLayout == model.ObjectType_chat || fromLayout == model.ObjectType_chatDerived { + return fmt.Errorf("can't convert from chat") + } + if toLayout == model.ObjectType_chat || toLayout == model.ObjectType_chatDerived { + return fmt.Errorf("can't convert to chat") + } + if fromLayout == model.ObjectType_note && toLayout == model.ObjectType_collection { return c.fromNoteToCollection(st) } @@ -146,7 +153,7 @@ func (c *layoutConverter) fromAnyToSet(space smartblock.Space, st *state.State) } addFeaturedRelationSetOf(st) - dvBlock, err := dataview.BlockBySource(c.objectStore, source) + dvBlock, err := dataview.BlockBySource(c.objectStore.SpaceIndex(space.Id()), source) if err != nil { return err } @@ -192,7 +199,7 @@ func (c *layoutConverter) listIDsFromSet(spaceID string, typesFromSet []string) return []string{}, nil } - records, err := c.objectStore.Query( + records, err := c.objectStore.SpaceIndex(spaceID).Query( database.Query{ Filters: filters, }, @@ -289,25 +296,23 @@ func (c *layoutConverter) generateFilters(spaceId string, typesAndRelations []st return nil, fmt.Errorf("partition ids by sb type: %w", err) } filters = c.appendTypesFilter(m[coresb.SmartBlockTypeObjectType], filters) - filters, err = c.appendRelationFilters(m[coresb.SmartBlockTypeRelation], filters) + filters, err = c.appendRelationFilters(spaceId, m[coresb.SmartBlockTypeRelation], filters) if err != nil { return nil, fmt.Errorf("append relation filters: %w", err) } return filters, nil } -func (c *layoutConverter) appendRelationFilters(relationIDs []string, filters []*model.BlockContentDataviewFilter) ([]*model.BlockContentDataviewFilter, error) { - if len(relationIDs) != 0 { - for _, relationID := range relationIDs { - relation, err := c.objectStore.GetRelationByID(relationID) - if err != nil { - return nil, fmt.Errorf("get relation by id %s: %w", relationID, err) - } - filters = append(filters, &model.BlockContentDataviewFilter{ - RelationKey: relation.Key, - Condition: model.BlockContentDataviewFilter_Exists, - }) +func (c *layoutConverter) appendRelationFilters(spaceId string, relationIDs []string, filters []*model.BlockContentDataviewFilter) ([]*model.BlockContentDataviewFilter, error) { + for _, relationID := range relationIDs { + relation, err := c.objectStore.SpaceIndex(spaceId).GetRelationById(relationID) + if err != nil { + return nil, fmt.Errorf("get relation by id %s: %w", relationID, err) } + filters = append(filters, &model.BlockContentDataviewFilter{ + RelationKey: relation.Key, + Condition: model.BlockContentDataviewFilter_Exists, + }) } return filters, nil } diff --git a/core/block/editor/dashboard.go b/core/block/editor/dashboard.go index 40993410ba..21f7f7cffa 100644 --- a/core/block/editor/dashboard.go +++ b/core/block/editor/dashboard.go @@ -13,7 +13,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" @@ -27,10 +27,10 @@ type Dashboard struct { basic.AllOperations collection.Collection - objectStore objectstore.ObjectStore + objectStore spaceindex.Store } -func NewDashboard(sb smartblock.SmartBlock, objectStore objectstore.ObjectStore, layoutConverter converter.LayoutConverter) *Dashboard { +func NewDashboard(sb smartblock.SmartBlock, objectStore spaceindex.Store, layoutConverter converter.LayoutConverter) *Dashboard { return &Dashboard{ SmartBlock: sb, AllOperations: basic.NewBasic(sb, objectStore, layoutConverter, nil, nil), @@ -75,6 +75,16 @@ func (p *Dashboard) updateObjects(info smartblock.ApplyInfo) (err error) { return } + go func() { + uErr := p.updateInStore(favoritedIds) + if uErr != nil { + log.Errorf("favorite: can't update in store: %v", uErr) + } + }() + return nil +} + +func (p *Dashboard) updateInStore(favoritedIds []string) error { records, err := p.objectStore.Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { @@ -82,15 +92,10 @@ func (p *Dashboard) updateObjects(info smartblock.ApplyInfo) (err error) { Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.Bool(true), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(p.SpaceID()), - }, }, }) if err != nil { - return + return err } var storeFavoritedIds = make([]string, 0, len(records)) for _, rec := range records { @@ -128,5 +133,5 @@ func (p *Dashboard) updateObjects(info smartblock.ApplyInfo) (err error) { } }(addedId) } - return + return nil } diff --git a/core/block/editor/dataview/dataview.go b/core/block/editor/dataview/dataview.go index 72f6b21986..4cbbb621a4 100644 --- a/core/block/editor/dataview/dataview.go +++ b/core/block/editor/dataview/dataview.go @@ -18,7 +18,7 @@ import ( "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/internalflag" @@ -50,7 +50,7 @@ type Dataview interface { GetDataviewBlock(s *state.State, blockID string) (dataview.Block, error) } -func NewDataview(sb smartblock.SmartBlock, objectStore objectstore.ObjectStore) Dataview { +func NewDataview(sb smartblock.SmartBlock, objectStore spaceindex.Store) Dataview { dv := &sdataview{ SmartBlock: sb, objectStore: objectStore, @@ -62,7 +62,7 @@ func NewDataview(sb smartblock.SmartBlock, objectStore objectstore.ObjectStore) type sdataview struct { smartblock.SmartBlock - objectStore objectstore.ObjectStore + objectStore spaceindex.Store } func (d *sdataview) GetDataviewBlock(s *state.State, blockID string) (dataview.Block, error) { @@ -144,7 +144,7 @@ func (d *sdataview) AddRelations(ctx session.Context, blockId string, relationKe return err } for _, key := range relationKeys { - relation, err2 := d.objectStore.FetchRelationByKey(d.SpaceID(), key) + relation, err2 := d.objectStore.FetchRelationByKey(key) if err2 != nil { return err2 } @@ -457,7 +457,7 @@ func getDataviewBlock(s *state.State, id string) (dataview.Block, error) { return nil, fmt.Errorf("not a dataview block") } -func BlockBySource(objectStore objectstore.ObjectStore, sources []string) (*model.BlockContentOfDataview, error) { +func BlockBySource(objectStore spaceindex.Store, sources []string) (*model.BlockContentOfDataview, error) { // Empty schema if len(sources) == 0 { return template.MakeDataviewContent(false, nil, nil), nil @@ -472,7 +472,7 @@ func BlockBySource(objectStore objectstore.ObjectStore, sources []string) (*mode // Finally, try relations relations := make([]*model.RelationLink, 0, len(sources)) for _, relId := range sources { - rel, err := objectStore.GetRelationByID(relId) + rel, err := objectStore.GetRelationById(relId) if err != nil { return nil, fmt.Errorf("failed to get relation %s: %w", relId, err) } diff --git a/core/block/editor/dataview/dataview_test.go b/core/block/editor/dataview/dataview_test.go index f95819279f..8c44ef6646 100644 --- a/core/block/editor/dataview/dataview_test.go +++ b/core/block/editor/dataview/dataview_test.go @@ -16,6 +16,7 @@ import ( "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" @@ -27,14 +28,14 @@ const ( ) type fixture struct { - store *objectstore.StoreFixture + store *spaceindex.StoreFixture sb *smarttest.SmartTest *sdataview } func newFixture(t *testing.T) *fixture { - store := objectstore.NewStoreFixture(t) + store := spaceindex.NewStoreFixture(t) sb := smarttest.New(objId) dv := NewDataview(sb, store).(*sdataview) @@ -109,11 +110,12 @@ func TestInjectActiveView(t *testing.T) { // given blocksToView := map[string]string{dv1: "view1", dv2: "view2"} fx := newFixture(t) - require.NoError(t, fx.store.SetActiveViews(objId, blocksToView)) + err := fx.store.SetActiveViews(objId, blocksToView) + require.NoError(t, err) info := getInfo() // when - err := fx.injectActiveViews(info) + err = fx.injectActiveViews(info) st := info.State // then diff --git a/core/block/editor/factory.go b/core/block/editor/factory.go index 960f8752d7..80bea7de0d 100644 --- a/core/block/editor/factory.go +++ b/core/block/editor/factory.go @@ -8,12 +8,15 @@ import ( "github.com/anyproto/anytype-heart/core/anytype/config" "github.com/anyproto/anytype-heart/core/block/cache" + "github.com/anyproto/anytype-heart/core/block/editor/accountobject" "github.com/anyproto/anytype-heart/core/block/editor/bookmark" + "github.com/anyproto/anytype-heart/core/block/editor/chatobject" "github.com/anyproto/anytype-heart/core/block/editor/converter" "github.com/anyproto/anytype-heart/core/block/editor/file" "github.com/anyproto/anytype-heart/core/block/editor/lastused" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/migration" + "github.com/anyproto/anytype-heart/core/block/object/idresolver" "github.com/anyproto/anytype-heart/core/block/process" "github.com/anyproto/anytype-heart/core/block/restriction" "github.com/anyproto/anytype-heart/core/block/source" @@ -27,6 +30,7 @@ import ( coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" ) @@ -37,6 +41,7 @@ type ObjectDeleter interface { } type accountService interface { + AccountID() string PersonalSpaceID() string MyParticipantId(spaceId string) string } @@ -68,6 +73,7 @@ type ObjectFactory struct { objectDeleter ObjectDeleter deviceService deviceService lastUsedUpdater lastused.ObjectUsageUpdater + spaceIdResolver idresolver.Resolver } func NewObjectFactory() *ObjectFactory { @@ -75,28 +81,32 @@ func NewObjectFactory() *ObjectFactory { } func (f *ObjectFactory) Init(a *app.App) (err error) { - f.bookmarkService = app.MustComponent[bookmark.BookmarkService](a) - f.fileBlockService = app.MustComponent[file.BlockService](a) - f.objectStore = app.MustComponent[objectstore.ObjectStore](a) - f.restrictionService = app.MustComponent[restriction.Service](a) - f.sourceService = app.MustComponent[source.Service](a) - f.fileService = app.MustComponent[files.Service](a) - f.fileStore = app.MustComponent[filestore.FileStore](a) f.config = app.MustComponent[*config.Config](a) - f.tempDirProvider = app.MustComponent[core.TempDirProvider](a) - f.layoutConverter = app.MustComponent[converter.LayoutConverter](a) f.picker = app.MustComponent[cache.ObjectGetter](a) f.indexer = app.MustComponent[smartblock.Indexer](a) + f.fileStore = app.MustComponent[filestore.FileStore](a) + f.objectStore = app.MustComponent[objectstore.ObjectStore](a) + f.fileService = app.MustComponent[files.Service](a) f.eventSender = app.MustComponent[event.Sender](a) f.spaceService = app.MustComponent[spaceService](a) + f.sourceService = app.MustComponent[source.Service](a) + f.objectDeleter = app.MustComponent[ObjectDeleter](a) + f.deviceService = app.MustComponent[deviceService](a) f.accountService = app.MustComponent[accountService](a) - f.fileObjectService = app.MustComponent[fileobject.Service](a) f.processService = app.MustComponent[process.Service](a) + f.fileReconciler = app.MustComponent[reconciler.Reconciler](a) + f.bookmarkService = app.MustComponent[bookmark.BookmarkService](a) + f.tempDirProvider = app.MustComponent[core.TempDirProvider](a) + f.layoutConverter = app.MustComponent[converter.LayoutConverter](a) + f.fileBlockService = app.MustComponent[file.BlockService](a) + f.fileObjectService = app.MustComponent[fileobject.Service](a) + f.restrictionService = app.MustComponent[restriction.Service](a) f.fileUploaderService = app.MustComponent[fileuploader.Service](a) f.objectDeleter = app.MustComponent[ObjectDeleter](a) f.fileReconciler = app.MustComponent[reconciler.Reconciler](a) f.deviceService = app.MustComponent[deviceService](a) f.lastUsedUpdater = app.MustComponent[lastused.ObjectUsageUpdater](a) + f.spaceIdResolver = app.MustComponent[idresolver.Resolver](a) return nil } @@ -145,20 +155,23 @@ func (f *ObjectFactory) InitObject(space smartblock.Space, id string, initCtx *s return sb, sb.Apply(initCtx.State, smartblock.NoHistory, smartblock.NoEvent, smartblock.NoRestrictions, smartblock.SkipIfNoChanges, smartblock.KeepInternalFlags, smartblock.IgnoreNoPermissions) } -func (f *ObjectFactory) produceSmartblock(space smartblock.Space) smartblock.SmartBlock { +func (f *ObjectFactory) produceSmartblock(space smartblock.Space) (smartblock.SmartBlock, spaceindex.Store) { + store := f.objectStore.SpaceIndex(space.Id()) return smartblock.New( space, f.accountService.MyParticipantId(space.Id()), f.fileStore, f.restrictionService, + store, f.objectStore, f.indexer, f.eventSender, - ) + f.spaceIdResolver, + ), store } func (f *ObjectFactory) New(space smartblock.Space, sbType coresb.SmartBlockType) (smartblock.SmartBlock, error) { - sb := f.produceSmartblock(space) + sb, store := f.produceSmartblock(space) switch sbType { case coresb.SmartBlockTypePage, coresb.SmartBlockTypeDate, @@ -166,36 +179,41 @@ func (f *ObjectFactory) New(space smartblock.Space, sbType coresb.SmartBlockType coresb.SmartBlockTypeBundledObjectType, coresb.SmartBlockTypeObjectType, coresb.SmartBlockTypeRelation, - coresb.SmartBlockTypeRelationOption: - return f.newPage(sb), nil + coresb.SmartBlockTypeRelationOption, + coresb.SmartBlockTypeChatObject: + return f.newPage(space.Id(), sb), nil case coresb.SmartBlockTypeArchive: - return NewArchive(sb, f.objectStore), nil + return NewArchive(sb, store), nil case coresb.SmartBlockTypeHome: - return NewDashboard(sb, f.objectStore, f.layoutConverter), nil + return NewDashboard(sb, store, f.layoutConverter), nil case coresb.SmartBlockTypeProfilePage, coresb.SmartBlockTypeAnytypeProfile: - return f.newProfile(sb), nil + return f.newProfile(space.Id(), sb), nil case coresb.SmartBlockTypeFileObject: - return f.newFile(sb), nil + return f.newFile(space.Id(), sb), nil case coresb.SmartBlockTypeTemplate, coresb.SmartBlockTypeBundledTemplate: - return f.newTemplate(sb), nil + return f.newTemplate(space.Id(), sb), nil case coresb.SmartBlockTypeWorkspace: - return f.newWorkspace(sb), nil + return f.newWorkspace(sb, store), nil case coresb.SmartBlockTypeSpaceView: return f.newSpaceView(sb), nil case coresb.SmartBlockTypeMissingObject: return NewMissingObject(sb), nil case coresb.SmartBlockTypeWidget: - return NewWidgetObject(sb, f.objectStore, f.layoutConverter), nil + return NewWidgetObject(sb, store, f.layoutConverter), nil case coresb.SmartBlockTypeNotificationObject: return NewNotificationObject(sb), nil case coresb.SmartBlockTypeSubObject: return nil, fmt.Errorf("subobject not supported via factory") case coresb.SmartBlockTypeParticipant: - return f.newParticipant(sb), nil + return f.newParticipant(space.Id(), sb, store), nil case coresb.SmartBlockTypeDevicesObject: return NewDevicesObject(sb, f.deviceService), nil + case coresb.SmartBlockTypeChatDerivedObject: + return chatobject.New(sb, f.accountService, f.eventSender, f.objectStore.GetCrdtDb(space.Id())), nil + case coresb.SmartBlockTypeAccountObject: + return accountobject.New(sb, store, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater, f.objectStore.GetCrdtDb(space.Id()), f.config), nil default: return nil, fmt.Errorf("unexpected smartblock type: %v", sbType) } diff --git a/core/block/editor/files.go b/core/block/editor/files.go index 06828d32e3..7068a5ad05 100644 --- a/core/block/editor/files.go +++ b/core/block/editor/files.go @@ -24,13 +24,14 @@ var fileRequiredRelations = append(pageRequiredRelations, []domain.RelationKey{ bundle.RelationKeyFileSyncStatus, }...) -func (f *ObjectFactory) newFile(sb smartblock.SmartBlock) *File { - basicComponent := basic.NewBasic(sb, f.objectStore, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater) +func (f *ObjectFactory) newFile(spaceId string, sb smartblock.SmartBlock) *File { + store := f.objectStore.SpaceIndex(spaceId) + basicComponent := basic.NewBasic(sb, store, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater) return &File{ SmartBlock: sb, ChangeReceiver: sb.(source.ChangeReceiver), AllOperations: basicComponent, - Text: stext.NewText(sb, f.objectStore, f.eventSender), + Text: stext.NewText(sb, store, f.eventSender), fileObjectService: f.fileObjectService, reconciler: f.fileReconciler, } diff --git a/core/block/editor/lastused/lastused.go b/core/block/editor/lastused/lastused.go index b1ea9736e2..520292f35d 100644 --- a/core/block/editor/lastused/lastused.go +++ b/core/block/editor/lastused/lastused.go @@ -169,7 +169,7 @@ func (u *updater) updateLastUsedDate(spc clientspace.Space, key Key, ts int64) e return fmt.Errorf("cannot update lastUsedDate for object with invalid smartBlock type. Only object types and relations are expected") } - details, err := u.store.GetObjectByUniqueKey(spc.Id(), uk) + details, err := u.store.SpaceIndex(spc.Id()).GetObjectByUniqueKey(uk) if err != nil { return fmt.Errorf("failed to get details: %w", err) } diff --git a/core/block/editor/lastused/lastused_test.go b/core/block/editor/lastused/lastused_test.go index 3e0b434cde..3cd9abc833 100644 --- a/core/block/editor/lastused/lastused_test.go +++ b/core/block/editor/lastused/lastused_test.go @@ -69,7 +69,7 @@ func TestUpdateLastUsedDate(t *testing.T) { } store := objectstore.NewStoreFixture(t) - store.AddObjects(t, []objectstore.TestObject{ + store.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(bundle.RelationKeyCamera.URL()), bundle.RelationKeySpaceId: pbtypes.String(spaceId), diff --git a/core/block/editor/lastused/mock_lastused/mock_ObjectUsageUpdater.go b/core/block/editor/lastused/mock_lastused/mock_ObjectUsageUpdater.go new file mode 100644 index 0000000000..a82b4862dc --- /dev/null +++ b/core/block/editor/lastused/mock_lastused/mock_ObjectUsageUpdater.go @@ -0,0 +1,258 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_lastused + +import ( + context "context" + + app "github.com/anyproto/any-sync/app" + + lastused "github.com/anyproto/anytype-heart/core/block/editor/lastused" + + mock "github.com/stretchr/testify/mock" +) + +// MockObjectUsageUpdater is an autogenerated mock type for the ObjectUsageUpdater type +type MockObjectUsageUpdater struct { + mock.Mock +} + +type MockObjectUsageUpdater_Expecter struct { + mock *mock.Mock +} + +func (_m *MockObjectUsageUpdater) EXPECT() *MockObjectUsageUpdater_Expecter { + return &MockObjectUsageUpdater_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: ctx +func (_m *MockObjectUsageUpdater) Close(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockObjectUsageUpdater_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockObjectUsageUpdater_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockObjectUsageUpdater_Expecter) Close(ctx interface{}) *MockObjectUsageUpdater_Close_Call { + return &MockObjectUsageUpdater_Close_Call{Call: _e.mock.On("Close", ctx)} +} + +func (_c *MockObjectUsageUpdater_Close_Call) Run(run func(ctx context.Context)) *MockObjectUsageUpdater_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockObjectUsageUpdater_Close_Call) Return(err error) *MockObjectUsageUpdater_Close_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockObjectUsageUpdater_Close_Call) RunAndReturn(run func(context.Context) error) *MockObjectUsageUpdater_Close_Call { + _c.Call.Return(run) + return _c +} + +// Init provides a mock function with given fields: a +func (_m *MockObjectUsageUpdater) Init(a *app.App) error { + ret := _m.Called(a) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*app.App) error); ok { + r0 = rf(a) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockObjectUsageUpdater_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' +type MockObjectUsageUpdater_Init_Call struct { + *mock.Call +} + +// Init is a helper method to define mock.On call +// - a *app.App +func (_e *MockObjectUsageUpdater_Expecter) Init(a interface{}) *MockObjectUsageUpdater_Init_Call { + return &MockObjectUsageUpdater_Init_Call{Call: _e.mock.On("Init", a)} +} + +func (_c *MockObjectUsageUpdater_Init_Call) Run(run func(a *app.App)) *MockObjectUsageUpdater_Init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*app.App)) + }) + return _c +} + +func (_c *MockObjectUsageUpdater_Init_Call) Return(err error) *MockObjectUsageUpdater_Init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockObjectUsageUpdater_Init_Call) RunAndReturn(run func(*app.App) error) *MockObjectUsageUpdater_Init_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: +func (_m *MockObjectUsageUpdater) Name() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockObjectUsageUpdater_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockObjectUsageUpdater_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockObjectUsageUpdater_Expecter) Name() *MockObjectUsageUpdater_Name_Call { + return &MockObjectUsageUpdater_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockObjectUsageUpdater_Name_Call) Run(run func()) *MockObjectUsageUpdater_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockObjectUsageUpdater_Name_Call) Return(name string) *MockObjectUsageUpdater_Name_Call { + _c.Call.Return(name) + return _c +} + +func (_c *MockObjectUsageUpdater_Name_Call) RunAndReturn(run func() string) *MockObjectUsageUpdater_Name_Call { + _c.Call.Return(run) + return _c +} + +// Run provides a mock function with given fields: ctx +func (_m *MockObjectUsageUpdater) Run(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Run") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockObjectUsageUpdater_Run_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Run' +type MockObjectUsageUpdater_Run_Call struct { + *mock.Call +} + +// Run is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockObjectUsageUpdater_Expecter) Run(ctx interface{}) *MockObjectUsageUpdater_Run_Call { + return &MockObjectUsageUpdater_Run_Call{Call: _e.mock.On("Run", ctx)} +} + +func (_c *MockObjectUsageUpdater_Run_Call) Run(run func(ctx context.Context)) *MockObjectUsageUpdater_Run_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockObjectUsageUpdater_Run_Call) Return(err error) *MockObjectUsageUpdater_Run_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockObjectUsageUpdater_Run_Call) RunAndReturn(run func(context.Context) error) *MockObjectUsageUpdater_Run_Call { + _c.Call.Return(run) + return _c +} + +// UpdateLastUsedDate provides a mock function with given fields: spaceId, key, timeStamp +func (_m *MockObjectUsageUpdater) UpdateLastUsedDate(spaceId string, key lastused.Key, timeStamp int64) { + _m.Called(spaceId, key, timeStamp) +} + +// MockObjectUsageUpdater_UpdateLastUsedDate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateLastUsedDate' +type MockObjectUsageUpdater_UpdateLastUsedDate_Call struct { + *mock.Call +} + +// UpdateLastUsedDate is a helper method to define mock.On call +// - spaceId string +// - key lastused.Key +// - timeStamp int64 +func (_e *MockObjectUsageUpdater_Expecter) UpdateLastUsedDate(spaceId interface{}, key interface{}, timeStamp interface{}) *MockObjectUsageUpdater_UpdateLastUsedDate_Call { + return &MockObjectUsageUpdater_UpdateLastUsedDate_Call{Call: _e.mock.On("UpdateLastUsedDate", spaceId, key, timeStamp)} +} + +func (_c *MockObjectUsageUpdater_UpdateLastUsedDate_Call) Run(run func(spaceId string, key lastused.Key, timeStamp int64)) *MockObjectUsageUpdater_UpdateLastUsedDate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(lastused.Key), args[2].(int64)) + }) + return _c +} + +func (_c *MockObjectUsageUpdater_UpdateLastUsedDate_Call) Return() *MockObjectUsageUpdater_UpdateLastUsedDate_Call { + _c.Call.Return() + return _c +} + +func (_c *MockObjectUsageUpdater_UpdateLastUsedDate_Call) RunAndReturn(run func(string, lastused.Key, int64)) *MockObjectUsageUpdater_UpdateLastUsedDate_Call { + _c.Call.Return(run) + return _c +} + +// NewMockObjectUsageUpdater creates a new instance of MockObjectUsageUpdater. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockObjectUsageUpdater(t interface { + mock.TestingT + Cleanup(func()) +}) *MockObjectUsageUpdater { + mock := &MockObjectUsageUpdater{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/block/editor/page.go b/core/block/editor/page.go index 2542e92e81..e7290495bc 100644 --- a/core/block/editor/page.go +++ b/core/block/editor/page.go @@ -18,7 +18,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/bundle" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -48,21 +48,22 @@ type Page struct { dataview.Dataview table.TableEditor - objectStore objectstore.ObjectStore + objectStore spaceindex.Store fileObjectService fileobject.Service objectDeleter ObjectDeleter } -func (f *ObjectFactory) newPage(sb smartblock.SmartBlock) *Page { +func (f *ObjectFactory) newPage(spaceId string, sb smartblock.SmartBlock) *Page { + store := f.objectStore.SpaceIndex(spaceId) fileComponent := file.NewFile(sb, f.fileBlockService, f.picker, f.processService, f.fileUploaderService) return &Page{ SmartBlock: sb, ChangeReceiver: sb.(source.ChangeReceiver), - AllOperations: basic.NewBasic(sb, f.objectStore, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater), + AllOperations: basic.NewBasic(sb, store, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater), IHistory: basic.NewHistory(sb), Text: stext.NewText( sb, - f.objectStore, + store, f.eventSender, ), File: fileComponent, @@ -70,14 +71,14 @@ func (f *ObjectFactory) newPage(sb smartblock.SmartBlock) *Page { sb, fileComponent, f.tempDirProvider, - f.objectStore, + store, f.fileService, f.fileObjectService, ), Bookmark: bookmark.NewBookmark(sb, f.bookmarkService), - Dataview: dataview.NewDataview(sb, f.objectStore), + Dataview: dataview.NewDataview(sb, store), TableEditor: table.NewEditor(sb), - objectStore: f.objectStore, + objectStore: store, fileObjectService: f.fileObjectService, objectDeleter: f.objectDeleter, } @@ -115,7 +116,7 @@ func (p *Page) isRelationDeleted(ctx *smartblock.InitContext) bool { } func (p *Page) deleteRelationOptions(spaceID string, relationKey string) error { - relationOptions, _, err := p.objectStore.QueryObjectIDs(database.Query{ + relationOptions, _, err := p.objectStore.QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyRelationKey.String(), @@ -155,7 +156,7 @@ func (p *Page) CreationStateMigration(ctx *smartblock.InitContext) migration.Mig if err != nil { log.Errorf("failed to create unique key: %v", err) } else { - otype, err := p.objectStore.GetObjectByUniqueKey(p.SpaceID(), uk) + otype, err := p.objectStore.GetObjectByUniqueKey(uk) if err != nil { log.Errorf("failed to get object by unique key: %v", err) } else { @@ -209,6 +210,16 @@ func (p *Page) CreationStateMigration(ctx *smartblock.InitContext) migration.Mig template.WithTitle, template.WithAddedFeaturedRelation(bundle.RelationKeyType), ) + case model.ObjectType_chat: + templates = append(templates, + template.WithTitle, + template.WithBlockChat, + ) + case model.ObjectType_chatDerived: + templates = append(templates, + template.WithTitle, + template.WithBlockChat, + ) // TODO case for relationOption? case model.ObjectType_tag: templates = append(templates, diff --git a/core/block/editor/participant.go b/core/block/editor/participant.go index 2000763758..f4b03160cf 100644 --- a/core/block/editor/participant.go +++ b/core/block/editor/participant.go @@ -10,7 +10,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/template" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spaceinfo" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -29,15 +29,15 @@ var participantRequiredRelations = []domain.RelationKey{ type participant struct { smartblock.SmartBlock basic.DetailsUpdatable - objectStore objectstore.ObjectStore + objectStore spaceindex.Store } -func (f *ObjectFactory) newParticipant(sb smartblock.SmartBlock) *participant { - basicComponent := basic.NewBasic(sb, f.objectStore, f.layoutConverter, nil, f.lastUsedUpdater) +func (f *ObjectFactory) newParticipant(spaceId string, sb smartblock.SmartBlock, spaceIndex spaceindex.Store) *participant { + basicComponent := basic.NewBasic(sb, spaceIndex, f.layoutConverter, nil, f.lastUsedUpdater) return &participant{ SmartBlock: sb, DetailsUpdatable: basicComponent, - objectStore: f.objectStore, + objectStore: spaceIndex, } } @@ -64,7 +64,7 @@ func (p *participant) Init(ctx *smartblock.InitContext) (err error) { template.WithAddedFeaturedRelation(bundle.RelationKeyBacklinks), ) - records, err := p.objectStore.QueryByID([]string{p.Id()}) + records, err := p.objectStore.QueryByIds([]string{p.Id()}) if err != nil { return err } diff --git a/core/block/editor/participant_test.go b/core/block/editor/participant_test.go index 601b6fd773..bcd88a02ec 100644 --- a/core/block/editor/participant_test.go +++ b/core/block/editor/participant_test.go @@ -12,6 +12,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spaceinfo" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -110,8 +111,8 @@ func TestParticipant_ModifyIdentityDetails(t *testing.T) { } } -func newStoreFixture(t *testing.T) *objectstore.StoreFixture { - store := objectstore.NewStoreFixture(t) +func newStoreFixture(t *testing.T) *spaceindex.StoreFixture { + store := spaceindex.NewStoreFixture(t) for _, rel := range []domain.RelationKey{ bundle.RelationKeyFeaturedRelations, bundle.RelationKeyIdentity, bundle.RelationKeyName, @@ -122,7 +123,7 @@ func newStoreFixture(t *testing.T) *objectstore.StoreFixture { bundle.RelationKeySpaceId, bundle.RelationKeyParticipantStatus, bundle.RelationKeyIsHiddenDiscovery, } { store.AddObjects(t, []objectstore.TestObject{{ - bundle.RelationKeySpaceId: pbtypes.String(""), + bundle.RelationKeySpaceId: pbtypes.String("space1"), bundle.RelationKeyUniqueKey: pbtypes.String(rel.URL()), bundle.RelationKeyId: pbtypes.String(rel.String()), bundle.RelationKeyRelationKey: pbtypes.String(rel.String()), diff --git a/core/block/editor/profile.go b/core/block/editor/profile.go index e3c447a0a4..10c6373ec1 100644 --- a/core/block/editor/profile.go +++ b/core/block/editor/profile.go @@ -36,15 +36,16 @@ type Profile struct { fileObjectService fileobject.Service } -func (f *ObjectFactory) newProfile(sb smartblock.SmartBlock) *Profile { +func (f *ObjectFactory) newProfile(spaceId string, sb smartblock.SmartBlock) *Profile { + store := f.objectStore.SpaceIndex(spaceId) fileComponent := file.NewFile(sb, f.fileBlockService, f.picker, f.processService, f.fileUploaderService) return &Profile{ SmartBlock: sb, - AllOperations: basic.NewBasic(sb, f.objectStore, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater), + AllOperations: basic.NewBasic(sb, store, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater), IHistory: basic.NewHistory(sb), Text: stext.NewText( sb, - f.objectStore, + store, f.eventSender, ), File: fileComponent, @@ -52,7 +53,7 @@ func (f *ObjectFactory) newProfile(sb smartblock.SmartBlock) *Profile { sb, fileComponent, f.tempDirProvider, - f.objectStore, + store, f.fileService, f.fileObjectService, ), diff --git a/core/block/editor/smartblock/dependencies_test.go b/core/block/editor/smartblock/dependencies_test.go new file mode 100644 index 0000000000..61fbad396f --- /dev/null +++ b/core/block/editor/smartblock/dependencies_test.go @@ -0,0 +1,184 @@ +package smartblock + +import ( + "testing" + + "github.com/gogo/protobuf/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + bb "github.com/anyproto/anytype-heart/tests/blockbuilder" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +func TestDependenciesSubscription(t *testing.T) { + t.Run("with existing dependencies", func(t *testing.T) { + mainObjId := "id" + fx := newFixture(mainObjId, t) + + space1obj1 := "obj1" + space1obj2 := "obj2" + space2obj1 := "obj3" + + fx.objectStore.AddObjects(t, testSpaceId, []objectstore.TestObject{ + { + bundle.RelationKeyId: pbtypes.String(space1obj1), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), + bundle.RelationKeyName: pbtypes.String("Object 1"), + }, + { + bundle.RelationKeyId: pbtypes.String(space1obj2), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), + bundle.RelationKeyName: pbtypes.String("Object 2"), + }, + }) + fx.objectStore.AddObjects(t, "space2", []objectstore.TestObject{ + { + bundle.RelationKeyId: pbtypes.String(space2obj1), + bundle.RelationKeySpaceId: pbtypes.String("space2"), + bundle.RelationKeyName: pbtypes.String("Object 3"), + }, + }) + + fx.spaceIdResolver.EXPECT().ResolveSpaceID(space1obj1).Return(testSpaceId, nil) + fx.spaceIdResolver.EXPECT().ResolveSpaceID(space1obj2).Return(testSpaceId, nil) + fx.spaceIdResolver.EXPECT().ResolveSpaceID(space2obj1).Return("space2", nil) + + root := bb.Root( + bb.ID(mainObjId), + bb.Children( + bb.Link(space1obj1), + bb.Link(space1obj2), + bb.Link(space2obj1), + ), + ) + + fx.Doc = state.NewDoc(mainObjId, root.BuildMap()).NewState() + objDetails := &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String(mainObjId), + bundle.RelationKeySpaceId.String(): pbtypes.String(testSpaceId), + bundle.RelationKeyName.String(): pbtypes.String("Main object"), + }, + } + + fx.Doc.(*state.State).SetDetails(objDetails) + + details, err := fx.fetchMeta() + require.NoError(t, err) + require.NotEmpty(t, details) + + wantDetails := []*model.ObjectViewDetailsSet{ + { + Id: mainObjId, + Details: &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String(mainObjId), + bundle.RelationKeySpaceId.String(): pbtypes.String(testSpaceId), + bundle.RelationKeyName.String(): pbtypes.String("Main object"), + }, + }, + }, + { + Id: space1obj1, + Details: &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String(space1obj1), + bundle.RelationKeySpaceId.String(): pbtypes.String(testSpaceId), + bundle.RelationKeyName.String(): pbtypes.String("Object 1"), + }, + }, + }, + { + Id: space1obj2, + Details: &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String(space1obj2), + bundle.RelationKeySpaceId.String(): pbtypes.String(testSpaceId), + bundle.RelationKeyName.String(): pbtypes.String("Object 2"), + }, + }, + }, + { + Id: space2obj1, + Details: &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String(space2obj1), + bundle.RelationKeySpaceId.String(): pbtypes.String("space2"), + bundle.RelationKeyName.String(): pbtypes.String("Object 3"), + }, + }, + }, + } + + assert.ElementsMatch(t, wantDetails, details) + + fx.closeRecordsSub() + }) + + t.Run("with added dependencies", func(t *testing.T) { + mainObjId := "id" + fx := newFixture(mainObjId, t) + + root := bb.Root( + bb.ID(mainObjId), + bb.Children(), + ) + fx.Doc = state.NewDoc(mainObjId, root.BuildMap()).NewState() + + details, err := fx.fetchMeta() + require.NoError(t, err) + require.Len(t, details, 1) // Only its own details + + // Simulate changes in state + + space1obj1 := "obj1" + space1obj2 := "obj2" + space2obj1 := "obj3" + + fx.objectStore.AddObjects(t, testSpaceId, []objectstore.TestObject{ + { + bundle.RelationKeyId: pbtypes.String(space1obj1), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), + bundle.RelationKeyName: pbtypes.String("Object 1"), + }, + { + bundle.RelationKeyId: pbtypes.String(space1obj2), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), + bundle.RelationKeyName: pbtypes.String("Object 2"), + }, + }) + fx.objectStore.AddObjects(t, "space2", []objectstore.TestObject{ + { + bundle.RelationKeyId: pbtypes.String(space2obj1), + bundle.RelationKeySpaceId: pbtypes.String("space2"), + bundle.RelationKeyName: pbtypes.String("Object 3"), + }, + }) + + fx.spaceIdResolver.EXPECT().ResolveSpaceID(space1obj1).Return(testSpaceId, nil) + fx.spaceIdResolver.EXPECT().ResolveSpaceID(space1obj2).Return(testSpaceId, nil) + fx.spaceIdResolver.EXPECT().ResolveSpaceID(space2obj1).Return("space2", nil) + + root = bb.Root( + bb.ID(mainObjId), + bb.Children( + bb.Link(space1obj1), + bb.Link(space1obj2), + bb.Link(space2obj1), + ), + ) + fx.Doc = state.NewDoc(mainObjId, root.BuildMap()).NewState() + + fx.CheckSubscriptions() + + assert.Contains(t, fx.smartBlock.lastDepDetails, space1obj1) + assert.Contains(t, fx.smartBlock.lastDepDetails, space1obj2) + assert.Contains(t, fx.smartBlock.lastDepDetails, space2obj1) + }) + +} diff --git a/core/block/editor/smartblock/links.go b/core/block/editor/smartblock/links.go index 315ed3493e..11a0cd5fa7 100644 --- a/core/block/editor/smartblock/links.go +++ b/core/block/editor/smartblock/links.go @@ -13,7 +13,7 @@ import ( ) func (sb *smartBlock) updateBackLinks(s *state.State) { - backLinks, err := sb.objectStore.GetInboundLinksByID(sb.Id()) + backLinks, err := sb.spaceIndex.GetInboundLinksById(sb.Id()) if err != nil { log.With("objectID", sb.Id()).Errorf("failed to get inbound links from object store: %s", err) return diff --git a/core/block/editor/smartblock/mock_Indexer.go b/core/block/editor/smartblock/mock_Indexer.go index b9086362e2..fd4a8d7af1 100644 --- a/core/block/editor/smartblock/mock_Indexer.go +++ b/core/block/editor/smartblock/mock_Indexer.go @@ -69,14 +69,14 @@ func (_c *MockIndexer_Close_Call) RunAndReturn(run func(context.Context) error) return _c } -// Index provides a mock function with given fields: ctx, info, options -func (_m *MockIndexer) Index(ctx context.Context, info DocInfo, options ...IndexOption) error { +// Index provides a mock function with given fields: info, options +func (_m *MockIndexer) Index(info DocInfo, options ...IndexOption) error { _va := make([]interface{}, len(options)) for _i := range options { _va[_i] = options[_i] } var _ca []interface{} - _ca = append(_ca, ctx, info) + _ca = append(_ca, info) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -85,8 +85,8 @@ func (_m *MockIndexer) Index(ctx context.Context, info DocInfo, options ...Index } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, DocInfo, ...IndexOption) error); ok { - r0 = rf(ctx, info, options...) + if rf, ok := ret.Get(0).(func(DocInfo, ...IndexOption) error); ok { + r0 = rf(info, options...) } else { r0 = ret.Error(0) } @@ -100,23 +100,22 @@ type MockIndexer_Index_Call struct { } // Index is a helper method to define mock.On call -// - ctx context.Context // - info DocInfo // - options ...IndexOption -func (_e *MockIndexer_Expecter) Index(ctx interface{}, info interface{}, options ...interface{}) *MockIndexer_Index_Call { +func (_e *MockIndexer_Expecter) Index(info interface{}, options ...interface{}) *MockIndexer_Index_Call { return &MockIndexer_Index_Call{Call: _e.mock.On("Index", - append([]interface{}{ctx, info}, options...)...)} + append([]interface{}{info}, options...)...)} } -func (_c *MockIndexer_Index_Call) Run(run func(ctx context.Context, info DocInfo, options ...IndexOption)) *MockIndexer_Index_Call { +func (_c *MockIndexer_Index_Call) Run(run func(info DocInfo, options ...IndexOption)) *MockIndexer_Index_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]IndexOption, len(args)-2) - for i, a := range args[2:] { + variadicArgs := make([]IndexOption, len(args)-1) + for i, a := range args[1:] { if a != nil { variadicArgs[i] = a.(IndexOption) } } - run(args[0].(context.Context), args[1].(DocInfo), variadicArgs...) + run(args[0].(DocInfo), variadicArgs...) }) return _c } @@ -126,7 +125,7 @@ func (_c *MockIndexer_Index_Call) Return(_a0 error) *MockIndexer_Index_Call { return _c } -func (_c *MockIndexer_Index_Call) RunAndReturn(run func(context.Context, DocInfo, ...IndexOption) error) *MockIndexer_Index_Call { +func (_c *MockIndexer_Index_Call) RunAndReturn(run func(DocInfo, ...IndexOption) error) *MockIndexer_Index_Call { _c.Call.Return(run) return _c } diff --git a/core/block/editor/smartblock/smartblock.go b/core/block/editor/smartblock/smartblock.go index 2cb436670c..20cab00ba8 100644 --- a/core/block/editor/smartblock/smartblock.go +++ b/core/block/editor/smartblock/smartblock.go @@ -20,6 +20,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/state" "github.com/anyproto/anytype-heart/core/block/editor/template" + "github.com/anyproto/anytype-heart/core/block/object/idresolver" "github.com/anyproto/anytype-heart/core/block/object/objectlink" "github.com/anyproto/anytype-heart/core/block/restriction" "github.com/anyproto/anytype-heart/core/block/simple" @@ -37,9 +38,11 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/pkg/lib/threads" + "github.com/anyproto/anytype-heart/space/spacecore/storage/sqlitestorage" "github.com/anyproto/anytype-heart/util/anonymize" "github.com/anyproto/anytype-heart/util/internalflag" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -61,7 +64,8 @@ const ( DoSnapshot SkipIfNoChanges KeepInternalFlags - IgnoreNoPermissions // Used only for read-only actions like InitObject or OpenObject + IgnoreNoPermissions + NotPushChanges // Used only for read-only actions like InitObject or OpenObject ) type Hook int @@ -94,9 +98,11 @@ func New( currentParticipantId string, fileStore filestore.FileStore, restrictionService restriction.Service, + spaceIndex spaceindex.Store, objectStore objectstore.ObjectStore, indexer Indexer, eventSender event.Sender, + spaceIdResolver idresolver.Resolver, ) SmartBlock { s := &smartBlock{ currentParticipantId: currentParticipantId, @@ -108,9 +114,12 @@ func New( fileStore: fileStore, restrictionService: restrictionService, - objectStore: objectStore, + spaceIndex: spaceIndex, indexer: indexer, eventSender: eventSender, + objectStore: objectStore, + spaceIdResolver: spaceIdResolver, + lastDepDetails: map[string]*pb.EventObjectDetailsSet{}, } return s } @@ -212,7 +221,7 @@ type Locker interface { } type Indexer interface { - Index(ctx context.Context, info DocInfo, options ...IndexOption) error + Index(info DocInfo, options ...IndexOption) error app.ComponentRunnable } @@ -243,9 +252,11 @@ type smartBlock struct { // Deps fileStore filestore.FileStore restrictionService restriction.Service + spaceIndex spaceindex.Store objectStore objectstore.ObjectStore indexer Indexer eventSender event.Sender + spaceIdResolver idresolver.Resolver } func (sb *smartBlock) SetLocker(locker Locker) { @@ -297,10 +308,6 @@ func (sb *smartBlock) GetAndUnsetFileKeys() (keys []pb.ChangeFileKeys) { return } -func (sb *smartBlock) ObjectStore() objectstore.ObjectStore { - return sb.objectStore -} - func (sb *smartBlock) Type() smartblock.SmartBlockType { return sb.source.Type() } @@ -321,7 +328,6 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) { } sb.undo = undo.NewHistory(0) sb.restrictions = sb.restrictionService.GetRestrictions(sb) - sb.lastDepDetails = map[string]*pb.EventObjectDetailsSet{} if ctx.State != nil { // need to store file keys in case we have some new files in the state sb.storeFileKeys(ctx.State) @@ -357,7 +363,7 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) { } ctx.State.AddBundledRelationLinks(relKeys...) if ctx.IsNewObject && ctx.State != nil { - source.NewSubObjectsAndProfileLinksMigration(sb.Type(), sb.space, sb.currentParticipantId, sb.objectStore).Migrate(ctx.State) + source.NewSubObjectsAndProfileLinksMigration(sb.Type(), sb.space, sb.currentParticipantId, sb.spaceIndex).Migrate(ctx.State) } if err = sb.injectLocalDetails(ctx.State); err != nil { @@ -449,19 +455,42 @@ func (sb *smartBlock) fetchMeta() (details []*model.ObjectViewDetailsSet, err er sb.closeRecordsSub() sb.closeRecordsSub = nil } + + depIds := sb.dependentSmartIds(sb.includeRelationObjectsAsDependents, true, true) + sb.setDependentIDs(depIds) + + perSpace, err := sb.partitionIdsBySpace(sb.depIds) + if err != nil { + return nil, fmt.Errorf("partiton by space: %w", err) + } + recordsCh := make(chan *types.Struct, 10) sb.recordsSub = database.NewSubscription(nil, recordsCh) - depIDs := sb.dependentSmartIds(sb.includeRelationObjectsAsDependents, true, true) - sb.setDependentIDs(depIDs) - var records []database.Record - records, sb.closeRecordsSub, err = sb.objectStore.QueryByIDAndSubscribeForChanges(sb.depIds, sb.recordsSub) - if err != nil { - // datastore unavailable, cancel the subscription - sb.recordsSub.Close() - sb.closeRecordsSub = nil - return + closers := make([]func(), 0, len(perSpace)) + + for spaceId, perSpaceDepIds := range perSpace { + spaceIndex := sb.objectStore.SpaceIndex(spaceId) + + recs, closeRecordsSub, err := spaceIndex.QueryByIdsAndSubscribeForChanges(perSpaceDepIds, sb.recordsSub) + if err != nil { + for _, closer := range closers { + closer() + } + // datastore unavailable, cancel the subscription + sb.recordsSub.Close() + sb.closeRecordsSub = nil + return nil, fmt.Errorf("subscribe: %w", err) + } + + closers = append(closers, closeRecordsSub) + records = append(records, recs...) + } + sb.closeRecordsSub = func() { + for _, closer := range closers { + closer() + } } details = make([]*model.ObjectViewDetailsSet, 0, len(records)+1) @@ -482,10 +511,30 @@ func (sb *smartBlock) fetchMeta() (details []*model.ObjectViewDetailsSet, err er return } +func (sb *smartBlock) partitionIdsBySpace(ids []string) (map[string][]string, error) { + perSpace := map[string][]string{} + for _, id := range ids { + spaceId, err := sb.spaceIdResolver.ResolveSpaceID(id) + if errors.Is(err, sqlitestorage.ErrObjectNotFound) { + perSpace[sb.space.Id()] = append(perSpace[sb.space.Id()], id) + continue + } + if err != nil { + return nil, fmt.Errorf("resolve space id: %w", err) + } + perSpace[spaceId] = append(perSpace[spaceId], id) + } + return perSpace, nil +} + func (sb *smartBlock) Lock() { sb.Locker.Lock() } +func (sb *smartBlock) TryLock() bool { + return sb.Locker.TryLock() +} + func (sb *smartBlock) Unlock() { sb.Locker.Unlock() } @@ -588,6 +637,7 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { skipIfNoChanges = false keepInternalFlags = false ignoreNoPermissions = false + notPushChanges = false ) for _, f := range flags { switch f { @@ -607,6 +657,8 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { keepInternalFlags = true case IgnoreNoPermissions: ignoreNoPermissions = true + case NotPushChanges: + notPushChanges = true } } @@ -676,6 +728,9 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { return nil } pushChange := func() error { + if notPushChanges { + return nil + } if !sb.source.ReadOnly() { // We can set details directly in object's state, they'll be indexed correctly st.SetLocalDetail(bundle.RelationKeyLastModifiedBy.String(), pbtypes.String(sb.currentParticipantId)) @@ -779,7 +834,7 @@ func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) { } func (sb *smartBlock) ResetToVersion(s *state.State) (err error) { - source.NewSubObjectsAndProfileLinksMigration(sb.Type(), sb.space, sb.currentParticipantId, sb.objectStore).Migrate(s) + source.NewSubObjectsAndProfileLinksMigration(sb.Type(), sb.space, sb.currentParticipantId, sb.spaceIndex).Migrate(s) s.SetParent(sb.Doc.(*state.State)) sb.storeFileKeys(s) sb.injectLocalDetails(s) @@ -800,13 +855,23 @@ func (sb *smartBlock) CheckSubscriptions() (changed bool) { return true } newIDs := sb.recordsSub.Subscribe(sb.depIds) - records, err := sb.objectStore.QueryByID(newIDs) + + perSpace, err := sb.partitionIdsBySpace(newIDs) if err != nil { - log.Errorf("queryById error: %v", err) + log.Errorf("partiton by space error: %v", err) } - for _, rec := range records { - sb.onMetaChange(rec.Details) + + for spaceId, ids := range perSpace { + spaceIndex := sb.objectStore.SpaceIndex(spaceId) + records, err := spaceIndex.QueryByIds(ids) + if err != nil { + log.Errorf("queryById error: %v", err) + } + for _, rec := range records { + sb.onMetaChange(rec.Details) + } } + return true } @@ -854,7 +919,7 @@ func (sb *smartBlock) AddRelationLinksToState(s *state.State, relationKeys ...st } // todo: filter-out existing relation links? // in the most cases it should save as an objectstore query - relations, err := sb.objectStore.FetchRelationByKeys(sb.SpaceID(), relationKeys...) + relations, err := sb.spaceIndex.FetchRelationByKeys(relationKeys...) if err != nil { return } @@ -894,7 +959,7 @@ func (sb *smartBlock) injectLocalDetails(s *state.State) error { } func (sb *smartBlock) getDetailsFromStore() (*types.Struct, error) { - storedDetails, err := sb.objectStore.GetDetails(sb.Id()) + storedDetails, err := sb.spaceIndex.GetDetails(sb.Id()) if err != nil || storedDetails == nil { return nil, err } @@ -903,7 +968,7 @@ func (sb *smartBlock) getDetailsFromStore() (*types.Struct, error) { func (sb *smartBlock) appendPendingDetails(details *types.Struct) (resultDetails *types.Struct, hasPendingLocalDetails bool) { // Consume pending details - err := sb.objectStore.UpdatePendingLocalDetails(sb.Id(), func(pending *types.Struct) (*types.Struct, error) { + err := sb.spaceIndex.UpdatePendingLocalDetails(sb.Id(), func(pending *types.Struct) (*types.Struct, error) { if len(pending.GetFields()) > 0 { hasPendingLocalDetails = true } @@ -1230,7 +1295,7 @@ func (sb *smartBlock) Relations(s *state.State) relationutils.Relations { } else { links = s.GetRelationLinks() } - rels, _ := sb.objectStore.FetchRelationByLinks(sb.SpaceID(), links) + rels, _ := sb.spaceIndex.FetchRelationByLinks(links) return rels } @@ -1288,7 +1353,7 @@ func (sb *smartBlock) getDocInfo(st *state.State) DocInfo { func (sb *smartBlock) runIndexer(s *state.State, opts ...IndexOption) { docInfo := sb.getDocInfo(s) - if err := sb.indexer.Index(context.Background(), docInfo, opts...); err != nil { + if err := sb.indexer.Index(docInfo, opts...); err != nil { log.Errorf("index object %s error: %s", sb.Id(), err) } } @@ -1437,6 +1502,11 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s } } + err := sb.deriveChatId(s) + if err != nil { + log.With("objectId", sb.Id()).Errorf("can't derive chat id: %v", err) + } + sb.setRestrictionsDetail(s) snippet := s.Snippet() @@ -1458,4 +1528,21 @@ func (sb *smartBlock) injectDerivedDetails(s *state.State, spaceID string, sbt s sb.updateBackLinks(s) } +func (sb *smartBlock) deriveChatId(s *state.State) error { + hasChat := pbtypes.GetBool(s.Details(), bundle.RelationKeyHasChat.String()) + if hasChat { + chatUk, err := domain.NewUniqueKey(smartblock.SmartBlockTypeChatDerivedObject, sb.Id()) + if err != nil { + return err + } + + chatId, err := sb.space.DeriveObjectID(context.Background(), chatUk) + if err != nil { + return err + } + s.SetDetailAndBundledRelation(bundle.RelationKeyChatId, pbtypes.String(chatId)) + } + return nil +} + type InitFunc = func(id string) *InitContext diff --git a/core/block/editor/smartblock/smartblock_test.go b/core/block/editor/smartblock/smartblock_test.go index 634879a59d..4afcd97c93 100644 --- a/core/block/editor/smartblock/smartblock_test.go +++ b/core/block/editor/smartblock/smartblock_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver" "github.com/anyproto/anytype-heart/core/block/restriction" "github.com/anyproto/anytype-heart/core/block/restriction/mock_restriction" "github.com/anyproto/anytype-heart/core/block/simple" @@ -25,7 +26,8 @@ import ( "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/internalflag" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -36,12 +38,6 @@ func TestSmartBlock_Init(t *testing.T) { id := "one" fx := newFixture(id, t) - fx.store.EXPECT().GetDetails(mock.Anything).Return(&model.ObjectDetails{ - Details: &types.Struct{Fields: map[string]*types.Value{}}, - }, nil).Maybe() - fx.store.EXPECT().GetInboundLinksByID(mock.Anything).Return(nil, nil).Maybe() - fx.store.EXPECT().UpdatePendingLocalDetails(mock.Anything, mock.Anything).Return(nil).Maybe() - // when initCtx := fx.init(t, []*model.Block{{Id: id}}) @@ -60,11 +56,6 @@ func TestSmartBlock_Apply(t *testing.T) { // given fx := newFixture("", t) - fx.store.EXPECT().GetDetails(mock.Anything).Maybe().Return(&model.ObjectDetails{ - Details: &types.Struct{Fields: map[string]*types.Value{}}, - }, nil) - fx.store.EXPECT().GetInboundLinksByID(mock.Anything).Return(nil, nil).Maybe() - fx.store.EXPECT().UpdatePendingLocalDetails(mock.Anything, mock.Anything).Return(nil).Maybe() fx.restrictionService.EXPECT().GetRestrictions(mock.Anything).Return(restriction.Restrictions{}) fx.init(t, []*model.Block{{Id: "1"}}) @@ -95,11 +86,6 @@ func TestBasic_SetAlign(t *testing.T) { // given fx := newFixture("", t) - fx.store.EXPECT().GetDetails(mock.Anything).Maybe().Return(&model.ObjectDetails{ - Details: &types.Struct{Fields: map[string]*types.Value{}}, - }, nil) - fx.store.EXPECT().GetInboundLinksByID(mock.Anything).Return(nil, nil).Maybe() - fx.store.EXPECT().UpdatePendingLocalDetails(mock.Anything, mock.Anything).Return(nil).Maybe() fx.restrictionService.EXPECT().GetRestrictions(mock.Anything).Return(restriction.Restrictions{}) fx.init(t, []*model.Block{ {Id: "test", ChildrenIds: []string{"title", "2"}}, @@ -120,11 +106,6 @@ func TestBasic_SetAlign(t *testing.T) { // given fx := newFixture("", t) - fx.store.EXPECT().GetDetails(mock.Anything).Maybe().Return(&model.ObjectDetails{ - Details: &types.Struct{Fields: map[string]*types.Value{}}, - }, nil) - fx.store.EXPECT().GetInboundLinksByID(mock.Anything).Return(nil, nil).Maybe() - fx.store.EXPECT().UpdatePendingLocalDetails(mock.Anything, mock.Anything).Return(nil).Maybe() fx.restrictionService.EXPECT().GetRestrictions(mock.Anything).Return(restriction.Restrictions{}) fx.init(t, []*model.Block{ {Id: "test", ChildrenIds: []string{"title", "2"}}, @@ -152,12 +133,20 @@ func TestSmartBlock_getDetailsFromStore(t *testing.T) { details := &types.Struct{ Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), + "id": pbtypes.String(id), "number": pbtypes.Float64(2.18281828459045), "🔥": pbtypes.StringList([]string{"Jeanne d'Arc", "Giordano Bruno", "Capocchio"}), }, } - fx.store.EXPECT().GetDetails(id).Return(&model.ObjectDetails{Details: details}, nil) + + err := fx.store.UpdateObjectDetails(context.Background(), id, &types.Struct{ + Fields: map[string]*types.Value{ + "id": pbtypes.String(id), + "number": pbtypes.Float64(2.18281828459045), + "🔥": pbtypes.StringList([]string{"Jeanne d'Arc", "Giordano Bruno", "Capocchio"}), + }, + }) + require.NoError(t, err) // when detailsFromStore, err := fx.getDetailsFromStore() @@ -171,34 +160,12 @@ func TestSmartBlock_getDetailsFromStore(t *testing.T) { // given fx := newFixture(id, t) - fx.store.EXPECT().GetDetails(id).Return(nil, nil) - // when details, err := fx.getDetailsFromStore() // then assert.NoError(t, err) - assert.Nil(t, details) - }) - - t.Run("failure on retrieving details from store", func(t *testing.T) { - // given - fx := newFixture(id, t) - - details := &model.ObjectDetails{Details: &types.Struct{ - Fields: map[string]*types.Value{ - "someKey": pbtypes.String("someValue"), - }, - }} - someErr := errors.New("some error") - fx.store.EXPECT().GetDetails(id).Return(details, someErr) - - // when - detailsFromStore, err := fx.getDetailsFromStore() - - // then - assert.True(t, errors.Is(err, someErr)) - assert.Nil(t, detailsFromStore) + assert.NotNil(t, details) }) } @@ -211,7 +178,12 @@ func TestSmartBlock_injectBackLinks(t *testing.T) { newBackLinks := []string{"4", "5"} fx := newFixture(id, t) - fx.store.EXPECT().GetInboundLinksByID(id).Return(newBackLinks, nil) + ctx := context.Background() + err := fx.store.UpdateObjectLinks(ctx, "4", []string{id}) + require.NoError(t, err) + err = fx.store.UpdateObjectLinks(ctx, "5", []string{id}) + require.NoError(t, err) + st := state.NewDoc("", nil).NewState() st.SetDetailAndBundledRelation(bundle.RelationKeyBacklinks, pbtypes.StringList(backLinks)) @@ -226,7 +198,15 @@ func TestSmartBlock_injectBackLinks(t *testing.T) { // given fx := newFixture(id, t) - fx.store.EXPECT().GetInboundLinksByID(id).Return(backLinks, nil) + ctx := context.Background() + err := fx.store.UpdateObjectLinks(ctx, "1", []string{id}) + require.NoError(t, err) + err = fx.store.UpdateObjectLinks(ctx, "2", []string{id}) + require.NoError(t, err) + err = fx.store.UpdateObjectLinks(ctx, "3", []string{id}) + require.NoError(t, err) + + // fx.store.EXPECT().GetInboundLinksById(id).Return(backLinks, nil) st := state.NewDoc("", nil).NewState() // when @@ -242,21 +222,6 @@ func TestSmartBlock_injectBackLinks(t *testing.T) { // given fx := newFixture(id, t) - fx.store.EXPECT().GetInboundLinksByID(id).Return(nil, nil) - st := state.NewDoc("", nil).NewState() - - // when - fx.updateBackLinks(st) - - // then - assert.Len(t, pbtypes.GetStringList(st.CombinedDetails(), bundle.RelationKeyBacklinks.String()), 0) - }) - - t.Run("failure on retrieving back links from the store", func(t *testing.T) { - // given - fx := newFixture(id, t) - - fx.store.EXPECT().GetInboundLinksByID(id).Return(nil, errors.New("some error from store")) st := state.NewDoc("", nil).NewState() // when @@ -276,9 +241,6 @@ func TestSmartBlock_updatePendingDetails(t *testing.T) { var hasPendingDetails bool details := &types.Struct{Fields: map[string]*types.Value{}} - fx.store.EXPECT().UpdatePendingLocalDetails(id, mock.Anything). - Run(func(id string, f func(*types.Struct) (*types.Struct, error)) { hasPendingDetails = false }). - Return(nil) // when _, result := fx.appendPendingDetails(details) @@ -293,24 +255,30 @@ func TestSmartBlock_updatePendingDetails(t *testing.T) { fx := newFixture(id, t) details := &types.Struct{Fields: map[string]*types.Value{}} - fx.store.EXPECT().UpdatePendingLocalDetails(id, mock.Anything). - Run(func(id string, f func(details *types.Struct) (*types.Struct, error)) { - details.Fields[bundle.RelationKeyIsDeleted.String()] = pbtypes.Bool(false) - }). - Return(nil) + + err := fx.store.UpdatePendingLocalDetails(id, func(det *types.Struct) (*types.Struct, error) { + det.Fields[bundle.RelationKeyIsDeleted.String()] = pbtypes.Bool(false) + return det, nil + }) + require.NoError(t, err) // when got, _ := fx.appendPendingDetails(details) // then - assert.Len(t, got.Fields, 1) + want := &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String(id), + bundle.RelationKeyIsDeleted.String(): pbtypes.Bool(false), + }, + } + assert.Equal(t, want, got) }) t.Run("failure on retrieving pending details from the store", func(t *testing.T) { // given fx := newFixture(id, t) - fx.store.EXPECT().UpdatePendingLocalDetails(id, mock.Anything).Return(errors.New("some error from store")) details := &types.Struct{} // when @@ -451,12 +419,6 @@ func TestInjectLocalDetails(t *testing.T) { fx.source.creator = domain.NewParticipantId("testSpace", "testIdentity") fx.source.createdDate = time.Now().Unix() - fx.store.EXPECT().GetDetails(id).Return(&model.ObjectDetails{Details: &types.Struct{Fields: map[string]*types.Value{}}}, nil) - fx.store.EXPECT().UpdatePendingLocalDetails(id, mock.Anything).Run(func(id string, f func(details *types.Struct) (*types.Struct, error)) { - _, err := f(&types.Struct{Fields: map[string]*types.Value{}}) - require.NoError(t, err) - }).Return(nil) - st := state.NewDoc("id", nil).NewState() err := fx.injectLocalDetails(st) @@ -478,7 +440,6 @@ func TestInjectDerivedDetails(t *testing.T) { t.Run("links are updated on injection", func(t *testing.T) { // given fx := newFixture(id, t) - fx.store.EXPECT().GetInboundLinksByID(id).Return(nil, nil) st := state.NewDoc("id", map[string]simple.Block{ id: simple.New(&model.Block{Id: id, ChildrenIds: []string{"dataview", "link"}}), @@ -497,17 +458,24 @@ func TestInjectDerivedDetails(t *testing.T) { } type fixture struct { - store *mock_objectstore.MockObjectStore + objectStore *objectstore.StoreFixture + store spaceindex.Store restrictionService *mock_restriction.MockService indexer *MockIndexer eventSender *mock_event.MockSender source *sourceStub + spaceIdResolver *mock_idresolver.MockResolver *smartBlock } +const testSpaceId = "space1" + func newFixture(id string, t *testing.T) *fixture { - objectStore := mock_objectstore.NewMockObjectStore(t) + objectStore := objectstore.NewStoreFixture(t) + spaceIndex := objectStore.SpaceIndex(testSpaceId) + + spaceIdResolver := mock_idresolver.NewMockResolver(t) indexer := NewMockIndexer(t) @@ -516,20 +484,23 @@ func newFixture(id string, t *testing.T) *fixture { sender := mock_event.NewMockSender(t) - sb := New(nil, "", nil, restrictionService, objectStore, indexer, sender).(*smartBlock) + sb := New(nil, "", nil, restrictionService, spaceIndex, objectStore, indexer, sender, spaceIdResolver).(*smartBlock) source := &sourceStub{ id: id, spaceId: "space1", sbType: smartblock.SmartBlockTypePage, } sb.source = source + return &fixture{ source: source, smartBlock: sb, - store: objectStore, + store: spaceIndex, restrictionService: restrictionService, indexer: indexer, eventSender: sender, + spaceIdResolver: spaceIdResolver, + objectStore: objectStore, } } diff --git a/core/block/editor/smartblock/smarttest/smarttest.go b/core/block/editor/smartblock/smarttest/smarttest.go index d1caf97d6a..b67c2cd09b 100644 --- a/core/block/editor/smartblock/smarttest/smarttest.go +++ b/core/block/editor/smartblock/smarttest/smarttest.go @@ -22,11 +22,10 @@ import ( "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/pkg/lib/threads" "github.com/anyproto/anytype-heart/util/pbtypes" - "github.com/anyproto/anytype-heart/util/testMock" ) func New(id string) *SmartTest { @@ -62,7 +61,7 @@ type SmartTest struct { App *app.App objectTree objecttree.ObjectTree isDeleted bool - os *testMock.MockObjectStore + os *spaceindex.StoreFixture space smartblock.Space // Rudimentary hooks @@ -142,10 +141,6 @@ func (st *SmartTest) Locked() bool { return false } -func (st *SmartTest) ObjectStore() objectstore.ObjectStore { - return st.os -} - func (st *SmartTest) SetIsDeleted() { st.isDeleted = true } @@ -393,6 +388,16 @@ func (st *SmartTest) History() undo.History { return st.hist } +func (st *SmartTest) StateRebuild(d state.Doc) (err error) { + d.(*state.State).SetParent(st.Doc.(*state.State)) + _, _, err = state.ApplyState(d.(*state.State), false) + return err +} + +func (st *SmartTest) StateAppend(func(d state.Doc) (s *state.State, changes []*pb.ChangeContent, err error)) error { + panic("not implemented") +} + func (st *SmartTest) AddBlock(b simple.Block) *SmartTest { st.Doc.(*state.State).Add(b) return st @@ -418,10 +423,6 @@ func (st *SmartTest) TryClose(objectTTL time.Duration) (res bool, err error) { return } -func (st *SmartTest) SetObjectStore(os *testMock.MockObjectStore) { - st.os = os -} - func (st *SmartTest) Inner() smartblock.SmartBlock { return nil } diff --git a/core/block/editor/spaceview.go b/core/block/editor/spaceview.go index f7b95616d8..b5b26e8f51 100644 --- a/core/block/editor/spaceview.go +++ b/core/block/editor/spaceview.go @@ -44,6 +44,7 @@ var spaceViewRequiredRelations = []domain.RelationKey{ type spaceService interface { OnViewUpdated(info spaceinfo.SpacePersistentInfo) OnWorkspaceChanged(spaceId string, details *types.Struct) + PersonalSpaceId() string } // SpaceView is a wrapper around smartblock.SmartBlock that indicates the current space state @@ -140,6 +141,15 @@ func (s *SpaceView) SetSpaceLocalInfo(info spaceinfo.SpaceLocalInfo) (err error) return s.Apply(st) } +func (s *SpaceView) SetOwner(ownerId string, createdDate int64) (err error) { + st := s.NewState() + if createdDate != 0 { + st.SetDetailAndBundledRelation(bundle.RelationKeyCreatedDate, pbtypes.Int64(createdDate)) + } + st.SetDetailAndBundledRelation(bundle.RelationKeyCreator, pbtypes.String(ownerId)) + return s.Apply(st) +} + func (s *SpaceView) SetAclIsEmpty(isEmpty bool) (err error) { st := s.NewState() st.SetDetailAndBundledRelation(bundle.RelationKeyIsAclShared, pbtypes.Bool(!isEmpty)) @@ -242,7 +252,6 @@ var workspaceKeysToCopy = []string{ bundle.RelationKeyIconImage.String(), bundle.RelationKeyIconOption.String(), bundle.RelationKeySpaceDashboardId.String(), - bundle.RelationKeyCreator.String(), bundle.RelationKeyCreatedDate.String(), } @@ -274,6 +283,9 @@ func (s *SpaceView) SetSpaceData(details *types.Struct) error { } } } + if k == bundle.RelationKeyCreatedDate.String() && s.GetLocalInfo().SpaceId != s.spaceService.PersonalSpaceId() { + continue + } changed = true st.SetDetailAndBundledRelation(domain.RelationKey(k), v) } diff --git a/core/block/editor/spaceview_test.go b/core/block/editor/spaceview_test.go index 60f7cc63d7..11a1b3cb03 100644 --- a/core/block/editor/spaceview_test.go +++ b/core/block/editor/spaceview_test.go @@ -16,7 +16,6 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spaceinfo" "github.com/anyproto/anytype-heart/util/pbtypes" - "github.com/anyproto/anytype-heart/util/testMock" ) func TestSpaceView_AccessType(t *testing.T) { @@ -120,20 +119,30 @@ func TestSpaceView_SharedSpacesLimit(t *testing.T) { require.Equal(t, 10, fx.GetSharedSpacesLimit()) } +func TestSpaceView_SetOwner(t *testing.T) { + fx := newSpaceViewFixture(t) + defer fx.finish() + err := fx.SetOwner("ownerId", 125) + require.NoError(t, err) + require.Equal(t, "ownerId", pbtypes.GetString(fx.CombinedDetails(), bundle.RelationKeyCreator.String())) + require.Equal(t, int64(125), pbtypes.GetInt64(fx.CombinedDetails(), bundle.RelationKeyCreatedDate.String())) +} + type spaceServiceStub struct { } +func (s *spaceServiceStub) PersonalSpaceId() string { + return "" +} + func (s *spaceServiceStub) OnViewUpdated(info spaceinfo.SpacePersistentInfo) { } func (s *spaceServiceStub) OnWorkspaceChanged(spaceId string, details *types.Struct) { } -func NewSpaceViewTest(t *testing.T, ctrl *gomock.Controller, targetSpaceId string, tree *mock_objecttree.MockObjectTree) (*SpaceView, error) { +func NewSpaceViewTest(t *testing.T, targetSpaceId string, tree *mock_objecttree.MockObjectTree) (*SpaceView, error) { sb := smarttest.NewWithTree("root", tree) - objectStore := testMock.NewMockObjectStore(ctrl) - objectStore.EXPECT().GetDetails(gomock.Any()).AnyTimes() - objectStore.EXPECT().Query(gomock.Any()).AnyTimes() a := &SpaceView{ SmartBlock: sb, spaceService: &spaceServiceStub{}, @@ -171,7 +180,7 @@ type spaceViewFixture struct { func newSpaceViewFixture(t *testing.T) *spaceViewFixture { ctrl := gomock.NewController(t) objectTree := mock_objecttree.NewMockObjectTree(ctrl) - a, err := NewSpaceViewTest(t, ctrl, "spaceId", objectTree) + a, err := NewSpaceViewTest(t, "spaceId", objectTree) require.NoError(t, err) return &spaceViewFixture{ SpaceView: a, diff --git a/core/block/editor/state/event.go b/core/block/editor/state/event.go index fe24ba08aa..c888720ef3 100644 --- a/core/block/editor/state/event.go +++ b/core/block/editor/state/event.go @@ -2,6 +2,7 @@ package state import ( "fmt" + "sort" "github.com/gogo/protobuf/types" @@ -362,3 +363,33 @@ func StructDiffIntoEventsWithSubIds(contextId string, diff *types.Struct, keys [ return } + +func sortEventMessages(msgs []simple.EventMessage) { + eventGroup := func(msg simple.EventMessage) int { + switch msg.Msg.Value.(type) { + case *pb.EventMessageValueOfBlockAdd: + return 0 + case *pb.EventMessageValueOfBlockDelete: + return 1 + case *pb.EventMessageValueOfBlockSetChildrenIds: + return 2 + case *pb.EventMessageValueOfObjectDetailsSet: + return 3 + case *pb.EventMessageValueOfObjectDetailsAmend: + return 4 + case *pb.EventMessageValueOfObjectDetailsUnset: + return 5 + case *pb.EventMessageValueOfBlockDataviewViewSet: + return 6 + case *pb.EventMessageValueOfBlockDataviewViewDelete: + return 7 + default: + return 1000 + } + } + + sort.SliceStable(msgs, func(i, j int) bool { + a, b := msgs[i], msgs[j] + return eventGroup(a) < eventGroup(b) + }) +} diff --git a/core/block/editor/state/event_test.go b/core/block/editor/state/event_test.go new file mode 100644 index 0000000000..e59a255e46 --- /dev/null +++ b/core/block/editor/state/event_test.go @@ -0,0 +1,48 @@ +package state + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/anyproto/anytype-heart/pb" +) + +func TestSortMessages(t *testing.T) { + input := []*pb.EventMessage{ + {Value: &pb.EventMessageValueOfBlockSetText{}}, + {Value: &pb.EventMessageValueOfBlockDelete{}}, + {Value: &pb.EventMessageValueOfBlockSetVerticalAlign{}}, + {Value: &pb.EventMessageValueOfBlockAdd{}}, + {Value: &pb.EventMessageValueOfObjectDetailsUnset{}}, + {Value: &pb.EventMessageValueOfBlockSetBackgroundColor{}}, + {Value: &pb.EventMessageValueOfObjectDetailsAmend{}}, + {Value: &pb.EventMessageValueOfBlockSetChildrenIds{}}, + {Value: &pb.EventMessageValueOfBlockSetAlign{}}, + {Value: &pb.EventMessageValueOfObjectDetailsSet{}}, + {Value: &pb.EventMessageValueOfBlockSetChildrenIds{}}, + {Value: &pb.EventMessageValueOfBlockDataviewViewDelete{}}, + {Value: &pb.EventMessageValueOfBlockDataviewViewSet{}}, + } + + want := WrapEventMessages(false, []*pb.EventMessage{ + {Value: &pb.EventMessageValueOfBlockAdd{}}, + {Value: &pb.EventMessageValueOfBlockDelete{}}, + {Value: &pb.EventMessageValueOfBlockSetChildrenIds{}}, + {Value: &pb.EventMessageValueOfBlockSetChildrenIds{}}, + {Value: &pb.EventMessageValueOfObjectDetailsSet{}}, + {Value: &pb.EventMessageValueOfObjectDetailsAmend{}}, + {Value: &pb.EventMessageValueOfObjectDetailsUnset{}}, + {Value: &pb.EventMessageValueOfBlockDataviewViewSet{}}, + {Value: &pb.EventMessageValueOfBlockDataviewViewDelete{}}, + {Value: &pb.EventMessageValueOfBlockSetText{}}, + {Value: &pb.EventMessageValueOfBlockSetVerticalAlign{}}, + {Value: &pb.EventMessageValueOfBlockSetBackgroundColor{}}, + {Value: &pb.EventMessageValueOfBlockSetAlign{}}, + }) + + got := WrapEventMessages(false, input) + sortEventMessages(got) + + assert.Equal(t, want, got) +} diff --git a/core/block/editor/state/state.go b/core/block/editor/state/state.go index 498833e40c..0474981a0e 100644 --- a/core/block/editor/state/state.go +++ b/core/block/editor/state/state.go @@ -685,6 +685,8 @@ func (s *State) apply(fast, one, withLayouts bool) (msgs []simple.EventMessage, } msgs = s.processTrailingDuplicatedEvents(msgs) + + sortEventMessages(msgs) log.Debugf("middle: state apply: %d affected; %d for remove; %d copied; %d changes; for a %v", len(affectedIds), len(toRemove), len(s.blocks), len(s.changes), time.Since(st)) return } @@ -1086,7 +1088,7 @@ func (s *State) Snippet() string { } return true }) - return textutil.Truncate(builder.String(), snippetMaxSize) + return textutil.TruncateEllipsized(builder.String(), snippetMaxSize) } func (s *State) FileRelationKeys() []string { diff --git a/core/block/editor/stext/text.go b/core/block/editor/stext/text.go index e8ccbb059c..3255ec4fe1 100644 --- a/core/block/editor/stext/text.go +++ b/core/block/editor/stext/text.go @@ -18,7 +18,7 @@ import ( "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/metrics" "github.com/anyproto/anytype-heart/pb" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/internalflag" @@ -39,7 +39,7 @@ type Text interface { func NewText( sb smartblock.SmartBlock, - objectStore objectstore.ObjectStore, + objectStore spaceindex.Store, eventSender event.Sender, ) Text { t := &textImpl{ @@ -57,7 +57,7 @@ var log = logging.Logger("anytype-mw-smartblock") type textImpl struct { smartblock.SmartBlock - objectStore objectstore.ObjectStore + objectStore spaceindex.Store eventSender event.Sender lastSetTextId string @@ -451,7 +451,7 @@ func (t *textImpl) TurnInto(ctx session.Context, style model.BlockContentTextSty var targetDetails *types.Struct if targetId := linkBlock.Model().GetLink().TargetBlockId; targetId != "" { // nolint:errcheck - result, _ := t.objectStore.QueryByID([]string{targetId}) + result, _ := t.objectStore.QueryByIds([]string{targetId}) if len(result) > 0 { targetDetails = result[0].Details } diff --git a/core/block/editor/stext/text_test.go b/core/block/editor/stext/text_test.go index f4c69fe609..cdb084ae3b 100644 --- a/core/block/editor/stext/text_test.go +++ b/core/block/editor/stext/text_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -20,10 +19,9 @@ import ( "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" - "github.com/anyproto/anytype-heart/util/testMock" ) func newTextBlock(id, contentText string, childrenIds ...string) simple.Block { @@ -534,7 +532,7 @@ func TestTextImpl_TurnInto(t *testing.T) { defer ctrl.Finish() sb := smarttest.New("test") - os := testMock.NewMockObjectStore(ctrl) + os := spaceindex.NewStoreFixture(t) sb.AddBlock(simple.New(&model.Block{Id: "test", ChildrenIds: []string{"1", "2"}})). AddBlock(newTextBlock("1", "")). AddBlock(link.NewLink(&model.Block{ @@ -548,15 +546,12 @@ func TestTextImpl_TurnInto(t *testing.T) { sender := mock_event.NewMockSender(t) tb := NewText(sb, os, sender) - os.EXPECT().QueryByID([]string{"targetId"}).Return([]database.Record{ + os.AddObjects(t, []spaceindex.TestObject{ { - Details: &types.Struct{ - Fields: map[string]*types.Value{ - "name": pbtypes.String("link name"), - }, - }, + bundle.RelationKeyId: pbtypes.String("targetId"), + bundle.RelationKeyName: pbtypes.String("link name"), }, - }, nil) + }) require.NoError(t, tb.TurnInto(nil, model.BlockContentText_Paragraph, "2")) secondBlockId := sb.Doc.Pick("test").Model().ChildrenIds[1] diff --git a/core/block/editor/storestate/builder.go b/core/block/editor/storestate/builder.go new file mode 100644 index 0000000000..22b1c35da7 --- /dev/null +++ b/core/block/editor/storestate/builder.go @@ -0,0 +1,102 @@ +package storestate + +import ( + "encoding/json" + + "github.com/anyproto/any-store/anyenc" + "github.com/valyala/fastjson" + + "github.com/anyproto/anytype-heart/pb" +) + +type Builder struct { + *pb.StoreChange +} + +func (b *Builder) init() { + if b.StoreChange == nil { + b.StoreChange = &pb.StoreChange{} + } +} + +func (b *Builder) Create(collection, id string, doc any) (err error) { + jsonString, err := b.toJSONString(doc) + if err != nil { + return + } + b.init() + b.ChangeSet = append(b.ChangeSet, &pb.StoreChangeContent{ + Change: &pb.StoreChangeContentChangeOfCreate{ + Create: &pb.DocumentCreate{ + Collection: collection, + DocumentId: id, + Value: jsonString, + }, + }, + }) + return +} + +func (b *Builder) Modify(collection, id string, keyPath []string, op pb.ModifyOp, val any) (err error) { + jsonString, err := b.toJSONString(val) + if err != nil { + return + } + b.init() + + keyMod := &pb.KeyModify{ + KeyPath: keyPath, + ModifyOp: op, + ModifyValue: jsonString, + } + + for _, ch := range b.ChangeSet { + if mod := ch.GetModify(); mod != nil { + if mod.Collection == collection && mod.DocumentId == id { + mod.Keys = append(mod.Keys, keyMod) + return + } + } + } + + b.ChangeSet = append(b.ChangeSet, &pb.StoreChangeContent{ + Change: &pb.StoreChangeContentChangeOfModify{ + Modify: &pb.DocumentModify{ + Collection: collection, + DocumentId: id, + Keys: []*pb.KeyModify{keyMod}, + }, + }, + }) + + return +} + +func (b *Builder) Delete(collection, id string) { + b.init() + b.ChangeSet = append(b.ChangeSet, &pb.StoreChangeContent{ + Change: &pb.StoreChangeContentChangeOfDelete{ + Delete: &pb.DocumentDelete{ + Collection: collection, + DocumentId: id, + }, + }, + }) +} + +func (b *Builder) toJSONString(doc any) (res string, err error) { + if str, ok := doc.(string); ok { + return str, nil + } + if fj, ok := doc.(*fastjson.Value); ok { + return fj.String(), nil + } + if anyEnc, ok := doc.(*anyenc.Value); ok { + return anyEnc.String(), nil + } + resBytes, err := json.Marshal(doc) + if err != nil { + return + } + return string(resBytes), nil +} diff --git a/core/block/editor/storestate/error.go b/core/block/editor/storestate/error.go new file mode 100644 index 0000000000..5d7de80284 --- /dev/null +++ b/core/block/editor/storestate/error.go @@ -0,0 +1,11 @@ +package storestate + +import "errors" + +var ( + ErrIgnore = errors.New("ignore") + ErrValidation = errors.New("validation") + ErrLog = errors.New("log") + ErrUnexpectedHandler = errors.New("unexpected handler") + ErrOrderNotFound = errors.New("order not found") +) diff --git a/core/block/editor/storestate/handler.go b/core/block/editor/storestate/handler.go new file mode 100644 index 0000000000..780dfab358 --- /dev/null +++ b/core/block/editor/storestate/handler.go @@ -0,0 +1,71 @@ +package storestate + +import ( + "context" + + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" + + "github.com/anyproto/anytype-heart/pb" +) + +type ChangeOp struct { + Change Change + State *StoreState + Value *anyenc.Value + Arena *anyenc.Arena +} + +type DeleteMode uint + +const ( + DeleteModeDelete DeleteMode = iota + DeleteModeMark +) + +type ModifyMode uint + +const ( + ModifyModeUpdate ModifyMode = iota + ModifyModeUpsert +) + +type Handler interface { + CollectionName() string + Init(ctx context.Context, s *StoreState) (err error) + BeforeCreate(ctx context.Context, ch ChangeOp) (err error) + BeforeModify(ctx context.Context, ch ChangeOp) (mode ModifyMode, err error) + BeforeDelete(ctx context.Context, ch ChangeOp) (mode DeleteMode, err error) + UpgradeKeyModifier(ch ChangeOp, key *pb.KeyModify, mod query.Modifier) query.Modifier +} + +type DefaultHandler struct { + Name string + ModifyMode ModifyMode + DeleteMode DeleteMode +} + +func (d DefaultHandler) CollectionName() string { + return d.Name +} + +func (d DefaultHandler) Init(ctx context.Context, s *StoreState) (err error) { + _, err = s.Collection(ctx, d.Name) + return +} + +func (d DefaultHandler) BeforeCreate(ctx context.Context, ch ChangeOp) (err error) { + return +} + +func (d DefaultHandler) BeforeModify(ctx context.Context, ch ChangeOp) (mode ModifyMode, err error) { + return d.ModifyMode, nil +} + +func (d DefaultHandler) BeforeDelete(ctx context.Context, ch ChangeOp) (mode DeleteMode, err error) { + return d.DeleteMode, nil +} + +func (d DefaultHandler) UpgradeKeyModifier(ch ChangeOp, key *pb.KeyModify, mod query.Modifier) query.Modifier { + return mod +} diff --git a/core/block/editor/storestate/modifier.go b/core/block/editor/storestate/modifier.go new file mode 100644 index 0000000000..ae0c167767 --- /dev/null +++ b/core/block/editor/storestate/modifier.go @@ -0,0 +1,160 @@ +package storestate + +import ( + "errors" + "fmt" + "strings" + + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" + + "github.com/anyproto/anytype-heart/pb" +) + +const ordersKey = "_o" + +func makeModifier(ch ChangeOp, h Handler) (modifier query.Modifier, err error) { + m := ch.Change.Change.GetModify() + chain := make(query.ModifierChain, 0, len(m.Keys)) + newModifier := func(mKey *pb.KeyModify, modOp string, val *anyenc.Value) (query.Modifier, error) { + modJSON := ch.Arena.NewObject() + valJSON := ch.Arena.NewObject() + valJSON.Set(strings.Join(mKey.KeyPath, "."), val) + modJSON.Set(modOp, valJSON) + anyMod, mErr := query.ParseModifier(modJSON) + if mErr != nil { + return nil, mErr + } + mod := query.ModifyFunc(func(a *anyenc.Arena, v *anyenc.Value) (result *anyenc.Value, modified bool, err error) { + if curOrder := getFieldOrder(val, mKey.KeyPath...); curOrder != "" && curOrder >= ch.Change.Order { + return v, false, nil + } + result, modified, err = anyMod.Modify(a, v) + if err == nil && modified { + setFieldOrder(a, result, ch.Change.Order, mKey.KeyPath...) + } + return + }) + ch.Value = val + return h.UpgradeKeyModifier(ch, mKey, mod), nil + } + + for _, mKey := range m.Keys { + var ( + val *anyenc.Value + mod query.Modifier + modOp string + ) + if len(mKey.KeyPath) == 0 { + return nil, errors.Join() + } + if mKey.ModifyValue != "" { + if val, err = anyenc.ParseJson(mKey.ModifyValue); err != nil { + return nil, err + } + } + switch mKey.ModifyOp { + case pb.ModifyOp_Set: + modOp = "$set" + case pb.ModifyOp_Unset: + val = ch.Arena.NewTrue() + modOp = "$unset" + case pb.ModifyOp_Inc: + if val == nil || val.Type() != anyenc.TypeNumber { + return nil, fmt.Errorf("unexpected value for $inc %v: '%s'", mKey.KeyPath, mKey.ModifyValue) + } + modOp = "$inc" + case pb.ModifyOp_AddToSet: + modOp = "$addToSet" + case pb.ModifyOp_Pull: + modOp = "$pull" + default: + return nil, fmt.Errorf("unexpected modify op: '%v", mKey.ModifyOp) + } + + if val == nil { + return nil, fmt.Errorf("no value for modifier: %v", mKey.KeyPath) + } + if mod, err = newModifier(mKey, modOp, val); err != nil { + return + } + chain = append(chain, mod) + } + return chain, nil +} + +func fillRootOrder(a *anyenc.Arena, v *anyenc.Value, order string) { + val := a.NewObject() + v.Set(ordersKey, val) + iterateKeysByPath(v, func(k string) { + if k != ordersKey { + val.Set(k, a.NewString(order)) + } + }) +} + +func getFieldOrder(v *anyenc.Value, fieldPath ...string) (order string) { + obj := v.GetObject(ordersKey) + if obj == nil { + return + } + for _, field := range fieldPath { + val := obj.Get(field) + if val == nil { + return + } + switch val.Type() { + case anyenc.TypeObject: + obj, _ = val.Object() + continue + case anyenc.TypeString: + return string(val.GetStringBytes()) + default: + return + } + } + return +} + +func setFieldOrder(a *anyenc.Arena, v *anyenc.Value, order string, fieldPath ...string) { + val := v.Get(ordersKey) + if val == nil || val.Type() != anyenc.TypeObject { + val = a.NewObject() + v.Set(ordersKey, val) + } + for i, field := range fieldPath { + if i == len(fieldPath)-1 { + // it's a last element in the path - set order anyway + val.Set(field, a.NewString(order)) + return + } + fieldVal := val.Get(field) + if fieldVal == nil || (fieldVal.Type() != anyenc.TypeObject && fieldVal.Type() != anyenc.TypeString) { + fieldVal = a.NewObject() + } + switch fieldVal.Type() { + case anyenc.TypeObject: + val.Set(field, fieldVal) + val = fieldVal + continue + case anyenc.TypeString: + prevOrder := string(fieldVal.GetStringBytes()) + fieldVal = a.NewObject() + val.Set(field, fieldVal) + val = fieldVal + iterateKeysByPath(v, func(k string) { + if k != field { + val.Set(k, a.NewString(prevOrder)) + } + }, fieldPath[:i+1]...) + } + } +} + +func iterateKeysByPath(v *anyenc.Value, f func(k string), fieldPath ...string) { + if obj := v.GetObject(fieldPath...); obj != nil { + obj.Visit(func(key []byte, v *anyenc.Value) { + f(string(key)) + }) + } +} diff --git a/core/block/editor/storestate/state.go b/core/block/editor/storestate/state.go new file mode 100644 index 0000000000..17e54b465b --- /dev/null +++ b/core/block/editor/storestate/state.go @@ -0,0 +1,310 @@ +package storestate + +import ( + "context" + "errors" + "fmt" + "time" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" + "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/lexid" + "github.com/valyala/fastjson" + "go.uber.org/zap" + + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +var ( + log = logger.NewNamed("storeState") +) + +const ( + IdFromChange = "$changeId" +) + +var lexId = lexid.Must(lexid.CharsAllNoEscape, 4, 100) + +const ( + collChangeOrders = "_change_orders" +) + +func New(ctx context.Context, id string, db anystore.DB, handlers ...Handler) (state *StoreState, err error) { + if len(handlers) == 0 { + return nil, fmt.Errorf("should be at least one handler") + } + + state = &StoreState{ + id: id, + handlers: map[string]Handler{}, + arena: &anyenc.Arena{}, + parser: &fastjson.Parser{}, + db: db, + } + + for _, h := range handlers { + if _, ok := state.handlers[h.CollectionName()]; ok { + return nil, fmt.Errorf("more than one handler for collection '%s'", h.CollectionName()) + } + state.handlers[h.CollectionName()] = h + } + + tx, err := db.WriteTx(ctx) + if err != nil { + return nil, err + } + + defer func() { + if err != nil { + if state.collChangeOrders != nil { + _ = state.collChangeOrders.Close() + // TODO: close all collections (maybe need to do smth like db.CollectionsPrefix) + } + _ = tx.Rollback() + } else { + err = tx.Commit() + } + }() + + if err = state.init(tx.Context()); err != nil { + return + } + return +} + +type ChangeSet struct { + Id string + Order string + Creator string + Changes []*pb.StoreChangeContent + Timestamp int64 +} + +type Change struct { + Id string + Order string + Creator string + Change *pb.StoreChangeContent + Timestamp int64 +} + +type StoreState struct { + id string + collChangeOrders anystore.Collection + + handlers map[string]Handler + + arena *anyenc.Arena + parser *fastjson.Parser + + db anystore.DB +} + +func (ss *StoreState) init(ctx context.Context) (err error) { + if ss.collChangeOrders, err = ss.Collection(ctx, collChangeOrders); err != nil { + return + } + for _, h := range ss.handlers { + if err = h.Init(ctx, ss); err != nil { + return + } + } + return +} + +func (ss *StoreState) NewTx(ctx context.Context) (*StoreStateTx, error) { + tx, err := ss.db.WriteTx(ctx) + if err != nil { + return nil, err + } + stx := &StoreStateTx{state: ss, tx: tx, ctx: tx.Context(), arena: &anyenc.Arena{}} + if err = stx.init(); err != nil { + return nil, err + } + return stx, nil +} + +func (ss *StoreState) Collection(ctx context.Context, name string) (anystore.Collection, error) { + return ss.db.Collection(ctx, ss.id+name) +} + +func (ss *StoreState) applyChangeSet(ctx context.Context, set ChangeSet) (err error) { + for _, ch := range set.Changes { + applyErr := ss.applyChange(ctx, Change{ + Id: set.Id, + Order: set.Order, + Change: ch, + Creator: set.Creator, + Timestamp: set.Timestamp, + }) + if applyErr == nil || errors.Is(applyErr, ErrIgnore) { + continue + } + if errors.Is(applyErr, ErrLog) { + log.Warn("change apply error", + zap.Error(applyErr), + zap.String("changeId", set.Id), + zap.String("order", set.Order), + ) + continue + } + err = applyErr + break + } + return +} + +func (ss *StoreState) applyChange(ctx context.Context, ch Change) (err error) { + ss.arena.Reset() + if create := ch.Change.GetCreate(); create != nil { + return ss.applyCreate(ctx, ch) + } + if modify := ch.Change.GetModify(); modify != nil { + return ss.applyModify(ctx, ch) + } + if del := ch.Change.GetDelete(); del != nil { + return ss.applyDelete(ctx, ch) + } + log.Warn("got unexpected store change", zap.String("change", pbtypes.Sprint(ch.Change))) + return +} + +func (ss *StoreState) applyCreate(ctx context.Context, ch Change) (err error) { + create := ch.Change.GetCreate() + + handler, err := ss.getHandler(create.Collection) + if err != nil { + return + } + + if create.DocumentId == IdFromChange { + create.DocumentId = ch.Id + } + // parse value and force set id + jsonValue, err := ss.parser.Parse(create.Value) + if err != nil { + return + } + value := ss.arena.NewFromFastJson(jsonValue) + value.Set("id", ss.arena.NewString(create.DocumentId)) + + // call handler + if err = handler.BeforeCreate(ctx, ss.changeOp(ch, value)); err != nil { + return + } + + // fill initial order + fillRootOrder(ss.arena, value, ch.Order) + + // insert + coll, err := ss.Collection(ctx, create.Collection) + if err != nil { + return err + } + + if err = coll.Insert(ctx, value); err != nil { + if errors.Is(err, anystore.ErrDocExists) { + return ErrIgnore + } + return + } + return +} + +func (ss *StoreState) applyModify(ctx context.Context, ch Change) (err error) { + modify := ch.Change.GetModify() + + handler, err := ss.getHandler(modify.Collection) + if err != nil { + return + } + + mod, err := makeModifier(ss.changeOp(ch, nil), handler) + if err != nil { + return + } + + changeOp := ss.changeOp(ch, nil) + + mode, err := handler.BeforeModify(ctx, changeOp) + if err != nil { + return + } + + coll, err := ss.Collection(ctx, modify.Collection) + if err != nil { + return + } + + var exec func(ctx context.Context, id any, m query.Modifier) (anystore.ModifyResult, error) + if mode == ModifyModeUpsert { + exec = coll.UpsertId + } else { + exec = coll.UpdateId + } + + // TODO: check result? + _, err = exec(ctx, modify.DocumentId, mod) + if err != nil { + if errors.Is(err, anystore.ErrDocNotFound) { + return ErrLog + } else { + return + } + } + return +} + +func (ss *StoreState) applyDelete(ctx context.Context, ch Change) (err error) { + del := ch.Change.GetDelete() + + handler, err := ss.getHandler(del.Collection) + if err != nil { + return + } + + mode, err := handler.BeforeDelete(ctx, ss.changeOp(ch, nil)) + if err != nil { + return + } + + coll, err := ss.Collection(ctx, del.Collection) + if err != nil { + return + } + switch mode { + case DeleteModeMark: + payload := ss.newDeleteMark(del.DocumentId) + fillRootOrder(ss.arena, payload, ch.Order) + return coll.UpdateOne(ctx, payload) + case DeleteModeDelete: + return coll.DeleteId(ctx, del.DocumentId) + } + return +} + +func (ss *StoreState) changeOp(ch Change, val *anyenc.Value) ChangeOp { + return ChangeOp{ + Change: ch, + State: ss, + Value: val, + Arena: ss.arena, + } +} + +func (ss *StoreState) newDeleteMark(id string) *anyenc.Value { + obj := ss.arena.NewObject() + obj.Set("id", ss.arena.NewString(id)) + obj.Set("_d", ss.arena.NewNumberInt(int(time.Now().UnixMilli()))) + return obj +} + +func (ss *StoreState) getHandler(collection string) (Handler, error) { + if h, ok := ss.handlers[collection]; ok { + return h, nil + } + return nil, errors.Join(ErrLog, ErrUnexpectedHandler, fmt.Errorf("'%s'", collection)) +} diff --git a/core/block/editor/storestate/state_test.go b/core/block/editor/storestate/state_test.go new file mode 100644 index 0000000000..1a77c24775 --- /dev/null +++ b/core/block/editor/storestate/state_test.go @@ -0,0 +1,187 @@ +package storestate + +import ( + "context" + "fmt" + "os" + "path/filepath" + "testing" + "time" + + anystore "github.com/anyproto/any-store" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/pb" +) + +var ctx = context.Background() + +func TestStoreStateTx_GetOrder(t *testing.T) { + t.Run("empty", func(t *testing.T) { + fx := newFixture(t, "test", DefaultHandler{Name: "tcoll"}) + tx, err := fx.NewTx(ctx) + require.NoError(t, err) + defer func() { + require.NoError(t, tx.Commit()) + }() + order, err := tx.GetOrder("changeId") + assert.ErrorIs(t, err, ErrOrderNotFound) + assert.Empty(t, order) + }) + t.Run("set-get", func(t *testing.T) { + fx := newFixture(t, "test", DefaultHandler{Name: "tcoll"}) + tx, err := fx.NewTx(ctx) + require.NoError(t, err) + require.NoError(t, tx.SetOrder("changeId", "1")) + order, err := tx.GetOrder("changeId") + require.NoError(t, err) + assert.Equal(t, "1", order) + assert.Equal(t, "1", tx.GetMaxOrder()) + require.NoError(t, tx.Commit()) + + tx, err = fx.NewTx(ctx) + require.NoError(t, err) + assert.Equal(t, "1", tx.GetMaxOrder()) + require.NoError(t, tx.SetOrder("changeId2", "2")) + assert.Equal(t, "2", tx.GetMaxOrder()) + require.NoError(t, tx.Commit()) + }) +} + +func TestStoreStateTx_ApplyChangeSet(t *testing.T) { + t.Run("create", func(t *testing.T) { + fx := newFixture(t, "objId", DefaultHandler{Name: "testColl"}) + tx, err := fx.NewTx(ctx) + require.NoError(t, err) + build := &Builder{} + assert.NoError(t, build.Create("testColl", "1", `{"key":"value"}`)) + require.NoError(t, tx.ApplyChangeSet(ChangeSet{ + Id: "1", + Order: "1", + Changes: build.ChangeSet, + })) + require.NoError(t, tx.Commit()) + + coll, err := fx.Collection(ctx, "testColl") + require.NoError(t, err) + doc, err := coll.FindId(ctx, "1") + require.NoError(t, err) + assert.Equal(t, "value", string(doc.Value().GetStringBytes("key"))) + + }) + t.Run("modify", func(t *testing.T) { + fx := newFixture(t, "objId", DefaultHandler{Name: "testColl"}) + tx, err := fx.NewTx(ctx) + require.NoError(t, err) + build := &Builder{} + assert.NoError(t, build.Create("testColl", "1", `{"key":"value"}`)) + assert.NoError(t, build.Modify("testColl", "1", []string{"key"}, pb.ModifyOp_Set, `"valueChanged"`)) + assert.NoError(t, build.Modify("testColl", "1", []string{"num"}, pb.ModifyOp_Inc, `2`)) + + require.NoError(t, tx.ApplyChangeSet(ChangeSet{ + Id: "1", + Order: "1", + Changes: build.ChangeSet, + })) + require.NoError(t, tx.Commit()) + + coll, err := fx.Collection(ctx, "testColl") + require.NoError(t, err) + count, err := coll.Count(ctx) + require.NoError(t, err) + assert.Equal(t, 1, count) + doc, err := coll.FindId(ctx, "1") + require.NoError(t, err) + assert.Equal(t, "valueChanged", string(doc.Value().GetStringBytes("key"))) + assert.Equal(t, float64(2), doc.Value().GetFloat64("num")) + }) + t.Run("delete", func(t *testing.T) { + fx := newFixture(t, "objId", DefaultHandler{Name: "testColl"}) + tx, err := fx.NewTx(ctx) + require.NoError(t, err) + build := &Builder{} + assert.NoError(t, build.Create("testColl", "1", `{"key":"value"}`)) + require.NoError(t, tx.ApplyChangeSet(ChangeSet{ + Id: "1", + Order: "1", + Changes: build.ChangeSet, + })) + require.NoError(t, tx.Commit()) + + tx, err = fx.NewTx(ctx) + require.NoError(t, err) + build = &Builder{} + build.Delete("testColl", "1") + require.NoError(t, tx.ApplyChangeSet(ChangeSet{ + Id: "1", + Order: "1", + Changes: build.ChangeSet, + })) + require.NoError(t, tx.Commit()) + + coll, err := fx.Collection(ctx, "testColl") + require.NoError(t, err) + count, err := coll.Count(ctx) + require.NoError(t, err) + assert.Equal(t, 0, count) + }) +} + +func TestBenchCreate(t *testing.T) { + // t.Skip() + var n = 100000 + fx := newFixture(t, "objId", DefaultHandler{Name: "testColl"}) + st := time.Now() + var changes = make([]ChangeSet, n) + for i := range n { + build := &Builder{} + assert.NoError(t, build.Create("testColl", fmt.Sprint(i), `{"some":"json"}`)) + changes[i] = ChangeSet{ + Id: fmt.Sprint(i), + Order: fmt.Sprint(i), + Changes: build.ChangeSet, + } + } + t.Logf("created %d changes for a %v", n, time.Since(st)) + st = time.Now() + tx, err := fx.NewTx(ctx) + require.NoError(t, err) + for _, ch := range changes { + assert.NoError(t, tx.ApplyChangeSet(ch)) + } + t.Logf("applied for a %v", time.Since(st)) + st = time.Now() + assert.NoError(t, tx.Commit()) + t.Logf("commited for a %v", time.Since(st)) +} + +type fixture struct { + *StoreState + db anystore.DB + tmpDir string +} + +func newFixture(t testing.TB, id string, handlers ...Handler) *fixture { + fx := &fixture{} + var err error + fx.tmpDir, err = os.MkdirTemp("", "storestate_*") + require.NoError(t, err) + fx.db, err = anystore.Open(ctx, filepath.Join(fx.tmpDir, "db.db"), nil) + require.NoError(t, err) + t.Cleanup(func() { + fx.finish(t) + }) + fx.StoreState, err = New(ctx, id, fx.db, handlers...) + require.NoError(t, err) + return fx +} + +func (fx *fixture) finish(t testing.TB) { + if fx.db != nil { + require.NoError(t, fx.db.Close()) + } + if fx.tmpDir != "" { + _ = os.RemoveAll(fx.tmpDir) + } +} diff --git a/core/block/editor/storestate/tx.go b/core/block/editor/storestate/tx.go new file mode 100644 index 0000000000..daa5e750d1 --- /dev/null +++ b/core/block/editor/storestate/tx.go @@ -0,0 +1,93 @@ +package storestate + +import ( + "context" + "errors" + "time" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" +) + +const maxOrderId = "_max" + +type StoreStateTx struct { + tx anystore.WriteTx + ctx context.Context + state *StoreState + arena *anyenc.Arena + maxOrder string + maxOrderChanged bool +} + +func (stx *StoreStateTx) init() (err error) { + stx.maxOrder, err = stx.GetOrder(maxOrderId) + if err != nil && !errors.Is(err, ErrOrderNotFound) { + return + } + return nil +} + +func (stx *StoreStateTx) GetOrder(changeId string) (orderId string, err error) { + doc, err := stx.state.collChangeOrders.FindId(stx.ctx, changeId) + if err != nil { + if errors.Is(err, anystore.ErrDocNotFound) { + err = ErrOrderNotFound + } + return + } + return string(doc.Value().GetStringBytes("o")), nil +} + +func (stx *StoreStateTx) GetMaxOrder() string { + return stx.maxOrder +} + +func (stx *StoreStateTx) NextOrder(prev string) string { + return lexId.Next(prev) +} + +func (stx *StoreStateTx) NextBeforeOrder(prev string, before string) (string, error) { + return lexId.NextBefore(prev, before) +} + +func (stx *StoreStateTx) SetOrder(changeId, order string) (err error) { + stx.arena.Reset() + obj := stx.arena.NewObject() + obj.Set("id", stx.arena.NewString(changeId)) + obj.Set("o", stx.arena.NewString(order)) + obj.Set("t", stx.arena.NewNumberInt(int(time.Now().UnixMilli()))) + if err = stx.state.collChangeOrders.UpsertOne(stx.ctx, obj); err != nil { + return + } + stx.checkMaxOrder(order) + return +} + +func (stx *StoreStateTx) checkMaxOrder(order string) { + if order > stx.maxOrder { + stx.maxOrder = order + stx.maxOrderChanged = true + } +} + +func (stx *StoreStateTx) ApplyChangeSet(ch ChangeSet) (err error) { + if err = stx.SetOrder(ch.Id, ch.Order); err != nil && !errors.Is(err, anystore.ErrDocExists) { + return + } + err = stx.state.applyChangeSet(stx.ctx, ch) + return err +} + +func (stx *StoreStateTx) Commit() (err error) { + if stx.maxOrderChanged { + if err = stx.SetOrder(maxOrderId, stx.maxOrder); err != nil { + return + } + } + return stx.tx.Commit() +} + +func (stx *StoreStateTx) Rollback() (err error) { + return stx.tx.Rollback() +} diff --git a/core/block/editor/template.go b/core/block/editor/template.go index 8862090456..4caa02ba97 100644 --- a/core/block/editor/template.go +++ b/core/block/editor/template.go @@ -16,9 +16,9 @@ type Template struct { *Page } -func (f *ObjectFactory) newTemplate(sb smartblock.SmartBlock) *Template { +func (f *ObjectFactory) newTemplate(spaceId string, sb smartblock.SmartBlock) *Template { return &Template{ - Page: f.newPage(sb), + Page: f.newPage(spaceId, sb), } } diff --git a/core/block/editor/template/template.go b/core/block/editor/template/template.go index 346891ea53..d1f804a94b 100644 --- a/core/block/editor/template/template.go +++ b/core/block/editor/template/template.go @@ -26,6 +26,7 @@ const ( DescriptionBlockId = "description" DataviewBlockId = "dataview" FeaturedRelationsId = "featuredRelations" + ChatId = "chat" ) var log = logging.Logger("anytype-state-template") @@ -416,6 +417,22 @@ var WithFeaturedRelations = StateTransformer(func(s *state.State) { } }) +var WithBlockChat = StateTransformer(func(s *state.State) { + blockExists := s.Exists(ChatId) + if blockExists { + return + } + + s.Set(simple.New(&model.Block{ + Id: ChatId, + Content: &model.BlockContentOfChat{Chat: &model.BlockContentChat{}}, + })) + + if err := s.InsertTo(s.RootId(), model.Block_Inner, ChatId); err != nil { + log.Errorf("template BlockChat failed to insert: %v", err) + } +}) + var WithAllBlocksEditsRestricted = StateTransformer(func(s *state.State) { s.Iterate(func(b simple.Block) (isContinue bool) { b.Model().Restrictions = &model.BlockRestrictions{ diff --git a/core/block/editor/widget.go b/core/block/editor/widget.go index 7bd25cec87..caaf152928 100644 --- a/core/block/editor/widget.go +++ b/core/block/editor/widget.go @@ -11,7 +11,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -27,7 +27,7 @@ type WidgetObject struct { func NewWidgetObject( sb smartblock.SmartBlock, - objectStore objectstore.ObjectStore, + objectStore spaceindex.Store, layoutConverter converter.LayoutConverter, ) *WidgetObject { bs := basic.NewBasic(sb, objectStore, layoutConverter, nil, nil) diff --git a/core/block/editor/workspaces.go b/core/block/editor/workspaces.go index 09477cd03e..ec8291a5ac 100644 --- a/core/block/editor/workspaces.go +++ b/core/block/editor/workspaces.go @@ -12,6 +12,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/metrics" "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -32,17 +33,17 @@ type Workspaces struct { migrator subObjectsMigrator } -func (f *ObjectFactory) newWorkspace(sb smartblock.SmartBlock) *Workspaces { +func (f *ObjectFactory) newWorkspace(sb smartblock.SmartBlock, store spaceindex.Store) *Workspaces { w := &Workspaces{ SmartBlock: sb, - AllOperations: basic.NewBasic(sb, f.objectStore, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater), + AllOperations: basic.NewBasic(sb, store, f.layoutConverter, f.fileObjectService, f.lastUsedUpdater), IHistory: basic.NewHistory(sb), Text: stext.NewText( sb, - f.objectStore, + store, f.eventSender, ), - Dataview: dataview.NewDataview(sb, f.objectStore), + Dataview: dataview.NewDataview(sb, store), spaceService: f.spaceService, config: f.config, } diff --git a/core/block/export/export.go b/core/block/export/export.go index 9f787f0ce5..4540137dab 100644 --- a/core/block/export/export.go +++ b/core/block/export/export.go @@ -363,18 +363,13 @@ func (e *exportContext) queryAndFilterObjectsByRelation(spaceId string, reqIds [ } func (e *exportContext) queryObjectsByIds(spaceId string, reqIds []string, relationFilter string) ([]database.Record, error) { - return e.objectStore.Query(database.Query{ + return e.objectStore.SpaceIndex(spaceId).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: relationFilter, Condition: model.BlockContentDataviewFilter_In, Value: pbtypes.StringList(reqIds), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, }, }) } @@ -659,7 +654,7 @@ func (e *exportContext) addRelationOptions(relationKey string) error { } func (e *exportContext) getRelationOptions(relationKey string) ([]database.Record, error) { - relationOptionsDetails, err := e.objectStore.Query(database.Query{ + relationOptionsDetails, err := e.objectStore.SpaceIndex(e.spaceId).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyLayout.String(), @@ -671,11 +666,6 @@ func (e *exportContext) getRelationOptions(relationKey string) ([]database.Recor Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.String(relationKey), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(e.spaceId), - }, }, }) if err != nil { @@ -775,7 +765,7 @@ func (e *exportContext) addNestedObjects(ids []string) error { } func (e *exportContext) addNestedObject(id string, nestedDocs map[string]*types.Struct) { - links, err := e.objectStore.GetOutboundLinksByID(id) + links, err := e.objectStore.SpaceIndex(e.spaceId).GetOutboundLinksById(id) if err != nil { log.Errorf("export failed to get outbound links for id: %s", err) return @@ -790,7 +780,7 @@ func (e *exportContext) addNestedObject(id string, nestedDocs map[string]*types. if !validType(sbt) { continue } - rec, qErr := e.objectStore.QueryByID([]string{link}) + rec, qErr := e.objectStore.SpaceIndex(e.spaceId).QueryByIds([]string{link}) if qErr != nil { log.Errorf("failed to query id %s, err: %s", qErr, err) continue @@ -805,10 +795,11 @@ func (e *exportContext) addNestedObject(id string, nestedDocs map[string]*types. } func (e *exportContext) fillLinkedFiles(id string) ([]string, error) { + spaceIndex := e.objectStore.SpaceIndex(e.spaceId) var fileObjectsIds []string err := cache.Do(e.picker, id, func(b sb.SmartBlock) error { b.NewState().IterateLinkedFiles(func(fileObjectId string) { - res, err := e.objectStore.Query(database.Query{ + res, err := spaceIndex.Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyId.String(), @@ -836,12 +827,13 @@ func (e *exportContext) fillLinkedFiles(id string) ([]string, error) { } func (e *exportContext) getExistedObjects(isProtobuf bool) error { - res, err := e.objectStore.List(e.spaceId, false) + spaceIndex := e.objectStore.SpaceIndex(e.spaceId) + res, err := spaceIndex.List(false) if err != nil { return err } if e.includeArchive { - archivedObjects, err := e.objectStore.List(e.spaceId, true) + archivedObjects, err := spaceIndex.List(true) if err != nil { return err } @@ -1109,7 +1101,7 @@ func (fn *namer) Get(path, hash, title, ext string) (name string) { return name } title = slug.Make(strings.TrimSuffix(title, ext)) - name = text.Truncate(title, fileLenLimit) + name = text.TruncateEllipsized(title, fileLenLimit) name = strings.TrimSuffix(name, text.TruncateEllipsis) var ( i = 0 diff --git a/core/block/export/export_test.go b/core/block/export/export_test.go index ba0aa69564..b86413ffa5 100644 --- a/core/block/export/export_test.go +++ b/core/block/export/export_test.go @@ -26,6 +26,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/addr" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider/mock_typeprovider" "github.com/anyproto/anytype-heart/tests/testutil" @@ -54,6 +55,9 @@ func TestFileNamer_Get(t *testing.T) { } assert.Equal(t, len(names), len(nl)) } + +const spaceId = "space1" + func TestExport_Export(t *testing.T) { t.Run("export success", func(t *testing.T) { // given @@ -62,9 +66,8 @@ func TestExport_Export(t *testing.T) { objectTypeUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, objectTypeId) assert.Nil(t, err) - spaceId := "spaceId" objectID := "id" - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []spaceindex.TestObject{ { bundle.RelationKeyId: pbtypes.String(objectID), bundle.RelationKeyType: pbtypes.String(objectTypeId), @@ -165,7 +168,6 @@ func TestExport_Export(t *testing.T) { t.Run("empty import", func(t *testing.T) { // given storeFixture := objectstore.NewStoreFixture(t) - spaceId := "spaceId" objectID := "id" objectGetter := mock_cache.NewMockObjectGetter(t) @@ -213,9 +215,8 @@ func TestExport_Export(t *testing.T) { storeFixture := objectstore.NewStoreFixture(t) objectTypeId := "customObjectType" - spaceId := "spaceId" objectID := "id" - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []spaceindex.TestObject{ { bundle.RelationKeyId: pbtypes.String(objectID), bundle.RelationKeyType: pbtypes.String(objectTypeId), @@ -260,34 +261,35 @@ func TestExport_Export(t *testing.T) { assert.Equal(t, 0, success) }) } + func Test_docsForExport(t *testing.T) { t.Run("get object with existing links", func(t *testing.T) { // given storeFixture := objectstore.NewStoreFixture(t) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyName: pbtypes.String("name1"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyName: pbtypes.String("name2"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) - err := storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err := storeFixture.SpaceIndex(spaceId).UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) provider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) - provider.EXPECT().Type("spaceId", "id1").Return(smartblock.SmartBlockTypePage, nil) + provider.EXPECT().Type(spaceId, "id1").Return(smartblock.SmartBlockTypePage, nil) e := &export{ objectStore: storeFixture, sbtProvider: provider, } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, }) @@ -302,29 +304,29 @@ func Test_docsForExport(t *testing.T) { t.Run("get object with non existing links", func(t *testing.T) { // given storeFixture := objectstore.NewStoreFixture(t) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyName: pbtypes.String("name"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) - err := storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err := storeFixture.SpaceIndex(spaceId).UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) provider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) - provider.EXPECT().Type("spaceId", "id1").Return(smartblock.SmartBlockTypePage, nil) + provider.EXPECT().Type(spaceId, "id1").Return(smartblock.SmartBlockTypePage, nil) e := &export{ objectStore: storeFixture, sbtProvider: provider, } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, }) @@ -340,15 +342,15 @@ func Test_docsForExport(t *testing.T) { // given storeFixture := objectstore.NewStoreFixture(t) relationKey := "key" - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), domain.RelationKey(relationKey): pbtypes.String("value"), bundle.RelationKeyType: pbtypes.String("objectType"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) - err := storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err := storeFixture.SpaceIndex(spaceId).UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) objectGetter := mock_cache.NewMockObjectGetter(t) @@ -392,7 +394,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, Format: model.Export_Protobuf, }) @@ -411,22 +413,22 @@ func Test_docsForExport(t *testing.T) { uniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), domain.RelationKey(relationKey): pbtypes.String("value"), bundle.RelationKeyType: pbtypes.String("objectType"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) - err = storeFixture.UpdateObjectLinks("id", []string{"id1"}) + err = storeFixture.SpaceIndex(spaceId).UpdateObjectLinks(context.Background(), "id", []string{"id1"}) assert.Nil(t, err) objectGetter := mock_cache.NewMockObjectGetter(t) @@ -470,7 +472,7 @@ func Test_docsForExport(t *testing.T) { picker: objectGetter, } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, Format: model.Export_Protobuf, }) @@ -490,19 +492,19 @@ func Test_docsForExport(t *testing.T) { uniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), domain.RelationKey(relationKey): pbtypes.String("value"), bundle.RelationKeyType: pbtypes.String("objectType"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_status)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) @@ -548,7 +550,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, Format: model.Export_Protobuf, @@ -571,12 +573,12 @@ func Test_docsForExport(t *testing.T) { optionUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelationOption, optionId) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), domain.RelationKey(relationKey): pbtypes.String(optionId), bundle.RelationKeyType: pbtypes.String("objectType"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(relationKey), @@ -584,14 +586,14 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_tag)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(optionId), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(optionUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relationOption)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) @@ -637,7 +639,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, Format: model.Export_Protobuf, @@ -673,26 +675,26 @@ func Test_docsForExport(t *testing.T) { templateObjectTypeId := "templateObjectTypeId" linkedObjectId := "linkedObjectId" - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), domain.RelationKey(relationKey): pbtypes.String("test"), bundle.RelationKeyType: pbtypes.String(objectTypeKey), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(objectTypeKey), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), bundle.RelationKeyRecommendedRelations: pbtypes.StringList([]string{recommendedRelationKey}), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeKey), }, { @@ -700,22 +702,22 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyRelationKey: pbtypes.String(recommendedRelationKey), bundle.RelationKeyUniqueKey: pbtypes.String(recommendedRelationUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(templateId), bundle.RelationKeyTargetObjectType: pbtypes.String(objectTypeKey), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(templateObjectTypeId), }, { bundle.RelationKeyId: pbtypes.String(linkedObjectId), bundle.RelationKeyType: pbtypes.String(objectTypeKey), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) - err = storeFixture.UpdateObjectLinks(templateId, []string{linkedObjectId}) + err = storeFixture.SpaceIndex(spaceId).UpdateObjectLinks(context.Background(), templateId, []string{linkedObjectId}) assert.Nil(t, err) objectGetter := mock_cache.NewMockObjectGetter(t) @@ -803,7 +805,7 @@ func Test_docsForExport(t *testing.T) { objectGetter.EXPECT().GetObject(context.Background(), linkedObjectId).Return(linkedObject, nil) provider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) - provider.EXPECT().Type("spaceId", linkedObjectId).Return(smartblock.SmartBlockTypePage, nil) + provider.EXPECT().Type(spaceId, linkedObjectId).Return(smartblock.SmartBlockTypePage, nil) e := &export{ objectStore: storeFixture, @@ -812,7 +814,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, Format: model.Export_Protobuf, @@ -832,18 +834,18 @@ func Test_docsForExport(t *testing.T) { objectTypeUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, objectTypeId) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyType: pbtypes.String(objectTypeId), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(objectTypeId), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), bundle.RelationKeyRecommendedRelations: pbtypes.StringList([]string{addr.MissingObject}), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) @@ -888,7 +890,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, Format: model.Export_Protobuf, @@ -908,24 +910,24 @@ func Test_docsForExport(t *testing.T) { objectTypeUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, objectTypeId) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyName: pbtypes.String("name1"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), }, { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyName: pbtypes.String("name2"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), }, { bundle.RelationKeyId: pbtypes.String(objectTypeId), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), }, }) @@ -970,7 +972,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, Format: model.Export_Protobuf, @@ -994,11 +996,11 @@ func Test_docsForExport(t *testing.T) { relationKeyUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyName: pbtypes.String("name1"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_set)), }, @@ -1006,14 +1008,14 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyId: pbtypes.String(objectTypeId), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), }, { bundle.RelationKeyId: pbtypes.String(bundle.RelationKeyTag.String()), bundle.RelationKeyName: pbtypes.String(bundle.RelationKeyTag.String()), bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyTag.String()), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), bundle.RelationKeyUniqueKey: pbtypes.String(bundle.RelationKeyTag.URL()), }, @@ -1021,7 +1023,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyName: pbtypes.String(relationKey), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), bundle.RelationKeyUniqueKey: pbtypes.String(relationKeyUniqueKey.Marshal()), }, @@ -1094,7 +1096,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, Format: model.Export_Protobuf, @@ -1114,11 +1116,11 @@ func Test_docsForExport(t *testing.T) { objectTypeUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, objectTypeId) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyName: pbtypes.String("name1"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_set)), }, @@ -1126,7 +1128,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyId: pbtypes.String(objectTypeId), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), }, }) @@ -1175,7 +1177,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, IncludeFiles: true, @@ -1196,11 +1198,11 @@ func Test_docsForExport(t *testing.T) { objectTypeUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, objectTypeId) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeyName: pbtypes.String("name1"), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_set)), }, @@ -1208,7 +1210,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyId: pbtypes.String(objectTypeId), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeId), }, }) @@ -1234,7 +1236,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, IncludeNested: true, IncludeFiles: true, @@ -1268,19 +1270,19 @@ func Test_docsForExport(t *testing.T) { relationObjectTypeUK, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, relationObjectTypeKey) assert.Nil(t, err) - storeFixture.AddObjects(t, []objectstore.TestObject{ + storeFixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id"), bundle.RelationKeySetOf: pbtypes.StringList([]string{relationKey}), bundle.RelationKeyType: pbtypes.String(objectTypeKey), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(relationObjectTypeKey), }, { @@ -1288,14 +1290,14 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), bundle.RelationKeyRecommendedRelations: pbtypes.StringList([]string{recommendedRelationKey}), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeKey), }, { bundle.RelationKeyId: pbtypes.String(relationObjectTypeKey), bundle.RelationKeyUniqueKey: pbtypes.String(relationObjectTypeUK.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), bundle.RelationKeyType: pbtypes.String(objectTypeKey), }, { @@ -1303,7 +1305,7 @@ func Test_docsForExport(t *testing.T) { bundle.RelationKeyRelationKey: pbtypes.String(recommendedRelationKey), bundle.RelationKeyUniqueKey: pbtypes.String(recommendedRelationUniqueKey.Marshal()), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) @@ -1378,7 +1380,7 @@ func Test_docsForExport(t *testing.T) { } expCtx := newExportContext(e, pb.RpcObjectListExportRequest{ - SpaceId: "spaceId", + SpaceId: spaceId, ObjectIds: []string{"id"}, Format: model.Export_Protobuf, }) @@ -1394,35 +1396,35 @@ func Test_docsForExport(t *testing.T) { func Test_provideFileName(t *testing.T) { t.Run("file dir for relation", func(t *testing.T) { // when - fileName := makeFileName("docId", "spaceId", pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeRelation) + fileName := makeFileName("docId", spaceId, pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeRelation) // then assert.Equal(t, relationsDirectory+string(filepath.Separator)+"docId.pb.json", fileName) }) t.Run("file dir for relation option", func(t *testing.T) { // when - fileName := makeFileName("docId", "spaceId", pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeRelationOption) + fileName := makeFileName("docId", spaceId, pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeRelationOption) // then assert.Equal(t, relationsOptionsDirectory+string(filepath.Separator)+"docId.pb.json", fileName) }) t.Run("file dir for types", func(t *testing.T) { // when - fileName := makeFileName("docId", "spaceId", pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeObjectType) + fileName := makeFileName("docId", spaceId, pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeObjectType) // then assert.Equal(t, typesDirectory+string(filepath.Separator)+"docId.pb.json", fileName) }) t.Run("file dir for objects", func(t *testing.T) { // when - fileName := makeFileName("docId", "spaceId", pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypePage) + fileName := makeFileName("docId", spaceId, pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypePage) // then assert.Equal(t, objectsDirectory+string(filepath.Separator)+"docId.pb.json", fileName) }) t.Run("file dir for files objects", func(t *testing.T) { // when - fileName := makeFileName("docId", "spaceId", pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeFileObject) + fileName := makeFileName("docId", spaceId, pbjson.NewConverter(nil).Ext(), nil, smartblock.SmartBlockTypeFileObject) // then assert.Equal(t, filesObjects+string(filepath.Separator)+"docId.pb.json", fileName) @@ -1430,36 +1432,36 @@ func Test_provideFileName(t *testing.T) { t.Run("space is not provided", func(t *testing.T) { // given st := state.NewDoc("root", nil).(*state.State) - st.SetDetail(bundle.RelationKeySpaceId.String(), pbtypes.String("spaceId")) + st.SetDetail(bundle.RelationKeySpaceId.String(), pbtypes.String(spaceId)) // when fileName := makeFileName("docId", "", pbjson.NewConverter(st).Ext(), st, smartblock.SmartBlockTypeFileObject) // then - assert.Equal(t, spaceDirectory+string(filepath.Separator)+"spaceId"+string(filepath.Separator)+filesObjects+string(filepath.Separator)+"docId.pb.json", fileName) + assert.Equal(t, spaceDirectory+string(filepath.Separator)+spaceId+string(filepath.Separator)+filesObjects+string(filepath.Separator)+"docId.pb.json", fileName) }) } func Test_queryObjectsFromStoreByIds(t *testing.T) { t.Run("query 10 objects", func(t *testing.T) { // given - fixture := objectstore.NewStoreFixture(t) + store := objectstore.NewStoreFixture(t) ids := make([]string, 0, 10) for i := 0; i < 10; i++ { id := fmt.Sprintf("%d", i) - fixture.AddObjects(t, []objectstore.TestObject{ + store.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(id), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) ids = append(ids, id) } - e := &export{objectStore: fixture} + e := &export{objectStore: store} expCtx := newExportContext(e, pb.RpcObjectListExportRequest{}) // when - records, err := expCtx.queryAndFilterObjectsByRelation("spaceId", ids, bundle.RelationKeyId.String()) + records, err := expCtx.queryAndFilterObjectsByRelation(spaceId, ids, bundle.RelationKeyId.String()) // then assert.Nil(t, err) @@ -1471,10 +1473,10 @@ func Test_queryObjectsFromStoreByIds(t *testing.T) { ids := make([]string, 0, 2000) for i := 0; i < 2000; i++ { id := fmt.Sprintf("%d", i) - fixture.AddObjects(t, []objectstore.TestObject{ + fixture.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(id), - bundle.RelationKeySpaceId: pbtypes.String("spaceId"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) ids = append(ids, id) @@ -1483,7 +1485,7 @@ func Test_queryObjectsFromStoreByIds(t *testing.T) { expCtx := newExportContext(e, pb.RpcObjectListExportRequest{}) // when - records, err := expCtx.queryAndFilterObjectsByRelation("spaceId", ids, bundle.RelationKeyId.String()) + records, err := expCtx.queryAndFilterObjectsByRelation(spaceId, ids, bundle.RelationKeyId.String()) // then assert.Nil(t, err) diff --git a/core/block/import/common/objectcreator/objectcreator.go b/core/block/import/common/objectcreator/objectcreator.go index 6e6f05a216..4044d956f8 100644 --- a/core/block/import/common/objectcreator/objectcreator.go +++ b/core/block/import/common/objectcreator/objectcreator.go @@ -104,7 +104,7 @@ func (oc *ObjectCreator) Create(dataObject *DataObject, sn *common.Snapshot) (*t ) defer func() { // delete file in ipfs if there is error after creation - oc.onFinish(err, st, filesToDelete) + oc.onFinish(err, spaceID, st, filesToDelete) }() common.UpdateObjectIDsInRelations(st, oldIDtoNew) @@ -295,21 +295,21 @@ func (oc *ObjectCreator) setRootBlock(snapshot *model.SmartBlockSnapshotBase, ne } } -func (oc *ObjectCreator) onFinish(err error, st *state.State, filesToDelete []string) { +func (oc *ObjectCreator) onFinish(err error, spaceId string, st *state.State, filesToDelete []string) { if err != nil { for _, bl := range st.Blocks() { if f := bl.GetFile(); f != nil { - oc.deleteFile(f.Hash) + oc.deleteFile(spaceId, f.Hash) } for _, hash := range filesToDelete { - oc.deleteFile(hash) + oc.deleteFile(spaceId, hash) } } } } -func (oc *ObjectCreator) deleteFile(hash string) { - inboundLinks, err := oc.objectStore.GetOutboundLinksByID(hash) +func (oc *ObjectCreator) deleteFile(spaceId string, hash string) { + inboundLinks, err := oc.objectStore.SpaceIndex(spaceId).GetOutboundLinksById(hash) if err != nil { log.With("file", hash).Errorf("failed to get inbound links for file: %s", err) } diff --git a/core/block/import/common/objectid/derivedobject.go b/core/block/import/common/objectid/derivedobject.go index 872f76d3ea..79a6645afe 100644 --- a/core/block/import/common/objectid/derivedobject.go +++ b/core/block/import/common/objectid/derivedobject.go @@ -79,13 +79,8 @@ func (d *derivedObject) GetInternalKey(sbType sb.SmartBlockType) string { } func (d *derivedObject) isDeletedObject(spaceId string, uniqueKey string) bool { - ids, _, err := d.objectStore.QueryObjectIDs(database.Query{ + ids, _, err := d.objectStore.SpaceIndex(spaceId).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceId), - }, { Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeyUniqueKey.String(), @@ -102,18 +97,13 @@ func (d *derivedObject) isDeletedObject(spaceId string, uniqueKey string) bool { } func (d *derivedObject) getInternalKey(spaceID, objectId string) (string, error) { - ids, err := d.objectStore.Query(database.Query{ + ids, err := d.objectStore.SpaceIndex(spaceID).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeyId.String(), Value: pbtypes.String(objectId), }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, }, }) if err == nil && len(ids) > 0 { diff --git a/core/block/import/common/objectid/deriveobject_test.go b/core/block/import/common/objectid/deriveobject_test.go index 2f9a5b28eb..5f4074bd75 100644 --- a/core/block/import/common/objectid/deriveobject_test.go +++ b/core/block/import/common/objectid/deriveobject_test.go @@ -50,7 +50,7 @@ func TestDerivedObject_GetIDAndPayload(t *testing.T) { uniqueKey, err := domain.NewUniqueKey(coresb.SmartBlockTypePage, "oldKey") assert.Nil(t, err) - sf.AddObjects(t, []objectstore.TestObject{ + sf.AddObjects(t, "spaceId", []objectstore.TestObject{ { bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), bundle.RelationKeyId: pbtypes.String("oldId"), @@ -86,7 +86,7 @@ func TestDerivedObject_GetIDAndPayload(t *testing.T) { uniqueKey, err := domain.NewUniqueKey(coresb.SmartBlockTypeRelation, "oldKey") assert.Nil(t, err) - sf.AddObjects(t, []objectstore.TestObject{ + sf.AddObjects(t, "spaceId", []objectstore.TestObject{ { bundle.RelationKeyUniqueKey: pbtypes.String(uniqueKey.Marshal()), bundle.RelationKeyId: pbtypes.String("oldId"), diff --git a/core/block/import/common/objectid/existingobject.go b/core/block/import/common/objectid/existingobject.go index 58e646cf32..ef01d6bd35 100644 --- a/core/block/import/common/objectid/existingobject.go +++ b/core/block/import/common/objectid/existingobject.go @@ -50,18 +50,13 @@ func (e *existingObject) getObjectByOldAnytypeID(spaceID string, sn *common.Snap oldAnytypeID := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeyOldAnytypeID.String()) // Check for imported objects - ids, _, err := e.objectStore.QueryObjectIDs(database.Query{ + ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeyOldAnytypeID.String(), Value: pbtypes.String(oldAnytypeID), }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, }, }) if err == nil && len(ids) > 0 { @@ -69,18 +64,13 @@ func (e *existingObject) getObjectByOldAnytypeID(spaceID string, sn *common.Snap } // Check for derived objects - ids, _, err = e.objectStore.QueryObjectIDs(database.Query{ + ids, _, err = e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeyUniqueKey.String(), Value: pbtypes.String(oldAnytypeID), // Old id equals to unique key }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, }, }) if err == nil && len(ids) > 0 { @@ -92,18 +82,13 @@ func (e *existingObject) getObjectByOldAnytypeID(spaceID string, sn *common.Snap func (e *existingObject) getExistingObject(spaceID string, sn *common.Snapshot) string { source := pbtypes.GetString(sn.Snapshot.Data.Details, bundle.RelationKeySourceFilePath.String()) - ids, _, err := e.objectStore.QueryObjectIDs(database.Query{ + ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, RelationKey: bundle.RelationKeySourceFilePath.String(), Value: pbtypes.String(source), }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, }, }) if err == nil && len(ids) > 0 { @@ -115,7 +100,7 @@ func (e *existingObject) getExistingObject(spaceID string, sn *common.Snapshot) func (e *existingObject) getExistingRelationOption(snapshot *common.Snapshot, spaceID string) string { name := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyName.String()) key := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationKey.String()) - ids, _, err := e.objectStore.QueryObjectIDs(database.Query{ + ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, @@ -132,11 +117,6 @@ func (e *existingObject) getExistingRelationOption(snapshot *common.Snapshot, sp RelationKey: bundle.RelationKeyLayout.String(), Value: pbtypes.Int64(int64(model.ObjectType_relationOption)), }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, }, }) if err == nil && len(ids) > 0 { @@ -148,7 +128,7 @@ func (e *existingObject) getExistingRelationOption(snapshot *common.Snapshot, sp func (e *existingObject) getExistingRelation(snapshot *common.Snapshot, spaceID string) string { name := pbtypes.GetString(snapshot.Snapshot.Data.Details, bundle.RelationKeyName.String()) format := pbtypes.GetFloat64(snapshot.Snapshot.Data.Details, bundle.RelationKeyRelationFormat.String()) - ids, _, err := e.objectStore.QueryObjectIDs(database.Query{ + ids, _, err := e.objectStore.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, @@ -165,11 +145,6 @@ func (e *existingObject) getExistingRelation(snapshot *common.Snapshot, spaceID RelationKey: bundle.RelationKeyLayout.String(), Value: pbtypes.Int64(int64(model.ObjectType_relation)), }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, }, }) if err == nil && len(ids) > 0 { diff --git a/core/block/import/markdown/import_test.go b/core/block/import/markdown/import_test.go index dc8c40e346..76860bf2ba 100644 --- a/core/block/import/markdown/import_test.go +++ b/core/block/import/markdown/import_test.go @@ -137,7 +137,7 @@ func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempD Param: fileNameToObjectId[testMdPath], }, }})), - blockbuilder.File("", blockbuilder.FileName(provider.TempDir()+testTxtPath), blockbuilder.FileType(model.BlockContentFile_File)), + blockbuilder.File("", blockbuilder.FileName(filepath.Join(provider.TempDir(), testTxtPath)), blockbuilder.FileType(model.BlockContentFile_File)), blockbuilder.Text("Test link to csv test4", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{ { Range: &model.Range{From: 17, To: 22}, @@ -201,7 +201,7 @@ func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempD Type: model.BlockContentTextMark_Bold, }, }})), - blockbuilder.File("", blockbuilder.FileName(provider.TempDir()+testTxtPath), blockbuilder.FileType(model.BlockContentFile_File)), + blockbuilder.File("", blockbuilder.FileName(filepath.Join(provider.TempDir(), testTxtPath)), blockbuilder.FileType(model.BlockContentFile_File)), blockbuilder.Text("test4", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{ { Range: &model.Range{From: 0, To: 5}, diff --git a/core/block/object/objectcreator/chat.go b/core/block/object/objectcreator/chat.go new file mode 100644 index 0000000000..bdf53f487d --- /dev/null +++ b/core/block/object/objectcreator/chat.go @@ -0,0 +1,85 @@ +package objectcreator + +import ( + "context" + "fmt" + "time" + + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/object/payloadcreator" + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/space/clientspace" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +func (s *service) createChat(ctx context.Context, space clientspace.Space, details *types.Struct) (string, *types.Struct, error) { + payload, err := space.CreateTreePayload(ctx, payloadcreator.PayloadCreationParams{ + Time: time.Now(), + SmartblockType: smartblock.SmartBlockTypeChatObject, + }) + if err != nil { + return "", nil, fmt.Errorf("create tree payload: %w", err) + } + + createState := state.NewDoc(payload.RootRawChange.Id, nil).(*state.State) + details.Fields[bundle.RelationKeyLayout.String()] = pbtypes.Int64(int64(model.ObjectType_chat)) + createState.SetDetails(details) + err = s.addChatDerivedObject(ctx, space, createState, payload.RootRawChange.Id) + if err != nil { + return "", nil, fmt.Errorf("add chat derived object: %w", err) + } + + id, newDetails, err := s.CreateSmartBlockFromStateInSpaceWithOptions(ctx, space, []domain.TypeKey{bundle.TypeKeyChat}, createState, WithPayload(&payload)) + if err != nil { + return "", nil, fmt.Errorf("create smartblock from state: %w", err) + } + + return id, newDetails, nil +} + +func (s *service) addChatDerivedObject(ctx context.Context, space clientspace.Space, st *state.State, chatObjectId string) error { + chatDetails := &types.Struct{Fields: map[string]*types.Value{}} + chatUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeChatDerivedObject, chatObjectId) + if err != nil { + return fmt.Errorf("create payload: %w", err) + } + chatDetails.Fields[bundle.RelationKeyUniqueKey.String()] = pbtypes.String(chatUniqueKey.Marshal()) + + chatReq := CreateObjectRequest{ + ObjectTypeKey: bundle.TypeKeyChatDerived, + Details: chatDetails, + } + + chatId, _, err := s.createObjectInSpace(ctx, space, chatReq) + if err != nil { + return fmt.Errorf("create object: %w", err) + } + + st.SetDetailAndBundledRelation(bundle.RelationKeyChatId, pbtypes.String(chatId)) + st.SetDetailAndBundledRelation(bundle.RelationKeyHasChat, pbtypes.Bool(true)) + return nil +} + +func (s *service) createChatDerived(ctx context.Context, space clientspace.Space, details *types.Struct) (string, *types.Struct, error) { + uniqueKey := pbtypes.GetString(details, bundle.RelationKeyUniqueKey.String()) + key, err := domain.UnmarshalUniqueKey(uniqueKey) + if err != nil { + return "", nil, fmt.Errorf("unmarshal unique key: %w", err) + } + + createState := state.NewDocWithUniqueKey("", nil, key).(*state.State) + details.Fields[bundle.RelationKeyLayout.String()] = pbtypes.Int64(int64(model.ObjectType_chatDerived)) + createState.SetDetails(details) + + id, newDetails, err := s.CreateSmartBlockFromStateInSpace(ctx, space, []domain.TypeKey{bundle.TypeKeyChatDerived}, createState) + if err != nil { + return "", nil, fmt.Errorf("create smartblock from state: %w", err) + } + + return id, newDetails, nil +} diff --git a/core/block/object/objectcreator/creator.go b/core/block/object/objectcreator/creator.go index 980db1202e..140bfa3a21 100644 --- a/core/block/object/objectcreator/creator.go +++ b/core/block/object/objectcreator/creator.go @@ -149,6 +149,10 @@ func (s *service) createObjectInSpace( return s.createRelation(ctx, space, details) case bundle.TypeKeyRelationOption: return s.createRelationOption(ctx, space, details) + case bundle.TypeKeyChat: + return s.createChat(ctx, space, details) + case bundle.TypeKeyChatDerived: + return s.createChatDerived(ctx, space, details) case bundle.TypeKeyFile: return "", nil, fmt.Errorf("files must be created via fileobject service") } diff --git a/core/block/object/objectcreator/installer.go b/core/block/object/objectcreator/installer.go index d2de7d2b51..1fa2156b4a 100644 --- a/core/block/object/objectcreator/installer.go +++ b/core/block/object/objectcreator/installer.go @@ -26,7 +26,7 @@ func (s *service) BundledObjectsIdsToInstall( ctx context.Context, space clientspace.Space, sourceObjectIds []string, -) (objectIds []string, err error) { +) (ids domain.BundledObjectIds, err error) { marketplaceSpace, err := s.spaceService.Get(ctx, addr.AnytypeMarketplaceWorkspace) if err != nil { return nil, fmt.Errorf("get marketplace space: %w", err) @@ -51,7 +51,10 @@ func (s *service) BundledObjectsIdsToInstall( if err != nil { return err } - objectIds = append(objectIds, objectId) + ids = append(ids, domain.BundledObjectId{ + SourceId: sourceObjectId, + DerivedObjectId: objectId, + }) return nil }) if err != nil { @@ -134,7 +137,7 @@ func (s *service) installObject(ctx context.Context, space clientspace.Space, in } func (s *service) listInstalledObjects(space clientspace.Space, sourceObjectIds []string) (map[string]*types.Struct, error) { - existingObjects, err := s.objectStore.Query(database.Query{ + existingObjects, err := s.objectStore.SpaceIndex(space.Id()).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeySourceObject.String(), @@ -142,9 +145,19 @@ func (s *service) listInstalledObjects(space clientspace.Space, sourceObjectIds Value: pbtypes.StringList(sourceObjectIds), }, { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(space.Id()), + Operator: model.BlockContentDataviewFilter_Or, + NestedFilters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyLayout.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(int64(model.ObjectType_objectType)), + }, + { + RelationKey: bundle.RelationKeyLayout.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }, }, }, }) @@ -274,16 +287,21 @@ func (s *service) queryDeletedObjects(space clientspace.Space, sourceObjectIDs [ if err != nil { return nil, err } - return s.objectStore.QueryRaw(&database.Filters{FilterObj: database.FiltersAnd{ + return s.objectStore.SpaceIndex(space.Id()).QueryRaw(&database.Filters{FilterObj: database.FiltersAnd{ + database.FiltersOr{ + database.FilterEq{ + Key: bundle.RelationKeyLayout.String(), + Value: pbtypes.Int64(int64(model.ObjectType_objectType)), + }, + database.FilterEq{ + Key: bundle.RelationKeyLayout.String(), + Value: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }, database.FilterIn{ Key: bundle.RelationKeySourceObject.String(), Value: sourceList, }, - database.FilterEq{ - Key: bundle.RelationKeySpaceId.String(), - Cond: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(space.Id()), - }, database.FiltersOr{ database.FilterEq{ Key: bundle.RelationKeyIsDeleted.String(), diff --git a/core/block/object/objectcreator/installer_test.go b/core/block/object/objectcreator/installer_test.go index df100fd4a0..b9fa01a542 100644 --- a/core/block/object/objectcreator/installer_test.go +++ b/core/block/object/objectcreator/installer_test.go @@ -7,6 +7,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -42,12 +43,13 @@ func TestInstaller_queryDeletedObjects(t *testing.T) { {false, true, "otherSpaceId", bundle.TypeKeyDiaryEntry}, {true, false, "otherSpaceId", bundle.RelationKeyAudioAlbum}, } { - store.AddObjects(t, []objectstore.TestObject{{ + store.AddObjects(t, obj.spaceId, []objectstore.TestObject{{ bundle.RelationKeyId: pbtypes.String(obj.key.URL()), bundle.RelationKeySpaceId: pbtypes.String(obj.spaceId), bundle.RelationKeySourceObject: pbtypes.String(obj.key.BundledURL()), bundle.RelationKeyIsDeleted: pbtypes.Bool(obj.isDeleted), bundle.RelationKeyIsArchived: pbtypes.Bool(obj.isArchived), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), }}) sourceObjectIds = append(sourceObjectIds, obj.key.BundledURL()) if obj.spaceId == spaceId && (obj.isDeleted || obj.isArchived) { diff --git a/core/block/object/objectcreator/object_type.go b/core/block/object/objectcreator/object_type.go index d7da953b46..23df89b7e9 100644 --- a/core/block/object/objectcreator/object_type.go +++ b/core/block/object/objectcreator/object_type.go @@ -101,7 +101,7 @@ func (s *service) prepareRecommendedRelationIds(ctx context.Context, space clien } func (s *service) installTemplatesForObjectType(spc clientspace.Space, typeKey domain.TypeKey) error { - bundledTemplates, err := s.objectStore.Query(database.Query{ + bundledTemplates, err := s.objectStore.SpaceIndex(spc.Id()).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyType.String(), @@ -147,7 +147,7 @@ func (s *service) listInstalledTemplatesForType(spc clientspace.Space, typeKey d if err != nil { return nil, fmt.Errorf("get type id by key: %w", err) } - alreadyInstalledTemplates, err := s.objectStore.Query(database.Query{ + alreadyInstalledTemplates, err := s.objectStore.SpaceIndex(spc.Id()).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyType.String(), @@ -159,11 +159,6 @@ func (s *service) listInstalledTemplatesForType(spc clientspace.Space, typeKey d Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.String(targetObjectTypeID), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spc.Id()), - }, }, }) if err != nil { diff --git a/core/block/object/objectcreator/set.go b/core/block/object/objectcreator/set.go index 82e331974e..7dc4d761e9 100644 --- a/core/block/object/objectcreator/set.go +++ b/core/block/object/objectcreator/set.go @@ -20,7 +20,7 @@ import ( func (s *service) createSet(ctx context.Context, space clientspace.Space, req *pb.RpcObjectCreateSetRequest) (setID string, newDetails *types.Struct, err error) { req.Details = internalflag.PutToDetails(req.Details, req.InternalFlags) - dvContent, err := dataview.BlockBySource(s.objectStore, req.Source) + dvContent, err := dataview.BlockBySource(s.objectStore.SpaceIndex(space.Id()), req.Source) if err != nil { return } diff --git a/core/block/object/objectcreator/smartblock.go b/core/block/object/objectcreator/smartblock.go index 7213d856ac..aa37552e12 100644 --- a/core/block/object/objectcreator/smartblock.go +++ b/core/block/object/objectcreator/smartblock.go @@ -140,6 +140,10 @@ func objectTypeKeysToSmartBlockType(typeKeys []domain.TypeKey) coresb.SmartBlock switch typeKey { case bundle.TypeKeyObjectType: return coresb.SmartBlockTypeObjectType + case bundle.TypeKeyChat: + return coresb.SmartBlockTypeChatObject + case bundle.TypeKeyChatDerived: + return coresb.SmartBlockTypeChatDerivedObject case bundle.TypeKeyRelation: return coresb.SmartBlockTypeRelation case bundle.TypeKeyRelationOption: diff --git a/core/block/object/objectgraph/graph.go b/core/block/object/objectgraph/graph.go index 8fb04826a2..a53728b6e4 100644 --- a/core/block/object/objectgraph/graph.go +++ b/core/block/object/objectgraph/graph.go @@ -1,6 +1,8 @@ package objectgraph import ( + "fmt" + "github.com/anyproto/any-sync/app" "github.com/gogo/protobuf/types" "github.com/samber/lo" @@ -65,7 +67,10 @@ func (gr *Builder) Name() (name string) { } func (gr *Builder) ObjectGraph(req *pb.RpcObjectGraphRequest) ([]*types.Struct, []*pb.RpcObjectGraphEdge, error) { - relations, err := gr.objectStore.ListAllRelations(req.SpaceId) + if req.SpaceId == "" { + return nil, nil, fmt.Errorf("spaceId is required") + } + relations, err := gr.objectStore.SpaceIndex(req.SpaceId).ListAllRelations() if err != nil { return nil, nil, err } @@ -75,6 +80,7 @@ func (gr *Builder) ObjectGraph(req *pb.RpcObjectGraphRequest) ([]*types.Struct, })...) resp, err := gr.subscriptionService.Search(subscription.SubscribeRequest{ + SpaceId: req.SpaceId, Source: req.SetSource, Filters: req.Filters, Keys: lo.Map(relations.Models(), func(rel *model.Relation, _ int) string { return rel.Key }), diff --git a/core/block/object/objectgraph/graph_test.go b/core/block/object/objectgraph/graph_test.go index 2dd282f921..b8c4cf78c8 100644 --- a/core/block/object/objectgraph/graph_test.go +++ b/core/block/object/objectgraph/graph_test.go @@ -13,7 +13,8 @@ import ( "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider/mock_typeprovider" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -21,13 +22,13 @@ import ( type fixture struct { Builder - objectStoreMock *mock_objectstore.MockObjectStore + objectStoreMock *objectstore.StoreFixture sbtProviderMock *mock_typeprovider.MockSmartBlockTypeProvider subscriptionServiceMock *mock_subscription.MockService } func newFixture(t *testing.T) *fixture { - objectStore := mock_objectstore.NewMockObjectStore(t) + objectStore := objectstore.NewStoreFixture(t) sbtProvider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) subscriptionService := mock_subscription.NewMockService(t) @@ -45,36 +46,80 @@ func newFixture(t *testing.T) *fixture { func Test(t *testing.T) { t.Run("sub request - added proper relations", func(t *testing.T) { - fixture := newFixture(t) - fixture.objectStoreMock.EXPECT().ListAllRelations(mock.Anything).Return([]*relationutils.Relation{ - {Relation: bundle.MustGetRelation(bundle.RelationKeyId)}, - {Relation: bundle.MustGetRelation(bundle.RelationKeyName)}, - {Relation: bundle.MustGetRelation(bundle.RelationKeyAuthor)}, - {Relation: bundle.MustGetRelation(bundle.RelationKeyLinkedProjects)}, - }, nil) - fixture.subscriptionServiceMock.EXPECT().Search(mock.Anything).Return(&subscription.SubscribeResponse{ + fx := newFixture(t) + spaceId := "space1" + fx.objectStoreMock.AddObjects(t, spaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyId.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_shorttext)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel3"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyAuthor.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel4"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyLinkedProjects.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + }) + fx.subscriptionServiceMock.EXPECT().Search(mock.Anything).Return(&subscription.SubscribeResponse{ Records: []*types.Struct{}, }, nil) - fixture.subscriptionServiceMock.EXPECT().Unsubscribe(mock.Anything).Return(nil) + fx.subscriptionServiceMock.EXPECT().Unsubscribe(mock.Anything).Return(nil) - req := &pb.RpcObjectGraphRequest{} - graph, edges, err := fixture.ObjectGraph(req) + req := &pb.RpcObjectGraphRequest{ + SpaceId: spaceId, + } + graph, edges, err := fx.ObjectGraph(req) assert.NoError(t, err) - assert.Equal(t, req.Keys[0], "links") - assert.Equal(t, len(req.Keys), 4) + assert.Equal(t, "links", req.Keys[0]) + assert.Equal(t, 4, len(req.Keys)) assert.True(t, len(graph) == 0) assert.True(t, len(edges) == 0) }) t.Run("graph", func(t *testing.T) { - fixture := newFixture(t) - fixture.objectStoreMock.EXPECT().ListAllRelations(mock.Anything).Return([]*relationutils.Relation{ - {Relation: bundle.MustGetRelation(bundle.RelationKeyId)}, - {Relation: bundle.MustGetRelation(bundle.RelationKeyName)}, - {Relation: bundle.MustGetRelation(bundle.RelationKeyAssignee)}, - {Relation: bundle.MustGetRelation(bundle.RelationKeyLinkedProjects)}, - }, nil) - fixture.subscriptionServiceMock.EXPECT().Search(mock.Anything).Return(&subscription.SubscribeResponse{ + fx := newFixture(t) + spaceId := "space1" + fx.objectStoreMock.AddObjects(t, spaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyId.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_shorttext)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel3"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyAuthor.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel4"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyLinkedProjects.String()), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + }) + fx.subscriptionServiceMock.EXPECT().Search(mock.Anything).Return(&subscription.SubscribeResponse{ Records: []*types.Struct{ {Fields: map[string]*types.Value{ bundle.RelationKeyId.String(): pbtypes.String("id1"), @@ -89,11 +134,13 @@ func Test(t *testing.T) { }}, }, }, nil) - fixture.subscriptionServiceMock.EXPECT().Unsubscribe(mock.Anything).Return(nil) - fixture.sbtProviderMock.EXPECT().Type(mock.Anything, mock.Anything).Return(smartblock.SmartBlockTypePage, nil) + fx.subscriptionServiceMock.EXPECT().Unsubscribe(mock.Anything).Return(nil) + fx.sbtProviderMock.EXPECT().Type(mock.Anything, mock.Anything).Return(smartblock.SmartBlockTypePage, nil) - req := &pb.RpcObjectGraphRequest{} - graph, edges, err := fixture.ObjectGraph(req) + req := &pb.RpcObjectGraphRequest{ + SpaceId: spaceId, + } + graph, edges, err := fx.ObjectGraph(req) assert.NoError(t, err) assert.True(t, len(graph) == 3) assert.True(t, len(edges) == 2) diff --git a/core/block/object/treemanager/treemanager.go b/core/block/object/treemanager/treemanager.go index a8b97574b0..16ff881bfa 100644 --- a/core/block/object/treemanager/treemanager.go +++ b/core/block/object/treemanager/treemanager.go @@ -5,6 +5,7 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/commonspace/object/treemanager" "go.uber.org/zap" @@ -79,6 +80,16 @@ func (m *treeManager) GetTree(ctx context.Context, spaceId, id string) (tr objec return sb.Tree(), nil } +func (m *treeManager) ValidateAndPutTree(ctx context.Context, spaceId string, payload treestorage.TreeStorageCreatePayload) error { + // TODO: this should be better done inside cache + spc, err := m.spaceService.Get(ctx, spaceId) + if err != nil { + return err + } + _, err = spc.TreeBuilder().PutTree(ctx, payload, nil) + return err +} + func (m *treeManager) MarkTreeDeleted(ctx context.Context, spaceId, treeId string) error { err := m.onDelete(domain.FullID{ SpaceID: spaceId, diff --git a/core/block/object/treesyncer/treesyncer.go b/core/block/object/treesyncer/treesyncer.go index 6b09d027bd..5bcea6a211 100644 --- a/core/block/object/treesyncer/treesyncer.go +++ b/core/block/object/treesyncer/treesyncer.go @@ -221,8 +221,8 @@ func (t *treeSyncer) requestTree(peerId, id string) { } func (t *treeSyncer) updateTree(p peer.Peer, id string) { - peerId := p.Id() log := log.With(zap.String("treeId", id), zap.String("spaceId", t.spaceId)) + peerId := p.Id() ctx := peer.CtxWithPeerId(t.mainCtx, peerId) tr, err := t.treeManager.GetTree(ctx, t.spaceId, id) if err != nil { diff --git a/core/block/restriction/object.go b/core/block/restriction/object.go index b98bc03d5e..d5a73df71b 100644 --- a/core/block/restriction/object.go +++ b/core/block/restriction/object.go @@ -85,6 +85,8 @@ var ( model.Restrictions_Template, }, model.ObjectType_participant: objRestrictAll, + model.ObjectType_chat: objRestrictEdit, + model.ObjectType_chatDerived: objRestrictEdit, model.ObjectType_tag: objRestrictEdit, } diff --git a/core/block/service.go b/core/block/service.go index 2a1cd0043a..f9b2cdcb8a 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -73,10 +73,6 @@ func init() { } } -type SmartblockOpener interface { - Open(id string) (sb smartblock.SmartBlock, err error) -} - func New() *Service { s := &Service{ openedObjs: &openedObjects{ @@ -401,7 +397,7 @@ func (s *Service) RemoveListOption(optionIds []string, checkInObjects bool) erro st := b.NewState() relKey := pbtypes.GetString(st.Details(), bundle.RelationKeyRelationKey.String()) - records, err := s.objectStore.Query(database.Query{ + records, err := s.objectStore.SpaceIndex(b.SpaceID()).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, @@ -506,7 +502,7 @@ func (s *Service) ObjectToBookmark(ctx context.Context, id string, url string) ( return } - res, err := s.objectStore.GetWithLinksInfoByID(spaceID, id) + res, err := s.objectStore.SpaceIndex(spaceID).GetWithLinksInfoById(id) if err != nil { return } diff --git a/core/block/source/mock_source/mock_Store.go b/core/block/source/mock_source/mock_Store.go new file mode 100644 index 0000000000..cdc4dd5598 --- /dev/null +++ b/core/block/source/mock_source/mock_Store.go @@ -0,0 +1,680 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_source + +import ( + context "context" + + pb "github.com/anyproto/anytype-heart/pb" + mock "github.com/stretchr/testify/mock" + + smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + + source "github.com/anyproto/anytype-heart/core/block/source" + + state "github.com/anyproto/anytype-heart/core/block/editor/state" + + storestate "github.com/anyproto/anytype-heart/core/block/editor/storestate" +) + +// MockStore is an autogenerated mock type for the Store type +type MockStore struct { + mock.Mock +} + +type MockStore_Expecter struct { + mock *mock.Mock +} + +func (_m *MockStore) EXPECT() *MockStore_Expecter { + return &MockStore_Expecter{mock: &_m.Mock} +} + +// Close provides a mock function with given fields: +func (_m *MockStore) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockStore_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockStore_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockStore_Expecter) Close() *MockStore_Close_Call { + return &MockStore_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockStore_Close_Call) Run(run func()) *MockStore_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_Close_Call) Return(err error) *MockStore_Close_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockStore_Close_Call) RunAndReturn(run func() error) *MockStore_Close_Call { + _c.Call.Return(run) + return _c +} + +// GetCreationInfo provides a mock function with given fields: +func (_m *MockStore) GetCreationInfo() (string, int64, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetCreationInfo") + } + + var r0 string + var r1 int64 + var r2 error + if rf, ok := ret.Get(0).(func() (string, int64, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() int64); ok { + r1 = rf() + } else { + r1 = ret.Get(1).(int64) + } + + if rf, ok := ret.Get(2).(func() error); ok { + r2 = rf() + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockStore_GetCreationInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCreationInfo' +type MockStore_GetCreationInfo_Call struct { + *mock.Call +} + +// GetCreationInfo is a helper method to define mock.On call +func (_e *MockStore_Expecter) GetCreationInfo() *MockStore_GetCreationInfo_Call { + return &MockStore_GetCreationInfo_Call{Call: _e.mock.On("GetCreationInfo")} +} + +func (_c *MockStore_GetCreationInfo_Call) Run(run func()) *MockStore_GetCreationInfo_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_GetCreationInfo_Call) Return(creatorObjectId string, createdDate int64, err error) *MockStore_GetCreationInfo_Call { + _c.Call.Return(creatorObjectId, createdDate, err) + return _c +} + +func (_c *MockStore_GetCreationInfo_Call) RunAndReturn(run func() (string, int64, error)) *MockStore_GetCreationInfo_Call { + _c.Call.Return(run) + return _c +} + +// GetFileKeysSnapshot provides a mock function with given fields: +func (_m *MockStore) GetFileKeysSnapshot() []*pb.ChangeFileKeys { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetFileKeysSnapshot") + } + + var r0 []*pb.ChangeFileKeys + if rf, ok := ret.Get(0).(func() []*pb.ChangeFileKeys); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*pb.ChangeFileKeys) + } + } + + return r0 +} + +// MockStore_GetFileKeysSnapshot_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFileKeysSnapshot' +type MockStore_GetFileKeysSnapshot_Call struct { + *mock.Call +} + +// GetFileKeysSnapshot is a helper method to define mock.On call +func (_e *MockStore_Expecter) GetFileKeysSnapshot() *MockStore_GetFileKeysSnapshot_Call { + return &MockStore_GetFileKeysSnapshot_Call{Call: _e.mock.On("GetFileKeysSnapshot")} +} + +func (_c *MockStore_GetFileKeysSnapshot_Call) Run(run func()) *MockStore_GetFileKeysSnapshot_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_GetFileKeysSnapshot_Call) Return(_a0 []*pb.ChangeFileKeys) *MockStore_GetFileKeysSnapshot_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockStore_GetFileKeysSnapshot_Call) RunAndReturn(run func() []*pb.ChangeFileKeys) *MockStore_GetFileKeysSnapshot_Call { + _c.Call.Return(run) + return _c +} + +// Heads provides a mock function with given fields: +func (_m *MockStore) Heads() []string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Heads") + } + + var r0 []string + if rf, ok := ret.Get(0).(func() []string); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + return r0 +} + +// MockStore_Heads_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Heads' +type MockStore_Heads_Call struct { + *mock.Call +} + +// Heads is a helper method to define mock.On call +func (_e *MockStore_Expecter) Heads() *MockStore_Heads_Call { + return &MockStore_Heads_Call{Call: _e.mock.On("Heads")} +} + +func (_c *MockStore_Heads_Call) Run(run func()) *MockStore_Heads_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_Heads_Call) Return(_a0 []string) *MockStore_Heads_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockStore_Heads_Call) RunAndReturn(run func() []string) *MockStore_Heads_Call { + _c.Call.Return(run) + return _c +} + +// Id provides a mock function with given fields: +func (_m *MockStore) Id() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Id") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockStore_Id_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Id' +type MockStore_Id_Call struct { + *mock.Call +} + +// Id is a helper method to define mock.On call +func (_e *MockStore_Expecter) Id() *MockStore_Id_Call { + return &MockStore_Id_Call{Call: _e.mock.On("Id")} +} + +func (_c *MockStore_Id_Call) Run(run func()) *MockStore_Id_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_Id_Call) Return(_a0 string) *MockStore_Id_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockStore_Id_Call) RunAndReturn(run func() string) *MockStore_Id_Call { + _c.Call.Return(run) + return _c +} + +// PushChange provides a mock function with given fields: params +func (_m *MockStore) PushChange(params source.PushChangeParams) (string, error) { + ret := _m.Called(params) + + if len(ret) == 0 { + panic("no return value specified for PushChange") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(source.PushChangeParams) (string, error)); ok { + return rf(params) + } + if rf, ok := ret.Get(0).(func(source.PushChangeParams) string); ok { + r0 = rf(params) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(source.PushChangeParams) error); ok { + r1 = rf(params) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockStore_PushChange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PushChange' +type MockStore_PushChange_Call struct { + *mock.Call +} + +// PushChange is a helper method to define mock.On call +// - params source.PushChangeParams +func (_e *MockStore_Expecter) PushChange(params interface{}) *MockStore_PushChange_Call { + return &MockStore_PushChange_Call{Call: _e.mock.On("PushChange", params)} +} + +func (_c *MockStore_PushChange_Call) Run(run func(params source.PushChangeParams)) *MockStore_PushChange_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(source.PushChangeParams)) + }) + return _c +} + +func (_c *MockStore_PushChange_Call) Return(id string, err error) *MockStore_PushChange_Call { + _c.Call.Return(id, err) + return _c +} + +func (_c *MockStore_PushChange_Call) RunAndReturn(run func(source.PushChangeParams) (string, error)) *MockStore_PushChange_Call { + _c.Call.Return(run) + return _c +} + +// PushStoreChange provides a mock function with given fields: ctx, params +func (_m *MockStore) PushStoreChange(ctx context.Context, params source.PushStoreChangeParams) (string, error) { + ret := _m.Called(ctx, params) + + if len(ret) == 0 { + panic("no return value specified for PushStoreChange") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, source.PushStoreChangeParams) (string, error)); ok { + return rf(ctx, params) + } + if rf, ok := ret.Get(0).(func(context.Context, source.PushStoreChangeParams) string); ok { + r0 = rf(ctx, params) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, source.PushStoreChangeParams) error); ok { + r1 = rf(ctx, params) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockStore_PushStoreChange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PushStoreChange' +type MockStore_PushStoreChange_Call struct { + *mock.Call +} + +// PushStoreChange is a helper method to define mock.On call +// - ctx context.Context +// - params source.PushStoreChangeParams +func (_e *MockStore_Expecter) PushStoreChange(ctx interface{}, params interface{}) *MockStore_PushStoreChange_Call { + return &MockStore_PushStoreChange_Call{Call: _e.mock.On("PushStoreChange", ctx, params)} +} + +func (_c *MockStore_PushStoreChange_Call) Run(run func(ctx context.Context, params source.PushStoreChangeParams)) *MockStore_PushStoreChange_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(source.PushStoreChangeParams)) + }) + return _c +} + +func (_c *MockStore_PushStoreChange_Call) Return(changeId string, err error) *MockStore_PushStoreChange_Call { + _c.Call.Return(changeId, err) + return _c +} + +func (_c *MockStore_PushStoreChange_Call) RunAndReturn(run func(context.Context, source.PushStoreChangeParams) (string, error)) *MockStore_PushStoreChange_Call { + _c.Call.Return(run) + return _c +} + +// ReadDoc provides a mock function with given fields: ctx, receiver, empty +func (_m *MockStore) ReadDoc(ctx context.Context, receiver source.ChangeReceiver, empty bool) (state.Doc, error) { + ret := _m.Called(ctx, receiver, empty) + + if len(ret) == 0 { + panic("no return value specified for ReadDoc") + } + + var r0 state.Doc + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, source.ChangeReceiver, bool) (state.Doc, error)); ok { + return rf(ctx, receiver, empty) + } + if rf, ok := ret.Get(0).(func(context.Context, source.ChangeReceiver, bool) state.Doc); ok { + r0 = rf(ctx, receiver, empty) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(state.Doc) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, source.ChangeReceiver, bool) error); ok { + r1 = rf(ctx, receiver, empty) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockStore_ReadDoc_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadDoc' +type MockStore_ReadDoc_Call struct { + *mock.Call +} + +// ReadDoc is a helper method to define mock.On call +// - ctx context.Context +// - receiver source.ChangeReceiver +// - empty bool +func (_e *MockStore_Expecter) ReadDoc(ctx interface{}, receiver interface{}, empty interface{}) *MockStore_ReadDoc_Call { + return &MockStore_ReadDoc_Call{Call: _e.mock.On("ReadDoc", ctx, receiver, empty)} +} + +func (_c *MockStore_ReadDoc_Call) Run(run func(ctx context.Context, receiver source.ChangeReceiver, empty bool)) *MockStore_ReadDoc_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(source.ChangeReceiver), args[2].(bool)) + }) + return _c +} + +func (_c *MockStore_ReadDoc_Call) Return(doc state.Doc, err error) *MockStore_ReadDoc_Call { + _c.Call.Return(doc, err) + return _c +} + +func (_c *MockStore_ReadDoc_Call) RunAndReturn(run func(context.Context, source.ChangeReceiver, bool) (state.Doc, error)) *MockStore_ReadDoc_Call { + _c.Call.Return(run) + return _c +} + +// ReadOnly provides a mock function with given fields: +func (_m *MockStore) ReadOnly() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ReadOnly") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockStore_ReadOnly_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadOnly' +type MockStore_ReadOnly_Call struct { + *mock.Call +} + +// ReadOnly is a helper method to define mock.On call +func (_e *MockStore_Expecter) ReadOnly() *MockStore_ReadOnly_Call { + return &MockStore_ReadOnly_Call{Call: _e.mock.On("ReadOnly")} +} + +func (_c *MockStore_ReadOnly_Call) Run(run func()) *MockStore_ReadOnly_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_ReadOnly_Call) Return(_a0 bool) *MockStore_ReadOnly_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockStore_ReadOnly_Call) RunAndReturn(run func() bool) *MockStore_ReadOnly_Call { + _c.Call.Return(run) + return _c +} + +// ReadStoreDoc provides a mock function with given fields: ctx, stateStore, onUpdateHook +func (_m *MockStore) ReadStoreDoc(ctx context.Context, stateStore *storestate.StoreState, onUpdateHook func()) error { + ret := _m.Called(ctx, stateStore, onUpdateHook) + + if len(ret) == 0 { + panic("no return value specified for ReadStoreDoc") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *storestate.StoreState, func()) error); ok { + r0 = rf(ctx, stateStore, onUpdateHook) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockStore_ReadStoreDoc_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadStoreDoc' +type MockStore_ReadStoreDoc_Call struct { + *mock.Call +} + +// ReadStoreDoc is a helper method to define mock.On call +// - ctx context.Context +// - stateStore *storestate.StoreState +// - onUpdateHook func() +func (_e *MockStore_Expecter) ReadStoreDoc(ctx interface{}, stateStore interface{}, onUpdateHook interface{}) *MockStore_ReadStoreDoc_Call { + return &MockStore_ReadStoreDoc_Call{Call: _e.mock.On("ReadStoreDoc", ctx, stateStore, onUpdateHook)} +} + +func (_c *MockStore_ReadStoreDoc_Call) Run(run func(ctx context.Context, stateStore *storestate.StoreState, onUpdateHook func())) *MockStore_ReadStoreDoc_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*storestate.StoreState), args[2].(func())) + }) + return _c +} + +func (_c *MockStore_ReadStoreDoc_Call) Return(err error) *MockStore_ReadStoreDoc_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockStore_ReadStoreDoc_Call) RunAndReturn(run func(context.Context, *storestate.StoreState, func()) error) *MockStore_ReadStoreDoc_Call { + _c.Call.Return(run) + return _c +} + +// SetPushChangeHook provides a mock function with given fields: onPushChange +func (_m *MockStore) SetPushChangeHook(onPushChange source.PushChangeHook) { + _m.Called(onPushChange) +} + +// MockStore_SetPushChangeHook_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetPushChangeHook' +type MockStore_SetPushChangeHook_Call struct { + *mock.Call +} + +// SetPushChangeHook is a helper method to define mock.On call +// - onPushChange source.PushChangeHook +func (_e *MockStore_Expecter) SetPushChangeHook(onPushChange interface{}) *MockStore_SetPushChangeHook_Call { + return &MockStore_SetPushChangeHook_Call{Call: _e.mock.On("SetPushChangeHook", onPushChange)} +} + +func (_c *MockStore_SetPushChangeHook_Call) Run(run func(onPushChange source.PushChangeHook)) *MockStore_SetPushChangeHook_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(source.PushChangeHook)) + }) + return _c +} + +func (_c *MockStore_SetPushChangeHook_Call) Return() *MockStore_SetPushChangeHook_Call { + _c.Call.Return() + return _c +} + +func (_c *MockStore_SetPushChangeHook_Call) RunAndReturn(run func(source.PushChangeHook)) *MockStore_SetPushChangeHook_Call { + _c.Call.Return(run) + return _c +} + +// SpaceID provides a mock function with given fields: +func (_m *MockStore) SpaceID() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SpaceID") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockStore_SpaceID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SpaceID' +type MockStore_SpaceID_Call struct { + *mock.Call +} + +// SpaceID is a helper method to define mock.On call +func (_e *MockStore_Expecter) SpaceID() *MockStore_SpaceID_Call { + return &MockStore_SpaceID_Call{Call: _e.mock.On("SpaceID")} +} + +func (_c *MockStore_SpaceID_Call) Run(run func()) *MockStore_SpaceID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_SpaceID_Call) Return(_a0 string) *MockStore_SpaceID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockStore_SpaceID_Call) RunAndReturn(run func() string) *MockStore_SpaceID_Call { + _c.Call.Return(run) + return _c +} + +// Type provides a mock function with given fields: +func (_m *MockStore) Type() smartblock.SmartBlockType { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Type") + } + + var r0 smartblock.SmartBlockType + if rf, ok := ret.Get(0).(func() smartblock.SmartBlockType); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(smartblock.SmartBlockType) + } + + return r0 +} + +// MockStore_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type MockStore_Type_Call struct { + *mock.Call +} + +// Type is a helper method to define mock.On call +func (_e *MockStore_Expecter) Type() *MockStore_Type_Call { + return &MockStore_Type_Call{Call: _e.mock.On("Type")} +} + +func (_c *MockStore_Type_Call) Run(run func()) *MockStore_Type_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockStore_Type_Call) Return(_a0 smartblock.SmartBlockType) *MockStore_Type_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockStore_Type_Call) RunAndReturn(run func() smartblock.SmartBlockType) *MockStore_Type_Call { + _c.Call.Return(run) + return _c +} + +// NewMockStore creates a new instance of MockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockStore(t interface { + mock.TestingT + Cleanup(func()) +}) *MockStore { + mock := &MockStore{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/block/source/service.go b/core/block/source/service.go index aa2f4ed55b..38cdabdace 100644 --- a/core/block/source/service.go +++ b/core/block/source/service.go @@ -23,6 +23,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/addr" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/space/spacecore/storage" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider" ) @@ -34,6 +35,7 @@ func New() Service { } type accountService interface { + AccountID() string MyParticipantId(string) string PersonalSpaceID() string } @@ -64,7 +66,7 @@ type service struct { accountKeysService accountservice.Service storageService storage.ClientStorage fileService files.Service - objectStore Store + objectStore objectstore.ObjectStore fileObjectMigrator fileObjectMigrator mu sync.Mutex @@ -78,9 +80,9 @@ func (s *service) Init(a *app.App) (err error) { s.accountService = app.MustComponent[accountService](a) s.accountKeysService = a.MustComponent(accountservice.CName).(accountservice.Service) s.storageService = a.MustComponent(spacestorage.CName).(storage.ClientStorage) + s.objectStore = app.MustComponent[objectstore.ObjectStore](a) s.fileService = app.MustComponent[files.Service](a) - s.objectStore = app.MustComponent[Store](a) s.fileObjectMigrator = app.MustComponent[fileObjectMigrator](a) return } @@ -96,8 +98,21 @@ type BuildOptions struct { func (b *BuildOptions) BuildTreeOpts() objecttreebuilder.BuildTreeOpts { return objecttreebuilder.BuildTreeOpts{ - Listener: b.Listener, - TreeBuilder: objecttree.BuildKeyFilterableObjectTree, + Listener: b.Listener, + TreeBuilder: func(treeStorage treestorage.TreeStorage, aclList list.AclList) (objecttree.ObjectTree, error) { + ot, err := objecttree.BuildKeyFilterableObjectTree(treeStorage, aclList) + if err != nil { + return nil, err + } + sbt, _, err := typeprovider.GetTypeAndKeyFromRoot(ot.Header()) + if err != nil { + return nil, err + } + if sbt == smartblock.SmartBlockTypeChatDerivedObject || sbt == smartblock.SmartBlockTypeAccountObject { + ot.SetFlusher(objecttree.MarkNewChangeFlusher()) + } + return ot, nil + }, TreeValidator: func(payload treestorage.TreeStorageCreatePayload, buildFunc objecttree.BuildObjectTreeFunc, aclList list.AclList) (retPayload treestorage.TreeStorageCreatePayload, err error) { return objecttree.ValidateFilterRawTree(payload, aclList) }, diff --git a/core/block/source/source.go b/core/block/source/source.go index 4145f0b2f1..821f0dadd6 100644 --- a/core/block/source/source.go +++ b/core/block/source/source.go @@ -27,7 +27,7 @@ import ( "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider" @@ -53,7 +53,9 @@ var ( func MarshalChange(change *pb.Change) (result []byte, dataType string, err error) { data := bytesPool.Get().([]byte)[:0] - defer bytesPool.Put(data) + defer func() { + bytesPool.Put(data) + }() data = slices.Grow(data, change.Size()) n, err := change.MarshalTo(data) @@ -76,7 +78,9 @@ func UnmarshalChange(treeChange *objecttree.Change, data []byte) (result any, er change := &pb.Change{} if treeChange.DataType == dataTypeSnappy { buf := bytesPool.Get().([]byte)[:0] - defer bytesPool.Put(buf) + defer func() { + bytesPool.Put(buf) + }() var n int if n, err = snappy.DecodedLen(data); err == nil { @@ -147,7 +151,7 @@ func (s *service) newTreeSource(ctx context.Context, space Space, id string, bui return nil, err } - return &source{ + src := &source{ ObjectTree: ot, id: id, space: space, @@ -157,9 +161,14 @@ func (s *service) newTreeSource(ctx context.Context, space Space, id string, bui accountKeysService: s.accountKeysService, sbtProvider: s.sbtProvider, fileService: s.fileService, - objectStore: s.objectStore, + objectStore: s.objectStore.SpaceIndex(space.Id()), fileObjectMigrator: s.fileObjectMigrator, - }, nil + } + if sbt == smartblock.SmartBlockTypeChatDerivedObject || sbt == smartblock.SmartBlockTypeAccountObject { + return &store{source: src}, nil + } + + return src, nil } type ObjectTreeProvider interface { @@ -171,11 +180,6 @@ type fileObjectMigrator interface { MigrateFileIdsInDetails(st *state.State, spc Space) } -type Store interface { - GetRelationByKey(spaceId string, key string) (*model.Relation, error) - QueryByID(ids []string) (records []database.Record, err error) -} - type source struct { objecttree.ObjectTree id string @@ -192,7 +196,7 @@ type source struct { accountService accountService accountKeysService accountservice.Service sbtProvider typeprovider.SmartBlockTypeProvider - objectStore Store + objectStore spaceindex.Store fileObjectMigrator fileObjectMigrator } @@ -202,7 +206,7 @@ func (s *source) Tree() objecttree.ObjectTree { return s.ObjectTree } -func (s *source) Update(ot objecttree.ObjectTree) { +func (s *source) Update(ot objecttree.ObjectTree) error { // here it should work, because we always have the most common snapshot of the changes in tree s.lastSnapshotId = ot.Root().Id prevSnapshot := s.lastSnapshotId @@ -224,23 +228,25 @@ func (s *source) Update(ot objecttree.ObjectTree) { if err != nil { log.With(zap.Error(err)).Debug("failed to append the state and send it to receiver") } + return nil } -func (s *source) Rebuild(ot objecttree.ObjectTree) { +func (s *source) Rebuild(ot objecttree.ObjectTree) error { if s.ObjectTree == nil { - return + return nil } doc, err := s.buildState() if err != nil { log.With(zap.Error(err)).Debug("failed to build state") - return + return nil } st := doc.(*state.State) err = s.receiver.StateRebuild(st) if err != nil { log.With(zap.Error(err)).Debug("failed to send the state to receiver") } + return nil } func (s *source) ReadOnly() bool { @@ -323,15 +329,10 @@ func (s *source) buildState() (doc state.Doc, err error) { } func (s *source) GetCreationInfo() (creatorObjectId string, createdDate int64, err error) { - root := s.ObjectTree.Root() - createdDate = root.Timestamp - header := s.ObjectTree.UnmarshalledHeader() - if header != nil && header.Timestamp != 0 && header.Timestamp < createdDate { - createdDate = header.Timestamp - } - if root != nil && root.Identity != nil { - creatorObjectId = domain.NewParticipantId(s.spaceID, root.Identity.Account()) + createdDate = header.Timestamp + if header.Identity != nil { + creatorObjectId = domain.NewParticipantId(s.spaceID, header.Identity.Account()) } return } diff --git a/core/block/source/store.go b/core/block/source/store.go new file mode 100644 index 0000000000..cfbed71307 --- /dev/null +++ b/core/block/source/store.go @@ -0,0 +1,244 @@ +package source + +import ( + "bytes" + "context" + "errors" + "fmt" + "slices" + "time" + + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree" + "github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/gogo/protobuf/proto" + "github.com/golang/snappy" + + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +type PushChangeHook func(params PushChangeParams) (id string, err error) + +var _ updatelistener.UpdateListener = (*store)(nil) + +type Store interface { + Source + ReadStoreDoc(ctx context.Context, stateStore *storestate.StoreState, onUpdateHook func()) (err error) + PushStoreChange(ctx context.Context, params PushStoreChangeParams) (changeId string, err error) + SetPushChangeHook(onPushChange PushChangeHook) +} + +type PushStoreChangeParams struct { + State *storestate.StoreState + Changes []*pb.StoreChangeContent + Time time.Time // used to derive the lastModifiedDate; Default is time.Now() +} + +var ( + _ updatelistener.UpdateListener = (*store)(nil) + _ Store = (*store)(nil) +) + +type store struct { + *source + store *storestate.StoreState + onUpdateHook func() + onPushChange PushChangeHook +} + +func (s *store) GetFileKeysSnapshot() []*pb.ChangeFileKeys { + return nil +} + +func (s *store) SetPushChangeHook(onPushChange PushChangeHook) { + s.onPushChange = onPushChange +} + +func (s *store) ReadDoc(ctx context.Context, receiver ChangeReceiver, empty bool) (doc state.Doc, err error) { + s.receiver = receiver + setter, ok := s.ObjectTree.(synctree.ListenerSetter) + if !ok { + err = fmt.Errorf("should be able to set listner inside object tree") + return + } + setter.SetListener(s) + + // Fake state, this kind of objects not support state operations + + st := state.NewDoc(s.id, nil).(*state.State) + // Set object type here in order to derive value of Type relation in smartblock.Init + st.SetObjectTypeKey(bundle.TypeKeyChatDerived) + st.SetDetailAndBundledRelation(bundle.RelationKeyLayout, pbtypes.Int64(int64(model.ObjectType_chatDerived))) + st.SetDetailAndBundledRelation(bundle.RelationKeyIsHidden, pbtypes.Bool(true)) + return st, nil +} + +func (s *store) PushChange(params PushChangeParams) (id string, err error) { + if s.onPushChange != nil { + return s.onPushChange(params) + } + return "", nil +} + +func (s *store) ReadStoreDoc(ctx context.Context, storeState *storestate.StoreState, onUpdateHook func()) (err error) { + s.onUpdateHook = onUpdateHook + s.store = storeState + + tx, err := s.store.NewTx(ctx) + if err != nil { + return + } + // checking if we have any data in the store regarding the tree (i.e. if tree is first arrived or created) + allIsNew := false + if _, err := tx.GetOrder(s.id); err != nil { + allIsNew = true + } + applier := &storeApply{ + tx: tx, + allIsNew: allIsNew, + ot: s.ObjectTree, + } + if err = applier.Apply(); err != nil { + return errors.Join(tx.Rollback(), err) + } + return tx.Commit() +} + +func (s *store) PushStoreChange(ctx context.Context, params PushStoreChangeParams) (changeId string, err error) { + tx, err := s.store.NewTx(ctx) + if err != nil { + return "", fmt.Errorf("new tx: %w", err) + } + rollback := func(err error) error { + return errors.Join(tx.Rollback(), err) + } + + change := &pb.StoreChange{ + ChangeSet: params.Changes, + } + data, dataType, err := MarshalStoreChange(change) + if err != nil { + return "", fmt.Errorf("marshal change: %w", err) + } + addResult, err := s.ObjectTree.AddContentWithValidator(ctx, objecttree.SignableChangeContent{ + Data: data, + Key: s.accountKeysService.Account().SignKey, + IsEncrypted: true, + DataType: dataType, + Timestamp: params.Time.Unix(), + }, func(change *treechangeproto.RawTreeChangeWithId) error { + order := tx.NextOrder(tx.GetMaxOrder()) + err = tx.ApplyChangeSet(storestate.ChangeSet{ + Id: change.Id, + Order: order, + Changes: params.Changes, + Creator: s.accountService.AccountID(), + Timestamp: params.Time.Unix(), + }) + if err != nil { + return fmt.Errorf("apply change set: %w", err) + } + return nil + }) + if err != nil { + return "", rollback(fmt.Errorf("add content: %w", err)) + } + + if len(addResult.Added) == 0 { + return "", rollback(fmt.Errorf("add changes list is empty")) + } + changeId = addResult.Added[0].Id + err = tx.Commit() + if err == nil { + s.onUpdateHook() + } + return changeId, err +} + +func (s *store) update(ctx context.Context, tree objecttree.ObjectTree) error { + tx, err := s.store.NewTx(ctx) + if err != nil { + return err + } + applier := &storeApply{ + tx: tx, + ot: tree, + } + if err = applier.Apply(); err != nil { + return errors.Join(tx.Rollback(), err) + } + err = tx.Commit() + if err == nil { + s.onUpdateHook() + } + return err +} + +func (s *store) Update(tree objecttree.ObjectTree) error { + err := s.update(context.Background(), tree) + if err != nil { + log.With("objectId", s.id).Errorf("update: failed to read store doc: %v", err) + } + return err +} + +func (s *store) Rebuild(tree objecttree.ObjectTree) error { + err := s.update(context.Background(), tree) + if err != nil { + log.With("objectId", s.id).Errorf("rebuild: failed to read store doc: %v", err) + } + return err +} + +func MarshalStoreChange(change *pb.StoreChange) (result []byte, dataType string, err error) { + data := bytesPool.Get().([]byte)[:0] + defer func() { + bytesPool.Put(data) + }() + + data = slices.Grow(data, change.Size()) + n, err := change.MarshalTo(data) + if err != nil { + return + } + data = data[:n] + + if n > snappyLowerLimit { + result = snappy.Encode(nil, data) + dataType = dataTypeSnappy + } else { + result = bytes.Clone(data) + } + + return +} + +func UnmarshalStoreChange(treeChange *objecttree.Change, data []byte) (result any, err error) { + change := &pb.StoreChange{} + if treeChange.DataType == dataTypeSnappy { + buf := bytesPool.Get().([]byte)[:0] + defer func() { + bytesPool.Put(buf) + }() + + var n int + if n, err = snappy.DecodedLen(data); err == nil { + buf = slices.Grow(buf, n)[:n] + var decoded []byte + decoded, err = snappy.Decode(buf, data) + if err == nil { + data = decoded + } + } + } + if err = proto.Unmarshal(data, change); err == nil { + result = change + } + return +} diff --git a/core/block/source/store_apply.go b/core/block/source/store_apply.go new file mode 100644 index 0000000000..94bacd2437 --- /dev/null +++ b/core/block/source/store_apply.go @@ -0,0 +1,166 @@ +package source + +import ( + "errors" + "fmt" + + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/pb" +) + +type storeApply struct { + tx *storestate.StoreStateTx + ot objecttree.ObjectTree + allIsNew bool + + prevOrder string + prevChange *objecttree.Change + + nextCachedOrder string + nextCacheChange map[string]struct{} +} + +func (a *storeApply) Apply() (err error) { + maxOrder := a.tx.GetMaxOrder() + isEmpty := maxOrder == "" + iterErr := a.ot.IterateRoot(UnmarshalStoreChange, func(change *objecttree.Change) bool { + // not a new change - remember and continue + if !a.allIsNew && !change.IsNew && !isEmpty { + a.prevChange = change + a.prevOrder = "" + return true + } + currOrder, curOrdErr := a.tx.GetOrder(change.Id) + if curOrdErr != nil { + if !errors.Is(curOrdErr, storestate.ErrOrderNotFound) { + err = curOrdErr + return false + } + } else { + // change has been handled before + a.prevChange = change + a.prevOrder = currOrder + return true + } + + prevOrder, prevOrdErr := a.getPrevOrder() + if prevOrdErr != nil { + if !errors.Is(prevOrdErr, storestate.ErrOrderNotFound) { + err = prevOrdErr + return false + } + if !isEmpty { + // it should not happen, consistency with tree and store broken + err = fmt.Errorf("unable to find previous order") + return false + } + } + + if prevOrder == a.tx.GetMaxOrder() { + // insert on top - just create next id + currOrder = a.tx.NextOrder(prevOrder) + } else { + // insert in the middle - find next order and create id between + nextOrder, nextOrdErr := a.findNextOrder(change.Id) + if nextOrdErr != nil { + // it should not happen, consistency with tree and store broken + err = errors.Join(nextOrdErr, fmt.Errorf("unable to find next order")) + return false + } + if currOrder, err = a.tx.NextBeforeOrder(prevOrder, nextOrder); err != nil { + return false + } + } + + if err = a.applyChange(change, currOrder); err != nil { + return false + } + a.prevOrder = currOrder + a.prevChange = change + return true + }) + if err == nil && iterErr != nil { + return iterErr + } + return +} + +func (a *storeApply) applyChange(change *objecttree.Change, order string) (err error) { + storeChange, ok := change.Model.(*pb.StoreChange) + if !ok { + // if it is root + if _, ok := change.Model.(*treechangeproto.TreeChangeInfo); ok { + return a.tx.SetOrder(change.Id, order) + } + return fmt.Errorf("unexpected change content type: %T", change.Model) + } + set := storestate.ChangeSet{ + Id: change.Id, + Order: order, + Changes: storeChange.ChangeSet, + Creator: change.Identity.Account(), + Timestamp: change.Timestamp, + } + err = a.tx.ApplyChangeSet(set) + // Skip invalid changes + if errors.Is(err, storestate.ErrValidation) { + return nil + } + return err +} + +func (a *storeApply) getPrevOrder() (order string, err error) { + if a.prevOrder != "" { + return a.prevOrder, nil + } + if a.prevChange == nil { + return "", nil + } + if order, err = a.tx.GetOrder(a.prevChange.Id); err != nil { + return + } + a.prevOrder = order + return +} + +func (a *storeApply) findNextOrder(changeId string) (order string, err error) { + if order = a.findNextInCache(changeId); order != "" { + return + } + + a.nextCacheChange = map[string]struct{}{} + iterErr := a.ot.IterateFrom(changeId, UnmarshalStoreChange, func(change *objecttree.Change) bool { + order, err = a.tx.GetOrder(change.Id) + if err != nil { + if errors.Is(err, storestate.ErrOrderNotFound) { + // no order - remember id and move forward + a.nextCacheChange[change.Id] = struct{}{} + return true + } else { + return false + } + } + // order found + a.nextCachedOrder = order + return false + }) + if err == nil && iterErr != nil { + return "", iterErr + } + return +} + +func (a *storeApply) findNextInCache(changeId string) (order string) { + if a.nextCacheChange == nil { + return "" + } + if _, ok := a.nextCacheChange[changeId]; ok { + return a.nextCachedOrder + } + a.nextCachedOrder = "" + a.nextCacheChange = nil + return "" +} diff --git a/core/block/source/store_apply_test.go b/core/block/source/store_apply_test.go new file mode 100644 index 0000000000..f373e3d41b --- /dev/null +++ b/core/block/source/store_apply_test.go @@ -0,0 +1,348 @@ +package source + +import ( + "context" + "fmt" + "os" + "path/filepath" + "sort" + "testing" + "time" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-sync/commonspace/object/accountdata" + "github.com/anyproto/any-sync/commonspace/object/acl/list" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree" + "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" + "github.com/anyproto/any-sync/util/crypto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + "github.com/anyproto/anytype-heart/core/block/editor/storestate" + "github.com/anyproto/anytype-heart/pb" +) + +var ctx = context.Background() + +func TestStoreApply_RealTree(t *testing.T) { + update := func(fx *storeFx, heads []string, chs []*treechangeproto.RawTreeChangeWithId) { + tx := fx.RequireTx(t) + defer tx.Rollback() + + _, err := fx.realTree.AddRawChangesWithUpdater(ctx, objecttree.RawChangesPayload{ + NewHeads: heads, + RawChanges: chs, + }, func(tree objecttree.ObjectTree, md objecttree.Mode) error { + applier := &storeApply{ + tx: tx, + ot: fx.realTree, + } + return applier.Apply() + }) + require.NoError(t, err) + require.NoError(t, tx.Commit()) + } + assertOrder := func(fx *storeFx, orders []string) { + var changes []*objecttree.Change + for _, order := range orders { + changes = append(changes, testChange(order, false)) + } + tx := fx.RequireTx(t) + defer tx.Rollback() + + fx.AssertOrder(t, tx, changes...) + } + t.Run("new real tree - 1,2,3 then 4,5", func(t *testing.T) { + fx := newRealTreeStoreFx(t) + newChanges := []*treechangeproto.RawTreeChangeWithId{ + fx.changeCreator.CreateRaw("1", fx.aclList.Head().Id, "0", false, "0"), + fx.changeCreator.CreateRaw("2", fx.aclList.Head().Id, "0", false, "1"), + fx.changeCreator.CreateRaw("3", fx.aclList.Head().Id, "0", true, "2"), + } + update(fx, []string{"3"}, newChanges) + newChanges = []*treechangeproto.RawTreeChangeWithId{ + fx.changeCreator.CreateRaw("4", fx.aclList.Head().Id, "0", false, "0"), + fx.changeCreator.CreateRaw("5", fx.aclList.Head().Id, "0", true, "4"), + } + update(fx, []string{"3", "5"}, newChanges) + assertOrder(fx, []string{"0", "1", "2", "3", "4", "5"}) + }) + t.Run("new real tree - 4,5 then 1,2,3", func(t *testing.T) { + fx := newRealTreeStoreFx(t) + newChanges := []*treechangeproto.RawTreeChangeWithId{ + fx.changeCreator.CreateRaw("4", fx.aclList.Head().Id, "0", false, "0"), + fx.changeCreator.CreateRaw("5", fx.aclList.Head().Id, "0", true, "4"), + } + update(fx, []string{"5"}, newChanges) + newChanges = []*treechangeproto.RawTreeChangeWithId{ + fx.changeCreator.CreateRaw("1", fx.aclList.Head().Id, "0", false, "0"), + fx.changeCreator.CreateRaw("2", fx.aclList.Head().Id, "0", false, "1"), + fx.changeCreator.CreateRaw("3", fx.aclList.Head().Id, "0", true, "2"), + } + update(fx, []string{"3", "5"}, newChanges) + assertOrder(fx, []string{"0", "1", "2", "3", "4", "5"}) + }) + t.Run("new real tree - 1,2,3,4,5 in one batch", func(t *testing.T) { + fx := newRealTreeStoreFx(t) + newChanges := []*treechangeproto.RawTreeChangeWithId{ + fx.changeCreator.CreateRaw("1", fx.aclList.Head().Id, "0", false, "0"), + fx.changeCreator.CreateRaw("2", fx.aclList.Head().Id, "0", false, "1"), + fx.changeCreator.CreateRaw("3", fx.aclList.Head().Id, "0", true, "2"), + fx.changeCreator.CreateRaw("4", fx.aclList.Head().Id, "0", false, "0"), + fx.changeCreator.CreateRaw("5", fx.aclList.Head().Id, "0", true, "4"), + } + update(fx, []string{"3", "4", "5"}, newChanges) + assertOrder(fx, []string{"0", "1", "2", "3", "4", "5"}) + }) +} + +func TestStoreApply_Apply(t *testing.T) { + t.Run("new tree", func(t *testing.T) { + fx := newMockTreeStoreFx(t) + tx := fx.RequireTx(t) + changes := []*objecttree.Change{ + testChange("1", false), + testChange("2", false), + testChange("3", false), + } + fx.ApplyChanges(t, tx, changes...) + require.NoError(t, tx.Commit()) + }) + t.Run("insert middle", func(t *testing.T) { + fx := newMockTreeStoreFx(t) + tx := fx.RequireTx(t) + changes := []*objecttree.Change{ + testChange("1", false), + testChange("2", false), + testChange("3", false), + } + fx.ApplyChanges(t, tx, changes...) + require.NoError(t, tx.Commit()) + + tx = fx.RequireTx(t) + changes = []*objecttree.Change{ + testChange("1", false), + testChange("1.1", true), + testChange("1.2", true), + testChange("1.3", true), + testChange("2", false), + testChange("2.2", true), + testChange("3", false), + } + fx.ExpectTreeFrom("1.1", changes[1:]...) + fx.ExpectTreeFrom("2.2", changes[6:]...) + fx.ApplyChanges(t, tx, changes...) + require.NoError(t, tx.Commit()) + }) + t.Run("append", func(t *testing.T) { + fx := newMockTreeStoreFx(t) + tx := fx.RequireTx(t) + changes := []*objecttree.Change{ + testChange("1", false), + testChange("2", false), + testChange("3", false), + } + fx.ApplyChanges(t, tx, changes...) + require.NoError(t, tx.Commit()) + + tx = fx.RequireTx(t) + changes = []*objecttree.Change{ + testChange("1", false), + testChange("2", false), + testChange("3", false), + testChange("4", true), + testChange("5", true), + testChange("6", true), + } + fx.ApplyChanges(t, tx, changes...) + require.NoError(t, tx.Commit()) + }) +} + +func TestStoreApply_Apply10000(t *testing.T) { + fx := newMockTreeStoreFx(t) + tx := fx.RequireTx(t) + changes := make([]*objecttree.Change, 100000) + for i := range changes { + changes[i] = testChange(fmt.Sprint(i), false) + } + st := time.Now() + applier := &storeApply{ + tx: tx, + ot: fx.mockTree, + } + fx.ExpectTree(changes...) + require.NoError(t, applier.Apply()) + t.Logf("apply dur: %v;", time.Since(st)) + st = time.Now() + require.NoError(t, tx.Commit()) + t.Logf("commit dur: %v;", time.Since(st)) + +} + +type storeFx struct { + state *storestate.StoreState + mockTree *mock_objecttree.MockObjectTree + realTree objecttree.ObjectTree + changeCreator *objecttree.MockChangeCreator + aclList list.AclList + db anystore.DB +} + +func (fx *storeFx) ExpectTree(changes ...*objecttree.Change) { + fx.mockTree.EXPECT().IterateRoot(gomock.Any(), gomock.Any()).DoAndReturn(func(_ objecttree.ChangeConvertFunc, f objecttree.ChangeIterateFunc) error { + for _, ch := range changes { + if !f(ch) { + return nil + } + } + return nil + }) +} + +func (fx *storeFx) ExpectTreeFrom(fromId string, changes ...*objecttree.Change) { + fx.mockTree.EXPECT().IterateFrom(fromId, gomock.Any(), gomock.Any()).DoAndReturn(func(_ string, _ objecttree.ChangeConvertFunc, f objecttree.ChangeIterateFunc) error { + for _, ch := range changes { + if !f(ch) { + return nil + } + } + return nil + }) +} + +func (fx *storeFx) RequireTx(t testing.TB) *storestate.StoreStateTx { + tx, err := fx.state.NewTx(ctx) + require.NoError(t, err) + return tx +} + +func (fx *storeFx) AssertOrder(t testing.TB, tx *storestate.StoreStateTx, changes ...*objecttree.Change) { + var expectedIds = make([]string, len(changes)) + var storeOrders = make([]string, len(changes)) + var err error + for i, ch := range changes { + expectedIds[i] = ch.Id + storeOrders[i], err = tx.GetOrder(ch.Id) + require.NoError(t, err) + } + assert.Equal(t, len(expectedIds), len(storeOrders)) + assert.True(t, sort.StringsAreSorted(storeOrders)) + t.Log(storeOrders) +} + +func (fx *storeFx) ApplyChanges(t *testing.T, tx *storestate.StoreStateTx, changes ...*objecttree.Change) { + applier := &storeApply{ + tx: tx, + ot: fx.mockTree, + } + fx.ExpectTree(changes...) + require.NoError(t, applier.Apply()) + fx.AssertOrder(t, tx, changes...) +} + +func newMockTreeStoreFx(t testing.TB) *storeFx { + tmpDir, err := os.MkdirTemp("", "source_store_*") + require.NoError(t, err) + + db, err := anystore.Open(ctx, filepath.Join(tmpDir, "test.db"), nil) + require.NoError(t, err) + + ctrl := gomock.NewController(t) + t.Cleanup(func() { + if db != nil { + _ = db.Close() + } + ctrl.Finish() + if tmpDir != "" { + _ = os.RemoveAll(tmpDir) + } + }) + + state, err := storestate.New(ctx, "source_test", db, storestate.DefaultHandler{Name: "default"}) + require.NoError(t, err) + + tree := mock_objecttree.NewMockObjectTree(ctrl) + tree.EXPECT().Id().Return("root").AnyTimes() + + return &storeFx{ + state: state, + mockTree: tree, + db: db, + } +} + +func newRealTreeStoreFx(t testing.TB) *storeFx { + tmpDir, err := os.MkdirTemp("", "source_store_*") + require.NoError(t, err) + + db, err := anystore.Open(ctx, filepath.Join(tmpDir, "test.db"), nil) + require.NoError(t, err) + + ctrl := gomock.NewController(t) + t.Cleanup(func() { + if db != nil { + _ = db.Close() + } + ctrl.Finish() + if tmpDir != "" { + _ = os.RemoveAll(tmpDir) + } + }) + + state, err := storestate.New(ctx, "source_test", db, storestate.DefaultHandler{Name: "default"}) + require.NoError(t, err) + aclList, _ := prepareAclList(t) + objTree, err := buildTree(aclList) + require.NoError(t, err) + fx := &storeFx{ + state: state, + realTree: objTree, + aclList: aclList, + changeCreator: objecttree.NewMockChangeCreator(), + db: db, + } + tx := fx.RequireTx(t) + defer tx.Rollback() + applier := &storeApply{ + tx: tx, + allIsNew: true, + ot: fx.realTree, + } + require.NoError(t, applier.Apply()) + require.NoError(t, tx.Commit()) + return fx +} + +func testChange(id string, isNew bool) *objecttree.Change { + _, pub, _ := crypto.GenerateRandomEd25519KeyPair() + + return &objecttree.Change{ + Id: id, + IsNew: isNew, + Model: &pb.StoreChange{}, + Identity: pub, + } +} + +func prepareAclList(t testing.TB) (list.AclList, *accountdata.AccountKeys) { + randKeys, err := accountdata.NewRandom() + require.NoError(t, err) + aclList, err := list.NewTestDerivedAcl("spaceId", randKeys) + require.NoError(t, err, "building acl list should be without error") + + return aclList, randKeys +} + +func buildTree(aclList list.AclList) (objecttree.ObjectTree, error) { + changeCreator := objecttree.NewMockChangeCreator() + treeStorage := changeCreator.CreateNewTreeStorage("0", aclList.Head().Id, false) + tree, err := objecttree.BuildTestableTree(treeStorage, aclList) + if err != nil { + return nil, err + } + tree.SetFlusher(objecttree.MarkNewChangeFlusher()) + return tree, nil +} diff --git a/core/block/source/sub_object_links_migration.go b/core/block/source/sub_object_links_migration.go index 7f1a385642..d02ca31314 100644 --- a/core/block/source/sub_object_links_migration.go +++ b/core/block/source/sub_object_links_migration.go @@ -15,6 +15,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/addr" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -26,10 +27,10 @@ type subObjectsAndProfileLinksMigration struct { identityObjectID string sbType smartblock.SmartBlockType space Space - objectStore Store + objectStore spaceindex.Store } -func NewSubObjectsAndProfileLinksMigration(sbType smartblock.SmartBlockType, space Space, identityObjectID string, objectStore Store) *subObjectsAndProfileLinksMigration { +func NewSubObjectsAndProfileLinksMigration(sbType smartblock.SmartBlockType, space Space, identityObjectID string, objectStore spaceindex.Store) *subObjectsAndProfileLinksMigration { return &subObjectsAndProfileLinksMigration{ space: space, identityObjectID: identityObjectID, @@ -192,7 +193,7 @@ func (m *subObjectsAndProfileLinksMigration) migrateFilter(filter *model.BlockCo log.With("relationKey", filter.RelationKey).Warnf("empty filter value") return nil } - relation, err := m.objectStore.GetRelationByKey(m.space.Id(), filter.RelationKey) + relation, err := m.objectStore.GetRelationByKey(filter.RelationKey) if err != nil { log.Warnf("migration: failed to get relation by key %s: %s", filter.RelationKey, err) } diff --git a/core/block/template/service.go b/core/block/template/service.go index 78911c7cd5..c74f8099c9 100644 --- a/core/block/template/service.go +++ b/core/block/template/service.go @@ -171,7 +171,7 @@ func (s *service) buildState(sb smartblock.SmartBlock) (st *state.State, err err return nil, spacestorage.ErrTreeStorageAlreadyDeleted } - err = s.updateTypeKey(st) + err = s.updateTypeKey(sb.SpaceID(), st) if err != nil { return } @@ -291,7 +291,7 @@ func (s *service) TemplateClone(spaceId string, id string) (templateId string, e } func (s *service) TemplateExportAll(ctx context.Context, path string) (string, error) { - docIds, _, err := s.store.QueryObjectIDs(database.Query{ + records, err := s.store.QueryCrossSpace(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyIsArchived.String(), @@ -314,12 +314,16 @@ func (s *service) TemplateExportAll(ctx context.Context, path string) (string, e if err != nil { return "", err } - if len(docIds) == 0 { + if len(records) == 0 { return "", fmt.Errorf("no templates") } + ids := make([]string, 0, len(records)) + for _, rec := range records { + ids = append(ids, pbtypes.GetString(rec.Details, bundle.RelationKeyId.String())) + } path, _, err = s.exporter.Export(ctx, pb.RpcObjectListExportRequest{ Path: path, - ObjectIds: docIds, + ObjectIds: ids, Format: model.Export_Protobuf, Zip: true, }) @@ -339,11 +343,11 @@ func (s *service) createBlankTemplateState(layout model.ObjectTypeLayout) (st *s return } -func (s *service) updateTypeKey(st *state.State) (err error) { +func (s *service) updateTypeKey(spaceId string, st *state.State) (err error) { objectTypeId := pbtypes.GetString(st.Details(), bundle.RelationKeyTargetObjectType.String()) if objectTypeId != "" { var uniqueKey domain.UniqueKey - uniqueKey, err = s.store.GetUniqueKeyById(objectTypeId) + uniqueKey, err = s.store.SpaceIndex(spaceId).GetUniqueKeyById(objectTypeId) if err != nil { err = fmt.Errorf("get target object type %s: %w", objectTypeId, err) } else if uniqueKey.SmartblockType() != coresb.SmartBlockTypeObjectType { diff --git a/core/chats.go b/core/chats.go index 994a57bdcf..5254b39d04 100644 --- a/core/chats.go +++ b/core/chats.go @@ -3,97 +3,117 @@ package core import ( "context" + "github.com/anyproto/anytype-heart/core/block/chats" "github.com/anyproto/anytype-heart/pb" ) -// TODO: chats are temporary done as dummy API for clients to merge the API +func (mw *Middleware) ChatAddMessage(cctx context.Context, req *pb.RpcChatAddMessageRequest) *pb.RpcChatAddMessageResponse { + ctx := mw.newContext(cctx) + chatService := getService[chats.Service](mw) -func (mw *Middleware) ObjectChatAdd(ctx context.Context, request *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse { - // TODO implement me - return &pb.RpcObjectChatAddResponse{ - Error: &pb.RpcObjectChatAddResponseError{ - Code: pb.RpcObjectChatAddResponseError_UNKNOWN_ERROR, - Description: "not implemented", - }, - } -} - -func (mw *Middleware) ChatAddMessage(ctx context.Context, request *pb.RpcChatAddMessageRequest) *pb.RpcChatAddMessageResponse { - // TODO implement me + messageId, err := chatService.AddMessage(cctx, ctx, req.ChatObjectId, req.Message) + code := mapErrorCode[pb.RpcChatAddMessageResponseErrorCode](err) return &pb.RpcChatAddMessageResponse{ + MessageId: messageId, + Event: ctx.GetResponseEvent(), Error: &pb.RpcChatAddMessageResponseError{ - Code: pb.RpcChatAddMessageResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatEditMessageContent(ctx context.Context, request *pb.RpcChatEditMessageContentRequest) *pb.RpcChatEditMessageContentResponse { - // TODO implement me +func (mw *Middleware) ChatEditMessageContent(cctx context.Context, req *pb.RpcChatEditMessageContentRequest) *pb.RpcChatEditMessageContentResponse { + chatService := getService[chats.Service](mw) + + err := chatService.EditMessage(cctx, req.ChatObjectId, req.MessageId, req.EditedMessage) + code := mapErrorCode[pb.RpcChatEditMessageContentResponseErrorCode](err) return &pb.RpcChatEditMessageContentResponse{ Error: &pb.RpcChatEditMessageContentResponseError{ - Code: pb.RpcChatEditMessageContentResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatToggleMessageReaction(ctx context.Context, request *pb.RpcChatToggleMessageReactionRequest) *pb.RpcChatToggleMessageReactionResponse { - // TODO implement me +func (mw *Middleware) ChatToggleMessageReaction(cctx context.Context, req *pb.RpcChatToggleMessageReactionRequest) *pb.RpcChatToggleMessageReactionResponse { + chatService := getService[chats.Service](mw) + + err := chatService.ToggleMessageReaction(cctx, req.ChatObjectId, req.MessageId, req.Emoji) + code := mapErrorCode[pb.RpcChatToggleMessageReactionResponseErrorCode](err) return &pb.RpcChatToggleMessageReactionResponse{ Error: &pb.RpcChatToggleMessageReactionResponseError{ - Code: pb.RpcChatToggleMessageReactionResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatDeleteMessage(ctx context.Context, request *pb.RpcChatDeleteMessageRequest) *pb.RpcChatDeleteMessageResponse { - // TODO implement me +func (mw *Middleware) ChatDeleteMessage(cctx context.Context, req *pb.RpcChatDeleteMessageRequest) *pb.RpcChatDeleteMessageResponse { + chatService := getService[chats.Service](mw) + + err := chatService.DeleteMessage(cctx, req.ChatObjectId, req.MessageId) + code := mapErrorCode[pb.RpcChatDeleteMessageResponseErrorCode](err) return &pb.RpcChatDeleteMessageResponse{ Error: &pb.RpcChatDeleteMessageResponseError{ - Code: pb.RpcChatDeleteMessageResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatGetMessages(ctx context.Context, request *pb.RpcChatGetMessagesRequest) *pb.RpcChatGetMessagesResponse { - // TODO implement me +func (mw *Middleware) ChatGetMessages(cctx context.Context, req *pb.RpcChatGetMessagesRequest) *pb.RpcChatGetMessagesResponse { + chatService := getService[chats.Service](mw) + + messages, err := chatService.GetMessages(cctx, req.ChatObjectId, req.BeforeOrderId, int(req.Limit)) + code := mapErrorCode[pb.RpcChatGetMessagesResponseErrorCode](err) return &pb.RpcChatGetMessagesResponse{ + Messages: messages, Error: &pb.RpcChatGetMessagesResponseError{ - Code: pb.RpcChatGetMessagesResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatGetMessagesByIds(ctx context.Context, request *pb.RpcChatGetMessagesByIdsRequest) *pb.RpcChatGetMessagesByIdsResponse { - // TODO implement me +func (mw *Middleware) ChatGetMessagesByIds(cctx context.Context, req *pb.RpcChatGetMessagesByIdsRequest) *pb.RpcChatGetMessagesByIdsResponse { + chatService := getService[chats.Service](mw) + + messages, err := chatService.GetMessagesByIds(cctx, req.ChatObjectId, req.MessageIds) + code := mapErrorCode[pb.RpcChatGetMessagesByIdsResponseErrorCode](err) return &pb.RpcChatGetMessagesByIdsResponse{ + Messages: messages, Error: &pb.RpcChatGetMessagesByIdsResponseError{ - Code: pb.RpcChatGetMessagesByIdsResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatSubscribeLastMessages(ctx context.Context, request *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse { - // TODO implement me +func (mw *Middleware) ChatSubscribeLastMessages(cctx context.Context, req *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse { + chatService := getService[chats.Service](mw) + + messages, numBefore, err := chatService.SubscribeLastMessages(cctx, req.ChatObjectId, int(req.Limit)) + code := mapErrorCode[pb.RpcChatSubscribeLastMessagesResponseErrorCode](err) return &pb.RpcChatSubscribeLastMessagesResponse{ + Messages: messages, + NumMessagesBefore: int32(numBefore), Error: &pb.RpcChatSubscribeLastMessagesResponseError{ - Code: pb.RpcChatSubscribeLastMessagesResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } -func (mw *Middleware) ChatUnsubscribe(ctx context.Context, request *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse { - // TODO implement me +func (mw *Middleware) ChatUnsubscribe(cctx context.Context, req *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse { + chatService := getService[chats.Service](mw) + + err := chatService.Unsubscribe(req.ChatObjectId) + code := mapErrorCode[pb.RpcChatUnsubscribeResponseErrorCode](err) return &pb.RpcChatUnsubscribeResponse{ Error: &pb.RpcChatUnsubscribeResponseError{ - Code: pb.RpcChatUnsubscribeResponseError_UNKNOWN_ERROR, - Description: "not implemented", + Code: code, + Description: getErrorDescription(err), }, } } diff --git a/core/configfetcher/configfetcher.go b/core/configfetcher/configfetcher.go index 50490cc4e8..d6fb96def1 100644 --- a/core/configfetcher/configfetcher.go +++ b/core/configfetcher/configfetcher.go @@ -2,6 +2,7 @@ package configfetcher import ( "context" + "errors" "sync" "time" @@ -14,10 +15,9 @@ import ( "github.com/anyproto/anytype-heart/core/event" "github.com/anyproto/anytype-heart/core/wallet" pbMiddle "github.com/anyproto/anytype-heart/pb" - "github.com/anyproto/anytype-heart/pkg/lib/cafe/pb" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/space/clientspace" "github.com/anyproto/anytype-heart/space/spacecore" ) @@ -35,54 +35,26 @@ type WorkspaceGetter interface { GetAllWorkspaces() ([]string, error) } -var defaultAccountState = &pb.AccountState{ - Status: &pb.AccountStateStatus{ - Status: pb.AccountState_Active, - DeletionDate: 0, - }, -} - type ConfigFetcher interface { app.ComponentRunnable - GetAccountState() *pb.AccountState Refetch() } -type personalSpaceIDGetter interface { - PersonalSpaceID() string +type techSpaceGetter interface { + TechSpace() *clientspace.TechSpace } type configFetcher struct { - store objectstore.ObjectStore - eventSender event.Sender - fetched chan struct{} - fetchedClosed sync.Once - + eventSender event.Sender periodicSync periodicsync.PeriodicSync client coordinatorclient.CoordinatorClient spaceService spacecore.SpaceCoreService - account personalSpaceIDGetter + getter techSpaceGetter wallet wallet.Wallet lastStatus model.AccountStatusType mutex sync.Mutex } -func (c *configFetcher) GetAccountState() (state *pb.AccountState) { - select { - case <-c.fetched: - case <-time.After(time.Second): - } - state = defaultAccountState - status, err := c.store.GetAccountStatus() - if err != nil { - log.Debug("failed to account state config from the store: %s", err) - } else { - state.Status.Status = pb.AccountStateStatusType(status.Status) - state.Status.DeletionDate = status.DeletionTimestamp - } - return state -} - func New() ConfigFetcher { return &configFetcher{} } @@ -93,14 +65,12 @@ func (c *configFetcher) Run(context.Context) error { } func (c *configFetcher) Init(a *app.App) (err error) { - c.store = a.MustComponent(objectstore.CName).(objectstore.ObjectStore) c.wallet = a.MustComponent(wallet.CName).(wallet.Wallet) c.eventSender = a.MustComponent(event.CName).(event.Sender) c.periodicSync = periodicsync.NewPeriodicSync(refreshIntervalSecs, timeout, c.updateStatus, logger.CtxLogger{Logger: log.Desugar()}) c.client = a.MustComponent(coordinatorclient.CName).(coordinatorclient.CoordinatorClient) c.spaceService = a.MustComponent(spacecore.CName).(spacecore.SpaceCoreService) - c.account = app.MustComponent[personalSpaceIDGetter](a) - c.fetched = make(chan struct{}) + c.getter = app.MustComponent[techSpaceGetter](a) c.lastStatus = initialStatus return nil } @@ -110,19 +80,10 @@ func (c *configFetcher) Name() (name string) { } func (c *configFetcher) updateStatus(ctx context.Context) (err error) { - defer func() { - c.fetchedClosed.Do(func() { - close(c.fetched) - }) - }() - personalSpaceID := c.account.PersonalSpaceID() - res, err := c.client.StatusCheck(ctx, personalSpaceID) - if err == coordinatorproto.ErrSpaceNotExists { - sp, cErr := c.spaceService.Get(ctx, personalSpaceID) - if cErr != nil { - return cErr - } - header, sErr := sp.Storage().SpaceHeader() + techSpace := c.getter.TechSpace() + res, err := c.client.StatusCheck(ctx, techSpace.Id()) + if errors.Is(err, coordinatorproto.ErrSpaceNotExists) { + header, sErr := techSpace.Storage().SpaceHeader() if sErr != nil { return sErr } @@ -142,10 +103,6 @@ func (c *configFetcher) updateStatus(ctx context.Context) (err error) { if err != nil { return } - err = c.store.SaveAccountStatus(res) - if err != nil { - return - } c.notifyClientApp(res) return } diff --git a/core/create.go b/core/create.go index 2e85936df9..a6546700be 100644 --- a/core/create.go +++ b/core/create.go @@ -3,6 +3,7 @@ package core import ( "context" "errors" + "fmt" "github.com/gogo/protobuf/types" @@ -33,13 +34,24 @@ func (mw *Middleware) ObjectCreate(cctx context.Context, req *pb.RpcObjectCreate TemplateId: req.TemplateId, } id, newDetails, err := creator.CreateObjectUsingObjectUniqueTypeKey(cctx, req.SpaceId, req.ObjectTypeUniqueKey, createReq) - if err != nil { return response(pb.RpcObjectCreateResponseError_UNKNOWN_ERROR, "", nil, err) } + if req.WithChat { + return response(pb.RpcObjectCreateResponseError_UNKNOWN_ERROR, "", nil, fmt.Errorf("WithChat is not implemented")) + } return response(pb.RpcObjectCreateResponseError_NULL, id, newDetails, nil) } +func (mw *Middleware) ObjectChatAdd(cctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse { + return &pb.RpcObjectChatAddResponse{ + Error: &pb.RpcObjectChatAddResponseError{ + Code: pb.RpcObjectChatAddResponseError_UNKNOWN_ERROR, + Description: "not implemented", + }, + } +} + func (mw *Middleware) ObjectCreateSet(cctx context.Context, req *pb.RpcObjectCreateSetRequest) *pb.RpcObjectCreateSetResponse { ctx := mw.newContext(cctx) response := func(code pb.RpcObjectCreateSetResponseErrorCode, id string, newDetails *types.Struct, err error) *pb.RpcObjectCreateSetResponse { @@ -74,7 +86,9 @@ func (mw *Middleware) ObjectCreateSet(cctx context.Context, req *pb.RpcObjectCre } return response(pb.RpcObjectCreateSetResponseError_UNKNOWN_ERROR, "", nil, err) } - + if req.WithChat { + return response(pb.RpcObjectCreateSetResponseError_UNKNOWN_ERROR, "", nil, fmt.Errorf("WithChat is not implemented")) + } return response(pb.RpcObjectCreateSetResponseError_NULL, id, newDetails, nil) } @@ -96,6 +110,10 @@ func (mw *Middleware) ObjectCreateBookmark(cctx context.Context, req *pb.RpcObje if err != nil { return response(pb.RpcObjectCreateBookmarkResponseError_UNKNOWN_ERROR, "", newDetails, err) } + if req.WithChat { + return response(pb.RpcObjectCreateBookmarkResponseError_UNKNOWN_ERROR, "", nil, fmt.Errorf("WithChat is not implemented")) + } + return response(pb.RpcObjectCreateBookmarkResponseError_NULL, id, newDetails, nil) } @@ -196,5 +214,9 @@ func (mw *Middleware) ObjectCreateFromUrl(cctx context.Context, req *pb.RpcObjec if err != nil { return response(pb.RpcObjectCreateFromUrlResponseError_UNKNOWN_ERROR, "", err, nil) } + + if req.WithChat { + return response(pb.RpcObjectCreateFromUrlResponseError_UNKNOWN_ERROR, "", fmt.Errorf("WithChat is not implemented"), nil) + } return response(pb.RpcObjectCreateFromUrlResponseError_NULL, id, nil, newDetails) } diff --git a/core/debug.go b/core/debug.go index d1ba429081..fe5010eec3 100644 --- a/core/debug.go +++ b/core/debug.go @@ -237,3 +237,21 @@ func (mw *Middleware) DebugAccountSelectTrace(cctx context.Context, req *pb.RpcD Path: path, } } + +func (mw *Middleware) DebugAnystoreObjectChanges(cctx context.Context, req *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse { + debugService := getService[debug.Debug](mw) + changes, wrongOrder, err := debugService.DebugAnystoreObjectChanges(cctx, req.ObjectId, req.OrderBy) + if err != nil { + return &pb.RpcDebugAnystoreObjectChangesResponse{ + Error: &pb.RpcDebugAnystoreObjectChangesResponseError{ + Code: pb.RpcDebugAnystoreObjectChangesResponseError_UNKNOWN_ERROR, + Description: getErrorDescription(err), + }, + } + } + + return &pb.RpcDebugAnystoreObjectChangesResponse{ + Changes: changes, + WrongOrder: wrongOrder, + } +} diff --git a/core/debug/service.go b/core/debug/service.go index 33008a0ebe..cf49fb6745 100644 --- a/core/debug/service.go +++ b/core/debug/service.go @@ -20,9 +20,12 @@ import ( "github.com/go-chi/chi/v5" "github.com/gogo/protobuf/jsonpb" + "github.com/anyproto/anytype-heart/core/block/cache" + "github.com/anyproto/anytype-heart/core/block/editor/anystoredebug" "github.com/anyproto/anytype-heart/core/block/editor/state" "github.com/anyproto/anytype-heart/core/block/object/idresolver" "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/space" @@ -43,6 +46,8 @@ type Debug interface { DumpLocalstore(ctx context.Context, spaceID string, objectIds []string, path string) (filename string, err error) SpaceSummary(ctx context.Context, spaceID string) (summary SpaceSummary, err error) TreeHeads(ctx context.Context, id string) (info TreeInfo, err error) + + DebugAnystoreObjectChanges(ctx context.Context, chatObjectId string, orderBy pb.RpcDebugAnystoreObjectChangesRequestOrderBy) ([]*pb.RpcDebugAnystoreObjectChangesResponseChange, bool, error) } type debug struct { @@ -50,6 +55,7 @@ type debug struct { spaceService space.Service resolver idresolver.Resolver statService debugstat.StatService + objectGetter cache.ObjectGetter server *http.Server } @@ -63,6 +69,7 @@ func (d *debug) Init(a *app.App) (err error) { d.spaceService = app.MustComponent[space.Service](a) d.resolver = app.MustComponent[idresolver.Resolver](a) d.statService, _ = a.Component(debugstat.CName).(debugstat.StatService) + d.objectGetter = app.MustComponent[cache.ObjectGetter](a) if d.statService == nil { d.statService = debugstat.NewNoOp() } @@ -231,7 +238,7 @@ func (d *debug) DumpTree(ctx context.Context, objectID string, path string, anon func (d *debug) DumpLocalstore(ctx context.Context, spaceID string, objIds []string, path string) (filename string, err error) { if len(objIds) == 0 { - objIds, err = d.store.ListIds() + objIds, err = d.store.ListIdsCrossSpace() if err != nil { return "", err } @@ -250,8 +257,10 @@ func (d *debug) DumpLocalstore(ctx context.Context, spaceID string, objIds []str var wr io.Writer m := jsonpb.Marshaler{Indent: " "} + store := d.store.SpaceIndex(spaceID) + for _, objId := range objIds { - doc, err := d.store.GetWithLinksInfoByID(spaceID, objId) + doc, err := store.GetWithLinksInfoById(objId) if err != nil { var err2 error wr, err2 = zw.Create(fmt.Sprintf("%s.txt", objId)) @@ -274,3 +283,46 @@ func (d *debug) DumpLocalstore(ctx context.Context, spaceID string, objIds []str } return filename, nil } + +func (d *debug) DebugAnystoreObjectChanges(ctx context.Context, chatObjectId string, orderBy pb.RpcDebugAnystoreObjectChangesRequestOrderBy) ([]*pb.RpcDebugAnystoreObjectChangesResponseChange, bool, error) { + var changesOut []*pb.RpcDebugAnystoreObjectChangesResponseChange + err := cache.Do(d.objectGetter, chatObjectId, func(sb anystoredebug.AnystoreDebug) error { + changes, err := sb.DebugChanges(ctx) + if err != nil { + return err + } + for _, ch := range changes { + var errString string + if ch.Error != nil { + errString = ch.Error.Error() + } + changesOut = append(changesOut, &pb.RpcDebugAnystoreObjectChangesResponseChange{ + ChangeId: ch.ChangeId, + OrderId: ch.OrderId, + Error: errString, + Change: ch.Change, + }) + } + return nil + }) + if err != nil { + return nil, false, err + } + + sortedByOrderId := make([]*pb.RpcDebugAnystoreObjectChangesResponseChange, len(changesOut)) + copy(sortedByOrderId, changesOut) + sort.Slice(sortedByOrderId, func(i, j int) bool { return sortedByOrderId[i].OrderId < sortedByOrderId[j].OrderId }) + + orderIsOK := true + for i, ch := range changesOut { + sortedByOrder := sortedByOrderId[i] + if ch.OrderId != sortedByOrder.OrderId { + orderIsOK = false + } + } + + if orderBy == pb.RpcDebugAnystoreObjectChangesRequest_ORDER_ID { + return sortedByOrderId, !orderIsOK, nil + } + return changesOut, !orderIsOK, nil +} diff --git a/core/debug/treearchive/ziptreestorage/treereadstorage.go b/core/debug/treearchive/ziptreestorage/treereadstorage.go index d89c3b70fe..604e08cef5 100644 --- a/core/debug/treearchive/ziptreestorage/treereadstorage.go +++ b/core/debug/treearchive/ziptreestorage/treereadstorage.go @@ -50,6 +50,10 @@ func NewZipTreeReadStorage(id string, zr *zip.ReadCloser) (st treestorage.TreeSt return } +func (t *zipTreeReadStorage) GetAllChangeIds() (chs []string, err error) { + return nil, fmt.Errorf("get all change ids should not be called") +} + func (z *zipTreeReadStorage) Id() string { return z.id } @@ -78,6 +82,10 @@ func (z *zipTreeReadStorage) GetRawChange(ctx context.Context, id string) (*tree return z.readChange(id) } +func (z *zipTreeReadStorage) GetAppendRawChange(ctx context.Context, buf []byte, id string) (*treechangeproto.RawTreeChangeWithId, error) { + return z.readChange(id) +} + func (z *zipTreeReadStorage) HasChange(ctx context.Context, id string) (ok bool, err error) { _, ok = z.files[id] return diff --git a/core/debug/treearchive/ziptreestorage/treewritestorage.go b/core/debug/treearchive/ziptreestorage/treewritestorage.go index 2d4bc2ac26..c80d87e3f6 100644 --- a/core/debug/treearchive/ziptreestorage/treewritestorage.go +++ b/core/debug/treearchive/ziptreestorage/treewritestorage.go @@ -4,6 +4,7 @@ import ( "archive/zip" "context" "encoding/json" + "fmt" "strings" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" @@ -42,6 +43,10 @@ func (z *zipTreeWriteStorage) Id() string { return z.id } +func (t *zipTreeWriteStorage) GetAllChangeIds() (chs []string, err error) { + return nil, fmt.Errorf("get all change ids should not be called") +} + func (z *zipTreeWriteStorage) Root() (*treechangeproto.RawTreeChangeWithId, error) { panic("should not be implemented") } @@ -78,6 +83,10 @@ func (z *zipTreeWriteStorage) GetRawChange(ctx context.Context, id string) (*tre panic("should not be called") } +func (z *zipTreeWriteStorage) GetAppendRawChange(ctx context.Context, buf []byte, id string) (*treechangeproto.RawTreeChangeWithId, error) { + panic("should not be called") +} + func (z *zipTreeWriteStorage) HasChange(ctx context.Context, id string) (ok bool, err error) { panic("should not be called") } diff --git a/core/debug/treeexporter.go b/core/debug/treeexporter.go index 32983fe0b0..ba0995874c 100644 --- a/core/debug/treeexporter.go +++ b/core/debug/treeexporter.go @@ -56,7 +56,7 @@ func (e *treeExporter) Export(ctx context.Context, path string, tree objecttree. } e.log.Printf("exported tree for a %v", time.Since(st)) - data, err := e.s.GetByIDs(e.id.SpaceID, []string{e.id.ObjectID}) + data, err := e.s.SpaceIndex(e.id.SpaceID).GetInfosByIds([]string{e.id.ObjectID}) if err != nil { e.log.Printf("can't fetch localstore info: %v", err) } else { diff --git a/core/domain/bundledObject.go b/core/domain/bundledObject.go new file mode 100644 index 0000000000..663083fc1b --- /dev/null +++ b/core/domain/bundledObject.go @@ -0,0 +1,38 @@ +package domain + +type BundledObjectId struct { + SourceId string + DerivedObjectId string +} + +type BundledObjectIds []BundledObjectId + +func (b BundledObjectIds) Len() int { + return len(b) +} + +func (b BundledObjectIds) SourceIds() []string { + ids := make([]string, 0, len(b)) + for _, bo := range b { + ids = append(ids, bo.SourceId) + } + return ids +} + +func (b BundledObjectIds) DerivedObjectIds() []string { + ids := make([]string, 0, len(b)) + for _, bo := range b { + ids = append(ids, bo.DerivedObjectId) + } + return ids +} + +func (b BundledObjectIds) Filter(f func(bo BundledObjectId) bool) BundledObjectIds { + res := make([]BundledObjectId, 0, len(b)) + for _, bo := range b { + if f(bo) { + res = append(res, bo) + } + } + return res +} diff --git a/core/domain/uniquekey.go b/core/domain/uniquekey.go index 8e1d242d68..54156eba55 100644 --- a/core/domain/uniquekey.go +++ b/core/domain/uniquekey.go @@ -24,6 +24,8 @@ var smartBlockTypeToKey = map[smartblock.SmartBlockType]string{ smartblock.SmartBlockTypePage: "page", // For migration purposes only, used for old profile data migration smartblock.SmartBlockTypeNotificationObject: "notification", smartblock.SmartBlockTypeDevicesObject: "devices", + smartblock.SmartBlockTypeChatDerivedObject: "chatDerived", + smartblock.SmartBlockTypeAccountObject: "account", } // UniqueKey is unique key composed of two parts: smartblock type and internal key. diff --git a/core/files/fileobject/fileindex.go b/core/files/fileobject/fileindex.go index f63ce2c19c..c6c280c812 100644 --- a/core/files/fileobject/fileindex.go +++ b/core/files/fileobject/fileindex.go @@ -2,13 +2,16 @@ package fileobject import ( "context" + "errors" "fmt" "strings" "sync" "time" + "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/cheggaaa/mb/v3" "github.com/gogo/protobuf/types" + format "github.com/ipfs/go-ipld-format" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/editor/state" @@ -17,6 +20,7 @@ import ( fileblock "github.com/anyproto/anytype-heart/core/block/simple/file" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/files" + "github.com/anyproto/anytype-heart/core/filestorage/rpcstore" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" @@ -122,7 +126,7 @@ func (ind *indexer) initQuery() { } func (ind *indexer) addToQueueFromObjectStore(ctx context.Context) error { - recs, err := ind.objectStore.Query(ind.query) + recs, err := ind.objectStore.QueryCrossSpace(ind.query) if err != nil { return fmt.Errorf("query: %w", err) } @@ -182,11 +186,24 @@ func (ind *indexer) runIndexingWorker() { default: } if err := ind.indexNext(ind.indexCtx); err != nil { - log.Errorf("index loop: %v", err) + logIndexLoop(err) } } } +func logIndexLoop(err error) { + if errors.Is(err, treestorage.ErrUnknownTreeId) { + return + } + if errors.Is(err, format.ErrNotFound{}) { + return + } + if errors.Is(err, rpcstore.ErrNoConnectionToAnyFileClient) { + return + } + log.Errorf("index loop: %v", err) +} + func (ind *indexer) indexNext(ctx context.Context) error { req, err := ind.indexQueue.NewCond().WaitOne(ctx) if err != nil { diff --git a/core/files/fileobject/fileindex_test.go b/core/files/fileobject/fileindex_test.go index 4aacf6a058..2792202007 100644 --- a/core/files/fileobject/fileindex_test.go +++ b/core/files/fileobject/fileindex_test.go @@ -160,7 +160,7 @@ func TestIndexer_addFromObjectStore(t *testing.T) { ctx := context.Background() // Use same testFileId everywhere to pass domain.IsFileId check. It doesn't matter that files are same here - fx.objectStoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.objectStoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyFileId: pbtypes.String(testFileId.String()), @@ -168,6 +168,8 @@ func TestIndexer_addFromObjectStore(t *testing.T) { bundle.RelationKeyFileIndexingStatus: pbtypes.Int64(int64(model.FileIndexingStatus_NotIndexed)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_file)), }, + }) + fx.objectStoreFixture.AddObjects(t, "space2", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id2"), bundle.RelationKeyFileId: pbtypes.String(testFileId.String()), @@ -175,6 +177,8 @@ func TestIndexer_addFromObjectStore(t *testing.T) { bundle.RelationKeyFileIndexingStatus: pbtypes.Int64(int64(model.FileIndexingStatus_Indexed)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_image)), }, + }) + fx.objectStoreFixture.AddObjects(t, "space3", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id3"), bundle.RelationKeyFileId: pbtypes.String(testFileId.String()), @@ -182,12 +186,16 @@ func TestIndexer_addFromObjectStore(t *testing.T) { bundle.RelationKeyFileIndexingStatus: pbtypes.Int64(int64(model.FileIndexingStatus_NotFound)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_video)), }, + }) + fx.objectStoreFixture.AddObjects(t, "space4", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id4"), bundle.RelationKeyFileId: pbtypes.String(testFileId.String()), bundle.RelationKeySpaceId: pbtypes.String("space4"), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_audio)), }, + }) + fx.objectStoreFixture.AddObjects(t, "space5", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id5"), bundle.RelationKeySpaceId: pbtypes.String("space5"), @@ -213,7 +221,7 @@ func TestIndexer_addFromObjectStore(t *testing.T) { fx := newIndexerFixture(t) ctx := context.Background() - fx.objectStoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.objectStoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyFileId: pbtypes.String(testFileId.String()), diff --git a/core/files/fileobject/filemodels/filerequest.go b/core/files/fileobject/filemodels/filerequest.go new file mode 100644 index 0000000000..2b9dc660aa --- /dev/null +++ b/core/files/fileobject/filemodels/filerequest.go @@ -0,0 +1,23 @@ +package filemodels + +import ( + "fmt" + + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/domain/objectorigin" +) + +type CreateRequest struct { + FileId domain.FileId + EncryptionKeys map[string]string + ObjectOrigin objectorigin.ObjectOrigin + AdditionalDetails *types.Struct + AsyncMetadataIndexing bool +} + +var ( + ErrObjectNotFound = fmt.Errorf("file object not found") + ErrEmptyFileId = fmt.Errorf("empty file id") +) diff --git a/core/files/fileobject/migration.go b/core/files/fileobject/migration.go index 2cd06280cb..fb6e5e3e35 100644 --- a/core/files/fileobject/migration.go +++ b/core/files/fileobject/migration.go @@ -14,6 +14,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/source" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/domain/objectorigin" + "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" @@ -25,7 +26,7 @@ import ( type migrationItem struct { FileObjectId string SpaceId string - CreateRequest CreateRequest + CreateRequest filemodels.CreateRequest UniqueKeyRaw string } @@ -124,7 +125,7 @@ func (s *service) migrateFile(space clientspace.Space, origin objectorigin.Objec queueIt := &migrationItem{ FileObjectId: fileObjectId, SpaceId: space.Id(), - CreateRequest: CreateRequest{ + CreateRequest: filemodels.CreateRequest{ FileId: fileId, EncryptionKeys: fileKeysChange.Keys, ObjectOrigin: origin, @@ -165,7 +166,7 @@ func (s *service) migrationQueueHandler(ctx context.Context, it *migrationItem) return persistentqueue.ActionDone, nil } -func (s *service) migrateDeriveObject(ctx context.Context, space clientspace.Space, req CreateRequest, uniqueKey domain.UniqueKey) (err error) { +func (s *service) migrateDeriveObject(ctx context.Context, space clientspace.Space, req filemodels.CreateRequest, uniqueKey domain.UniqueKey) (err error) { if req.FileId == "" { return fmt.Errorf("file hash is empty") } diff --git a/core/files/fileobject/migration_test.go b/core/files/fileobject/migration_test.go index 144891cb16..fed8174096 100644 --- a/core/files/fileobject/migration_test.go +++ b/core/files/fileobject/migration_test.go @@ -211,7 +211,7 @@ func TestMigrateIds(t *testing.T) { space := mock_clientspace.NewMockSpace(t) space.EXPECT().IsPersonal().Return(true) - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, "spaceId2", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(fileId.String()), bundle.RelationKeyFileId: pbtypes.String("fileId"), diff --git a/core/files/fileobject/mock_fileobject/mock_Service.go b/core/files/fileobject/mock_fileobject/mock_Service.go index aac93f9db3..c808d2d327 100644 --- a/core/files/fileobject/mock_fileobject/mock_Service.go +++ b/core/files/fileobject/mock_fileobject/mock_Service.go @@ -9,7 +9,7 @@ import ( domain "github.com/anyproto/anytype-heart/core/domain" - fileobject "github.com/anyproto/anytype-heart/core/files/fileobject" + filemodels "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" mock "github.com/stretchr/testify/mock" @@ -84,7 +84,7 @@ func (_c *MockService_Close_Call) RunAndReturn(run func(context.Context) error) } // Create provides a mock function with given fields: ctx, spaceId, req -func (_m *MockService) Create(ctx context.Context, spaceId string, req fileobject.CreateRequest) (string, *types.Struct, error) { +func (_m *MockService) Create(ctx context.Context, spaceId string, req filemodels.CreateRequest) (string, *types.Struct, error) { ret := _m.Called(ctx, spaceId, req) if len(ret) == 0 { @@ -94,16 +94,16 @@ func (_m *MockService) Create(ctx context.Context, spaceId string, req fileobjec var r0 string var r1 *types.Struct var r2 error - if rf, ok := ret.Get(0).(func(context.Context, string, fileobject.CreateRequest) (string, *types.Struct, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, filemodels.CreateRequest) (string, *types.Struct, error)); ok { return rf(ctx, spaceId, req) } - if rf, ok := ret.Get(0).(func(context.Context, string, fileobject.CreateRequest) string); ok { + if rf, ok := ret.Get(0).(func(context.Context, string, filemodels.CreateRequest) string); ok { r0 = rf(ctx, spaceId, req) } else { r0 = ret.Get(0).(string) } - if rf, ok := ret.Get(1).(func(context.Context, string, fileobject.CreateRequest) *types.Struct); ok { + if rf, ok := ret.Get(1).(func(context.Context, string, filemodels.CreateRequest) *types.Struct); ok { r1 = rf(ctx, spaceId, req) } else { if ret.Get(1) != nil { @@ -111,7 +111,7 @@ func (_m *MockService) Create(ctx context.Context, spaceId string, req fileobjec } } - if rf, ok := ret.Get(2).(func(context.Context, string, fileobject.CreateRequest) error); ok { + if rf, ok := ret.Get(2).(func(context.Context, string, filemodels.CreateRequest) error); ok { r2 = rf(ctx, spaceId, req) } else { r2 = ret.Error(2) @@ -128,14 +128,14 @@ type MockService_Create_Call struct { // Create is a helper method to define mock.On call // - ctx context.Context // - spaceId string -// - req fileobject.CreateRequest +// - req filemodels.CreateRequest func (_e *MockService_Expecter) Create(ctx interface{}, spaceId interface{}, req interface{}) *MockService_Create_Call { return &MockService_Create_Call{Call: _e.mock.On("Create", ctx, spaceId, req)} } -func (_c *MockService_Create_Call) Run(run func(ctx context.Context, spaceId string, req fileobject.CreateRequest)) *MockService_Create_Call { +func (_c *MockService_Create_Call) Run(run func(ctx context.Context, spaceId string, req filemodels.CreateRequest)) *MockService_Create_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(fileobject.CreateRequest)) + run(args[0].(context.Context), args[1].(string), args[2].(filemodels.CreateRequest)) }) return _c } @@ -145,7 +145,7 @@ func (_c *MockService_Create_Call) Return(id string, object *types.Struct, err e return _c } -func (_c *MockService_Create_Call) RunAndReturn(run func(context.Context, string, fileobject.CreateRequest) (string, *types.Struct, error)) *MockService_Create_Call { +func (_c *MockService_Create_Call) RunAndReturn(run func(context.Context, string, filemodels.CreateRequest) (string, *types.Struct, error)) *MockService_Create_Call { _c.Call.Return(run) return _c } @@ -207,17 +207,17 @@ func (_c *MockService_CreateFromImport_Call) RunAndReturn(run func(domain.FullFi return _c } -// DeleteFileData provides a mock function with given fields: objectId -func (_m *MockService) DeleteFileData(objectId string) error { - ret := _m.Called(objectId) +// DeleteFileData provides a mock function with given fields: spaceId, objectId +func (_m *MockService) DeleteFileData(spaceId string, objectId string) error { + ret := _m.Called(spaceId, objectId) if len(ret) == 0 { panic("no return value specified for DeleteFileData") } var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(objectId) + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(spaceId, objectId) } else { r0 = ret.Error(0) } @@ -231,14 +231,15 @@ type MockService_DeleteFileData_Call struct { } // DeleteFileData is a helper method to define mock.On call +// - spaceId string // - objectId string -func (_e *MockService_Expecter) DeleteFileData(objectId interface{}) *MockService_DeleteFileData_Call { - return &MockService_DeleteFileData_Call{Call: _e.mock.On("DeleteFileData", objectId)} +func (_e *MockService_Expecter) DeleteFileData(spaceId interface{}, objectId interface{}) *MockService_DeleteFileData_Call { + return &MockService_DeleteFileData_Call{Call: _e.mock.On("DeleteFileData", spaceId, objectId)} } -func (_c *MockService_DeleteFileData_Call) Run(run func(objectId string)) *MockService_DeleteFileData_Call { +func (_c *MockService_DeleteFileData_Call) Run(run func(spaceId string, objectId string)) *MockService_DeleteFileData_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) + run(args[0].(string), args[1].(string)) }) return _c } @@ -248,7 +249,7 @@ func (_c *MockService_DeleteFileData_Call) Return(_a0 error) *MockService_Delete return _c } -func (_c *MockService_DeleteFileData_Call) RunAndReturn(run func(string) error) *MockService_DeleteFileData_Call { +func (_c *MockService_DeleteFileData_Call) RunAndReturn(run func(string, string) error) *MockService_DeleteFileData_Call { _c.Call.Return(run) return _c } diff --git a/core/files/fileobject/service.go b/core/files/fileobject/service.go index 9e82dc0b00..367419ea8a 100644 --- a/core/files/fileobject/service.go +++ b/core/files/fileobject/service.go @@ -2,6 +2,7 @@ package fileobject import ( "context" + "errors" "fmt" "sync" "time" @@ -22,6 +23,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/domain/objectorigin" "github.com/anyproto/anytype-heart/core/files" + "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" "github.com/anyproto/anytype-heart/core/files/fileoffloader" "github.com/anyproto/anytype-heart/core/filestorage/filesync" "github.com/anyproto/anytype-heart/core/syncstatus/filesyncstatus" @@ -44,19 +46,14 @@ import ( // TODO UNsugar var log = logging.Logger("fileobject") -var ( - ErrObjectNotFound = fmt.Errorf("file object not found") - ErrEmptyFileId = fmt.Errorf("empty file id") -) - const CName = "fileobject" type Service interface { app.ComponentRunnable InitEmptyFileState(st *state.State) - DeleteFileData(objectId string) error - Create(ctx context.Context, spaceId string, req CreateRequest) (id string, object *types.Struct, err error) + DeleteFileData(spaceId string, objectId string) error + Create(ctx context.Context, spaceId string, req filemodels.CreateRequest) (id string, object *types.Struct, err error) CreateFromImport(fileId domain.FullFileId, origin objectorigin.ObjectOrigin) (string, error) GetFileIdFromObject(objectId string) (domain.FullFileId, error) GetFileIdFromObjectWaitLoad(ctx context.Context, objectId string) (domain.FullFileId, error) @@ -174,7 +171,7 @@ func (s *service) deleteMigratedFilesInNonPersonalSpaces(ctx context.Context) er return err } - objectIds, _, err := s.objectStore.QueryObjectIDs(database.Query{ + records, err := s.objectStore.QueryCrossSpace(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyFileId.String(), @@ -194,8 +191,12 @@ func (s *service) deleteMigratedFilesInNonPersonalSpaces(ctx context.Context) er if err != nil { return err } - if len(objectIds) > 0 { - if err = s.objectArchiver.SetListIsArchived(objectIds, true); err != nil { + if len(records) > 0 { + ids := make([]string, 0, len(records)) + for _, record := range records { + ids = append(ids, pbtypes.GetString(record.Details, bundle.RelationKeyId.String())) + } + if err = s.objectArchiver.SetListIsArchived(ids, true); err != nil { return err } } @@ -205,7 +206,7 @@ func (s *service) deleteMigratedFilesInNonPersonalSpaces(ctx context.Context) er // After migrating to new sync queue we need to ensure that all not synced files are added to the queue func (s *service) ensureNotSyncedFilesAddedToQueue() error { - records, err := s.objectStore.Query(database.Query{ + records, err := s.objectStore.QueryCrossSpace(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyFileId.String(), @@ -257,15 +258,8 @@ func (s *service) EnsureFileAddedToSyncQueue(id domain.FullID, details *types.St func (s *service) Close(ctx context.Context) error { s.closeWg.Wait() - return s.indexer.close() -} - -type CreateRequest struct { - FileId domain.FileId - EncryptionKeys map[string]string - ObjectOrigin objectorigin.ObjectOrigin - AdditionalDetails *types.Struct - AsyncMetadataIndexing bool + err := s.migrationQueue.Close() + return errors.Join(err, s.indexer.close()) } func (s *service) InitEmptyFileState(st *state.State) { @@ -278,7 +272,7 @@ func (s *service) InitEmptyFileState(st *state.State) { ) } -func (s *service) Create(ctx context.Context, spaceId string, req CreateRequest) (id string, object *types.Struct, err error) { +func (s *service) Create(ctx context.Context, spaceId string, req filemodels.CreateRequest) (id string, object *types.Struct, err error) { space, err := s.spaceService.Get(ctx, spaceId) if err != nil { return "", nil, fmt.Errorf("get space: %w", err) @@ -296,7 +290,7 @@ func (s *service) Create(ctx context.Context, spaceId string, req CreateRequest) return id, object, nil } -func (s *service) createInSpace(ctx context.Context, space clientspace.Space, req CreateRequest) (id string, object *types.Struct, err error) { +func (s *service) createInSpace(ctx context.Context, space clientspace.Space, req filemodels.CreateRequest) (id string, object *types.Struct, err error) { if req.FileId == "" { return "", nil, fmt.Errorf("file hash is empty") } @@ -369,7 +363,7 @@ func (s *service) makeInitialDetails(fileId domain.FileId, origin objectorigin.O // CreateFromImport creates file object from imported raw IPFS file. Encryption keys for this file should exist in file store. func (s *service) CreateFromImport(fileId domain.FullFileId, origin objectorigin.ObjectOrigin) (string, error) { // Check that fileId is not a file object id - recs, _, err := s.objectStore.QueryObjectIDs(database.Query{ + recs, _, err := s.objectStore.SpaceIndex(fileId.SpaceId).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyId.String(), @@ -395,7 +389,7 @@ func (s *service) CreateFromImport(fileId domain.FullFileId, origin objectorigin if err != nil { return "", fmt.Errorf("get file keys: %w", err) } - fileObjectId, _, err = s.Create(context.Background(), fileId.SpaceId, CreateRequest{ + fileObjectId, _, err = s.Create(context.Background(), fileId.SpaceId, filemodels.CreateRequest{ FileId: fileId.FileId, EncryptionKeys: keys, ObjectOrigin: origin, @@ -414,32 +408,8 @@ func (s *service) addToSyncQueue(objectId string, fileId domain.FullFileId, uplo return nil } -func (s *service) GetObjectIdByFileId(fileId domain.FullFileId) (string, error) { - records, err := s.objectStore.Query(database.Query{ - Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeyFileId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(fileId.FileId.String()), - }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(fileId.SpaceId), - }, - }, - }) - if err != nil { - return "", fmt.Errorf("query objects by file hash: %w", err) - } - if len(records) == 0 { - return "", ErrObjectNotFound - } - return pbtypes.GetString(records[0].Details, bundle.RelationKeyId.String()), nil -} - func (s *service) GetObjectDetailsByFileId(fileId domain.FullFileId) (string, *types.Struct, error) { - records, err := s.objectStore.Query(database.Query{ + records, err := s.objectStore.SpaceIndex(fileId.SpaceId).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyFileId.String(), @@ -457,21 +427,24 @@ func (s *service) GetObjectDetailsByFileId(fileId domain.FullFileId) (string, *t return "", nil, fmt.Errorf("query objects by file hash: %w", err) } if len(records) == 0 { - return "", nil, ErrObjectNotFound + return "", nil, filemodels.ErrObjectNotFound } details := records[0].Details return pbtypes.GetString(details, bundle.RelationKeyId.String()), details, nil } func (s *service) GetFileIdFromObject(objectId string) (domain.FullFileId, error) { - details, err := s.objectStore.GetDetails(objectId) + spaceId, err := s.spaceIdResolver.ResolveSpaceID(objectId) + if err != nil { + return domain.FullFileId{}, fmt.Errorf("resolve space id: %w", err) + } + details, err := s.objectStore.SpaceIndex(spaceId).GetDetails(objectId) if err != nil { return domain.FullFileId{}, fmt.Errorf("get object details: %w", err) } - spaceId := pbtypes.GetString(details.Details, bundle.RelationKeySpaceId.String()) fileId := pbtypes.GetString(details.Details, bundle.RelationKeyFileId.String()) if fileId == "" { - return domain.FullFileId{}, ErrEmptyFileId + return domain.FullFileId{}, filemodels.ErrEmptyFileId } return domain.FullFileId{ SpaceId: spaceId, @@ -495,7 +468,7 @@ func (s *service) GetFileIdFromObjectWaitLoad(ctx context.Context, objectId stri details := sb.Details() id.FileId = domain.FileId(pbtypes.GetString(details, bundle.RelationKeyFileId.String())) if id.FileId == "" { - return ErrEmptyFileId + return filemodels.ErrEmptyFileId } return nil }) @@ -527,12 +500,12 @@ func (s *service) resolveSpaceIdWithRetry(ctx context.Context, objectId string) return spaceId, err } -func (s *service) DeleteFileData(objectId string) error { +func (s *service) DeleteFileData(spaceId string, objectId string) error { fullId, err := s.GetFileIdFromObject(objectId) if err != nil { return fmt.Errorf("get file id from object: %w", err) } - records, err := s.objectStore.Query(database.Query{ + records, err := s.objectStore.QueryCrossSpace(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyId.String(), @@ -556,7 +529,7 @@ func (s *service) DeleteFileData(objectId string) error { if err := s.fileSync.DeleteFile(objectId, fullId); err != nil { return fmt.Errorf("failed to remove file from sync: %w", err) } - _, err = s.fileOffloader.FileOffload(context.Background(), objectId, true) + _, err = s.fileOffloader.FileOffloadFullId(context.Background(), domain.FullID{SpaceID: spaceId, ObjectID: objectId}, true) if err != nil { return err } diff --git a/core/files/fileobject/service_test.go b/core/files/fileobject/service_test.go index c8dc3350b5..b8c2999e88 100644 --- a/core/files/fileobject/service_test.go +++ b/core/files/fileobject/service_test.go @@ -25,6 +25,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/event/mock_event" "github.com/anyproto/anytype-heart/core/files" + "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" "github.com/anyproto/anytype-heart/core/files/fileoffloader" "github.com/anyproto/anytype-heart/core/filestorage" "github.com/anyproto/anytype-heart/core/filestorage/filesync" @@ -269,6 +270,6 @@ func TestGetFileIdFromObjectWaitLoad(t *testing.T) { fx.spaceService.EXPECT().Get(ctx, spaceId).Return(space, nil) _, err := fx.GetFileIdFromObjectWaitLoad(ctx, testFileObjectId) - require.ErrorIs(t, err, ErrEmptyFileId) + require.ErrorIs(t, err, filemodels.ErrEmptyFileId) }) } diff --git a/core/files/fileoffloader/offloader.go b/core/files/fileoffloader/offloader.go index 65a0ec65fe..deb724ba13 100644 --- a/core/files/fileoffloader/offloader.go +++ b/core/files/fileoffloader/offloader.go @@ -13,6 +13,7 @@ import ( ipld "github.com/ipfs/go-ipld-format" "go.uber.org/zap" + "github.com/anyproto/anytype-heart/core/block/object/idresolver" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/files/filehelper" "github.com/anyproto/anytype-heart/core/filestorage" @@ -34,17 +35,19 @@ type Service interface { app.Component FileOffload(ctx context.Context, objectId string, includeNotPinned bool) (totalSize uint64, err error) + FileOffloadFullId(ctx context.Context, id domain.FullID, includeNotPinned bool) (totalSize uint64, err error) FilesOffload(ctx context.Context, objectIds []string, includeNotPinned bool) (err error) FileSpaceOffload(ctx context.Context, spaceId string, includeNotPinned bool) (filesOffloaded int, totalSize uint64, err error) FileOffloadRaw(ctx context.Context, id domain.FullFileId) (totalSize uint64, err error) } type service struct { - objectStore objectstore.ObjectStore - fileStore filestore.FileStore - dagService ipld.DAGService - commonFile fileservice.FileService - fileStorage filestorage.FileStorage + objectStore objectstore.ObjectStore + fileStore filestore.FileStore + dagService ipld.DAGService + commonFile fileservice.FileService + fileStorage filestorage.FileStorage + spaceIdResolver idresolver.Resolver } func New() Service { @@ -57,6 +60,7 @@ func (s *service) Init(a *app.App) error { s.commonFile = app.MustComponent[fileservice.FileService](a) s.dagService = s.commonFile.DAGService() s.fileStorage = app.MustComponent[filestorage.FileStorage](a) + s.spaceIdResolver = app.MustComponent[idresolver.Resolver](a) return nil } @@ -65,7 +69,15 @@ func (s *service) Name() string { } func (s *service) FileOffload(ctx context.Context, objectId string, includeNotPinned bool) (totalSize uint64, err error) { - details, err := s.objectStore.GetDetails(objectId) + spaceId, err := s.spaceIdResolver.ResolveSpaceID(objectId) + if err != nil { + return 0, fmt.Errorf("resolve space id: %w", err) + } + return s.FileOffloadFullId(ctx, domain.FullID{SpaceID: spaceId, ObjectID: objectId}, includeNotPinned) +} + +func (s *service) FileOffloadFullId(ctx context.Context, id domain.FullID, includeNotPinned bool) (totalSize uint64, err error) { + details, err := s.objectStore.SpaceIndex(id.SpaceID).GetDetails(id.ObjectID) if err != nil { return 0, fmt.Errorf("get object details: %w", err) } @@ -109,7 +121,7 @@ func (s *service) offloadAllFiles(ctx context.Context, includeNotPinned bool) (e gc := s.fileStorage.NewLocalStoreGarbageCollector() if !includeNotPinned { - records, err := s.objectStore.Query(database.Query{ + records, err := s.objectStore.QueryCrossSpace(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyFileId.String(), @@ -144,13 +156,8 @@ func (s *service) offloadAllFiles(ctx context.Context, includeNotPinned bool) (e } func (s *service) FileSpaceOffload(ctx context.Context, spaceId string, includeNotPinned bool) (filesOffloaded int, totalSize uint64, err error) { - records, err := s.objectStore.Query(database.Query{ + records, err := s.objectStore.SpaceIndex(spaceId).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, { RelationKey: bundle.RelationKeyFileId.String(), Condition: model.BlockContentDataviewFilter_NotEmpty, @@ -185,18 +192,13 @@ func (s *service) offloadFileSafe(ctx context.Context, record database.Record, includeNotPinned bool, ) (uint64, error) { - existingObjects, err := s.objectStore.Query(database.Query{ + existingObjects, err := s.objectStore.SpaceIndex(spaceId).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyFileId.String(), Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.String(fileId), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_NotEqual, - Value: pbtypes.String(spaceId), - }, }, }) if err != nil { diff --git a/core/files/fileoffloader/offloader_test.go b/core/files/fileoffloader/offloader_test.go index 023ea9143b..acbe22d031 100644 --- a/core/files/fileoffloader/offloader_test.go +++ b/core/files/fileoffloader/offloader_test.go @@ -11,12 +11,14 @@ import ( "github.com/anyproto/any-sync/commonfile/fileservice" "github.com/stretchr/testify/require" + "github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver" "github.com/anyproto/anytype-heart/core/filestorage" "github.com/anyproto/anytype-heart/core/syncstatus/filesyncstatus" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/datastore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/tests/testutil" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -33,6 +35,8 @@ func newFixture(t *testing.T) *fixture { objectStore := objectstore.NewStoreFixture(t) fileStore := filestore.New() dataStoreProvider, err := datastore.NewInMemory() + spaceIdResolver := mock_idresolver.NewMockResolver(t) + require.NoError(t, err) offloader := New() @@ -44,6 +48,7 @@ func newFixture(t *testing.T) *fixture { a.Register(commonFileService) a.Register(objectStore) a.Register(offloader) + a.Register(testutil.PrepareMock(ctx, a, spaceIdResolver)) err = a.Start(ctx) require.NoError(t, err) @@ -65,7 +70,7 @@ func TestOffloadAllFiles(t *testing.T) { fileNode2, err := fx.commonFile.AddFile(ctx, generateTestFileData(t, 2*1024*1024)) require.NoError(t, err) - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("fileObjectId1"), bundle.RelationKeyFileId: pbtypes.String(fileNode1.Cid().String()), diff --git a/core/files/files.go b/core/files/files.go index eea4446f1d..d13662b944 100644 --- a/core/files/files.go +++ b/core/files/files.go @@ -643,7 +643,6 @@ func (s *service) FileByHash(ctx context.Context, id domain.FullFileId) (File, e // info from ipfs fileList, err = s.fileIndexInfo(ctx, id, false) if err != nil { - log.With("fileId", id.FileId.String()).Errorf("FileByHash: failed to retrieve from IPFS: %s", err) return nil, err } ok, err := s.fileStore.IsFileImported(id.FileId) diff --git a/core/files/fileuploader/uploader.go b/core/files/fileuploader/uploader.go index 851385f83f..b1ca0039f4 100644 --- a/core/files/fileuploader/uploader.go +++ b/core/files/fileuploader/uploader.go @@ -25,7 +25,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/domain/objectorigin" "github.com/anyproto/anytype-heart/core/files" - "github.com/anyproto/anytype-heart/core/files/fileobject" + "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" "github.com/anyproto/anytype-heart/pkg/lib/core" "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/mill" @@ -47,7 +47,7 @@ type service struct { fileService files.Service tempDirProvider core.TempDirProvider picker cache.ObjectGetter - fileObjectService fileobject.Service + fileObjectService FileObjectService } func New() Service { @@ -75,7 +75,7 @@ func (f *service) Init(a *app.App) error { f.fileService = app.MustComponent[files.Service](a) f.tempDirProvider = app.MustComponent[core.TempDirProvider](a) f.picker = app.MustComponent[cache.ObjectGetter](a) - f.fileObjectService = app.MustComponent[fileobject.Service](a) + f.fileObjectService = app.MustComponent[FileObjectService](a) return nil } @@ -141,9 +141,14 @@ func (ur UploadResult) ToBlock() file.Block { }).(file.Block) } +type FileObjectService interface { + GetObjectDetailsByFileId(fileId domain.FullFileId) (string, *types.Struct, error) + Create(ctx context.Context, spaceId string, req filemodels.CreateRequest) (id string, object *types.Struct, err error) +} + type uploader struct { spaceId string - fileObjectService fileobject.Service + fileObjectService FileObjectService picker cache.ObjectGetter block file.Block getReader func(ctx context.Context) (*fileReader, error) @@ -492,7 +497,7 @@ func (u *uploader) getOrCreateFileObject(ctx context.Context, addResult *files.A if err == nil { return id, details, nil } - if errors.Is(err, fileobject.ErrObjectNotFound) { + if errors.Is(err, filemodels.ErrObjectNotFound) { err = nil } if err != nil { @@ -500,7 +505,7 @@ func (u *uploader) getOrCreateFileObject(ctx context.Context, addResult *files.A } } - fileObjectId, fileObjectDetails, err := u.fileObjectService.Create(ctx, u.spaceId, fileobject.CreateRequest{ + fileObjectId, fileObjectDetails, err := u.fileObjectService.Create(ctx, u.spaceId, filemodels.CreateRequest{ FileId: addResult.FileId, EncryptionKeys: addResult.EncryptionKeys.EncryptionKeys, ObjectOrigin: u.origin, diff --git a/core/files/reconciler/reconciler.go b/core/files/reconciler/reconciler.go index b4d4935f0d..4005914518 100644 --- a/core/files/reconciler/reconciler.go +++ b/core/files/reconciler/reconciler.go @@ -178,7 +178,7 @@ func (r *reconciler) markAsReconciled(fileObjectId string, fileId domain.FullFil } func (r *reconciler) reconcileRemoteStorage(ctx context.Context) error { - records, err := r.objectStore.Query(database.Query{ + records, err := r.objectStore.QueryCrossSpace(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyFileId.String(), diff --git a/core/files/reconciler/reconciler_test.go b/core/files/reconciler/reconciler_test.go index 5407ad2138..d5ec3f430f 100644 --- a/core/files/reconciler/reconciler_test.go +++ b/core/files/reconciler/reconciler_test.go @@ -89,7 +89,7 @@ func newFixture(t *testing.T) *fixture { func TestReconcileRemoteStorage(t *testing.T) { fx := newFixture(t) - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("objectId1"), bundle.RelationKeyFileId: pbtypes.String(testFileId.String()), diff --git a/core/filestorage/filesync/upload.go b/core/filestorage/filesync/upload.go index b6d99215c6..6dfb1d0562 100644 --- a/core/filestorage/filesync/upload.go +++ b/core/filestorage/filesync/upload.go @@ -14,6 +14,7 @@ import ( "github.com/anyproto/any-sync/net/peer" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" + format "github.com/ipfs/go-ipld-format" "github.com/samber/lo" "go.uber.org/zap" @@ -163,10 +164,12 @@ func (s *fileSync) retryingHandler(ctx context.Context, it *QueueItem) (persiste } } if limitErr == nil || !limitErrorIsLogged { - log.Error("retry uploading file error", - zap.String("fileId", fileId.String()), zap.Error(err), - zap.String("objectId", it.ObjectId), - ) + if !format.IsNotFound(err) && !strings.Contains(err.Error(), "failed to fetch all nodes") { + log.Error("retry uploading file error", + zap.String("fileId", fileId.String()), zap.Error(err), + zap.String("objectId", it.ObjectId), + ) + } } return persistentqueue.ActionRetry, nil diff --git a/core/filestorage/rpcstore/client.go b/core/filestorage/rpcstore/client.go index e97a507a4f..57307192c2 100644 --- a/core/filestorage/rpcstore/client.go +++ b/core/filestorage/rpcstore/client.go @@ -9,10 +9,12 @@ import ( "time" "github.com/anyproto/any-sync/commonfile/fileproto" + "github.com/anyproto/any-sync/commonfile/fileproto/fileprotoerr" "github.com/anyproto/any-sync/net/pool" "github.com/anyproto/any-sync/net/rpc/rpcerr" "github.com/cheggaaa/mb/v3" "github.com/ipfs/go-cid" + format "github.com/ipfs/go-ipld-format" "go.uber.org/zap" "golang.org/x/exp/slices" "storj.io/drpc" @@ -183,7 +185,11 @@ func (c *client) get(ctx context.Context, spaceID string, cd cid.Cid) (data []by Cid: cd.Bytes(), }) if err != nil { - return rpcerr.Unwrap(err) + err = rpcerr.Unwrap(err) + if errors.Is(err, fileprotoerr.ErrCIDNotFound) { + return format.ErrNotFound{Cid: cd} + } + return err } log.Debug("get cid", zap.String("cid", cd.String())) c.stat.Add(st, len(resp.Data)) diff --git a/core/filestorage/rpcstore/clientmgr.go b/core/filestorage/rpcstore/clientmgr.go index e4c7218a99..b85da308e7 100644 --- a/core/filestorage/rpcstore/clientmgr.go +++ b/core/filestorage/rpcstore/clientmgr.go @@ -2,9 +2,9 @@ package rpcstore import ( "context" + "errors" "fmt" "math/rand" - "sync" "time" "github.com/anyproto/any-sync/app/ocache" @@ -16,6 +16,7 @@ import ( "golang.org/x/exp/slices" "github.com/anyproto/anytype-heart/space/spacecore/peerstore" + "github.com/anyproto/anytype-heart/util/contexthelper" ) const ( @@ -28,7 +29,8 @@ type operationNameKeyType string const operationNameKey operationNameKeyType = "operationName" var ( - clientCreateTimeout = 1 * time.Minute + clientCreateTimeout = 1 * time.Minute + ErrNoConnectionToAnyFileClient = errors.New("no connection to any file client") ) func newClientManager(pool pool.Pool, peerStore peerstore.PeerStore, peerUpdateCh chan struct{}) *clientManager { @@ -45,6 +47,7 @@ func newClientManager(pool pool.Pool, peerStore peerstore.PeerStore, peerUpdateC checkPeersCh: peerUpdateCh, pool: pool, peerStore: peerStore, + addLimiter: make(chan struct{}, 1), } cm.ctx, cm.ctxCancel = context.WithCancel(context.Background()) cm.ctx = context.WithValue(cm.ctx, operationNameKey, "checkPeerLoop") @@ -63,18 +66,24 @@ type clientManager struct { pool pool.Pool peerStore peerstore.PeerStore - mu sync.RWMutex + addLimiter chan struct{} } func (m *clientManager) add(ctx context.Context, ts ...*task) (err error) { - m.mu.Lock() + ctx, cancel := contexthelper.ContextWithCloseChan(ctx, m.ctx.Done()) + defer cancel() + select { + case m.addLimiter <- struct{}{}: + case <-ctx.Done(): + return ctx.Err() + } if m.ocache.Len() == 0 { if err = m.checkPeers(ctx, true); err != nil { - m.mu.Unlock() + <-m.addLimiter return } } - m.mu.Unlock() + <-m.addLimiter return m.mb.Add(ctx, ts...) } @@ -178,7 +187,7 @@ func (m *clientManager) checkPeers(ctx context.Context, needClient bool) (err er } // try to add new nodePeerIds - nodePeerIds := m.peerStore.ResponsibleFilePeers() + nodePeerIds := slices.Clone(m.peerStore.ResponsibleFilePeers()) rand.Shuffle(len(nodePeerIds), func(i, j int) { nodePeerIds[i], nodePeerIds[j] = nodePeerIds[j], nodePeerIds[i] }) @@ -192,7 +201,7 @@ func (m *clientManager) checkPeers(ctx context.Context, needClient bool) (err er addPeer(peerId) } if m.ocache.Len() == 0 { - return fmt.Errorf("no connection to any file client") + return ErrNoConnectionToAnyFileClient } return nil } diff --git a/core/filestorage/rpcstore/store_test.go b/core/filestorage/rpcstore/store_test.go index 8e946b5337..2285414442 100644 --- a/core/filestorage/rpcstore/store_test.go +++ b/core/filestorage/rpcstore/store_test.go @@ -9,7 +9,6 @@ import ( "github.com/anyproto/any-sync/accountservice/mock_accountservice" "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/commonfile/fileblockstore" "github.com/anyproto/any-sync/commonfile/fileproto" "github.com/anyproto/any-sync/commonfile/fileproto/fileprotoerr" "github.com/anyproto/any-sync/commonspace/object/accountdata" @@ -18,6 +17,7 @@ import ( "github.com/anyproto/any-sync/nodeconf/mock_nodeconf" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" + format "github.com/ipfs/go-ipld-format" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -77,7 +77,7 @@ func TestStore_Get(t *testing.T) { } b, err := fx.Get(ctx, bs[0].Cid()) assert.Nil(t, b) - assert.ErrorIs(t, err, fileblockstore.ErrCIDNotFound) + assert.ErrorIs(t, err, format.ErrNotFound{}) }) } diff --git a/core/history/history.go b/core/history/history.go index 36f9de9978..22c08895c4 100644 --- a/core/history/history.go +++ b/core/history/history.go @@ -102,7 +102,7 @@ func (h *history) Show(id domain.FullID, versionID string) (bs *model.ObjectView Types: true, }) // nolint:errcheck - meta, _ := h.objectStore.QueryByID(dependentObjectIDs) + meta, _ := h.objectStore.QueryByIdCrossSpace(dependentObjectIDs) meta = append(meta, database.Record{Details: s.CombinedDetails()}) details := make([]*model.ObjectViewDetailsSet, 0, len(meta)) @@ -113,7 +113,7 @@ func (h *history) Show(id domain.FullID, versionID string) (bs *model.ObjectView }) } - relations, err := h.objectStore.FetchRelationByLinks(id.SpaceID, s.PickRelationLinks()) + relations, err := h.objectStore.SpaceIndex(id.SpaceID).FetchRelationByLinks(s.PickRelationLinks()) if err != nil { return nil, nil, fmt.Errorf("fetch relations by links: %w", err) } @@ -263,7 +263,7 @@ func (h *history) DiffVersions(req *pb.RpcHistoryDiffVersionsRequest) ([]*pb.Eve Relations: false, Types: true, }) - meta, err := h.objectStore.QueryByID(dependentObjectIDs) + meta, err := h.objectStore.QueryByIdCrossSpace(dependentObjectIDs) if err != nil { return nil, nil, fmt.Errorf("get dependencies: %w", err) } diff --git a/core/identity/ownidentity.go b/core/identity/ownidentity.go index 64fa43397f..bcb339a17d 100644 --- a/core/identity/ownidentity.go +++ b/core/identity/ownidentity.go @@ -19,12 +19,12 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/files/fileacl" "github.com/anyproto/anytype-heart/pkg/lib/bundle" - coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/datastore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space" + "github.com/anyproto/anytype-heart/space/clientspace" "github.com/anyproto/anytype-heart/util/badgerhelper" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -93,18 +93,12 @@ func (s *ownProfileSubscription) run(ctx context.Context) (err error) { if err != nil { return err } - s.myIdentity = s.accountService.AccountID() - - uniqueKey, err := domain.NewUniqueKey(coresb.SmartBlockTypeProfilePage, "") - if err != nil { - return err - } - personalSpace, err := s.spaceService.GetPersonalSpace(ctx) + techSpace, err := s.spaceService.GetTechSpace(ctx) if err != nil { return fmt.Errorf("get space: %w", err) } - profileObjectId, err := personalSpace.DeriveObjectID(ctx, uniqueKey) + id, err := techSpace.(*clientspace.TechSpace).TechSpace.AccountObjectId() if err != nil { return err } @@ -117,7 +111,7 @@ func (s *ownProfileSubscription) run(ctx context.Context) (err error) { closeSub func() ) - records, closeSub, err = s.objectStore.QueryByIDAndSubscribeForChanges([]string{profileObjectId}, sub) + records, closeSub, err = s.objectStore.SpaceIndex(s.spaceService.TechSpaceId()).QueryByIdsAndSubscribeForChanges([]string{id}, sub) if err != nil { return err } diff --git a/core/identity/ownidentity_test.go b/core/identity/ownidentity_test.go index ccb6ca3f6c..81b67d1e73 100644 --- a/core/identity/ownidentity_test.go +++ b/core/identity/ownidentity_test.go @@ -22,8 +22,9 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/datastore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" + "github.com/anyproto/anytype-heart/space/clientspace" "github.com/anyproto/anytype-heart/space/mock_space" + "github.com/anyproto/anytype-heart/space/techspace/mock_techspace" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -34,6 +35,7 @@ type ownSubscriptionFixture struct { objectStoreFixture *objectstore.StoreFixture spaceService *mock_space.MockService fileAclService *mock_fileacl.MockService + techSpace *mock_techspace.MockTechSpace coordinatorClient *inMemoryIdentityRepo testObserver *testObserver } @@ -64,6 +66,7 @@ func newOwnSubscriptionFixture(t *testing.T) *ownSubscriptionFixture { accountService := mock_account.NewMockService(t) spaceService := mock_space.NewMockService(t) objectStore := objectstore.NewStoreFixture(t) + techSpace := mock_techspace.NewMockTechSpace(t) coordinatorClient := newInMemoryIdentityRepo() fileAclService := mock_fileacl.NewMockService(t) dataStoreProvider, err := datastore.NewInMemory() @@ -93,6 +96,7 @@ func newOwnSubscriptionFixture(t *testing.T) *ownSubscriptionFixture { coordinatorClient: coordinatorClient, testObserver: testObserver, objectStoreFixture: objectStore, + techSpace: techSpace, fileAclService: fileAclService, accountService: accountService, } @@ -112,9 +116,10 @@ func TestOwnProfileSubscription(t *testing.T) { newName := "foobar" t.Run("do not take global name from profile details", func(t *testing.T) { fx := newOwnSubscriptionFixture(t) - personalSpace := mock_clientspace.NewMockSpace(t) - personalSpace.EXPECT().DeriveObjectID(mock.Anything, mock.Anything).Return(testProfileObjectId, nil) - fx.spaceService.EXPECT().GetPersonalSpace(mock.Anything).Return(personalSpace, nil) + fx.accountService.EXPECT().AccountID().Return("identity1") + fx.spaceService.EXPECT().GetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + fx.techSpace.EXPECT().AccountObjectId().Return(testProfileObjectId, nil) + fx.spaceService.EXPECT().TechSpaceId().Return("space1") accountSymKey := crypto.NewAES() fx.spaceService.EXPECT().AccountMetadataSymKey().Return(accountSymKey) fx.accountService.EXPECT().SignData(mock.Anything).RunAndReturn(func(data []byte) ([]byte, error) { @@ -137,7 +142,7 @@ func TestOwnProfileSubscription(t *testing.T) { time.Sleep(testBatchTimeout / 4) - fx.objectStoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.objectStoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(testProfileObjectId), bundle.RelationKeySpaceId: pbtypes.String("space1"), @@ -187,9 +192,10 @@ func TestOwnProfileSubscription(t *testing.T) { t.Run("rewrite global name from channel signal", func(t *testing.T) { fx := newOwnSubscriptionFixture(t) - personalSpace := mock_clientspace.NewMockSpace(t) - personalSpace.EXPECT().DeriveObjectID(mock.Anything, mock.Anything).Return(testProfileObjectId, nil) - fx.spaceService.EXPECT().GetPersonalSpace(mock.Anything).Return(personalSpace, nil) + fx.accountService.EXPECT().AccountID().Return("identity1") + fx.spaceService.EXPECT().GetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + fx.techSpace.EXPECT().AccountObjectId().Return(testProfileObjectId, nil) + fx.spaceService.EXPECT().TechSpaceId().Return("space1") accountSymKey := crypto.NewAES() fx.spaceService.EXPECT().AccountMetadataSymKey().Return(accountSymKey) fx.accountService.EXPECT().SignData(mock.Anything).RunAndReturn(func(data []byte) ([]byte, error) { @@ -235,9 +241,10 @@ func TestOwnProfileSubscription(t *testing.T) { t.Run("push profile to identity repo in batches", func(t *testing.T) { fx := newOwnSubscriptionFixture(t) - personalSpace := mock_clientspace.NewMockSpace(t) - personalSpace.EXPECT().DeriveObjectID(mock.Anything, mock.Anything).Return(testProfileObjectId, nil) - fx.spaceService.EXPECT().GetPersonalSpace(mock.Anything).Return(personalSpace, nil) + fx.accountService.EXPECT().AccountID().Return("identity1") + fx.spaceService.EXPECT().GetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + fx.techSpace.EXPECT().AccountObjectId().Return(testProfileObjectId, nil) + fx.spaceService.EXPECT().TechSpaceId().Return("space1") accountSymKey := crypto.NewAES() fx.spaceService.EXPECT().AccountMetadataSymKey().Return(accountSymKey) fx.accountService.EXPECT().SignData(mock.Anything).RunAndReturn(func(data []byte) ([]byte, error) { @@ -260,7 +267,7 @@ func TestOwnProfileSubscription(t *testing.T) { time.Sleep(testBatchTimeout / 4) - fx.objectStoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.objectStoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(testProfileObjectId), bundle.RelationKeySpaceId: pbtypes.String("space1"), @@ -274,7 +281,7 @@ func TestOwnProfileSubscription(t *testing.T) { fx.updateGlobalName(newName) time.Sleep(testBatchTimeout / 4) - fx.objectStoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.objectStoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(testProfileObjectId), bundle.RelationKeySpaceId: pbtypes.String("space1"), @@ -337,9 +344,10 @@ func TestOwnProfileSubscription(t *testing.T) { func TestWaitForDetails(t *testing.T) { fx := newOwnSubscriptionFixture(t) - personalSpace := mock_clientspace.NewMockSpace(t) - personalSpace.EXPECT().DeriveObjectID(mock.Anything, mock.Anything).Return(testProfileObjectId, nil) - fx.spaceService.EXPECT().GetPersonalSpace(mock.Anything).Return(personalSpace, nil) + fx.accountService.EXPECT().AccountID().Return("identity1") + fx.spaceService.EXPECT().GetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + fx.techSpace.EXPECT().AccountObjectId().Return(testProfileObjectId, nil) + fx.spaceService.EXPECT().TechSpaceId().Return("space1") accountSymKey := crypto.NewAES() fx.spaceService.EXPECT().AccountMetadataSymKey().Return(accountSymKey) fx.accountService.EXPECT().SignData(mock.Anything).RunAndReturn(func(data []byte) ([]byte, error) { @@ -372,7 +380,7 @@ func TestWaitForDetails(t *testing.T) { Key: "key1", }, }, nil) - fx.objectStoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.objectStoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(testProfileObjectId), bundle.RelationKeySpaceId: pbtypes.String("space1"), @@ -407,7 +415,7 @@ func TestWaitForDetails(t *testing.T) { func TestStartWithError(t *testing.T) { fx := newOwnSubscriptionFixture(t) - fx.spaceService.EXPECT().GetPersonalSpace(mock.Anything).Return(nil, fmt.Errorf("space error")) + fx.spaceService.EXPECT().GetTechSpace(mock.Anything).Return(nil, fmt.Errorf("space error")) t.Run("GetMyProfileDetails before run with cancelled input context", func(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/core/indexer/fulltext.go b/core/indexer/fulltext.go index 451782108f..821835e1ec 100644 --- a/core/indexer/fulltext.go +++ b/core/indexer/fulltext.go @@ -40,15 +40,7 @@ func (i *indexer) ForceFTIndex() { // MUST NOT be called more than once func (i *indexer) ftLoopRoutine() { ticker := time.NewTicker(ftIndexInterval) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go func() { - select { - case <-i.quit: - cancel() - case <-ctx.Done(): - } - }() + ctx := i.runCtx i.runFullTextIndexer(ctx) defer close(i.ftQueueFinished) @@ -218,21 +210,22 @@ func (i *indexer) prepareSearchDocument(ctx context.Context, id string) (docs [] } func (i *indexer) ftInit() error { - if ft := i.store.FTSearch(); ft != nil { + if ft := i.ftsearch; ft != nil { docCount, err := ft.DocCount() if err != nil { return err } if docCount == 0 { - ids, err := i.store.ListIds() + // query objects that are existing in the store + // if they are not existing in the object store, they will be indexed and added via reindexOutdatedObjects or on receiving via any-sync + ids, err := i.store.ListIdsCrossSpace() if err != nil { return err } - for _, id := range ids { - if err := i.store.AddToIndexQueue(id); err != nil { - return err - } + if err := i.store.AddToIndexQueue(i.runCtx, ids...); err != nil { + return err } + } } return nil diff --git a/core/indexer/fulltext_test.go b/core/indexer/fulltext_test.go index 6e1d9035b4..d7acd82e91 100644 --- a/core/indexer/fulltext_test.go +++ b/core/indexer/fulltext_test.go @@ -61,7 +61,7 @@ func NewIndexerFixture(t *testing.T) *IndexerFixture { testApp.Register(ds) testApp.Register(walletService) - testApp.Register(objectStore.FTSearch()) + testApp.Register(objectStore.FullText) indxr := &indexer{} @@ -81,14 +81,15 @@ func NewIndexerFixture(t *testing.T) *IndexerFixture { indxr.btHash = hasher indxr.fileStore = fileStore - indxr.ftsearch = objectStore.FTSearch() + indxr.ftsearch = objectStore.FullText indexerFx.ftsearch = indxr.ftsearch indexerFx.pickerFx = mock_cache.NewMockObjectGetter(t) indxr.picker = indexerFx.pickerFx - indxr.quit = make(chan struct{}) + indxr.spaceIndexers = make(map[string]*spaceIndexer) indxr.forceFt = make(chan struct{}) indxr.config = &config.Config{NetworkMode: pb.RpcAccount_LocalOnly} - + indxr.runCtx, indxr.runCtxCancel = context.WithCancel(ctx) + // go indxr.indexBatchLoop() return indexerFx } @@ -326,7 +327,7 @@ func TestRunFullTextIndexer(t *testing.T) { blockbuilder.ID("blockId1"), ), ))) - indexerFx.store.AddToIndexQueue("objectId" + strconv.Itoa(i)) + indexerFx.store.AddToIndexQueue(context.Background(), "objectId"+strconv.Itoa(i)) indexerFx.pickerFx.EXPECT().GetObject(mock.Anything, "objectId"+strconv.Itoa(i)).Return(smartTest, nil).Once() } @@ -352,7 +353,7 @@ func TestRunFullTextIndexer(t *testing.T) { ), ))) indexerFx.pickerFx.EXPECT().GetObject(mock.Anything, "objectId"+strconv.Itoa(i)).Return(smartTest, nil).Once() - indexerFx.store.AddToIndexQueue("objectId" + strconv.Itoa(i)) + indexerFx.store.AddToIndexQueue(context.Background(), "objectId"+strconv.Itoa(i)) } @@ -381,7 +382,7 @@ func TestPrepareSearchDocument_Reindex_Removed(t *testing.T) { blockbuilder.ID("blockId1"), ), ))) - indexerFx.store.AddToIndexQueue("objectId1") + indexerFx.store.AddToIndexQueue(context.Background(), "objectId1") indexerFx.pickerFx.EXPECT().GetObject(mock.Anything, mock.Anything).Return(smartTest, nil) indexerFx.runFullTextIndexer(context.Background()) diff --git a/core/indexer/indexer.go b/core/indexer/indexer.go index cc94e819b5..66dc98797f 100644 --- a/core/indexer/indexer.go +++ b/core/indexer/indexer.go @@ -2,22 +2,16 @@ package indexer import ( "context" - "crypto/sha256" - "fmt" - "strings" "sync" - "time" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/spacestorage" "go.uber.org/zap" - "golang.org/x/exp/slices" "github.com/anyproto/anytype-heart/core/anytype/config" "github.com/anyproto/anytype-heart/core/block/cache" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/source" - "github.com/anyproto/anytype-heart/metrics" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore" @@ -46,7 +40,7 @@ type Indexer interface { ReindexMarketplaceSpace(space clientspace.Space) error ReindexSpace(space clientspace.Space) error RemoveIndexes(spaceId string) (err error) - Index(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption) error + Index(info smartblock.DocInfo, options ...smartblock.IndexOption) error app.ComponentRunnable } @@ -62,15 +56,18 @@ type indexer struct { ftsearch ftsearch.FTSearch storageService storage.ClientStorage - quit chan struct{} + runCtx context.Context + runCtxCancel context.CancelFunc ftQueueFinished chan struct{} config *config.Config btHash Hasher forceFt chan struct{} + // state lock sync.Mutex reindexLogFields []zap.Field + spaceIndexers map[string]*spaceIndexer } func (i *indexer) Init(a *app.App) (err error) { @@ -81,10 +78,10 @@ func (i *indexer) Init(a *app.App) (err error) { i.fileStore = app.MustComponent[filestore.FileStore](a) i.ftsearch = app.MustComponent[ftsearch.FTSearch](a) i.picker = app.MustComponent[cache.ObjectGetter](a) - i.quit = make(chan struct{}) - i.ftQueueFinished = make(chan struct{}) + i.runCtx, i.runCtxCancel = context.WithCancel(context.Background()) i.forceFt = make(chan struct{}) i.config = app.MustComponent[*config.Config](a) + i.spaceIndexers = map[string]*spaceIndexer{} return } @@ -100,25 +97,32 @@ func (i *indexer) StartFullTextIndex() (err error) { if ftErr := i.ftInit(); ftErr != nil { log.Errorf("can't init ft: %v", ftErr) } + i.ftQueueFinished = make(chan struct{}) go i.ftLoopRoutine() return } func (i *indexer) Close(ctx context.Context) (err error) { - close(i.quit) - // we need to wait for the ftQueue processing to be finished gracefully. Because we may be in the middle of badger transaction - <-i.ftQueueFinished + i.lock.Lock() + for spaceId, si := range i.spaceIndexers { + err = si.close() + if err != nil { + log.With("spaceId", spaceId, "error", err).Errorf("close spaceIndexer") + } + delete(i.spaceIndexers, spaceId) + } + i.lock.Unlock() + if i.runCtxCancel != nil { + i.runCtxCancel() + // we need to wait for the ftQueue processing to be finished gracefully. Because we may be in the middle of badger transaction + <-i.ftQueueFinished + } return nil } func (i *indexer) RemoveAclIndexes(spaceId string) (err error) { - ids, _, err := i.store.QueryObjectIDs(database.Query{ + ids, _, err := i.store.SpaceIndex(spaceId).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, { RelationKey: bundle.RelationKeyLayout.String(), Condition: model.BlockContentDataviewFilter_Equal, @@ -129,119 +133,17 @@ func (i *indexer) RemoveAclIndexes(spaceId string) (err error) { if err != nil { return } - return i.store.DeleteDetails(ids...) -} - -func (i *indexer) Index(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption) error { - // options are stored in smartblock pkg because of cyclic dependency :( - startTime := time.Now() - opts := &smartblock.IndexOptions{} - for _, o := range options { - o(opts) - } - err := i.storageService.BindSpaceID(info.Space.Id(), info.Id) - if err != nil { - log.Error("failed to bind space id", zap.Error(err), zap.String("id", info.Id)) - return err - } - headHashToIndex := headsHash(info.Heads) - saveIndexedHash := func() { - if headHashToIndex == "" { - return - } - - err = i.store.SaveLastIndexedHeadsHash(info.Id, headHashToIndex) - if err != nil { - log.With("objectID", info.Id).Errorf("failed to save indexed heads hash: %v", err) - } - } - - indexDetails, indexLinks := info.SmartblockType.Indexable() - if !indexDetails && !indexLinks { - return nil - } - - lastIndexedHash, err := i.store.GetLastIndexedHeadsHash(info.Id) - if err != nil { - log.With("object", info.Id).Errorf("failed to get last indexed heads hash: %v", err) - } - - if opts.SkipIfHeadsNotChanged { - if headHashToIndex == "" { - log.With("objectID", info.Id).Errorf("heads hash is empty") - } else if lastIndexedHash == headHashToIndex { - log.With("objectID", info.Id).Debugf("heads not changed, skipping indexing") - return nil - } - } - - details := info.Details - - indexSetTime := time.Now() - var hasError bool - if indexLinks { - if err = i.store.UpdateObjectLinks(info.Id, info.Links); err != nil { - hasError = true - log.With("objectID", info.Id).Errorf("failed to save object links: %v", err) - } - } - - indexLinksTime := time.Now() - if indexDetails { - if err := i.store.UpdateObjectDetails(ctx, info.Id, details); err != nil { - hasError = true - log.With("objectID", info.Id).Errorf("can't update object store: %v", err) - } else { - // todo: remove temp log - if lastIndexedHash == headHashToIndex { - l := log.With("objectID", info.Id). - With("hashesAreEqual", lastIndexedHash == headHashToIndex). - With("lastHashIsEmpty", lastIndexedHash == ""). - With("skipFlagSet", opts.SkipIfHeadsNotChanged) - - if opts.SkipIfHeadsNotChanged { - l.Warnf("details have changed, but heads are equal") - } else { - l.Debugf("details have changed, but heads are equal") - } - } - } - - if !(opts.SkipFullTextIfHeadsNotChanged && lastIndexedHash == headHashToIndex) { - if err := i.store.AddToIndexQueue(info.Id); err != nil { - log.With("objectID", info.Id).Errorf("can't add id to index queue: %v", err) - } - } - } else { - _ = i.store.DeleteDetails(info.Id) - } - indexDetailsTime := time.Now() - detailsCount := 0 - if details.GetFields() != nil { - detailsCount = len(details.GetFields()) - } - - if !hasError { - saveIndexedHash() - } - - metrics.Service.Send(&metrics.IndexEvent{ - ObjectId: info.Id, - IndexLinksTimeMs: indexLinksTime.Sub(indexSetTime).Milliseconds(), - IndexDetailsTimeMs: indexDetailsTime.Sub(indexLinksTime).Milliseconds(), - IndexSetRelationsTimeMs: indexSetTime.Sub(startTime).Milliseconds(), - DetailsCount: detailsCount, - }) - - return nil + return i.store.SpaceIndex(spaceId).DeleteDetails(i.runCtx, ids) } -func headsHash(heads []string) string { - if len(heads) == 0 { - return "" +func (i *indexer) Index(info smartblock.DocInfo, options ...smartblock.IndexOption) error { + i.lock.Lock() + spaceInd, ok := i.spaceIndexers[info.Space.Id()] + if !ok { + spaceInd = newSpaceIndexer(i.runCtx, i.store.SpaceIndex(info.Space.Id()), i.store, i.storageService) + i.spaceIndexers[info.Space.Id()] = spaceInd } - slices.Sort(heads) + i.lock.Unlock() - sum := sha256.Sum256([]byte(strings.Join(heads, ","))) - return fmt.Sprintf("%x", sum) + return spaceInd.Index(info, options...) } diff --git a/core/indexer/indexer_test.go b/core/indexer/indexer_test.go index a085842310..29b8bb53ae 100644 --- a/core/indexer/indexer_test.go +++ b/core/indexer/indexer_test.go @@ -10,11 +10,17 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" "github.com/anyproto/anytype-heart/tests/blockbuilder" "github.com/anyproto/anytype-heart/tests/testutil" ) +var ctx = context.Background() + func TestIndexer(t *testing.T) { + space := mock_clientspace.NewMockSpace(t) + space.EXPECT().Id().Return("spaceId1").Maybe() + for _, testCase := range []struct { name string options smartblock.IndexOption @@ -33,6 +39,7 @@ func TestIndexer(t *testing.T) { indexerFx := NewIndexerFixture(t) smartTest := smarttest.New("objectId1") smartTest.SetSpaceId("spaceId1") + smartTest.SetSpace(space) smartTest.Doc = testutil.BuildStateFromAST(blockbuilder.Root( blockbuilder.ID("root"), blockbuilder.Children( @@ -44,14 +51,14 @@ func TestIndexer(t *testing.T) { smartTest.SetType(coresb.SmartBlockTypePage) indexerFx.storageServiceFx.EXPECT().BindSpaceID(mock.Anything, mock.Anything).Return(nil) - indexerFx.store.SaveLastIndexedHeadsHash("objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") + indexerFx.store.SpaceIndex("spaceId1").SaveLastIndexedHeadsHash(ctx, "objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") // when - err := indexerFx.Index(context.Background(), smartTest.GetDocInfo(), testCase.options) + err := indexerFx.Index(smartTest.GetDocInfo(), testCase.options) // then assert.NoError(t, err) - count, _ := indexerFx.store.ListIDsFromFullTextQueue(0) + count, _ := indexerFx.store.ListIdsFromFullTextQueue(0) assert.Equal(t, 0, len(count)) }) @@ -60,6 +67,7 @@ func TestIndexer(t *testing.T) { indexerFx := NewIndexerFixture(t) smartTest := smarttest.New("objectId1") smartTest.SetSpaceId("spaceId1") + smartTest.SetSpace(space) smartTest.Doc = testutil.BuildStateFromAST(blockbuilder.Root( blockbuilder.ID("root"), blockbuilder.Children( @@ -71,14 +79,14 @@ func TestIndexer(t *testing.T) { smartTest.SetType(coresb.SmartBlockTypePage) indexerFx.storageServiceFx.EXPECT().BindSpaceID(mock.Anything, mock.Anything).Return(nil) - indexerFx.store.SaveLastIndexedHeadsHash("objectId1", "randomHash") + indexerFx.store.SpaceIndex("spaceId1").SaveLastIndexedHeadsHash(ctx, "objectId1", "randomHash") // when - err := indexerFx.Index(context.Background(), smartTest.GetDocInfo(), testCase.options) + err := indexerFx.Index(smartTest.GetDocInfo(), testCase.options) // then assert.NoError(t, err) - count, _ := indexerFx.store.ListIDsFromFullTextQueue(0) + count, _ := indexerFx.store.ListIdsFromFullTextQueue(0) assert.Equal(t, 1, len(count)) }) } @@ -88,6 +96,7 @@ func TestIndexer(t *testing.T) { indexerFx := NewIndexerFixture(t) smartTest := smarttest.New("objectId1") smartTest.SetSpaceId("spaceId1") + smartTest.SetSpace(space) smartTest.Doc = testutil.BuildStateFromAST(blockbuilder.Root( blockbuilder.ID("root"), blockbuilder.Children( @@ -99,14 +108,14 @@ func TestIndexer(t *testing.T) { smartTest.SetType(coresb.SmartBlockTypePage) indexerFx.storageServiceFx.EXPECT().BindSpaceID(mock.Anything, mock.Anything).Return(nil) - indexerFx.store.SaveLastIndexedHeadsHash("objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") + indexerFx.store.SpaceIndex("spaceId1").SaveLastIndexedHeadsHash(ctx, "objectId1", "7f40bc2814f5297818461f889780a870ea033fe64c5a261117f2b662515a3dba") // when - err := indexerFx.Index(context.Background(), smartTest.GetDocInfo()) + err := indexerFx.Index(smartTest.GetDocInfo()) // then assert.NoError(t, err) - count, _ := indexerFx.store.ListIDsFromFullTextQueue(0) + count, _ := indexerFx.store.ListIdsFromFullTextQueue(0) assert.Equal(t, 1, len(count)) }) } diff --git a/core/indexer/mock_indexer/mock_Indexer.go b/core/indexer/mock_indexer/mock_Indexer.go index 689c00c4b2..91d628f976 100644 --- a/core/indexer/mock_indexer/mock_Indexer.go +++ b/core/indexer/mock_indexer/mock_Indexer.go @@ -104,14 +104,14 @@ func (_c *MockIndexer_ForceFTIndex_Call) RunAndReturn(run func()) *MockIndexer_F return _c } -// Index provides a mock function with given fields: ctx, info, options -func (_m *MockIndexer) Index(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption) error { +// Index provides a mock function with given fields: info, options +func (_m *MockIndexer) Index(info smartblock.DocInfo, options ...smartblock.IndexOption) error { _va := make([]interface{}, len(options)) for _i := range options { _va[_i] = options[_i] } var _ca []interface{} - _ca = append(_ca, ctx, info) + _ca = append(_ca, info) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -120,8 +120,8 @@ func (_m *MockIndexer) Index(ctx context.Context, info smartblock.DocInfo, optio } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, smartblock.DocInfo, ...smartblock.IndexOption) error); ok { - r0 = rf(ctx, info, options...) + if rf, ok := ret.Get(0).(func(smartblock.DocInfo, ...smartblock.IndexOption) error); ok { + r0 = rf(info, options...) } else { r0 = ret.Error(0) } @@ -135,23 +135,22 @@ type MockIndexer_Index_Call struct { } // Index is a helper method to define mock.On call -// - ctx context.Context // - info smartblock.DocInfo // - options ...smartblock.IndexOption -func (_e *MockIndexer_Expecter) Index(ctx interface{}, info interface{}, options ...interface{}) *MockIndexer_Index_Call { +func (_e *MockIndexer_Expecter) Index(info interface{}, options ...interface{}) *MockIndexer_Index_Call { return &MockIndexer_Index_Call{Call: _e.mock.On("Index", - append([]interface{}{ctx, info}, options...)...)} + append([]interface{}{info}, options...)...)} } -func (_c *MockIndexer_Index_Call) Run(run func(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption)) *MockIndexer_Index_Call { +func (_c *MockIndexer_Index_Call) Run(run func(info smartblock.DocInfo, options ...smartblock.IndexOption)) *MockIndexer_Index_Call { _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]smartblock.IndexOption, len(args)-2) - for i, a := range args[2:] { + variadicArgs := make([]smartblock.IndexOption, len(args)-1) + for i, a := range args[1:] { if a != nil { variadicArgs[i] = a.(smartblock.IndexOption) } } - run(args[0].(context.Context), args[1].(smartblock.DocInfo), variadicArgs...) + run(args[0].(smartblock.DocInfo), variadicArgs...) }) return _c } @@ -161,7 +160,7 @@ func (_c *MockIndexer_Index_Call) Return(_a0 error) *MockIndexer_Index_Call { return _c } -func (_c *MockIndexer_Index_Call) RunAndReturn(run func(context.Context, smartblock.DocInfo, ...smartblock.IndexOption) error) *MockIndexer_Index_Call { +func (_c *MockIndexer_Index_Call) RunAndReturn(run func(smartblock.DocInfo, ...smartblock.IndexOption) error) *MockIndexer_Index_Call { _c.Call.Return(run) return _c } diff --git a/core/indexer/reindex.go b/core/indexer/reindex.go index 216f425c52..91bc53dfe3 100644 --- a/core/indexer/reindex.go +++ b/core/indexer/reindex.go @@ -4,12 +4,9 @@ import ( "context" "errors" "fmt" - "strings" "time" anystore "github.com/anyproto/any-store" - "github.com/anyproto/any-sync/util/slice" - "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" "go.uber.org/zap" @@ -207,7 +204,8 @@ func (i *indexer) ReindexSpace(space clientspace.Space) (err error) { } } - i.addSyncDetails(space) + go i.addSyncDetails(space) + return i.saveLatestChecksums(space.Id()) } @@ -223,9 +221,10 @@ func (i *indexer) addSyncDetails(space clientspace.Space) { if err != nil { log.Debug("failed to add sync status relations", zap.Error(err)) } + store := i.store.SpaceIndex(space.Id()) for _, id := range ids { err := space.DoLockedIfNotExists(id, func() error { - return i.store.ModifyObjectDetails(id, func(details *types.Struct) (*types.Struct, bool, error) { + return store.ModifyObjectDetails(id, func(details *types.Struct) (*types.Struct, bool, error) { details = helper.InjectsSyncDetails(details, syncStatus, syncError) return details, true, nil }) @@ -237,7 +236,8 @@ func (i *indexer) addSyncDetails(space clientspace.Space) { } func (i *indexer) reindexDeletedObjects(space clientspace.Space) error { - recs, err := i.store.Query(database.Query{ + store := i.store.SpaceIndex(space.Id()) + recs, err := store.Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyIsDeleted.String(), @@ -261,7 +261,7 @@ func (i *indexer) reindexDeletedObjects(space clientspace.Space) error { continue } if status != "" { - err = i.store.DeleteObject(domain.FullID{SpaceID: space.Id(), ObjectID: objectId}) + err = store.DeleteObject(objectId) if err != nil { log.With("spaceId", space.Id(), "objectId", objectId).Errorf("failed to reindex deleted object: %s", err) } @@ -274,13 +274,9 @@ func (i *indexer) removeOldFiles(spaceId string, flags reindexFlags) error { if !flags.removeOldFiles { return nil } - ids, _, err := i.store.QueryObjectIDs(database.Query{ + store := i.store.SpaceIndex(spaceId) + ids, _, err := store.QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, { RelationKey: bundle.RelationKeyLayout.String(), Condition: model.BlockContentDataviewFilter_In, @@ -302,7 +298,7 @@ func (i *indexer) removeOldFiles(spaceId string, flags reindexFlags) error { } for _, id := range ids { if domain.IsFileId(id) { - err = i.store.DeleteDetails(id) + err = store.DeleteDetails(i.runCtx, []string{id}) if err != nil { log.Errorf("delete old file %s: %s", id, err) } @@ -340,7 +336,8 @@ func (i *indexer) ReindexMarketplaceSpace(space clientspace.Space) error { } if flags.bundledTemplates { - existing, _, err := i.store.QueryObjectIDs(database.Query{ + store := i.store.SpaceIndex(space.Id()) + existing, _, err := store.QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyType.String(), @@ -353,7 +350,7 @@ func (i *indexer) ReindexMarketplaceSpace(space clientspace.Space) error { return fmt.Errorf("query bundled templates: %w", err) } for _, id := range existing { - err = i.store.DeleteObject(domain.FullID{SpaceID: space.Id(), ObjectID: id}) + err = store.DeleteObject(id) if err != nil { log.Errorf("delete old bundled template %s: %s", id, err) } @@ -372,51 +369,19 @@ func (i *indexer) ReindexMarketplaceSpace(space clientspace.Space) error { } func (i *indexer) removeDetails(spaceId string) error { - err := i.removeOldObjects() - if err != nil { - err = nil - log.Errorf("reindex failed to removeOldObjects: %v", err) - } - ids, err := i.store.ListIdsBySpace(spaceId) + store := i.store.SpaceIndex(spaceId) + ids, err := store.ListIds() if err != nil { log.Errorf("reindex failed to get all ids(removeAllIndexedObjects): %v", err) } for _, id := range ids { - if err = i.store.DeleteDetails(id); err != nil { + if err = store.DeleteDetails(i.runCtx, []string{id}); err != nil { log.Errorf("reindex failed to delete details(removeAllIndexedObjects): %v", err) } } return err } -// removeOldObjects removes all objects that are not supported anymore (e.g. old subobjects) and no longer returned by the underlying source -func (i *indexer) removeOldObjects() (err error) { - ids, err := i.store.ListIds() - if err != nil { - return err - } - ids = slice.Filter(ids, func(id string) bool { - if strings.HasPrefix(id, addr.RelationKeyToIdPrefix) { - return true - } - if strings.HasPrefix(id, addr.ObjectTypeKeyToIdPrefix) { - return true - } - if bson.IsObjectIdHex(id) { - return true - } - return false - }) - - if len(ids) == 0 { - return - } - - err = i.store.DeleteDetails(ids...) - log.With(zap.Int("count", len(ids)), zap.Error(err)).Warnf("removeOldObjects") - return err -} - func (i *indexer) removeCommonIndexes(spaceId string, space clientspace.Space, flags reindexFlags) (err error) { if flags.any() { log.Infof("start store reindex (%s)", flags.String()) @@ -432,7 +397,8 @@ func (i *indexer) removeCommonIndexes(spaceId string, space clientspace.Space, f } if flags.eraseLinks { - ids, err := i.store.ListIdsBySpace(spaceId) + store := i.store.SpaceIndex(spaceId) + ids, err := store.ListIds() if err != nil { log.Errorf("reindex failed to get all ids(eraseLinks): %v", err) } @@ -448,7 +414,7 @@ func (i *indexer) removeCommonIndexes(spaceId string, space clientspace.Space, f } for _, id := range ids { - if err = i.store.DeleteLinks(id); err != nil { + if err = store.DeleteLinks([]string{id}); err != nil { log.Errorf("reindex failed to delete links(eraseLinks): %v", err) } } @@ -477,6 +443,7 @@ func (i *indexer) reindexIDs(ctx context.Context, space smartblock.Space, reinde } func (i *indexer) reindexOutdatedObjects(ctx context.Context, space clientspace.Space) (toReindex, success int, err error) { + store := i.store.SpaceIndex(space.Id()) tids := space.StoredIds() var idsToReindex []string for _, tid := range tids { @@ -484,7 +451,7 @@ func (i *indexer) reindexOutdatedObjects(ctx context.Context, space clientspace. log.With("tree", tid).Errorf("reindexOutdatedObjects failed to get tree to reindex: %s", err) } - lastHash, err := i.store.GetLastIndexedHeadsHash(tid) + lastHash, err := store.GetLastIndexedHeadsHash(ctx, tid) if err != nil { logErr(err) continue @@ -513,15 +480,20 @@ func (i *indexer) reindexOutdatedObjects(ctx context.Context, space clientspace. return len(idsToReindex), success, nil } -func (i *indexer) reindexDoc(ctx context.Context, space smartblock.Space, id string) error { +func (i *indexer) reindexDoc(space smartblock.Space, id string) error { return space.Do(id, func(sb smartblock.SmartBlock) error { - return i.Index(ctx, sb.GetDocInfo()) + return i.Index(sb.GetDocInfo()) }) } func (i *indexer) reindexIdsIgnoreErr(ctx context.Context, space smartblock.Space, ids ...string) (successfullyReindexed int) { for _, id := range ids { - err := i.reindexDoc(ctx, space, id) + select { + case <-ctx.Done(): + return + default: + } + err := i.reindexDoc(space, id) if err != nil { log.With("objectID", id).Errorf("failed to reindex: %v", err) } else { diff --git a/core/indexer/reindex_test.go b/core/indexer/reindex_test.go index 64e6b33857..85b1e5005e 100644 --- a/core/indexer/reindex_test.go +++ b/core/indexer/reindex_test.go @@ -66,7 +66,7 @@ func TestReindexMarketplaceSpace(t *testing.T) { err = indexerFx.ReindexMarketplaceSpace(virtualSpace) // then - details, err := indexerFx.store.GetDetails(addr.MissingObject) + details, err := indexerFx.store.SpaceIndex("space1").GetDetails(addr.MissingObject) assert.Nil(t, err) assert.NotNil(t, details) }) @@ -75,17 +75,19 @@ func TestReindexMarketplaceSpace(t *testing.T) { // given fx := NewIndexerFixture(t) + store := fx.store.SpaceIndex("space1") + favs := []string{"fav1", "fav2"} trash := []string{"trash1", "trash2"} - err := fx.store.UpdateObjectLinks("home", favs) + err := store.UpdateObjectLinks(ctx, "home", favs) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("bin", trash) + err = store.UpdateObjectLinks(ctx, "bin", trash) require.NoError(t, err) - homeLinks, err := fx.store.GetOutboundLinksByID("home") + homeLinks, err := store.GetOutboundLinksById("home") require.Equal(t, favs, homeLinks) - archiveLinks, err := fx.store.GetOutboundLinksByID("bin") + archiveLinks, err := store.GetOutboundLinksById("bin") require.Equal(t, trash, archiveLinks) checksums := fx.getLatestChecksums(true) @@ -103,11 +105,11 @@ func TestReindexMarketplaceSpace(t *testing.T) { assert.NoError(t, err) // then - homeLinks, err = fx.store.GetOutboundLinksByID("home") + homeLinks, err = store.GetOutboundLinksById("home") assert.NoError(t, err) assert.Equal(t, favs, homeLinks) - archiveLinks, err = fx.store.GetOutboundLinksByID("bin") + archiveLinks, err = store.GetOutboundLinksById("bin") assert.NoError(t, err) assert.Equal(t, trash, archiveLinks) @@ -118,7 +120,7 @@ func TestReindexMarketplaceSpace(t *testing.T) { t.Run("full marketplace reindex on force flag update", func(t *testing.T) { // given fx := NewIndexerFixture(t) - fx.objectStore.AddObjects(t, []objectstore.TestObject{map[domain.RelationKey]*types.Value{ + fx.objectStore.AddObjects(t, spaceId, []objectstore.TestObject{map[domain.RelationKey]*types.Value{ bundle.RelationKeyId: pbtypes.String("relationThatWillBeDeleted"), bundle.RelationKeyName: pbtypes.String("Relation-That-Will-Be-Deleted"), bundle.RelationKeySpaceId: pbtypes.String(spaceId), @@ -141,7 +143,7 @@ func TestReindexMarketplaceSpace(t *testing.T) { assert.NoError(t, err) // then - det, err := fx.store.GetDetails("relationThatWillBeDeleted") + det, err := fx.store.SpaceIndex("space1").GetDetails("relationThatWillBeDeleted") assert.NoError(t, err) assert.Empty(t, det.Details.Fields) }) @@ -154,23 +156,29 @@ func TestReindexDeletedObjects(t *testing.T) { spaceId3 = "spaceId3" ) fx := NewIndexerFixture(t) + fx.sourceFx.EXPECT().IDsListerBySmartblockType(mock.Anything, mock.Anything).Return(idsLister{Ids: []string{}}, nil).Maybe() - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, spaceId1, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("1"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), }, + }) + fx.objectStore.AddObjects(t, spaceId2, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("2"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), }, + }) + fx.objectStore.AddObjects(t, spaceId3, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("3"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), bundle.RelationKeySpaceId: pbtypes.String(spaceId3), }, { - bundle.RelationKeyId: pbtypes.String("4"), + bundle.RelationKeyId: pbtypes.String("4"), + bundle.RelationKeyName: pbtypes.String("4"), }, }) @@ -185,14 +193,11 @@ func TestReindexDeletedObjects(t *testing.T) { t.Run("reindex first space", func(t *testing.T) { storage1 := mock_spacestorage.NewMockSpaceStorage(gomock.NewController(t)) storage1.EXPECT().TreeDeletedStatus("1").Return(spacestorage.TreeDeletedStatusDeleted, nil) - storage1.EXPECT().TreeDeletedStatus("2").Return("", nil) space1 := mock_space.NewMockSpace(t) space1.EXPECT().Id().Return(spaceId1) space1.EXPECT().Storage().Return(storage1) space1.EXPECT().StoredIds().Return([]string{}).Maybe() - fx.sourceFx.EXPECT().IDsListerBySmartblockType(mock.Anything, mock.Anything).Return(idsLister{Ids: []string{}}, nil) - err = fx.ReindexSpace(space1) require.NoError(t, err) @@ -209,7 +214,6 @@ func TestReindexDeletedObjects(t *testing.T) { space2.EXPECT().Id().Return(spaceId2) space2.EXPECT().Storage().Return(storage2) space2.EXPECT().StoredIds().Return([]string{}).Maybe() - fx.sourceFx.EXPECT().IDsListerBySmartblockType(mock.Anything, mock.Anything).Return(idsLister{Ids: []string{}}, nil) err = fx.ReindexSpace(space2) require.NoError(t, err) @@ -250,7 +254,7 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { }, ) - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, spaceId1, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("fav1"), bundle.RelationKeySpaceId: pbtypes.String(spaceId1), @@ -267,6 +271,8 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { bundle.RelationKeyId: pbtypes.String("trash2"), bundle.RelationKeySpaceId: pbtypes.String(spaceId1), }, + }) + fx.objectStore.AddObjects(t, spaceId2, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("obj1"), bundle.RelationKeySpaceId: pbtypes.String(spaceId2), @@ -293,15 +299,16 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { // given favs := []string{"fav1", "fav2"} trash := []string{"trash1", "trash2"} - err = fx.store.UpdateObjectLinks("home", favs) + store := fx.store.SpaceIndex("space1") + err = store.UpdateObjectLinks(ctx, "home", favs) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("bin", trash) + err = store.UpdateObjectLinks(ctx, "bin", trash) require.NoError(t, err) - homeLinks, err := fx.store.GetOutboundLinksByID("home") + homeLinks, err := store.GetOutboundLinksById("home") require.Equal(t, favs, homeLinks) - archiveLinks, err := fx.store.GetOutboundLinksByID("bin") + archiveLinks, err := store.GetOutboundLinksById("bin") require.Equal(t, trash, archiveLinks) space1 := mock_space.NewMockSpace(t) @@ -313,11 +320,11 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { assert.NoError(t, err) // then - homeLinks, err = fx.store.GetOutboundLinksByID("home") + homeLinks, err = store.GetOutboundLinksById("home") assert.NoError(t, err) assert.Empty(t, homeLinks) - archiveLinks, err = fx.store.GetOutboundLinksByID("bin") + archiveLinks, err = store.GetOutboundLinksById("bin") assert.NoError(t, err) assert.Empty(t, archiveLinks) @@ -330,18 +337,19 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { obj1links := []string{"obj2", "obj3"} obj2links := []string{"obj1"} obj3links := []string{"obj2"} - err = fx.store.UpdateObjectLinks("obj1", obj1links) + store := fx.store.SpaceIndex(spaceId2) + err = store.UpdateObjectLinks(ctx, "obj1", obj1links) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("obj2", obj2links) + err = store.UpdateObjectLinks(ctx, "obj2", obj2links) require.NoError(t, err) - err = fx.store.UpdateObjectLinks("obj3", obj3links) + err = store.UpdateObjectLinks(ctx, "obj3", obj3links) require.NoError(t, err) - storedObj1links, err := fx.store.GetOutboundLinksByID("obj1") + storedObj1links, err := store.GetOutboundLinksById("obj1") require.Equal(t, obj1links, storedObj1links) - storedObj2links, err := fx.store.GetOutboundLinksByID("obj2") + storedObj2links, err := store.GetOutboundLinksById("obj2") require.Equal(t, obj2links, storedObj2links) - storedObj3links, err := fx.store.GetOutboundLinksByID("obj3") + storedObj3links, err := store.GetOutboundLinksById("obj3") require.Equal(t, obj3links, storedObj3links) space1 := mock_space.NewMockSpace(t) @@ -353,13 +361,13 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { assert.NoError(t, err) // then - storedObj1links, err = fx.store.GetOutboundLinksByID("obj1") + storedObj1links, err = store.GetOutboundLinksById("obj1") assert.NoError(t, err) assert.Empty(t, storedObj1links) - storedObj2links, err = fx.store.GetOutboundLinksByID("obj2") + storedObj2links, err = store.GetOutboundLinksById("obj2") assert.NoError(t, err) assert.Empty(t, storedObj2links) - storedObj3links, err = fx.store.GetOutboundLinksByID("obj3") + storedObj3links, err = store.GetOutboundLinksById("obj3") assert.NoError(t, err) assert.Empty(t, storedObj3links) @@ -369,32 +377,13 @@ func TestIndexer_ReindexSpace_EraseLinks(t *testing.T) { }) } -func (fx *IndexerFixture) queryDeletedObjectIds(t *testing.T, spaceId string) []string { - ids, _, err := fx.objectStore.QueryObjectIDs(database.Query{ - Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, - { - RelationKey: bundle.RelationKeyIsDeleted.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.Bool(true), - }, - }, - }) - require.NoError(t, err) - return ids -} - func TestReindex_addSyncRelations(t *testing.T) { t.Run("addSyncRelations local only", func(t *testing.T) { // given const spaceId1 = "spaceId1" fx := NewIndexerFixture(t) - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, spaceId1, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("1"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), @@ -421,10 +410,9 @@ func TestReindex_addSyncRelations(t *testing.T) { space1.EXPECT().DoLockedIfNotExists("2", mock.AnythingOfType("func() error")).Return(nil) // when - err := fx.ReindexSpace(space1) + fx.addSyncDetails(space1) // then - require.NoError(t, err) }) t.Run("addSyncRelations", func(t *testing.T) { @@ -432,7 +420,7 @@ func TestReindex_addSyncRelations(t *testing.T) { const spaceId1 = "spaceId1" fx := NewIndexerFixture(t) - fx.objectStore.AddObjects(t, []objectstore.TestObject{ + fx.objectStore.AddObjects(t, spaceId1, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("1"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), @@ -461,11 +449,27 @@ func TestReindex_addSyncRelations(t *testing.T) { fx.config.NetworkMode = pb.RpcAccount_DefaultConfig // when - err := fx.ReindexSpace(space1) + fx.addSyncDetails(space1) + }) +} - // then - require.NoError(t, err) +func (fx *IndexerFixture) queryDeletedObjectIds(t *testing.T, spaceId string) []string { + ids, _, err := fx.objectStore.SpaceIndex(spaceId).QueryObjectIds(database.Query{ + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeySpaceId.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.String(spaceId), + }, + { + RelationKey: bundle.RelationKeyIsDeleted.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Bool(true), + }, + }, }) + require.NoError(t, err) + return ids } type idsLister struct { diff --git a/core/indexer/spaceindexer.go b/core/indexer/spaceindexer.go new file mode 100644 index 0000000000..69f1ad99f3 --- /dev/null +++ b/core/indexer/spaceindexer.go @@ -0,0 +1,231 @@ +package indexer + +import ( + "context" + "crypto/sha256" + "fmt" + "strings" + "time" + + "github.com/cheggaaa/mb/v3" + "go.uber.org/zap" + "golang.org/x/exp/slices" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/metrics" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" + "github.com/anyproto/anytype-heart/space/spacecore/storage" +) + +type spaceIndexer struct { + runCtx context.Context + spaceIndex spaceindex.Store + objectStore objectstore.ObjectStore + storageService storage.ClientStorage + batcher *mb.MB[indexTask] +} + +func newSpaceIndexer(runCtx context.Context, spaceIndex spaceindex.Store, objectStore objectstore.ObjectStore, storageService storage.ClientStorage) *spaceIndexer { + ind := &spaceIndexer{ + runCtx: runCtx, + spaceIndex: spaceIndex, + objectStore: objectStore, + storageService: storageService, + batcher: mb.New[indexTask](100), + } + go ind.indexBatchLoop() + return ind +} + +func (i *spaceIndexer) close() error { + return i.batcher.Close() +} + +type indexTask struct { + info smartblock.DocInfo + options []smartblock.IndexOption + done chan error +} + +func (i *spaceIndexer) indexBatchLoop() { + for { + tasks, err := i.batcher.Wait(i.runCtx) + if err != nil { + return + } + if iErr := i.indexBatch(tasks); iErr != nil { + log.Warnf("indexBatch error: %v", iErr) + } + } +} + +func (i *spaceIndexer) indexBatch(tasks []indexTask) (err error) { + tx, err := i.spaceIndex.WriteTx(i.runCtx) + if err != nil { + return err + } + st := time.Now() + + closeTasks := func(closeErr error) { + for _, t := range tasks { + if closeErr != nil { + select { + case t.done <- closeErr: + default: + } + } else { + close(t.done) + } + } + } + + defer func() { + if err != nil { + _ = tx.Rollback() + } else { + if err = tx.Commit(); err != nil { + closeTasks(err) + } else { + closeTasks(nil) + } + log.Infof("indexBatch: indexed %d docs for a %v: err: %v", len(tasks), time.Since(st), err) + } + }() + + for _, task := range tasks { + if iErr := i.index(tx.Context(), task.info, task.options...); iErr != nil { + task.done <- iErr + } + } + return +} + +func (i *spaceIndexer) Index(info smartblock.DocInfo, options ...smartblock.IndexOption) error { + done := make(chan error) + if err := i.batcher.Add(i.runCtx, indexTask{ + info: info, + options: options, + done: done, + }); err != nil { + return err + } + select { + case <-i.runCtx.Done(): + return i.runCtx.Err() + case err := <-done: + return err + } +} + +func (i *spaceIndexer) index(ctx context.Context, info smartblock.DocInfo, options ...smartblock.IndexOption) error { + // options are stored in smartblock pkg because of cyclic dependency :( + startTime := time.Now() + opts := &smartblock.IndexOptions{} + for _, o := range options { + o(opts) + } + err := i.storageService.BindSpaceID(info.Space.Id(), info.Id) + if err != nil { + log.Error("failed to bind space id", zap.Error(err), zap.String("id", info.Id)) + return err + } + headHashToIndex := headsHash(info.Heads) + saveIndexedHash := func() { + if headHashToIndex == "" { + return + } + + err = i.spaceIndex.SaveLastIndexedHeadsHash(ctx, info.Id, headHashToIndex) + if err != nil { + log.With("objectID", info.Id).Errorf("failed to save indexed heads hash: %v", err) + } + } + + indexDetails, indexLinks := info.SmartblockType.Indexable() + if !indexDetails && !indexLinks { + return nil + } + + lastIndexedHash, err := i.spaceIndex.GetLastIndexedHeadsHash(ctx, info.Id) + if err != nil { + log.With("object", info.Id).Errorf("failed to get last indexed heads hash: %v", err) + } + + if opts.SkipIfHeadsNotChanged { + if headHashToIndex == "" { + log.With("objectID", info.Id).Errorf("heads hash is empty") + } else if lastIndexedHash == headHashToIndex { + log.With("objectID", info.Id).Debugf("heads not changed, skipping indexing") + return nil + } + } + + details := info.Details + + indexSetTime := time.Now() + var hasError bool + if indexLinks { + if err = i.spaceIndex.UpdateObjectLinks(ctx, info.Id, info.Links); err != nil { + hasError = true + log.With("objectID", info.Id).Errorf("failed to save object links: %v", err) + } + } + + indexLinksTime := time.Now() + if indexDetails { + if err := i.spaceIndex.UpdateObjectDetails(ctx, info.Id, details); err != nil { + hasError = true + log.With("objectID", info.Id).Errorf("can't update object store: %v", err) + } else if lastIndexedHash == headHashToIndex { + l := log.With("objectID", info.Id). + With("hashesAreEqual", lastIndexedHash == headHashToIndex). + With("lastHashIsEmpty", lastIndexedHash == ""). + With("skipFlagSet", opts.SkipIfHeadsNotChanged) + + if opts.SkipIfHeadsNotChanged { + l.Warnf("details have changed, but heads are equal") + } else { + l.Debugf("details have changed, but heads are equal") + } + } + + if !(opts.SkipFullTextIfHeadsNotChanged && lastIndexedHash == headHashToIndex) { + // Use component's context because ctx from parameter contains transaction + if err := i.objectStore.AddToIndexQueue(i.runCtx, info.Id); err != nil { + log.With("objectID", info.Id).Errorf("can't add id to index queue: %v", err) + } + } + } else { + _ = i.spaceIndex.DeleteDetails(ctx, []string{info.Id}) + } + indexDetailsTime := time.Now() + detailsCount := 0 + if details.GetFields() != nil { + detailsCount = len(details.GetFields()) + } + + if !hasError { + saveIndexedHash() + } + + metrics.Service.Send(&metrics.IndexEvent{ + ObjectId: info.Id, + IndexLinksTimeMs: indexLinksTime.Sub(indexSetTime).Milliseconds(), + IndexDetailsTimeMs: indexDetailsTime.Sub(indexLinksTime).Milliseconds(), + IndexSetRelationsTimeMs: indexSetTime.Sub(startTime).Milliseconds(), + DetailsCount: detailsCount, + }) + + return nil +} + +func headsHash(heads []string) string { + if len(heads) == 0 { + return "" + } + slices.Sort(heads) + + sum := sha256.Sum256([]byte(strings.Join(heads, ","))) + return fmt.Sprintf("%x", sum) +} diff --git a/core/invitestore/invitestore_test.go b/core/invitestore/invitestore_test.go index 44a5530378..f0be0cd5ce 100644 --- a/core/invitestore/invitestore_test.go +++ b/core/invitestore/invitestore_test.go @@ -14,6 +14,7 @@ import ( "go.uber.org/mock/gomock" "github.com/anyproto/anytype-heart/core/anytype/config" + "github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver" "github.com/anyproto/anytype-heart/core/event/mock_event" "github.com/anyproto/anytype-heart/core/files/fileoffloader" "github.com/anyproto/anytype-heart/core/filestorage" @@ -49,6 +50,7 @@ func newFixture(t *testing.T) *fixture { wallet := mock_wallet.NewMockWallet(t) wallet.EXPECT().Name().Return(wallet2.CName) wallet.EXPECT().RepoPath().Return("repo/path") + spaceIdResolver := mock_idresolver.NewMockResolver(t) a := new(app.App) a.Register(objectstore.NewStoreFixture(t)) @@ -64,6 +66,7 @@ func newFixture(t *testing.T) *fixture { a.Register(testutil.PrepareMock(ctx, a, mock_accountservice.NewMockService(ctrl))) a.Register(testutil.PrepareMock(ctx, a, wallet)) a.Register(&config.Config{DisableFileConfig: true, NetworkMode: pb.RpcAccount_DefaultConfig, PeferYamuxTransport: true}) + a.Register(testutil.PrepareMock(ctx, a, spaceIdResolver)) err = a.Start(ctx) require.NoError(t, err) diff --git a/core/kanban/group_checkbox.go b/core/kanban/group_checkbox.go index a84f22356d..6e9e26f787 100644 --- a/core/kanban/group_checkbox.go +++ b/core/kanban/group_checkbox.go @@ -1,6 +1,8 @@ package kanban import ( + "fmt" + "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) @@ -9,6 +11,9 @@ type GroupCheckBox struct { } func (gCh *GroupCheckBox) InitGroups(spaceID string, f *database.Filters) error { + if spaceID == "" { + return fmt.Errorf("spaceId is required") + } return nil } diff --git a/core/kanban/group_status.go b/core/kanban/group_status.go index dab33b2a8b..59f57b875e 100644 --- a/core/kanban/group_status.go +++ b/core/kanban/group_status.go @@ -1,6 +1,7 @@ package kanban import ( + "fmt" "sort" "github.com/anyproto/anytype-heart/pkg/lib/database" @@ -15,7 +16,10 @@ type GroupStatus struct { } func (gs *GroupStatus) InitGroups(spaceID string, f *database.Filters) error { - options, err := database.ListRelationOptions(gs.store, spaceID, gs.key) + if spaceID == "" { + return fmt.Errorf("spaceId is required") + } + options, err := gs.store.SpaceIndex(spaceID).ListRelationOptions(gs.key) if err != nil { return err } diff --git a/core/kanban/group_tag.go b/core/kanban/group_tag.go index 9ac1e6cd56..9a60473b54 100644 --- a/core/kanban/group_tag.go +++ b/core/kanban/group_tag.go @@ -20,12 +20,9 @@ type GroupTag struct { } func (t *GroupTag) InitGroups(spaceID string, f *database.Filters) error { - spaceFilter := database.FilterEq{ - Key: bundle.RelationKeySpaceId.String(), - Cond: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceID), + if spaceID == "" { + return fmt.Errorf("spaceId is required") } - filterTag := database.FiltersAnd{ database.FilterNot{Filter: database.FilterEmpty{Key: t.Key}}, } @@ -47,13 +44,20 @@ func (t *GroupTag) InitGroups(spaceID string, f *database.Filters) error { Cond: model.BlockContentDataviewFilter_Equal, Value: pbtypes.Int64(int64(model.ObjectType_relationOption)), }, - } - if spaceID != "" { - relationOptionFilter = append(relationOptionFilter, spaceFilter) + database.FilterEq{ + Key: bundle.RelationKeyIsArchived.String(), + Cond: model.BlockContentDataviewFilter_NotEqual, + Value: pbtypes.Bool(true), + }, + database.FilterEq{ + Key: bundle.RelationKeyIsDeleted.String(), + Cond: model.BlockContentDataviewFilter_NotEqual, + Value: pbtypes.Bool(true), + }, } f.FilterObj = database.FiltersOr{f.FilterObj, relationOptionFilter} - records, err := t.store.QueryRaw(f, 0, 0) + records, err := t.store.SpaceIndex(spaceID).QueryRaw(f, 0, 0) if err != nil { return fmt.Errorf("init kanban by tag, objectStore query error: %w", err) } diff --git a/core/kanban/mock_kanban/mock_Service.go b/core/kanban/mock_kanban/mock_Service.go new file mode 100644 index 0000000000..b5a1fc611f --- /dev/null +++ b/core/kanban/mock_kanban/mock_Service.go @@ -0,0 +1,186 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_kanban + +import ( + app "github.com/anyproto/any-sync/app" + kanban "github.com/anyproto/anytype-heart/core/kanban" + mock "github.com/stretchr/testify/mock" +) + +// MockService is an autogenerated mock type for the Service type +type MockService struct { + mock.Mock +} + +type MockService_Expecter struct { + mock *mock.Mock +} + +func (_m *MockService) EXPECT() *MockService_Expecter { + return &MockService_Expecter{mock: &_m.Mock} +} + +// Grouper provides a mock function with given fields: spaceID, key +func (_m *MockService) Grouper(spaceID string, key string) (kanban.Grouper, error) { + ret := _m.Called(spaceID, key) + + if len(ret) == 0 { + panic("no return value specified for Grouper") + } + + var r0 kanban.Grouper + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (kanban.Grouper, error)); ok { + return rf(spaceID, key) + } + if rf, ok := ret.Get(0).(func(string, string) kanban.Grouper); ok { + r0 = rf(spaceID, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(kanban.Grouper) + } + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(spaceID, key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockService_Grouper_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Grouper' +type MockService_Grouper_Call struct { + *mock.Call +} + +// Grouper is a helper method to define mock.On call +// - spaceID string +// - key string +func (_e *MockService_Expecter) Grouper(spaceID interface{}, key interface{}) *MockService_Grouper_Call { + return &MockService_Grouper_Call{Call: _e.mock.On("Grouper", spaceID, key)} +} + +func (_c *MockService_Grouper_Call) Run(run func(spaceID string, key string)) *MockService_Grouper_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *MockService_Grouper_Call) Return(_a0 kanban.Grouper, _a1 error) *MockService_Grouper_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockService_Grouper_Call) RunAndReturn(run func(string, string) (kanban.Grouper, error)) *MockService_Grouper_Call { + _c.Call.Return(run) + return _c +} + +// Init provides a mock function with given fields: a +func (_m *MockService) Init(a *app.App) error { + ret := _m.Called(a) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*app.App) error); ok { + r0 = rf(a) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockService_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' +type MockService_Init_Call struct { + *mock.Call +} + +// Init is a helper method to define mock.On call +// - a *app.App +func (_e *MockService_Expecter) Init(a interface{}) *MockService_Init_Call { + return &MockService_Init_Call{Call: _e.mock.On("Init", a)} +} + +func (_c *MockService_Init_Call) Run(run func(a *app.App)) *MockService_Init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*app.App)) + }) + return _c +} + +func (_c *MockService_Init_Call) Return(err error) *MockService_Init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockService_Init_Call) RunAndReturn(run func(*app.App) error) *MockService_Init_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: +func (_m *MockService) Name() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockService_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockService_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockService_Expecter) Name() *MockService_Name_Call { + return &MockService_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockService_Name_Call) Run(run func()) *MockService_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockService_Name_Call) Return(name string) *MockService_Name_Call { + _c.Call.Return(name) + return _c +} + +func (_c *MockService_Name_Call) RunAndReturn(run func() string) *MockService_Name_Call { + _c.Call.Return(run) + return _c +} + +// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockService(t interface { + mock.TestingT + Cleanup(func()) +}) *MockService { + mock := &MockService{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/kanban/service.go b/core/kanban/service.go index e468459143..b442ad07a1 100644 --- a/core/kanban/service.go +++ b/core/kanban/service.go @@ -59,7 +59,10 @@ func (s *service) Name() (name string) { } func (s *service) Grouper(spaceID string, key string) (Grouper, error) { - rel, err := s.objectStore.FetchRelationByKey(spaceID, key) + if spaceID == "" { + return nil, fmt.Errorf("spaceId is required") + } + rel, err := s.objectStore.SpaceIndex(spaceID).FetchRelationByKey(key) if err != nil { return nil, fmt.Errorf("can't get relation %s: %w", key, err) } diff --git a/core/kanban/service_test.go b/core/kanban/service_test.go index af8d40f327..fb2a5c44b8 100644 --- a/core/kanban/service_test.go +++ b/core/kanban/service_test.go @@ -20,6 +20,7 @@ import ( ) func Test_GrouperTags(t *testing.T) { + const spaceId = "space1" tmpDir, _ := ioutil.TempDir("", "") defer os.RemoveAll(tmpDir) @@ -30,12 +31,12 @@ func Test_GrouperTags(t *testing.T) { objectStore := objectstore.NewStoreFixture(t) - objectStore.AddObjects(t, []objectstore.TestObject{ + objectStore.AddObjects(t, spaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("tag1"), bundle.RelationKeyUniqueKey: pbtypes.String("rel-tag"), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_tag)), - bundle.RelationKeySpaceId: pbtypes.String(""), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), }, }) @@ -46,7 +47,9 @@ func Test_GrouperTags(t *testing.T) { Start(context.Background()) require.NoError(t, err) - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), "rel-tag", &types.Struct{ + store := objectStore.SpaceIndex(spaceId) + + require.NoError(t, store.UpdateObjectDetails(context.Background(), "rel-tag", &types.Struct{ Fields: map[string]*types.Value{ "id": pbtypes.String("rel-tag"), "relationKey": pbtypes.String("tag"), @@ -60,7 +63,7 @@ func Test_GrouperTags(t *testing.T) { idTag2 := bson.NewObjectId().Hex() idTag3 := bson.NewObjectId().Hex() - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), idTag1, &types.Struct{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), idTag1, &types.Struct{ Fields: map[string]*types.Value{ "id": pbtypes.String(idTag1), "relationKey": pbtypes.String("tag"), @@ -69,7 +72,7 @@ func Test_GrouperTags(t *testing.T) { }, })) - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), idTag2, &types.Struct{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), idTag2, &types.Struct{ Fields: map[string]*types.Value{ "id": pbtypes.String(idTag2), "relationKey": pbtypes.String("tag"), @@ -77,7 +80,7 @@ func Test_GrouperTags(t *testing.T) { "layout": pbtypes.Int64(int64(model.ObjectType_relationOption)), }, })) - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), idTag3, &types.Struct{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), idTag3, &types.Struct{ Fields: map[string]*types.Value{ "id": pbtypes.String(idTag3), "relationKey": pbtypes.String("tag"), @@ -91,35 +94,35 @@ func Test_GrouperTags(t *testing.T) { id3 := bson.NewObjectId().Hex() id4 := bson.NewObjectId().Hex() - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), id1, &types.Struct{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), id1, &types.Struct{ Fields: map[string]*types.Value{"name": pbtypes.String("one")}, })) - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), id2, &types.Struct{Fields: map[string]*types.Value{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), id2, &types.Struct{Fields: map[string]*types.Value{ "name": pbtypes.String("two"), "tag": pbtypes.StringList([]string{idTag1}), }})) - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), id3, &types.Struct{Fields: map[string]*types.Value{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), id3, &types.Struct{Fields: map[string]*types.Value{ "name": pbtypes.String("three"), "tag": pbtypes.StringList([]string{idTag1, idTag2, idTag3}), }})) - require.NoError(t, objectStore.UpdateObjectDetails(context.Background(), id4, &types.Struct{Fields: map[string]*types.Value{ + require.NoError(t, store.UpdateObjectDetails(context.Background(), id4, &types.Struct{Fields: map[string]*types.Value{ "name": pbtypes.String("four"), "tag": pbtypes.StringList([]string{idTag1, idTag3}), }})) - grouper, err := kanbanSrv.Grouper("", "tag") + grouper, err := kanbanSrv.Grouper(spaceId, "tag") require.NoError(t, err) - err = grouper.InitGroups("", nil) + err = grouper.InitGroups(spaceId, nil) require.NoError(t, err) groups, err := grouper.MakeDataViewGroups() require.NoError(t, err) require.Len(t, groups, 6) f := &database.Filters{FilterObj: database.FilterEq{Key: "name", Cond: 1, Value: pbtypes.String("three")}} - err = grouper.InitGroups("", f) + err = grouper.InitGroups(spaceId, f) require.NoError(t, err) groups, err = grouper.MakeDataViewGroups() require.NoError(t, err) diff --git a/core/navigation.go b/core/navigation.go index 96edc11b2d..2aa8ecd850 100644 --- a/core/navigation.go +++ b/core/navigation.go @@ -4,14 +4,14 @@ import ( "context" "fmt" - "github.com/anyproto/any-sync/app" - "github.com/anyproto/anytype-heart/core/block/object/idresolver" "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider" + "github.com/anyproto/anytype-heart/util/pbtypes" ) func (mw *Middleware) NavigationListObjects(cctx context.Context, req *pb.RpcNavigationListObjectsRequest) *pb.RpcNavigationListObjectsResponse { @@ -25,7 +25,7 @@ func (mw *Middleware) NavigationListObjects(cctx context.Context, req *pb.RpcNav return response(pb.RpcNavigationListObjectsResponseError_UNKNOWN_ERROR, nil, fmt.Errorf("not implemented")) } -func (mw *Middleware) NavigationGetObjectInfoWithLinks(cctx context.Context, req *pb.RpcNavigationGetObjectInfoWithLinksRequest) *pb.RpcNavigationGetObjectInfoWithLinksResponse { +func (mw *Middleware) NavigationGetObjectInfoWithLinks(_ context.Context, req *pb.RpcNavigationGetObjectInfoWithLinksRequest) *pb.RpcNavigationGetObjectInfoWithLinksResponse { response := func(code pb.RpcNavigationGetObjectInfoWithLinksResponseErrorCode, object *model.ObjectInfoWithLinks, err error) *pb.RpcNavigationGetObjectInfoWithLinksResponse { m := &pb.RpcNavigationGetObjectInfoWithLinksResponse{Error: &pb.RpcNavigationGetObjectInfoWithLinksResponseError{Code: code}, Object: object} if err != nil { @@ -40,21 +40,23 @@ func (mw *Middleware) NavigationGetObjectInfoWithLinks(cctx context.Context, req } resolver := getService[idresolver.Resolver](mw) - store := app.MustComponent[objectstore.ObjectStore](mw.applicationService.GetApp()) - spaceID, err := resolver.ResolveSpaceID(req.ObjectId) + spaceId, err := resolver.ResolveSpaceID(req.ObjectId) if err != nil { - return response(pb.RpcNavigationGetObjectInfoWithLinksResponseError_UNKNOWN_ERROR, nil, fmt.Errorf("resolve spaceID: %w", err)) + return response(pb.RpcNavigationGetObjectInfoWithLinksResponseError_UNKNOWN_ERROR, nil, fmt.Errorf("resolve spaceId: %w", err)) } - page, err := store.GetWithLinksInfoByID(spaceID, req.ObjectId) + + store := getService[objectstore.ObjectStore](mw) + index := store.SpaceIndex(spaceId) + page, err := index.GetWithLinksInfoById(req.ObjectId) if err != nil { return response(pb.RpcNavigationGetObjectInfoWithLinksResponseError_UNKNOWN_ERROR, nil, err) } sbTypeProvider := getService[typeprovider.SmartBlockTypeProvider](mw) - filter := func(Objects []*model.ObjectInfo) []*model.ObjectInfo { + filter := func(objects []*model.ObjectInfo) []*model.ObjectInfo { var filtered []*model.ObjectInfo - for _, obj := range Objects { - sbType, err := sbTypeProvider.Type(spaceID, obj.Id) + for _, obj := range objects { + sbType, err := sbTypeProvider.Type(spaceId, obj.Id) if err != nil { log.Error("get smartblock type: %v", err) } @@ -62,6 +64,10 @@ func (mw *Middleware) NavigationGetObjectInfoWithLinks(cctx context.Context, req continue } + if pbtypes.GetString(obj.Details, bundle.RelationKeySpaceId.String()) != spaceId { + continue + } + filtered = append(filtered, obj) } return filtered diff --git a/core/object.go b/core/object.go index 16e1e3e604..03a7e21d36 100644 --- a/core/object.go +++ b/core/object.go @@ -20,6 +20,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain/objectorigin" "github.com/anyproto/anytype-heart/core/indexer" "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/core/subscription/crossspacesub" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" @@ -93,8 +94,9 @@ func (mw *Middleware) ObjectSearch(cctx context.Context, req *pb.RpcObjectSearch } ds := mw.applicationService.GetApp().MustComponent(objectstore.CName).(objectstore.ObjectStore) - records, err := ds.Query(database.Query{ + records, err := ds.SpaceIndex(req.SpaceId).Query(database.Query{ Filters: req.Filters, + SpaceId: req.SpaceId, Sorts: req.Sorts, Offset: int(req.Offset), Limit: int(req.Limit), @@ -143,12 +145,13 @@ func (mw *Middleware) ObjectSearchWithMeta(cctx context.Context, req *pb.RpcObje if req.ReturnHTMLHighlightsInsteadOfRanges { highlighter = ftsearch.HtmlHighlightFormatter } - results, err := ds.Query(database.Query{ + results, err := ds.SpaceIndex(req.SpaceId).Query(database.Query{ Filters: req.Filters, Sorts: req.Sorts, Offset: int(req.Offset), Limit: int(req.Limit), FullText: req.FullText, + SpaceId: req.SpaceId, Highlighter: highlighter, }) @@ -198,26 +201,11 @@ func (mw *Middleware) enrichWithDateSuggestion(ctx context.Context, records []da } var rec database.Record - var spaceID string - for _, f := range req.Filters { - if f.RelationKey == bundle.RelationKeySpaceId.String() { - if f.Condition == model.BlockContentDataviewFilter_Equal { - spaceID = f.Value.GetStringValue() - } - if f.Condition == model.BlockContentDataviewFilter_In { - spaces := f.Value.GetListValue().Values - if len(spaces) > 0 { - spaceID = spaces[0].GetStringValue() - } - } - break - } - } - rec, err := mw.makeSuggestedDateRecord(ctx, spaceID, dt) + rec, err := mw.makeSuggestedDateRecord(ctx, req.SpaceId, dt) if err != nil { return nil, fmt.Errorf("make date record: %w", err) } - f, _ := database.MakeFilters(req.Filters, store) //nolint:errcheck + f, _ := database.MakeFilters(req.Filters, store.SpaceIndex(req.SpaceId)) //nolint:errcheck if f.FilterObject(rec.Details) { return append([]database.Record{rec}, records...), nil } @@ -327,6 +315,7 @@ func (mw *Middleware) ObjectSearchSubscribe(cctx context.Context, req *pb.RpcObj subService := mw.applicationService.GetApp().MustComponent(subscription.CName).(subscription.Service) resp, err := subService.Search(subscription.SubscribeRequest{ + SpaceId: req.SpaceId, SubId: req.SubId, Filters: req.Filters, Sorts: req.Sorts, @@ -336,7 +325,6 @@ func (mw *Middleware) ObjectSearchSubscribe(cctx context.Context, req *pb.RpcObj AfterId: req.AfterId, BeforeId: req.BeforeId, Source: req.Source, - IgnoreWorkspace: req.IgnoreWorkspace, NoDepSubscription: req.NoDepSubscription, CollectionId: req.CollectionId, }) @@ -352,8 +340,49 @@ func (mw *Middleware) ObjectSearchSubscribe(cctx context.Context, req *pb.RpcObj } } -func (mw *Middleware) ObjectGroupsSubscribe(cctx context.Context, req *pb.RpcObjectGroupsSubscribeRequest) *pb.RpcObjectGroupsSubscribeResponse { - ctx := mw.newContext(cctx) +func (mw *Middleware) ObjectCrossSpaceSearchSubscribe(cctx context.Context, req *pb.RpcObjectCrossSpaceSearchSubscribeRequest) *pb.RpcObjectCrossSpaceSearchSubscribeResponse { + subService := getService[crossspacesub.Service](mw) + resp, err := subService.Subscribe(subscription.SubscribeRequest{ + SubId: req.SubId, + Filters: req.Filters, + Sorts: req.Sorts, + Keys: req.Keys, + Source: req.Source, + NoDepSubscription: req.NoDepSubscription, + CollectionId: req.CollectionId, + }) + if err != nil { + return &pb.RpcObjectCrossSpaceSearchSubscribeResponse{ + Error: &pb.RpcObjectCrossSpaceSearchSubscribeResponseError{ + Code: pb.RpcObjectCrossSpaceSearchSubscribeResponseError_UNKNOWN_ERROR, + Description: getErrorDescription(err), + }, + } + } + + return &pb.RpcObjectCrossSpaceSearchSubscribeResponse{ + SubId: resp.SubId, + Records: resp.Records, + Dependencies: resp.Dependencies, + Counters: resp.Counters, + } +} + +func (mw *Middleware) ObjectCrossSpaceSearchUnsubscribe(cctx context.Context, req *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) *pb.RpcObjectCrossSpaceSearchUnsubscribeResponse { + subService := getService[crossspacesub.Service](mw) + err := subService.Unsubscribe(req.SubId) + if err != nil { + return &pb.RpcObjectCrossSpaceSearchUnsubscribeResponse{ + Error: &pb.RpcObjectCrossSpaceSearchUnsubscribeResponseError{ + Code: pb.RpcObjectCrossSpaceSearchUnsubscribeResponseError_UNKNOWN_ERROR, + Description: getErrorDescription(err), + }, + } + } + return &pb.RpcObjectCrossSpaceSearchUnsubscribeResponse{} +} + +func (mw *Middleware) ObjectGroupsSubscribe(_ context.Context, req *pb.RpcObjectGroupsSubscribeRequest) *pb.RpcObjectGroupsSubscribeResponse { errResponse := func(err error) *pb.RpcObjectGroupsSubscribeResponse { r := &pb.RpcObjectGroupsSubscribeResponse{ Error: &pb.RpcObjectGroupsSubscribeResponseError{ @@ -372,7 +401,7 @@ func (mw *Middleware) ObjectGroupsSubscribe(cctx context.Context, req *pb.RpcObj subService := mw.applicationService.GetApp().MustComponent(subscription.CName).(subscription.Service) - resp, err := subService.SubscribeGroups(ctx, *req) + resp, err := subService.SubscribeGroups(*req) if err != nil { return errResponse(err) } diff --git a/core/payments/payments.go b/core/payments/payments.go index d070ead218..7b95f74b38 100644 --- a/core/payments/payments.go +++ b/core/payments/payments.go @@ -3,7 +3,6 @@ package payments import ( "context" "errors" - "sync" "time" "unicode/utf8" @@ -24,6 +23,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/logging" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/deletioncontroller" + "github.com/anyproto/anytype-heart/util/contexthelper" ) const CName = "payments" @@ -123,14 +123,15 @@ func New() Service { } type service struct { - cache cache.CacheService - ppclient ppclient.AnyPpClientService - wallet wallet.Wallet - mx sync.Mutex - periodicGetStatus periodicsync.PeriodicSync - eventSender event.Sender - profileUpdater globalNamesUpdater - ns nameservice.Service + cache cache.CacheService + ppclient ppclient.AnyPpClientService + wallet wallet.Wallet + getSubscriptionLimiter chan struct{} + periodicGetStatus periodicsync.PeriodicSync + eventSender event.Sender + profileUpdater globalNamesUpdater + ns nameservice.Service + closing chan struct{} multiplayerLimitsUpdater deletioncontroller.DeletionController fileLimitsUpdater filesync.FileSync @@ -150,6 +151,8 @@ func (s *service) Init(a *app.App) (err error) { s.profileUpdater = app.MustComponent[globalNamesUpdater](a) s.multiplayerLimitsUpdater = app.MustComponent[deletioncontroller.DeletionController](a) s.fileLimitsUpdater = app.MustComponent[filesync.FileSync](a) + s.getSubscriptionLimiter = make(chan struct{}, 1) + s.closing = make(chan struct{}) return nil } @@ -159,12 +162,12 @@ func (s *service) Run(ctx context.Context) (err error) { if val != nil && val.(bool) { return nil } - s.periodicGetStatus.Run() return nil } func (s *service) Close(_ context.Context) (err error) { + close(s.closing) s.periodicGetStatus.Close() return nil } @@ -190,7 +193,7 @@ func (s *service) sendMembershipUpdateEvent(status *pb.RpcMembershipGetStatusRes }) } -// Logic: +// GetSubscriptionStatus Logic: // // 1. Check in cache. if req.NoCache -> do not check in cache. // 2. If found in cache -> return it @@ -203,9 +206,17 @@ func (s *service) sendMembershipUpdateEvent(status *pb.RpcMembershipGetStatusRes // 8. UpdateLimits // 9. Enable cache again if status is active func (s *service) GetSubscriptionStatus(ctx context.Context, req *pb.RpcMembershipGetStatusRequest) (*pb.RpcMembershipGetStatusResponse, error) { - s.mx.Lock() - defer s.mx.Unlock() - + // wrap context to stop in-flight request in case of component close + ctx, cancel := contexthelper.ContextWithCloseChan(ctx, s.closing) + defer cancel() + select { + case <-ctx.Done(): + return nil, ctx.Err() + case s.getSubscriptionLimiter <- struct{}{}: + defer func() { + <-s.getSubscriptionLimiter + }() + } // 1 - check in cache first var ( cachedStatus *pb.RpcMembershipGetStatusResponse @@ -676,9 +687,11 @@ func (s *service) GetVerificationEmail(ctx context.Context, req *pb.RpcMembershi // 1 - send request bsr := proto.GetVerificationEmailRequest{ // payment node will check if signature matches with this OwnerAnyID - OwnerAnyId: s.wallet.Account().SignKey.GetPublic().Account(), - Email: req.Email, - SubscribeToNewsletter: req.SubscribeToNewsletter, + OwnerAnyId: s.wallet.Account().SignKey.GetPublic().Account(), + Email: req.Email, + SubscribeToNewsletter: req.SubscribeToNewsletter, + InsiderTipsAndTutorials: req.InsiderTipsAndTutorials, + IsOnboardingList: req.IsOnboardingList, } payload, err := bsr.Marshal() diff --git a/core/payments/payments_test.go b/core/payments/payments_test.go index 456c121ce1..24f3ffb4f5 100644 --- a/core/payments/payments_test.go +++ b/core/payments/payments_test.go @@ -1021,6 +1021,8 @@ func TestGetVerificationEmail(t *testing.T) { req := &pb.RpcMembershipGetVerificationEmailRequest{} req.Email = "some@mail.com" req.SubscribeToNewsletter = true + req.InsiderTipsAndTutorials = false + req.IsOnboardingList = false // Call the function being tested _, err := fx.GetVerificationEmail(ctx, req) diff --git a/core/relationutils/relation.go b/core/relationutils/relation.go index 81ae47cf77..a811d7718f 100644 --- a/core/relationutils/relation.go +++ b/core/relationutils/relation.go @@ -27,7 +27,6 @@ func RelationFromStruct(st *types.Struct) *Relation { ObjectTypes: pbtypes.GetStringList(st, bundle.RelationKeyRelationFormatObjectTypes.String()), MaxCount: maxCount, Description: pbtypes.GetString(st, bundle.RelationKeyDescription.String()), - Scope: model.RelationScope(pbtypes.GetFloat64(st, bundle.RelationKeyScope.String())), Creator: pbtypes.GetString(st, bundle.RelationKeyCreator.String()), Revision: pbtypes.GetInt64(st, bundle.RelationKeyRevision.String()), }, @@ -61,7 +60,6 @@ func (r *Relation) ToStruct() *types.Struct { bundle.RelationKeyRelationKey.String(): pbtypes.String(r.GetKey()), bundle.RelationKeyRelationMaxCount.String(): pbtypes.Float64(float64(r.GetMaxCount())), bundle.RelationKeyRelationReadonlyValue.String(): pbtypes.Bool(r.GetReadOnly()), - bundle.RelationKeyScope.String(): pbtypes.Float64(float64(r.GetScope())), bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelation.BundledURL()), // TODO Is it ok? bundle.RelationKeyUniqueKey.String(): pbtypes.String(domain.RelationKey(r.GetKey()).URL()), diff --git a/core/subscription/collection.go b/core/subscription/collection.go index e0965670ba..9d065c5a23 100644 --- a/core/subscription/collection.go +++ b/core/subscription/collection.go @@ -10,12 +10,13 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/util/pbtypes" "github.com/anyproto/anytype-heart/util/slice" ) type collectionObserver struct { + spaceId string collectionID string subID string objectsCh <-chan []string @@ -27,18 +28,21 @@ type collectionObserver struct { closeCh chan struct{} cache *cache - objectStore objectstore.ObjectStore + objectStore spaceindex.Store collectionService CollectionService recBatch *mb.MB + + spaceSubscription *spaceSubscriptions } -func (s *service) newCollectionObserver(collectionID string, subID string) (*collectionObserver, error) { +func (s *spaceSubscriptions) newCollectionObserver(spaceId string, collectionID string, subID string) (*collectionObserver, error) { initialObjectIDs, objectsCh, err := s.collectionService.SubscribeForCollection(collectionID, subID) if err != nil { return nil, fmt.Errorf("subscribe for collection: %w", err) } obs := &collectionObserver{ + spaceId: spaceId, collectionID: collectionID, subID: subID, objectsCh: objectsCh, @@ -51,6 +55,8 @@ func (s *service) newCollectionObserver(collectionID string, subID string) (*col collectionService: s.collectionService, idsSet: map[string]struct{}{}, + + spaceSubscription: s, } obs.ids = initialObjectIDs for _, id := range initialObjectIDs { @@ -61,7 +67,7 @@ func (s *service) newCollectionObserver(collectionID string, subID string) (*col for { select { case objectIDs := <-objectsCh: - obs.updateIDs(objectIDs) + obs.updateIds(objectIDs) case <-obs.closeCh: return } @@ -86,13 +92,13 @@ func (c *collectionObserver) close() { func (c *collectionObserver) listEntries() []*entry { c.lock.RLock() defer c.lock.RUnlock() - entries := fetchEntries(c.cache, c.objectStore, c.ids) + entries := c.spaceSubscription.fetchEntries(c.ids) res := make([]*entry, len(entries)) copy(res, entries) return res } -func (c *collectionObserver) updateIDs(ids []string) { +func (c *collectionObserver) updateIds(ids []string) { c.lock.Lock() defer c.lock.Unlock() @@ -105,7 +111,7 @@ func (c *collectionObserver) updateIDs(ids []string) { } c.ids = ids - entries := fetchEntries(c.cache, c.objectStore, append(removed, added...)) + entries := c.spaceSubscription.fetchEntriesLocked(append(removed, added...)) for _, e := range entries { err := c.recBatch.Add(database.Record{ Details: e.data, @@ -178,10 +184,8 @@ func (c *collectionSub) close() { c.sortedSub.close() } -func (s *service) newCollectionSub( - id, collectionID string, keys, filterDepIds []string, flt database.Filter, order database.Order, limit, offset int, disableDepSub bool, -) (*collectionSub, error) { - obs, err := s.newCollectionObserver(collectionID, id) +func (s *spaceSubscriptions) newCollectionSub(id string, spaceId string, collectionID string, keys, filterDepIds []string, flt database.Filter, order database.Order, limit, offset int, disableDepSub bool) (*collectionSub, error) { + obs, err := s.newCollectionObserver(spaceId, collectionID, id) if err != nil { return nil, err } @@ -191,7 +195,7 @@ func (s *service) newCollectionSub( flt = database.FiltersAnd{obs, flt} } - ssub := s.newSortedSub(id, keys, flt, order, limit, offset) + ssub := s.newSortedSub(id, spaceId, keys, flt, order, limit, offset) ssub.disableDep = disableDepSub if !ssub.disableDep { ssub.forceSubIds = filterDepIds @@ -215,11 +219,17 @@ func (s *service) newCollectionSub( return sub, nil } -func fetchEntries(cache *cache, objectStore objectstore.ObjectStore, ids []string) []*entry { +func (s *spaceSubscriptions) fetchEntriesLocked(ids []string) []*entry { + s.m.Lock() + defer s.m.Unlock() + return s.fetchEntries(ids) +} + +func (s *spaceSubscriptions) fetchEntries(ids []string) []*entry { res := make([]*entry, 0, len(ids)) missingIDs := make([]string, 0, len(ids)) for _, id := range ids { - if e := cache.Get(id); e != nil { + if e := s.cache.Get(id); e != nil { res = append(res, e) continue } @@ -229,7 +239,7 @@ func fetchEntries(cache *cache, objectStore objectstore.ObjectStore, ids []strin if len(missingIDs) == 0 { return res } - recs, err := objectStore.QueryByID(missingIDs) + recs, err := s.objectStore.QueryByIds(missingIDs) if err != nil { log.Error("can't query by ids:", err) } diff --git a/core/subscription/collection_group.go b/core/subscription/collection_group.go index 5be1622c0e..7e52260760 100644 --- a/core/subscription/collection_group.go +++ b/core/subscription/collection_group.go @@ -11,7 +11,7 @@ type collectionGroupSub struct { colObserver *collectionObserver } -func (s *service) newCollectionGroupSub(id string, relKey string, f *database.Filters, groups []*model.BlockContentDataviewGroup, colObserver *collectionObserver) *collectionGroupSub { +func (s *spaceSubscriptions) newCollectionGroupSub(id string, relKey string, f *database.Filters, groups []*model.BlockContentDataviewGroup, colObserver *collectionObserver) *collectionGroupSub { sub := &collectionGroupSub{ groupSub: s.newGroupSub(id, relKey, f, groups), colObserver: colObserver, diff --git a/core/subscription/collection_test.go b/core/subscription/collection_test.go new file mode 100644 index 0000000000..7805e1eafc --- /dev/null +++ b/core/subscription/collection_test.go @@ -0,0 +1,106 @@ +package subscription + +import ( + "testing" + + "github.com/cheggaaa/mb" + "github.com/gogo/protobuf/types" + "github.com/stretchr/testify/assert" + + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +func Test_newCollectionObserver(t *testing.T) { + spaceId := "spaceId" + t.Run("fetch entries from cache", func(t *testing.T) { + // given + collectionService := NewMockCollectionService(t) + collectionID := "collectionId" + subId := "subId" + ch := make(chan []string) + collectionService.EXPECT().SubscribeForCollection(collectionID, subId).Return([]string{"id"}, ch, nil) + store := spaceindex.NewStoreFixture(t) + cache := newCache() + cache.Set(&entry{id: "id1", data: &types.Struct{Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String("id1"), + }}}) + cache.Set(&entry{id: "id2", data: &types.Struct{Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String("id2"), + }}}) + batcher := mb.New(0) + c := &spaceSubscriptions{ + collectionService: collectionService, + objectStore: store, + recBatch: batcher, + cache: cache, + } + + // when + observer, err := c.newCollectionObserver(spaceId, collectionID, subId) + + // then + assert.NoError(t, err) + expectedIds := []string{"id1", "id2"} + ch <- expectedIds + close(observer.closeCh) + msgs := batcher.Wait() + + var receivedIds []string + for _, msg := range msgs { + id := pbtypes.GetString(msg.(database.Record).Details, "id") + receivedIds = append(receivedIds, id) + } + assert.Equal(t, expectedIds, receivedIds) + err = batcher.Close() + assert.NoError(t, err) + }) + t.Run("fetch entries from object store", func(t *testing.T) { + // given + collectionService := NewMockCollectionService(t) + collectionID := "collectionId" + subId := "subId" + ch := make(chan []string) + collectionService.EXPECT().SubscribeForCollection(collectionID, subId).Return([]string{"id"}, ch, nil) + store := spaceindex.NewStoreFixture(t) + + store.AddObjects(t, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("id1"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), + }, + { + bundle.RelationKeyId: pbtypes.String("id2"), + bundle.RelationKeySpaceId: pbtypes.String(spaceId), + }, + }) + batcher := mb.New(0) + c := &spaceSubscriptions{ + collectionService: collectionService, + objectStore: store, + recBatch: batcher, + cache: newCache(), + } + + // when + observer, err := c.newCollectionObserver(spaceId, collectionID, subId) + + // then + assert.NoError(t, err) + expectedIds := []string{"id1", "id2"} + ch <- expectedIds + close(observer.closeCh) + msgs := batcher.Wait() + + var receivedIds []string + for _, msg := range msgs { + id := pbtypes.GetString(msg.(database.Record).Details, "id") + receivedIds = append(receivedIds, id) + } + assert.Equal(t, expectedIds, receivedIds) + err = batcher.Close() + assert.NoError(t, err) + }) +} diff --git a/core/subscription/context.go b/core/subscription/context.go index e36f698fd4..133b4f15ab 100644 --- a/core/subscription/context.go +++ b/core/subscription/context.go @@ -354,3 +354,51 @@ func (ctx *opCtx) reset() { } } } + +type EventMatcher struct { + OnAdd func(*pb.EventObjectSubscriptionAdd) + OnRemove func(*pb.EventObjectSubscriptionRemove) + OnPosition func(*pb.EventObjectSubscriptionPosition) + OnSet func(*pb.EventObjectDetailsSet) + OnUnset func(*pb.EventObjectDetailsUnset) + OnAmend func(*pb.EventObjectDetailsAmend) + OnCounters func(*pb.EventObjectSubscriptionCounters) + OnGroups func(*pb.EventObjectSubscriptionGroups) +} + +func (m EventMatcher) Match(msg *pb.EventMessage) { + switch v := msg.Value.(type) { + case *pb.EventMessageValueOfSubscriptionAdd: + if m.OnAdd != nil { + m.OnAdd(v.SubscriptionAdd) + } + case *pb.EventMessageValueOfSubscriptionRemove: + if m.OnRemove != nil { + m.OnRemove(v.SubscriptionRemove) + } + case *pb.EventMessageValueOfSubscriptionPosition: + if m.OnPosition != nil { + m.OnPosition(v.SubscriptionPosition) + } + case *pb.EventMessageValueOfObjectDetailsSet: + if m.OnSet != nil { + m.OnSet(v.ObjectDetailsSet) + } + case *pb.EventMessageValueOfObjectDetailsUnset: + if m.OnUnset != nil { + m.OnUnset(v.ObjectDetailsUnset) + } + case *pb.EventMessageValueOfObjectDetailsAmend: + if m.OnAmend != nil { + m.OnAmend(v.ObjectDetailsAmend) + } + case *pb.EventMessageValueOfSubscriptionCounters: + if m.OnCounters != nil { + m.OnCounters(v.SubscriptionCounters) + } + case *pb.EventMessageValueOfSubscriptionGroups: + if m.OnGroups != nil { + m.OnGroups(v.SubscriptionGroups) + } + } +} diff --git a/core/subscription/crossspacesub/crossspacesub.go b/core/subscription/crossspacesub/crossspacesub.go new file mode 100644 index 0000000000..c6144c88d4 --- /dev/null +++ b/core/subscription/crossspacesub/crossspacesub.go @@ -0,0 +1,227 @@ +package crossspacesub + +import ( + "context" + "errors" + "fmt" + "sync" + + "github.com/cheggaaa/mb/v3" + "go.uber.org/zap" + + "github.com/anyproto/anytype-heart/core/event" + subscriptionservice "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/pb" +) + +type crossSpaceSubscription struct { + subId string + + request subscriptionservice.SubscribeRequest + + eventSender event.Sender + subscriptionService subscriptionservice.Service + + ctx context.Context + ctxCancel context.CancelFunc + queue *mb.MB[*pb.EventMessage] + + lock sync.Mutex + // spaceId => subId + perSpaceSubscriptions map[string]string + // internal sub id (bson id) => total count + totalCounts map[string]int64 +} + +func newCrossSpaceSubscription(subId string, request subscriptionservice.SubscribeRequest, eventSender event.Sender, subscriptionService subscriptionservice.Service, initialSpaceIds []string) (*crossSpaceSubscription, *subscriptionservice.SubscribeResponse, error) { + ctx, ctxCancel := context.WithCancel(context.Background()) + s := &crossSpaceSubscription{ + ctx: ctx, + ctxCancel: ctxCancel, + subId: subId, + request: request, + eventSender: eventSender, + subscriptionService: subscriptionService, + perSpaceSubscriptions: make(map[string]string), + totalCounts: map[string]int64{}, + queue: mb.New[*pb.EventMessage](0), + } + aggregatedResp := &subscriptionservice.SubscribeResponse{ + SubId: subId, + Counters: &pb.EventObjectSubscriptionCounters{}, + } + for _, spaceId := range initialSpaceIds { + resp, err := s.addSpace(spaceId, false) + if err != nil { + return nil, nil, fmt.Errorf("add space: %w", err) + } + aggregatedResp.Records = append(aggregatedResp.Records, resp.Records...) + aggregatedResp.Dependencies = append(aggregatedResp.Dependencies, resp.Dependencies...) + aggregatedResp.Counters.Total += resp.Counters.Total + + s.updateTotalCount(resp.SubId, resp.Counters.Total) + } + return s, aggregatedResp, nil +} + +func (s *crossSpaceSubscription) run() { + for { + msgs, err := s.queue.Wait(s.ctx) + if errors.Is(err, context.Canceled) { + return + } + if err != nil { + log.Error("wait messages", zap.Error(err), zap.String("subId", s.subId)) + } + for _, msg := range msgs { + s.patchEvent(msg) + } + + s.eventSender.Broadcast(&pb.Event{ + Messages: msgs, + }) + } +} + +func (s *crossSpaceSubscription) patchEvent(msg *pb.EventMessage) { + matcher := subscriptionservice.EventMatcher{ + OnAdd: func(add *pb.EventObjectSubscriptionAdd) { + add.SubId = s.subId + add.AfterId = "" + }, + OnRemove: func(remove *pb.EventObjectSubscriptionRemove) { + remove.SubId = s.subId + }, + OnPosition: func(position *pb.EventObjectSubscriptionPosition) { + position.SubId = s.subId + position.AfterId = "" + }, + OnSet: func(set *pb.EventObjectDetailsSet) { + set.SubIds = []string{s.subId} + }, + OnUnset: func(unset *pb.EventObjectDetailsUnset) { + unset.SubIds = []string{s.subId} + }, + OnAmend: func(amend *pb.EventObjectDetailsAmend) { + amend.SubIds = []string{s.subId} + }, + OnCounters: func(counters *pb.EventObjectSubscriptionCounters) { + total := s.updateTotalCount(counters.SubId, counters.Total) + counters.Total = total + counters.SubId = s.subId + }, + OnGroups: func(groups *pb.EventObjectSubscriptionGroups) { + groups.SubId = s.subId + }, + } + matcher.Match(msg) +} + +func (s *crossSpaceSubscription) close() error { + s.ctxCancel() + return s.queue.Close() +} + +func (s *crossSpaceSubscription) AddSpace(spaceId string) error { + s.lock.Lock() + defer s.lock.Unlock() + _, err := s.addSpace(spaceId, true) + if err != nil { + return fmt.Errorf("add space: %w", err) + } + + return nil +} + +func (s *crossSpaceSubscription) addSpace(spaceId string, asyncInit bool) (*subscriptionservice.SubscribeResponse, error) { + if _, ok := s.perSpaceSubscriptions[spaceId]; ok { + return nil, nil + } + + req := s.request + // Will be generated automatically + req.SubId = "" + req.Internal = true + req.InternalQueue = s.queue + req.SpaceId = spaceId + req.AsyncInit = asyncInit + + resp, err := s.subscriptionService.Search(req) + if err != nil { + return nil, err + } + s.perSpaceSubscriptions[spaceId] = resp.SubId + return resp, nil +} + +func (s *crossSpaceSubscription) RemoveSpace(spaceId string) { + s.lock.Lock() + defer s.lock.Unlock() + err := s.removeSpace(spaceId) + if err != nil { + log.Error("remove space", zap.Error(err), zap.String("subId", s.subId), zap.String("spaceId", spaceId)) + } +} + +func (s *crossSpaceSubscription) removeSpace(spaceId string) error { + subId, ok := s.perSpaceSubscriptions[spaceId] + if ok { + ids, err := s.subscriptionService.UnsubscribeAndReturnIds(spaceId, subId) + if err != nil { + return err + } + for _, id := range ids { + err = s.queue.Add(s.ctx, &pb.EventMessage{ + Value: &pb.EventMessageValueOfSubscriptionRemove{ + SubscriptionRemove: &pb.EventObjectSubscriptionRemove{ + SubId: s.subId, + Id: id, + }, + }, + }) + if err != nil { + return fmt.Errorf("send remove event to queue: %w", err) + } + } + + total := s.removeTotalCount(subId) + err = s.queue.Add(s.ctx, &pb.EventMessage{ + Value: &pb.EventMessageValueOfSubscriptionCounters{ + SubscriptionCounters: &pb.EventObjectSubscriptionCounters{ + SubId: subId, + Total: total, + }, + }, + }) + if err != nil { + return fmt.Errorf("send counters event to queue: %w", err) + } + delete(s.perSpaceSubscriptions, spaceId) + } + return nil +} + +func (s *crossSpaceSubscription) updateTotalCount(internalSubId string, perSpaceTotal int64) int64 { + s.lock.Lock() + defer s.lock.Unlock() + + s.totalCounts[internalSubId] = perSpaceTotal + + return s.getTotalCount() +} + +// removeTotalCount should be only called under s.lock +func (s *crossSpaceSubscription) removeTotalCount(internalSubId string) int64 { + delete(s.totalCounts, internalSubId) + + return s.getTotalCount() +} + +// getTotalCount should be only called under s.lock +func (s *crossSpaceSubscription) getTotalCount() int64 { + var total int64 + for _, t := range s.totalCounts { + total += t + } + return total +} diff --git a/core/subscription/crossspacesub/service.go b/core/subscription/crossspacesub/service.go new file mode 100644 index 0000000000..b9c6b002e8 --- /dev/null +++ b/core/subscription/crossspacesub/service.go @@ -0,0 +1,120 @@ +package crossspacesub + +import ( + "context" + "fmt" + "sync" + + "github.com/anyproto/any-sync/app" + "github.com/globalsign/mgo/bson" + + "github.com/anyproto/anytype-heart/core/event" + subscriptionservice "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/pkg/lib/logging" + "github.com/anyproto/anytype-heart/space" +) + +var log = logging.Logger(CName).Desugar() + +const CName = "core.subscription.crossspacesub" + +type Service interface { + app.ComponentRunnable + Subscribe(req subscriptionservice.SubscribeRequest) (resp *subscriptionservice.SubscribeResponse, err error) + Unsubscribe(subId string) error +} + +type service struct { + spaceService space.Service + subscriptionService subscriptionservice.Service + eventSender event.Sender + + componentCtx context.Context + componentCtxCancel context.CancelFunc + + lock sync.Mutex + spaceViewsSubId string + spaceViewTargetIds map[string]string + spaceIds []string + subscriptions map[string]*crossSpaceSubscription +} + +func New() Service { + return &service{} +} + +func (s *service) Init(a *app.App) error { + s.componentCtx, s.componentCtxCancel = context.WithCancel(context.Background()) + s.spaceService = app.MustComponent[space.Service](a) + s.subscriptionService = app.MustComponent[subscriptionservice.Service](a) + s.eventSender = app.MustComponent[event.Sender](a) + s.subscriptions = map[string]*crossSpaceSubscription{} + s.spaceViewTargetIds = map[string]string{} + + return nil +} + +func (s *service) Name() (name string) { + return CName +} + +func (s *service) Run(ctx context.Context) error { + return s.runSpaceViewSub() +} + +func (s *service) Close(ctx context.Context) error { + s.componentCtxCancel() + s.lock.Lock() + err := s.subscriptionService.Unsubscribe(s.spaceViewsSubId) + s.lock.Unlock() + return err +} + +func (s *service) Subscribe(req subscriptionservice.SubscribeRequest) (*subscriptionservice.SubscribeResponse, error) { + if !req.NoDepSubscription { + return nil, fmt.Errorf("dependency subscription is not yet supported") + } + if req.Limit != 0 { + return nil, fmt.Errorf("limit is not supported") + } + if req.AfterId != "" || req.BeforeId != "" { + return nil, fmt.Errorf("pagination is not supported") + } + if req.CollectionId != "" { + return nil, fmt.Errorf("collection is not supported") + } + if req.SubId == "" { + req.SubId = bson.NewObjectId().Hex() + } + if len(req.Sorts) > 0 { + return nil, fmt.Errorf("sorting is not supported") + } + + s.lock.Lock() + defer s.lock.Unlock() + spaceSub, resp, err := newCrossSpaceSubscription(req.SubId, req, s.eventSender, s.subscriptionService, s.spaceIds) + if err != nil { + return nil, fmt.Errorf("new cross space subscription: %w", err) + } + s.subscriptions[req.SubId] = spaceSub + go spaceSub.run() + return resp, nil +} + +func (s *service) Unsubscribe(subId string) error { + s.lock.Lock() + defer s.lock.Unlock() + + sub, ok := s.subscriptions[subId] + if !ok { + return fmt.Errorf("subscription not found") + } + + err := sub.close() + if err != nil { + return fmt.Errorf("close subscription: %w", err) + } + delete(s.subscriptions, subId) + + return nil +} diff --git a/core/subscription/crossspacesub/service_test.go b/core/subscription/crossspacesub/service_test.go new file mode 100644 index 0000000000..370817e18f --- /dev/null +++ b/core/subscription/crossspacesub/service_test.go @@ -0,0 +1,432 @@ +package crossspacesub + +import ( + "context" + "testing" + "time" + + "github.com/anyproto/any-sync/app" + "github.com/cheggaaa/mb/v3" + "github.com/gogo/protobuf/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/core/event/mock_event" + "github.com/anyproto/anytype-heart/core/kanban/mock_kanban" + subscriptionservice "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/space/mock_space" + "github.com/anyproto/anytype-heart/tests/testutil" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +type fixture struct { + *service + + objectStore *objectstore.StoreFixture + spaceService *mock_space.MockService + eventQueue *mb.MB[*pb.EventMessage] +} + +const techSpaceId = "techSpaceId" + +func newFixture(t *testing.T) *fixture { + ctx := context.Background() + a := &app.App{} + + eventQueue := mb.New[*pb.EventMessage](0) + + // Deps for subscription service + kanbanService := mock_kanban.NewMockService(t) + eventSender := mock_event.NewMockSender(t) + eventSender.EXPECT().Broadcast(mock.Anything).Run(func(e *pb.Event) { + for _, msg := range e.Messages { + eventQueue.Add(context.Background(), msg) + } + }).Maybe() + objectStore := objectstore.NewStoreFixture(t) + collService := &dummyCollectionService{} + // Own deps + subscriptionService := subscriptionservice.New() + spaceService := mock_space.NewMockService(t) + spaceService.EXPECT().TechSpaceId().Return(techSpaceId).Maybe() + + a.Register(testutil.PrepareMock(ctx, a, kanbanService)) + a.Register(testutil.PrepareMock(ctx, a, eventSender)) + a.Register(objectStore) + a.Register(collService) + a.Register(subscriptionService) + a.Register(testutil.PrepareMock(ctx, a, spaceService)) + + s := New() + a.Register(s) + err := a.Start(ctx) + require.NoError(t, err) + + t.Cleanup(func() { + closeCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + err = a.Close(closeCtx) + require.NoError(t, err) + }) + + return &fixture{ + service: s.(*service), + objectStore: objectStore, + spaceService: spaceService, + eventQueue: eventQueue, + } +} + +func TestSubscribe(t *testing.T) { + t.Run("with existing space", func(t *testing.T) { + fx := newFixture(t) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Add space view and objects + fx.objectStore.AddObjects(t, techSpaceId, []objectstore.TestObject{ + givenSpaceViewObject("spaceView1", "space1", model.Account_Active, model.SpaceStatus_Ok), + }) + + // Subscribe + resp, err := fx.Subscribe(givenRequest()) + require.NoError(t, err) + require.NotNil(t, resp) + assert.NotEmpty(t, resp.SubId) + assert.Empty(t, resp.Records) + assert.Empty(t, resp.Dependencies) + + // Add objects + obj1 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + obj1, + }) + + // Wait events + msgs, err := fx.eventQueue.NewCond().WithMin(3).Wait(ctx) + require.NoError(t, err) + + want := []*pb.EventMessage{ + makeDetailsSetEvent(resp.SubId, obj1.Details()), + makeAddEvent(resp.SubId, obj1.Id()), + makeCountersEvent(resp.SubId, 1), + } + assert.Equal(t, want, msgs) + + t.Run("update object", func(t *testing.T) { + obj1 = objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + bundle.RelationKeyName: pbtypes.String("John Doe"), + } + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + obj1, + }) + + // Wait events + msgs, err = fx.eventQueue.NewCond().WithMin(1).Wait(ctx) + require.NoError(t, err) + + want = []*pb.EventMessage{ + makeDetailsAmendEvent(resp.SubId, obj1.Id(), []*pb.EventObjectDetailsAmendKeyValue{ + { + Key: bundle.RelationKeyName.String(), + Value: pbtypes.String("John Doe"), + }, + }), + } + assert.Equal(t, want, msgs) + }) + }) + + t.Run("without existing space", func(t *testing.T) { + fx := newFixture(t) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Subscribe + resp, err := fx.Subscribe(givenRequest()) + require.NoError(t, err) + require.NotNil(t, resp) + assert.NotEmpty(t, resp.SubId) + assert.Empty(t, resp.Records) + assert.Empty(t, resp.Dependencies) + + t.Run("add first space", func(t *testing.T) { + // Add space view + fx.objectStore.AddObjects(t, techSpaceId, []objectstore.TestObject{ + givenSpaceViewObject("spaceView1", "space1", model.Account_Active, model.SpaceStatus_Ok), + }) + + // Add objects + obj1 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + obj1, + }) + + // Wait events + msgs, err := fx.eventQueue.NewCond().WithMin(3).Wait(ctx) + require.NoError(t, err) + + want := []*pb.EventMessage{ + makeDetailsSetEvent(resp.SubId, obj1.Details()), + makeAddEvent(resp.SubId, obj1.Id()), + makeCountersEvent(resp.SubId, 1), + } + assert.Equal(t, want, msgs) + + // Add another objects + obj2 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant2"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + obj2, + }) + + // Wait events + msgs, err = fx.eventQueue.NewCond().WithMin(3).Wait(ctx) + require.NoError(t, err) + + want = []*pb.EventMessage{ + makeDetailsSetEvent(resp.SubId, obj2.Details()), + makeAddEvent(resp.SubId, obj2.Id()), + makeCountersEvent(resp.SubId, 2), + } + assert.Equal(t, want, msgs) + }) + + t.Run("add second space", func(t *testing.T) { + // Add space view + fx.objectStore.AddObjects(t, techSpaceId, []objectstore.TestObject{ + givenSpaceViewObject("spaceView2", "space2", model.Account_Active, model.SpaceStatus_Ok), + }) + + // Add objects + obj1 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant3"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + fx.objectStore.AddObjects(t, "space2", []objectstore.TestObject{ + obj1, + }) + + // Wait events + msgs, err := fx.eventQueue.NewCond().WithMin(3).Wait(ctx) + require.NoError(t, err) + + want := []*pb.EventMessage{ + makeDetailsSetEvent(resp.SubId, obj1.Details()), + makeAddEvent(resp.SubId, obj1.Id()), + makeCountersEvent(resp.SubId, 3), + } + assert.Equal(t, want, msgs) + }) + + }) + + t.Run("remove space view", func(t *testing.T) { + fx := newFixture(t) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // Add space view and objects + fx.objectStore.AddObjects(t, techSpaceId, []objectstore.TestObject{ + givenSpaceViewObject("spaceView1", "space1", model.Account_Active, model.SpaceStatus_Ok), + }) + obj1 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + obj2 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant2"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + obj1, + obj2, + }) + + // Subscribe + resp, err := fx.Subscribe(givenRequest()) + require.NoError(t, err) + require.NotNil(t, resp) + assert.NotEmpty(t, resp.SubId) + assert.Equal(t, []*types.Struct{obj1.Details(), obj2.Details()}, resp.Records) + + // Remove space view by changing its status + fx.objectStore.AddObjects(t, techSpaceId, []objectstore.TestObject{ + givenSpaceViewObject("spaceView1", "space1", model.Account_Deleted, model.SpaceStatus_Unknown), + }) + + // Wait events + msgs, err := fx.eventQueue.NewCond().WithMin(3).Wait(ctx) + require.NoError(t, err) + + want := []*pb.EventMessage{ + makeRemoveEvent(resp.SubId, obj1.Id()), + makeRemoveEvent(resp.SubId, obj2.Id()), + makeCountersEvent(resp.SubId, 0), + } + assert.Equal(t, want, msgs) + }) +} + +func TestUnsubscribe(t *testing.T) { + t.Run("subscription not found", func(t *testing.T) { + fx := newFixture(t) + + err := fx.Unsubscribe("subId") + require.Error(t, err) + }) + + t.Run("with existing subscription", func(t *testing.T) { + fx := newFixture(t) + + // Add space view + fx.objectStore.AddObjects(t, techSpaceId, []objectstore.TestObject{ + givenSpaceViewObject("spaceView1", "space1", model.Account_Active, model.SpaceStatus_Ok), + }) + + // Subscribe + resp, err := fx.Subscribe(givenRequest()) + require.NoError(t, err) + require.NotNil(t, resp) + assert.NotEmpty(t, resp.SubId) + + // Unsubscribe + err = fx.Unsubscribe(resp.SubId) + require.NoError(t, err) + + // Add objects + obj1 := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("participant1"), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_participant)), + } + fx.objectStore.AddObjects(t, "space1", []objectstore.TestObject{ + obj1, + }) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond) + defer cancel() + + // Wait events + msgs, err := fx.eventQueue.NewCond().WithMin(1).Wait(ctx) + require.ErrorIs(t, err, context.DeadlineExceeded) + assert.Empty(t, msgs) + }) +} + +func makeDetailsSetEvent(subId string, details *types.Struct) *pb.EventMessage { + return &pb.EventMessage{ + Value: &pb.EventMessageValueOfObjectDetailsSet{ + ObjectDetailsSet: &pb.EventObjectDetailsSet{ + Id: pbtypes.GetString(details, bundle.RelationKeyId.String()), + SubIds: []string{ + subId, + }, + Details: details, + }, + }, + } +} + +func makeDetailsAmendEvent(subId string, id string, details []*pb.EventObjectDetailsAmendKeyValue) *pb.EventMessage { + return &pb.EventMessage{ + Value: &pb.EventMessageValueOfObjectDetailsAmend{ + ObjectDetailsAmend: &pb.EventObjectDetailsAmend{ + Id: id, + SubIds: []string{ + subId, + }, + Details: details, + }, + }, + } +} + +func makeAddEvent(subId string, id string) *pb.EventMessage { + return &pb.EventMessage{ + Value: &pb.EventMessageValueOfSubscriptionAdd{ + SubscriptionAdd: &pb.EventObjectSubscriptionAdd{ + SubId: subId, + Id: id, + AfterId: "", + }, + }, + } +} + +func makeCountersEvent(subId string, total int) *pb.EventMessage { + return &pb.EventMessage{ + Value: &pb.EventMessageValueOfSubscriptionCounters{ + SubscriptionCounters: &pb.EventObjectSubscriptionCounters{ + SubId: subId, + Total: int64(total), + }, + }, + } +} + +func makeRemoveEvent(subId string, id string) *pb.EventMessage { + return &pb.EventMessage{ + Value: &pb.EventMessageValueOfSubscriptionRemove{ + SubscriptionRemove: &pb.EventObjectSubscriptionRemove{ + SubId: subId, + Id: id, + }, + }, + } +} + +type dummyCollectionService struct{} + +func (d *dummyCollectionService) Init(a *app.App) (err error) { + return nil +} + +func (d *dummyCollectionService) Name() (name string) { + return "dummyCollectionService" +} + +func (d *dummyCollectionService) SubscribeForCollection(collectionID string, subscriptionID string) ([]string, <-chan []string, error) { + return nil, nil, nil +} + +func (d *dummyCollectionService) UnsubscribeFromCollection(collectionID string, subscriptionID string) { +} + +func givenRequest() subscriptionservice.SubscribeRequest { + return subscriptionservice.SubscribeRequest{ + NoDepSubscription: true, + Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyLayout.String(), bundle.RelationKeyName.String()}, + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyLayout.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(int64(model.ObjectType_participant)), + }, + }, + } +} + +func givenSpaceViewObject(id string, targetSpaceId string, accountStatus model.AccountStatusType, localStatus model.SpaceStatus) objectstore.TestObject { + return objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String(id), + bundle.RelationKeyTargetSpaceId: pbtypes.String(targetSpaceId), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_spaceView)), + bundle.RelationKeySpaceAccountStatus: pbtypes.Int64(int64(accountStatus)), + bundle.RelationKeySpaceLocalStatus: pbtypes.Int64(int64(localStatus)), + } +} diff --git a/core/subscription/crossspacesub/spaceviewsub.go b/core/subscription/crossspacesub/spaceviewsub.go new file mode 100644 index 0000000000..4d96c591af --- /dev/null +++ b/core/subscription/crossspacesub/spaceviewsub.go @@ -0,0 +1,112 @@ +package crossspacesub + +import ( + "context" + "errors" + "fmt" + + "github.com/cheggaaa/mb/v3" + "go.uber.org/zap" + + subscriptionservice "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/util/pbtypes" + "github.com/anyproto/anytype-heart/util/slice" +) + +func (s *service) runSpaceViewSub() error { + resp, err := s.subscriptionService.Search(subscriptionservice.SubscribeRequest{ + SpaceId: s.spaceService.TechSpaceId(), + Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyTargetSpaceId.String()}, + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyLayout.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(int64(model.ObjectType_spaceView)), + }, + { + RelationKey: bundle.RelationKeySpaceAccountStatus.String(), + Condition: model.BlockContentDataviewFilter_NotIn, + Value: pbtypes.IntList(int(model.Account_Deleted)), + }, + { + RelationKey: bundle.RelationKeySpaceLocalStatus.String(), + Condition: model.BlockContentDataviewFilter_In, + Value: pbtypes.IntList(int(model.SpaceStatus_Ok), int(model.SpaceStatus_Unknown)), + }, + }, + Internal: true, + }) + if err != nil { + return fmt.Errorf("subscribe: %w", err) + } + + s.lock.Lock() + defer s.lock.Unlock() + s.spaceViewsSubId = resp.SubId + s.spaceViewTargetIds = make(map[string]string, len(resp.Records)) + for _, r := range resp.Records { + id := pbtypes.GetString(r, bundle.RelationKeyId.String()) + targetId := pbtypes.GetString(r, bundle.RelationKeyTargetSpaceId.String()) + s.spaceViewTargetIds[id] = targetId + s.spaceIds = append(s.spaceIds, targetId) + } + + go s.monitorSpaceViewSub(resp.Output) + + return nil +} + +func (s *service) monitorSpaceViewSub(queue *mb.MB[*pb.EventMessage]) { + matcher := subscriptionservice.EventMatcher{ + OnSet: s.onSpaceViewSet, + OnRemove: s.onSpaceViewRemove, + } + + for { + msgs, err := queue.Wait(s.componentCtx) + if errors.Is(err, context.Canceled) { + return + } + if err != nil { + log.Error("monitor space views", zap.Error(err)) + continue + } + + s.lock.Lock() + for _, msg := range msgs { + matcher.Match(msg) + } + s.lock.Unlock() + } +} + +func (s *service) onSpaceViewSet(msg *pb.EventObjectDetailsSet) { + id := pbtypes.GetString(msg.Details, bundle.RelationKeyId.String()) + targetId := pbtypes.GetString(msg.Details, bundle.RelationKeyTargetSpaceId.String()) + + if _, ok := s.spaceViewTargetIds[id]; !ok { + s.spaceViewTargetIds[id] = targetId + s.spaceIds = append(s.spaceIds, targetId) + + for _, sub := range s.subscriptions { + err := sub.AddSpace(targetId) + if err != nil { + log.Error("onSpaceViewSet: add space", zap.Error(err), zap.String("spaceId", targetId)) + } + } + } +} + +func (s *service) onSpaceViewRemove(msg *pb.EventObjectSubscriptionRemove) { + targetId, ok := s.spaceViewTargetIds[msg.Id] + if ok { + for _, sub := range s.subscriptions { + sub.RemoveSpace(targetId) + } + s.spaceIds = slice.RemoveMut(s.spaceIds, targetId) + delete(s.spaceViewTargetIds, msg.Id) + } +} diff --git a/core/subscription/debug.go b/core/subscription/debug.go index 971a09b463..2826446a15 100644 --- a/core/subscription/debug.go +++ b/core/subscription/debug.go @@ -18,26 +18,26 @@ import ( "github.com/anyproto/anytype-heart/util/pbtypes" ) -func (s *service) initDebugger() { +func (s *spaceSubscriptions) initDebugger() { s.subDebugger = newSubDebugger() } -func (s *service) debugEvents(ev *pb.Event) { +func (s *spaceSubscriptions) debugEvents(ev *pb.Event) { for _, msg := range ev.Messages { s.subDebugger.addEvent(msg) } } -func (s *service) DebugRouter(r chi.Router) { +func (s *spaceSubscriptions) DebugRouter(r chi.Router) { r.Get("/per_object", debug.PlaintextHandler(s.debugPerObject)) r.Get("/per_subscription", debug.PlaintextHandler(s.debugPerSubscription)) } -func (s *service) debugPerObject(w io.Writer, req *http.Request) error { +func (s *spaceSubscriptions) debugPerObject(w io.Writer, req *http.Request) error { return s.subDebugger.printPerObject(w, req) } -func (s *service) debugPerSubscription(w io.Writer, req *http.Request) error { +func (s *spaceSubscriptions) debugPerSubscription(w io.Writer, req *http.Request) error { return s.subDebugger.printPerSubscription(w, req) } diff --git a/core/subscription/dep.go b/core/subscription/dep.go index 651a7e2f36..2bd4000fef 100644 --- a/core/subscription/dep.go +++ b/core/subscription/dep.go @@ -9,7 +9,7 @@ import ( "github.com/anyproto/anytype-heart/util/slice" ) -func newDependencyService(s *service) *dependencyService { +func newDependencyService(s *spaceSubscriptions) *dependencyService { return &dependencyService{ s: s, isRelationObjMap: map[string]bool{}, @@ -17,23 +17,23 @@ func newDependencyService(s *service) *dependencyService { } type dependencyService struct { - s *service + s *spaceSubscriptions isRelationObjMap map[string]bool } -func (ds *dependencyService) makeSubscriptionByEntries(subId string, allEntries, activeEntries []*entry, keys, depKeys, filterDepIds []string) *simpleSub { - depSub := ds.s.newSimpleSub(subId, keys, true) +func (ds *dependencyService) makeSubscriptionByEntries(subId string, spaceId string, allEntries, activeEntries []*entry, keys, depKeys, filterDepIds []string) *simpleSub { + depSub := ds.s.newSimpleSub(subId, spaceId, keys, true) depSub.forceIds = filterDepIds - depEntries := ds.depEntriesByEntries(&opCtx{entries: allEntries}, ds.depIdsByEntries(activeEntries, depKeys, depSub.forceIds)) + depEntries := ds.depEntriesByEntries(&opCtx{entries: allEntries}, spaceId, ds.depIdsByEntries(activeEntries, depKeys, depSub.forceIds)) depSub.init(depEntries) return depSub } -func (ds *dependencyService) refillSubscription(ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []string) { +func (ds *dependencyService) refillSubscription(spaceId string, ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []string) { depIds := ds.depIdsByEntries(entries, depKeys, sub.forceIds) if !sub.isEqualIds(depIds) { - depEntries := ds.depEntriesByEntries(ctx, depIds) + depEntries := ds.depEntriesByEntries(ctx, spaceId, depIds) sub.refill(ctx, depEntries) } return @@ -53,7 +53,7 @@ func (ds *dependencyService) depIdsByEntries(entries []*entry, depKeys, forceIds return } -func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, depIds []string) (depEntries []*entry) { +func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, spaceId string, depIds []string) (depEntries []*entry) { if len(depIds) == 0 { return } @@ -89,7 +89,7 @@ func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, depIds []string) (d } } if len(missIds) > 0 { - records, err := ds.s.objectStore.QueryByID(missIds) + records, err := ds.s.objectStore.QueryByIds(missIds) if err != nil { log.Errorf("can't query by id: %v", err) } @@ -111,7 +111,7 @@ var ignoredKeys = map[string]struct{}{ bundle.RelationKeyFeaturedRelations.String(): {}, // relation format for featuredRelations has mistakenly set to Object instead of shorttext } -func (ds *dependencyService) isRelationObject(key string) bool { +func (ds *dependencyService) isRelationObject(spaceId string, key string) bool { if _, ok := ignoredKeys[key]; ok { return false } @@ -132,9 +132,9 @@ func (ds *dependencyService) isRelationObject(key string) bool { return isObj } -func (ds *dependencyService) depKeys(keys []string) (depKeys []string) { +func (ds *dependencyService) depKeys(spaceId string, keys []string) (depKeys []string) { for _, key := range keys { - if ds.isRelationObject(key) { + if ds.isRelationObject(spaceId, key) { depKeys = append(depKeys, key) } } diff --git a/core/subscription/fixture_test.go b/core/subscription/fixture_test.go index 21c42808a5..16948a2766 100644 --- a/core/subscription/fixture_test.go +++ b/core/subscription/fixture_test.go @@ -16,29 +16,32 @@ import ( "github.com/anyproto/anytype-heart/core/event" "github.com/anyproto/anytype-heart/core/event/mock_event" "github.com/anyproto/anytype-heart/core/kanban" + "github.com/anyproto/anytype-heart/core/kanban/mock_kanban" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/space/spacecore/typeprovider/mock_typeprovider" - "github.com/anyproto/anytype-heart/util/testMock" - "github.com/anyproto/anytype-heart/util/testMock/mockKanban" + "github.com/anyproto/anytype-heart/tests/testutil" ) type fixture struct { - Service + *service a *app.App ctrl *gomock.Controller - store *testMock.MockObjectStore + store *objectstore.StoreFixture sender *mock_event.MockSender events []*pb.Event collectionService *collectionServiceMock - kanban *mockKanban.MockService + kanban *mock_kanban.MockService } func newFixture(t *testing.T) *fixture { + ctx := context.Background() + ctrl := gomock.NewController(t) a := new(app.App) - testMock.RegisterMockObjectStore(ctrl, a) - kanban := testMock.RegisterMockKanban(ctrl, a) + store := objectstore.NewStoreFixture(t) + a.Register(store) + kanbanService := mock_kanban.NewMockService(t) sbtProvider := mock_typeprovider.NewMockSmartBlockTypeProvider(t) sbtProvider.EXPECT().Name().Return("smartBlockTypeProvider") sbtProvider.EXPECT().Init(mock.Anything).Return(nil) @@ -46,14 +49,15 @@ func newFixture(t *testing.T) *fixture { collectionService := &collectionServiceMock{MockCollectionService: NewMockCollectionService(t)} a.Register(collectionService) + a.Register(testutil.PrepareMock(ctx, a, kanbanService)) fx := &fixture{ - Service: New(), + service: New().(*service), a: a, ctrl: ctrl, - store: a.MustComponent(objectstore.CName).(*testMock.MockObjectStore), + store: store, collectionService: collectionService, - kanban: kanban, + kanban: kanbanService, } sender := mock_event.NewMockSender(t) sender.EXPECT().Init(mock.Anything).Return(nil) @@ -62,11 +66,10 @@ func newFixture(t *testing.T) *fixture { fx.events = append(fx.events, e) }).Maybe() fx.sender = sender - a.Register(fx.Service) + a.Register(fx.service) a.Register(fx.sender) - fx.store.EXPECT().SubscribeForAll(gomock.Any()) - require.NoError(t, a.Start(context.Background())) + require.NoError(t, a.Start(ctx)) return fx } diff --git a/core/subscription/group.go b/core/subscription/group.go index 4aa3a8c9e4..af74d7acad 100644 --- a/core/subscription/group.go +++ b/core/subscription/group.go @@ -10,7 +10,7 @@ import ( "github.com/anyproto/anytype-heart/util/slice" ) -func (s *service) newGroupSub(id string, relKey string, f *database.Filters, groups []*model.BlockContentDataviewGroup) *groupSub { +func (s *spaceSubscriptions) newGroupSub(id string, relKey string, f *database.Filters, groups []*model.BlockContentDataviewGroup) *groupSub { sub := &groupSub{ id: id, relKey: relKey, diff --git a/core/subscription/group_test.go b/core/subscription/group_test.go index 4018ddfba7..c32a546c67 100644 --- a/core/subscription/group_test.go +++ b/core/subscription/group_test.go @@ -3,13 +3,15 @@ package subscription import ( "testing" + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/require" - "github.com/valyala/fastjson" + "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/core/kanban" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -62,7 +64,7 @@ func TestGroupTag(t *testing.T) { q := database.Query{} - f, err := database.NewFilters(q, database.NewMockObjectStore(t), &fastjson.Arena{}) + f, err := database.NewFilters(q, spaceindex.NewStoreFixture(t), &anyenc.Arena{}, &collate.Buffer{}) require.NoError(t, err) filterTag := database.FilterNot{Filter: database.FilterEmpty{Key: kanbanKey}} f.FilterObj = database.FiltersAnd{f.FilterObj, filterTag} diff --git a/core/subscription/internalsub_test.go b/core/subscription/internalsub_test.go index 51d86d36b0..37319d0ecc 100644 --- a/core/subscription/internalsub_test.go +++ b/core/subscription/internalsub_test.go @@ -28,7 +28,8 @@ func wrapToEventMessages(vals []pb.IsEventMessageValue) []*pb.EventMessage { func TestInternalSubscriptionSingle(t *testing.T) { fx := NewInternalTestService(t) resp, err := fx.Search(SubscribeRequest{ - SubId: "test", + SpaceId: testSpaceId, + SubId: "test", Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyPriority.String(), @@ -44,7 +45,7 @@ func TestInternalSubscriptionSingle(t *testing.T) { require.Empty(t, resp.Records) t.Run("amend details not related to filter", func(t *testing.T) { - fx.AddObjects(t, []objectstore.TestObject{ + fx.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyName: pbtypes.String("task1"), @@ -53,7 +54,7 @@ func TestInternalSubscriptionSingle(t *testing.T) { }, }) time.Sleep(batchTime) - fx.AddObjects(t, []objectstore.TestObject{ + fx.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyName: pbtypes.String("task1 renamed"), @@ -74,7 +75,7 @@ func TestInternalSubscriptionSingle(t *testing.T) { }) t.Run("amend details related to filter -- remove from subscription", func(t *testing.T) { - fx.AddObjects(t, []objectstore.TestObject{ + fx.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id2"), bundle.RelationKeyName: pbtypes.String("task2"), @@ -83,7 +84,7 @@ func TestInternalSubscriptionSingle(t *testing.T) { }) time.Sleep(batchTime) - fx.AddObjects(t, []objectstore.TestObject{ + fx.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id2"), bundle.RelationKeyName: pbtypes.String("task2"), @@ -102,7 +103,7 @@ func TestInternalSubscriptionSingle(t *testing.T) { require.Equal(t, wrapToEventMessages(want), msgs) }) - t.Run("close", func(t *testing.T) { + t.Run("unsubscribe", func(t *testing.T) { err = fx.Unsubscribe("test") require.NoError(t, err) @@ -112,7 +113,7 @@ func TestInternalSubscriptionSingle(t *testing.T) { t.Run("try to add after close", func(t *testing.T) { time.Sleep(batchTime) - fx.AddObjects(t, []objectstore.TestObject{ + fx.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id3"), bundle.RelationKeyName: pbtypes.String("task2"), @@ -125,7 +126,8 @@ func TestInternalSubscriptionSingle(t *testing.T) { func TestInternalSubscriptionMultiple(t *testing.T) { fx := newFixtureWithRealObjectStore(t) resp1, err := fx.Search(SubscribeRequest{ - SubId: "internal1", + SpaceId: testSpaceId, + SubId: "internal1", Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyPriority.String(), @@ -137,7 +139,8 @@ func TestInternalSubscriptionMultiple(t *testing.T) { Internal: true, }) _, err = fx.Search(SubscribeRequest{ - SubId: "client1", + SpaceId: testSpaceId, + SubId: "client1", Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyPriority.String(), @@ -148,7 +151,8 @@ func TestInternalSubscriptionMultiple(t *testing.T) { Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyPriority.String()}, }) _, err = fx.Search(SubscribeRequest{ - SubId: "client2", + SpaceId: testSpaceId, + SubId: "client2", Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyPriority.String(), @@ -159,7 +163,8 @@ func TestInternalSubscriptionMultiple(t *testing.T) { Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyPriority.String()}, }) resp4, err := fx.Search(SubscribeRequest{ - SubId: "internal2", + SpaceId: testSpaceId, + SubId: "internal2", Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyName.String(), @@ -175,7 +180,7 @@ func TestInternalSubscriptionMultiple(t *testing.T) { require.Empty(t, resp1.Records) t.Run("amend details not related to filter", func(t *testing.T) { - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyName: pbtypes.String("task1"), @@ -184,7 +189,7 @@ func TestInternalSubscriptionMultiple(t *testing.T) { }, }) time.Sleep(batchTime) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeyName: pbtypes.String("task1 renamed"), @@ -208,7 +213,7 @@ func TestInternalSubscriptionMultiple(t *testing.T) { }) t.Run("amend details related to filter -- remove from subscription", func(t *testing.T) { - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id2"), bundle.RelationKeyName: pbtypes.String("task2"), @@ -217,7 +222,7 @@ func TestInternalSubscriptionMultiple(t *testing.T) { }) time.Sleep(batchTime) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id2"), bundle.RelationKeyName: pbtypes.String("task2"), @@ -240,7 +245,7 @@ func TestInternalSubscriptionMultiple(t *testing.T) { }) t.Run("add item satisfying filters from all subscription", func(t *testing.T) { - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id3"), bundle.RelationKeyName: pbtypes.String("Jane Doe"), @@ -267,6 +272,125 @@ func TestInternalSubscriptionMultiple(t *testing.T) { }) } +func TestInternalSubCustomQueue(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + subId := "test" + fx := newFixtureWithRealObjectStore(t) + + queue := mb2.New[*pb.EventMessage](0) + + resp, err := fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, + SubId: subId, + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyPriority.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(10), + }, + }, + Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyPriority.String()}, + Internal: true, + InternalQueue: queue, + }) + require.NoError(t, err) + require.Same(t, resp.Output, queue) + + obj := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("id1"), + bundle.RelationKeyName: pbtypes.String("Jane Doe"), + bundle.RelationKeyPriority: pbtypes.Int64(10), + } + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{obj}) + + want := []pb.IsEventMessageValue{ + &pb.EventMessageValueOfObjectDetailsSet{ + ObjectDetailsSet: &pb.EventObjectDetailsSet{ + Id: "id1", + SubIds: []string{subId}, + Details: obj.Details(), + }, + }, + &pb.EventMessageValueOfSubscriptionAdd{ + SubscriptionAdd: &pb.EventObjectSubscriptionAdd{ + SubId: subId, + Id: "id1", + }, + }, + &pb.EventMessageValueOfSubscriptionCounters{ + SubscriptionCounters: &pb.EventObjectSubscriptionCounters{ + SubId: subId, + Total: 1, + }, + }, + } + + msgs, err := queue.NewCond().WithMin(len(want)).Wait(ctx) + require.NoError(t, err) + require.Equal(t, wrapToEventMessages(want), msgs) +} + +func TestInternalSubAsyncInit(t *testing.T) { + ctx := context.Background() + subId := "test" + fx := newFixtureWithRealObjectStore(t) + obj := objectstore.TestObject{ + bundle.RelationKeyId: pbtypes.String("id1"), + bundle.RelationKeyName: pbtypes.String("Jane Doe"), + bundle.RelationKeyPriority: pbtypes.Int64(10), + } + + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ + obj, + }) + + resp, err := fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, + SubId: subId, + Filters: []*model.BlockContentDataviewFilter{ + { + RelationKey: bundle.RelationKeyPriority.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Int64(10), + }, + }, + Keys: []string{bundle.RelationKeyId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyPriority.String()}, + Internal: true, + AsyncInit: true, + }) + + require.NoError(t, err) + require.Empty(t, resp.Records) + + want := []pb.IsEventMessageValue{ + &pb.EventMessageValueOfObjectDetailsSet{ + ObjectDetailsSet: &pb.EventObjectDetailsSet{ + Id: "id1", + SubIds: []string{subId}, + Details: obj.Details(), + }, + }, + &pb.EventMessageValueOfSubscriptionAdd{ + SubscriptionAdd: &pb.EventObjectSubscriptionAdd{ + SubId: subId, + Id: "id1", + }, + }, + &pb.EventMessageValueOfSubscriptionCounters{ + SubscriptionCounters: &pb.EventObjectSubscriptionCounters{ + SubId: subId, + Total: 1, + }, + }, + } + + msgs, err := resp.Output.NewCond().WithMin(len(want)).Wait(ctx) + require.NoError(t, err) + require.Equal(t, wrapToEventMessages(want), msgs) +} + func givenMessagesForFirstObject(subIds ...string) []pb.IsEventMessageValue { var msgs []pb.IsEventMessageValue msgs = append(msgs, &pb.EventMessageValueOfObjectDetailsSet{ diff --git a/core/subscription/mock_subscription/mock_Service.go b/core/subscription/mock_subscription/mock_Service.go index 0ffbe80217..0a717feec8 100644 --- a/core/subscription/mock_subscription/mock_Service.go +++ b/core/subscription/mock_subscription/mock_Service.go @@ -11,8 +11,6 @@ import ( pb "github.com/anyproto/anytype-heart/pb" - session "github.com/anyproto/anytype-heart/core/session" - subscription "github.com/anyproto/anytype-heart/core/subscription" types "github.com/gogo/protobuf/types" @@ -272,9 +270,9 @@ func (_c *MockService_Search_Call) RunAndReturn(run func(subscription.SubscribeR return _c } -// SubscribeGroups provides a mock function with given fields: ctx, req -func (_m *MockService) SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) { - ret := _m.Called(ctx, req) +// SubscribeGroups provides a mock function with given fields: req +func (_m *MockService) SubscribeGroups(req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) { + ret := _m.Called(req) if len(ret) == 0 { panic("no return value specified for SubscribeGroups") @@ -282,19 +280,19 @@ func (_m *MockService) SubscribeGroups(ctx session.Context, req pb.RpcObjectGrou var r0 *pb.RpcObjectGroupsSubscribeResponse var r1 error - if rf, ok := ret.Get(0).(func(session.Context, pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error)); ok { - return rf(ctx, req) + if rf, ok := ret.Get(0).(func(pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error)); ok { + return rf(req) } - if rf, ok := ret.Get(0).(func(session.Context, pb.RpcObjectGroupsSubscribeRequest) *pb.RpcObjectGroupsSubscribeResponse); ok { - r0 = rf(ctx, req) + if rf, ok := ret.Get(0).(func(pb.RpcObjectGroupsSubscribeRequest) *pb.RpcObjectGroupsSubscribeResponse); ok { + r0 = rf(req) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*pb.RpcObjectGroupsSubscribeResponse) } } - if rf, ok := ret.Get(1).(func(session.Context, pb.RpcObjectGroupsSubscribeRequest) error); ok { - r1 = rf(ctx, req) + if rf, ok := ret.Get(1).(func(pb.RpcObjectGroupsSubscribeRequest) error); ok { + r1 = rf(req) } else { r1 = ret.Error(1) } @@ -308,15 +306,14 @@ type MockService_SubscribeGroups_Call struct { } // SubscribeGroups is a helper method to define mock.On call -// - ctx session.Context // - req pb.RpcObjectGroupsSubscribeRequest -func (_e *MockService_Expecter) SubscribeGroups(ctx interface{}, req interface{}) *MockService_SubscribeGroups_Call { - return &MockService_SubscribeGroups_Call{Call: _e.mock.On("SubscribeGroups", ctx, req)} +func (_e *MockService_Expecter) SubscribeGroups(req interface{}) *MockService_SubscribeGroups_Call { + return &MockService_SubscribeGroups_Call{Call: _e.mock.On("SubscribeGroups", req)} } -func (_c *MockService_SubscribeGroups_Call) Run(run func(ctx session.Context, req pb.RpcObjectGroupsSubscribeRequest)) *MockService_SubscribeGroups_Call { +func (_c *MockService_SubscribeGroups_Call) Run(run func(req pb.RpcObjectGroupsSubscribeRequest)) *MockService_SubscribeGroups_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(session.Context), args[1].(pb.RpcObjectGroupsSubscribeRequest)) + run(args[0].(pb.RpcObjectGroupsSubscribeRequest)) }) return _c } @@ -326,7 +323,7 @@ func (_c *MockService_SubscribeGroups_Call) Return(_a0 *pb.RpcObjectGroupsSubscr return _c } -func (_c *MockService_SubscribeGroups_Call) RunAndReturn(run func(session.Context, pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error)) *MockService_SubscribeGroups_Call { +func (_c *MockService_SubscribeGroups_Call) RunAndReturn(run func(pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error)) *MockService_SubscribeGroups_Call { _c.Call.Return(run) return _c } @@ -599,6 +596,65 @@ func (_c *MockService_UnsubscribeAll_Call) RunAndReturn(run func() error) *MockS return _c } +// UnsubscribeAndReturnIds provides a mock function with given fields: spaceId, subId +func (_m *MockService) UnsubscribeAndReturnIds(spaceId string, subId string) ([]string, error) { + ret := _m.Called(spaceId, subId) + + if len(ret) == 0 { + panic("no return value specified for UnsubscribeAndReturnIds") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) ([]string, error)); ok { + return rf(spaceId, subId) + } + if rf, ok := ret.Get(0).(func(string, string) []string); ok { + r0 = rf(spaceId, subId) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(spaceId, subId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockService_UnsubscribeAndReturnIds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnsubscribeAndReturnIds' +type MockService_UnsubscribeAndReturnIds_Call struct { + *mock.Call +} + +// UnsubscribeAndReturnIds is a helper method to define mock.On call +// - spaceId string +// - subId string +func (_e *MockService_Expecter) UnsubscribeAndReturnIds(spaceId interface{}, subId interface{}) *MockService_UnsubscribeAndReturnIds_Call { + return &MockService_UnsubscribeAndReturnIds_Call{Call: _e.mock.On("UnsubscribeAndReturnIds", spaceId, subId)} +} + +func (_c *MockService_UnsubscribeAndReturnIds_Call) Run(run func(spaceId string, subId string)) *MockService_UnsubscribeAndReturnIds_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string)) + }) + return _c +} + +func (_c *MockService_UnsubscribeAndReturnIds_Call) Return(_a0 []string, _a1 error) *MockService_UnsubscribeAndReturnIds_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockService_UnsubscribeAndReturnIds_Call) RunAndReturn(run func(string, string) ([]string, error)) *MockService_UnsubscribeAndReturnIds_Call { + _c.Call.Return(run) + return _c +} + // NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewMockService(t interface { diff --git a/core/subscription/nodebug.go b/core/subscription/nodebug.go index cf7fb98ec9..5d7afff18e 100644 --- a/core/subscription/nodebug.go +++ b/core/subscription/nodebug.go @@ -7,8 +7,8 @@ import "github.com/anyproto/anytype-heart/pb" type subDebugger struct { } -func (s *service) initDebugger() { +func (s *spaceSubscriptions) initDebugger() { } -func (s *service) debugEvents(ev *pb.Event) { +func (s *spaceSubscriptions) debugEvents(ev *pb.Event) { } diff --git a/core/syncstatus/syncsubscriptions/objectsubscription.go b/core/subscription/objectsubscription/objsubscription.go similarity index 85% rename from core/syncstatus/syncsubscriptions/objectsubscription.go rename to core/subscription/objectsubscription/objsubscription.go index 90545517d4..9117a500ff 100644 --- a/core/syncstatus/syncsubscriptions/objectsubscription.go +++ b/core/subscription/objectsubscription/objsubscription.go @@ -1,4 +1,4 @@ -package syncsubscriptions +package objectsubscription import ( "context" @@ -13,6 +13,12 @@ import ( "github.com/anyproto/anytype-heart/util/pbtypes" ) +type ( + extract[T any] func(*types.Struct) (string, T) + update[T any] func(string, *types.Value, T) T + unset[T any] func([]string, T) T +) + type entry[T any] struct { data T } @@ -25,12 +31,6 @@ func newEntry[T any](data T) *entry[T] { return &entry[T]{data: data} } -type ( - extract[T any] func(*types.Struct) (string, T) - update[T any] func(string, *types.Value, T) T - unset[T any] func([]string, T) T -) - type SubscriptionParams[T any] struct { Request subscription.SubscribeRequest Extract extract[T] @@ -38,23 +38,6 @@ type SubscriptionParams[T any] struct { Unset unset[T] } -func NewIdSubscription(service subscription.Service, request subscription.SubscribeRequest) *ObjectSubscription[struct{}] { - return &ObjectSubscription[struct{}]{ - request: request, - service: service, - ch: make(chan struct{}), - extract: func(t *types.Struct) (string, struct{}) { - return pbtypes.GetString(t, bundle.RelationKeyId.String()), struct{}{} - }, - update: func(s string, value *types.Value, s2 struct{}) struct{} { - return struct{}{} - }, - unset: func(strings []string, s struct{}) struct{} { - return struct{}{} - }, - } -} - type ObjectSubscription[T any] struct { request subscription.SubscribeRequest service subscription.Service @@ -69,7 +52,34 @@ type ObjectSubscription[T any] struct { mx sync.Mutex } +func NewIdSubscription(service subscription.Service, request subscription.SubscribeRequest) *ObjectSubscription[struct{}] { + return New(service, SubscriptionParams[struct{}]{ + Request: request, + Extract: func(t *types.Struct) (string, struct{}) { + return pbtypes.GetString(t, bundle.RelationKeyId.String()), struct{}{} + }, + Update: func(s string, value *types.Value, s2 struct{}) struct{} { + return struct{}{} + }, + Unset: func(strings []string, s struct{}) struct{} { + return struct{}{} + }, + }) +} + +func New[T any](service subscription.Service, params SubscriptionParams[T]) *ObjectSubscription[T] { + return &ObjectSubscription[T]{ + request: params.Request, + service: service, + ch: make(chan struct{}), + extract: params.Extract, + update: params.Update, + unset: params.Unset, + } +} + func (o *ObjectSubscription[T]) Run() error { + o.request.Internal = true resp, err := o.service.Search(o.request) if err != nil { return err diff --git a/core/syncstatus/syncsubscriptions/objectsubscription_test.go b/core/subscription/objectsubscription/objsubscription_test.go similarity index 99% rename from core/syncstatus/syncsubscriptions/objectsubscription_test.go rename to core/subscription/objectsubscription/objsubscription_test.go index 8dabe872be..0f7891e404 100644 --- a/core/syncstatus/syncsubscriptions/objectsubscription_test.go +++ b/core/subscription/objectsubscription/objsubscription_test.go @@ -1,4 +1,4 @@ -package syncsubscriptions +package objectsubscription import ( "context" diff --git a/core/subscription/service.go b/core/subscription/service.go index 6276e32705..fd2e5b79e6 100644 --- a/core/subscription/service.go +++ b/core/subscription/service.go @@ -7,19 +7,20 @@ import ( "sync" "time" + "github.com/anyproto/any-store/anyenc" "github.com/anyproto/any-sync/app" "github.com/cheggaaa/mb" mb2 "github.com/cheggaaa/mb/v3" "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" "golang.org/x/exp/slices" + "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/core/event" "github.com/anyproto/anytype-heart/core/kanban" - "github.com/anyproto/anytype-heart/core/session" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" @@ -42,6 +43,7 @@ func New() Service { } type SubscribeRequest struct { + SpaceId string SubId string Filters []*model.BlockContentDataviewFilter Sorts []*model.BlockContentDataviewSort @@ -52,15 +54,17 @@ type SubscribeRequest struct { // (optional) pagination: middleware will return results after given id AfterId string // (optional) pagination: middleware will return results before given id - BeforeId string - Source []string - IgnoreWorkspace string + BeforeId string + Source []string // disable dependent subscription NoDepSubscription bool CollectionId string // Internal indicates that subscription will send events into message queue instead of global client's event system Internal bool + // InternalQueue is used when Internal flag is set to true. If it's nil, new queue will be created + InternalQueue *mb2.MB[*pb.EventMessage] + AsyncInit bool } type SubscribeResponse struct { @@ -77,8 +81,9 @@ type Service interface { Search(req SubscribeRequest) (resp *SubscribeResponse, err error) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb.RpcObjectSubscribeIdsResponse, err error) SubscribeIds(subId string, ids []string) (records []*types.Struct, err error) - SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) + SubscribeGroups(req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) Unsubscribe(subIds ...string) (err error) + UnsubscribeAndReturnIds(spaceId string, subId string) ([]string, error) UnsubscribeAll() (err error) SubscriptionIDs() []string @@ -101,48 +106,196 @@ type CollectionService interface { } type service struct { - cache *cache - ds *dependencyService - - subscriptionKeys []string - subscriptions map[string]subscription - - customOutput map[string]*mb2.MB[*pb.EventMessage] - recBatch *mb.MB + lock sync.Mutex + spaceSubs map[string]*spaceSubscriptions + // Deps objectStore objectstore.ObjectStore kanban kanban.Service collectionService CollectionService eventSender event.Sender + arenaPool *anyenc.ArenaPool +} - m sync.Mutex - ctxBuf *opCtx +type internalSubOutput struct { + externallyManaged bool + queue *mb2.MB[*pb.EventMessage] +} - subDebugger *subDebugger - arenaPool *fastjson.ArenaPool +func newInternalSubOutput(queue *mb2.MB[*pb.EventMessage]) *internalSubOutput { + if queue == nil { + return &internalSubOutput{ + queue: mb2.New[*pb.EventMessage](0), + } + } + return &internalSubOutput{ + externallyManaged: true, + queue: queue, + } +} + +func (o *internalSubOutput) add(msgs ...*pb.EventMessage) error { + return o.queue.Add(context.TODO(), msgs...) +} + +func (o *internalSubOutput) close() error { + if !o.externallyManaged { + return o.queue.Close() + } + return nil +} + +func (s *service) Name() string { + return CName } func (s *service) Init(a *app.App) (err error) { - s.cache = newCache() - s.ds = newDependencyService(s) - s.subscriptions = make(map[string]subscription) - s.customOutput = map[string]*mb2.MB[*pb.EventMessage]{} s.objectStore = app.MustComponent[objectstore.ObjectStore](a) s.kanban = app.MustComponent[kanban.Service](a) - s.recBatch = mb.New(0) s.collectionService = app.MustComponent[CollectionService](a) s.eventSender = app.MustComponent[event.Sender](a) - s.ctxBuf = &opCtx{c: s.cache} - s.initDebugger() - s.arenaPool = &fastjson.ArenaPool{} + + s.spaceSubs = map[string]*spaceSubscriptions{} + s.arenaPool = &anyenc.ArenaPool{} return } -func (s *service) Name() (name string) { - return CName +func (s *service) Run(ctx context.Context) (err error) { + return +} + +func (s *service) Close(ctx context.Context) error { + s.lock.Lock() + defer s.lock.Unlock() + var err error + for _, spaceSub := range s.spaceSubs { + err = errors.Join(err, spaceSub.Close(ctx)) + } + return err +} + +func (s *service) Search(req SubscribeRequest) (resp *SubscribeResponse, err error) { + spaceSubs, err := s.getSpaceSubscriptions(req.SpaceId) + if err != nil { + return nil, err + } + return spaceSubs.Search(req) +} + +func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb.RpcObjectSubscribeIdsResponse, err error) { + spaceSubs, err := s.getSpaceSubscriptions(req.SpaceId) + if err != nil { + return nil, err + } + return spaceSubs.SubscribeIdsReq(req) +} + +func (s *service) SubscribeIds(subId string, ids []string) (records []*types.Struct, err error) { + return } -func (s *service) Run(context.Context) (err error) { +func (s *service) SubscribeGroups(req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) { + spaceSubs, err := s.getSpaceSubscriptions(req.SpaceId) + if err != nil { + return nil, err + } + return spaceSubs.SubscribeGroups(req) +} + +func (s *service) Unsubscribe(subIds ...string) (err error) { + s.lock.Lock() + for _, spaceSub := range s.spaceSubs { + err = errors.Join(spaceSub.Unsubscribe(subIds...)) + } + s.lock.Unlock() + return err +} + +func (s *service) UnsubscribeAndReturnIds(spaceId string, subId string) ([]string, error) { + spaceSub, err := s.getSpaceSubscriptions(spaceId) + if err != nil { + return nil, fmt.Errorf("get space subs: %w", err) + } + + return spaceSub.UnsubscribeAndReturnIds(subId) +} + +func (s *service) UnsubscribeAll() (err error) { + s.lock.Lock() + for _, spaceSub := range s.spaceSubs { + err = errors.Join(spaceSub.UnsubscribeAll()) + } + s.lock.Unlock() + return err +} + +func (s *service) SubscriptionIDs() []string { + var ids []string + s.lock.Lock() + for _, spaceSub := range s.spaceSubs { + ids = append(ids, spaceSub.SubscriptionIDs()...) + } + s.lock.Unlock() + return ids +} + +func (s *service) getSpaceSubscriptions(spaceId string) (*spaceSubscriptions, error) { + if spaceId == "" { + return nil, fmt.Errorf("spaceId is empty") + } + s.lock.Lock() + defer s.lock.Unlock() + + spaceSubs, ok := s.spaceSubs[spaceId] + if !ok { + cache := newCache() + spaceSubs = &spaceSubscriptions{ + cache: cache, + subscriptionKeys: make([]string, 0, 20), + subscriptions: make(map[string]subscription, 20), + customOutput: map[string]*internalSubOutput{}, + recBatch: mb.New(0), + objectStore: s.objectStore.SpaceIndex(spaceId), + kanban: s.kanban, + collectionService: s.collectionService, + eventSender: s.eventSender, + ctxBuf: &opCtx{c: cache}, + arenaPool: s.arenaPool, + } + spaceSubs.ds = newDependencyService(spaceSubs) + spaceSubs.initDebugger() + err := spaceSubs.Run(context.Background()) + if err != nil { + return nil, fmt.Errorf("run space subscriptions: %w", err) + } + s.spaceSubs[spaceId] = spaceSubs + } + return spaceSubs, nil +} + +type spaceSubscriptions struct { + subscriptionKeys []string + subscriptions map[string]subscription + + customOutput map[string]*internalSubOutput + recBatch *mb.MB + + // Deps + objectStore spaceindex.Store + kanban kanban.Service + collectionService CollectionService + eventSender event.Sender + + m sync.Mutex + cache *cache + ds *dependencyService + ctxBuf *opCtx + + subDebugger *subDebugger + arenaPool *anyenc.ArenaPool +} + +func (s *spaceSubscriptions) Run(context.Context) (err error) { s.objectStore.SubscribeForAll(func(rec database.Record) { s.recBatch.Add(rec) }) @@ -150,24 +303,24 @@ func (s *service) Run(context.Context) (err error) { return } -func (s *service) getSubscription(id string) (subscription, bool) { +func (s *spaceSubscriptions) getSubscription(id string) (subscription, bool) { sub, ok := s.subscriptions[id] return sub, ok } -func (s *service) setSubscription(id string, sub subscription) { +func (s *spaceSubscriptions) setSubscription(id string, sub subscription) { s.subscriptions[id] = sub if !slices.Contains(s.subscriptionKeys, id) { s.subscriptionKeys = append(s.subscriptionKeys, id) } } -func (s *service) deleteSubscription(id string) { +func (s *spaceSubscriptions) deleteSubscription(id string) { delete(s.subscriptions, id) s.subscriptionKeys = slice.RemoveMut(s.subscriptionKeys, id) } -func (s *service) iterateSubscriptions(proc func(sub subscription)) { +func (s *spaceSubscriptions) iterateSubscriptions(proc func(sub subscription)) { for _, subId := range s.subscriptionKeys { sub, ok := s.getSubscription(subId) if ok && sub != nil { @@ -176,7 +329,10 @@ func (s *service) iterateSubscriptions(proc func(sub subscription)) { } } -func (s *service) Search(req SubscribeRequest) (*SubscribeResponse, error) { +func (s *spaceSubscriptions) Search(req SubscribeRequest) (*SubscribeResponse, error) { + if req.SpaceId == "" { + return nil, fmt.Errorf("spaceId is required") + } if req.SubId == "" { req.SubId = bson.NewObjectId().Hex() } @@ -190,23 +346,28 @@ func (s *service) Search(req SubscribeRequest) (*SubscribeResponse, error) { arena := s.arenaPool.Get() defer s.arenaPool.Put(arena) - f, err := database.NewFilters(q, s.objectStore, arena) + f, err := database.NewFilters(q, s.objectStore, arena, &collate.Buffer{}) if err != nil { return nil, fmt.Errorf("new database filters: %w", err) } if len(req.Source) > 0 { - sourceFilter, err := s.filtersFromSource(req.Source) + sourceFilter, err := s.filtersFromSource(req.SpaceId, req.Source) if err != nil { return nil, fmt.Errorf("can't make filter from source: %w", err) } f.FilterObj = database.FiltersAnd{f.FilterObj, sourceFilter} } + entries, err := queryEntries(s.objectStore, f) + if err != nil { + return nil, err + } + s.m.Lock() defer s.m.Unlock() - filterDepIds := s.depIdsFromFilter(req.Filters) + filterDepIds := s.depIdsFromFilter(req.SpaceId, req.Filters) if existing, ok := s.getSubscription(req.SubId); ok { s.deleteSubscription(req.SubId) existing.close() @@ -221,11 +382,11 @@ func (s *service) Search(req SubscribeRequest) (*SubscribeResponse, error) { if req.CollectionId != "" { return s.subscribeForCollection(req, f, filterDepIds) } - return s.subscribeForQuery(req, f, filterDepIds) + return s.subscribeForQuery(req, f, entries, filterDepIds) } -func (s *service) subscribeForQuery(req SubscribeRequest, f *database.Filters, filterDepIds []string) (*SubscribeResponse, error) { - sub := s.newSortedSub(req.SubId, req.Keys, f.FilterObj, f.Order, int(req.Limit), int(req.Offset)) +func (s *spaceSubscriptions) subscribeForQuery(req SubscribeRequest, f *database.Filters, entries []*entry, filterDepIds []string) (*SubscribeResponse, error) { + sub := s.newSortedSub(req.SubId, req.SpaceId, req.Keys, f.FilterObj, f.Order, int(req.Limit), int(req.Offset)) if req.NoDepSubscription { sub.disableDep = true } else { @@ -240,7 +401,7 @@ func (s *service) subscribeForQuery(req SubscribeRequest, f *database.Filters, f nestedCount++ f, ok := nestedFilter.(*database.FilterNestedIn) if ok { - childSub := s.newSortedSub(req.SubId+fmt.Sprintf("-nested-%d", nestedCount), []string{"id"}, f.FilterForNestedObjects, nil, 0, 0) + childSub := s.newSortedSub(req.SubId+fmt.Sprintf("-nested-%d", nestedCount), req.SpaceId, []string{"id"}, f.FilterForNestedObjects, nil, 0, 0) err := initSubEntries(s.objectStore, &database.Filters{FilterObj: f.FilterForNestedObjects}, childSub) if err != nil { return fmt.Errorf("init nested sub %s entries: %w", childSub.id, err) @@ -257,22 +418,42 @@ func (s *service) subscribeForQuery(req SubscribeRequest, f *database.Filters, f } } - err := initSubEntries(s.objectStore, f, sub) - if err != nil { - return nil, fmt.Errorf("init sub entries: %w", err) + var outputQueue *mb2.MB[*pb.EventMessage] + if req.Internal { + output := newInternalSubOutput(req.InternalQueue) + outputQueue = output.queue + s.customOutput[req.SubId] = output + } + + if req.AsyncInit { + err := sub.init(nil) + if err != nil { + return nil, fmt.Errorf("async: init sub entries: %w", err) + } + s.onChangeWithinContext(entries, func(ctxBuf *opCtx) { + sub.onChange(ctxBuf) + }) + + } else { + err := sub.init(entries) + if err != nil { + return nil, fmt.Errorf("init sub entries: %w", err) + } } + s.setSubscription(sub.id, sub) prev, next := sub.counters() var depRecords, subRecords []*types.Struct - subRecords = sub.getActiveRecords() - if sub.depSub != nil { - depRecords = sub.depSub.getActiveRecords() - } - if req.Internal { - s.customOutput[req.SubId] = mb2.New[*pb.EventMessage](0) + if !req.AsyncInit { + subRecords = sub.getActiveRecords() + + if sub.depSub != nil { + depRecords = sub.depSub.getActiveRecords() + } } + return &SubscribeResponse{ Records: subRecords, Dependencies: depRecords, @@ -282,11 +463,11 @@ func (s *service) subscribeForQuery(req SubscribeRequest, f *database.Filters, f NextCount: int64(prev), PrevCount: int64(next), }, - Output: s.customOutput[req.SubId], + Output: outputQueue, }, nil } -func initSubEntries(objectStore objectstore.ObjectStore, f *database.Filters, sub *sortedSub) error { +func initSubEntries(objectStore spaceindex.Store, f *database.Filters, sub *sortedSub) error { entries, err := queryEntries(objectStore, f) if err != nil { return err @@ -297,7 +478,7 @@ func initSubEntries(objectStore objectstore.ObjectStore, f *database.Filters, su return nil } -func queryEntries(objectStore objectstore.ObjectStore, f *database.Filters) ([]*entry, error) { +func queryEntries(objectStore spaceindex.Store, f *database.Filters) ([]*entry, error) { records, err := objectStore.QueryRaw(f, 0, 0) if err != nil { return nil, fmt.Errorf("objectStore query error: %w", err) @@ -312,8 +493,8 @@ func queryEntries(objectStore objectstore.ObjectStore, f *database.Filters) ([]* return entries, nil } -func (s *service) subscribeForCollection(req SubscribeRequest, f *database.Filters, filterDepIds []string) (*SubscribeResponse, error) { - sub, err := s.newCollectionSub(req.SubId, req.CollectionId, req.Keys, filterDepIds, f.FilterObj, f.Order, int(req.Limit), int(req.Offset), req.NoDepSubscription) +func (s *spaceSubscriptions) subscribeForCollection(req SubscribeRequest, f *database.Filters, filterDepIds []string) (*SubscribeResponse, error) { + sub, err := s.newCollectionSub(req.SubId, req.SpaceId, req.CollectionId, req.Keys, filterDepIds, f.FilterObj, f.Order, int(req.Limit), int(req.Offset), req.NoDepSubscription) if err != nil { return nil, err } @@ -330,8 +511,11 @@ func (s *service) subscribeForCollection(req SubscribeRequest, f *database.Filte depRecords = sub.sortedSub.depSub.getActiveRecords() } + var outputQueue *mb2.MB[*pb.EventMessage] if req.Internal { - s.customOutput[req.SubId] = mb2.New[*pb.EventMessage](0) + output := newInternalSubOutput(req.InternalQueue) + outputQueue = output.queue + s.customOutput[req.SubId] = output } return &SubscribeResponse{ @@ -343,12 +527,15 @@ func (s *service) subscribeForCollection(req SubscribeRequest, f *database.Filte NextCount: int64(prev), PrevCount: int64(next), }, - Output: s.customOutput[req.SubId], + Output: outputQueue, }, nil } -func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb.RpcObjectSubscribeIdsResponse, err error) { - records, err := s.objectStore.QueryByID(req.Ids) +func (s *spaceSubscriptions) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb.RpcObjectSubscribeIdsResponse, err error) { + if req.SpaceId == "" { + return nil, fmt.Errorf("spaceId is required") + } + records, err := s.objectStore.QueryByIds(req.Ids) if err != nil { return } @@ -360,7 +547,7 @@ func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb s.m.Lock() defer s.m.Unlock() - sub := s.newSimpleSub(req.SubId, req.Keys, !req.NoDepSubscription) + sub := s.newSimpleSub(req.SubId, req.SpaceId, req.Keys, !req.NoDepSubscription) entries := make([]*entry, 0, len(records)) for _, r := range records { entries = append(entries, &entry{ @@ -388,7 +575,7 @@ func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb }, nil } -func (s *service) SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) { +func (s *spaceSubscriptions) SubscribeGroups(req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) { subId := "" s.m.Lock() @@ -401,13 +588,13 @@ func (s *service) SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSub arena := s.arenaPool.Get() defer s.arenaPool.Put(arena) - flt, err := database.NewFilters(q, s.objectStore, arena) + flt, err := database.NewFilters(q, s.objectStore, arena, &collate.Buffer{}) if err != nil { return nil, err } if len(req.Source) > 0 { - sourceFilter, err := s.filtersFromSource(req.Source) + sourceFilter, err := s.filtersFromSource(req.SpaceId, req.Source) if err != nil { return nil, fmt.Errorf("can't make filter from source: %w", err) } @@ -416,7 +603,7 @@ func (s *service) SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSub var colObserver *collectionObserver if req.CollectionId != "" { - colObserver, err = s.newCollectionObserver(req.CollectionId, req.SubId) + colObserver, err = s.newCollectionObserver(req.SpaceId, req.CollectionId, req.SubId) if err != nil { return nil, err } @@ -485,31 +672,58 @@ func (s *service) SubscribeGroups(ctx session.Context, req pb.RpcObjectGroupsSub }, nil } -func (s *service) SubscribeIds(subId string, ids []string) (records []*types.Struct, err error) { +func (s *spaceSubscriptions) SubscribeIds(subId string, ids []string) (records []*types.Struct, err error) { return } -func (s *service) Unsubscribe(subIds ...string) error { +func (s *spaceSubscriptions) Unsubscribe(subIds ...string) error { s.m.Lock() defer s.m.Unlock() for _, subId := range subIds { if sub, ok := s.getSubscription(subId); ok { - out := s.customOutput[subId] - if out != nil { - err := out.Close() - if err != nil { - return fmt.Errorf("close subscription %s: %w", subId, err) - } - s.customOutput[subId] = nil + err := s.unsubscribe(subId, sub) + if err != nil { + return err } - sub.close() - s.deleteSubscription(subId) } } return nil } -func (s *service) UnsubscribeAll() (err error) { +func (s *spaceSubscriptions) unsubscribe(subId string, sub subscription) error { + out := s.customOutput[subId] + if out != nil { + err := out.close() + if err != nil { + return fmt.Errorf("close subscription %s: %w", subId, err) + } + s.customOutput[subId] = nil + } + sub.close() + s.deleteSubscription(subId) + return nil +} + +func (s *spaceSubscriptions) UnsubscribeAndReturnIds(subId string) ([]string, error) { + s.m.Lock() + defer s.m.Unlock() + + if sub, ok := s.getSubscription(subId); ok { + recs := sub.getActiveRecords() + ids := make([]string, 0, len(recs)) + for _, rec := range recs { + ids = append(ids, pbtypes.GetString(rec, bundle.RelationKeyId.String())) + } + err := s.unsubscribe(subId, sub) + if err != nil { + return nil, err + } + return ids, nil + } + return nil, fmt.Errorf("subscription not found") +} + +func (s *spaceSubscriptions) UnsubscribeAll() (err error) { s.m.Lock() defer s.m.Unlock() for _, sub := range s.subscriptions { @@ -520,13 +734,13 @@ func (s *service) UnsubscribeAll() (err error) { return } -func (s *service) SubscriptionIDs() []string { +func (s *spaceSubscriptions) SubscriptionIDs() []string { s.m.Lock() defer s.m.Unlock() return s.subscriptionKeys } -func (s *service) recordsHandler() { +func (s *spaceSubscriptions) recordsHandler() { var entries []*entry nilIfExists := func(id string) { for i, e := range entries { @@ -551,7 +765,7 @@ func (s *service) recordsHandler() { }) } // filter nil entries - var filtered = entries[:0] + filtered := entries[:0] for _, e := range entries { if e != nil { filtered = append(filtered, e) @@ -565,22 +779,26 @@ func (s *service) recordsHandler() { } } -func (s *service) onChange(entries []*entry) time.Duration { +func (s *spaceSubscriptions) onChange(entries []*entry) time.Duration { s.m.Lock() defer s.m.Unlock() - var subCount, depCount int + + return s.onChangeWithinContext(entries, func(ctxBuf *opCtx) { + s.iterateSubscriptions(func(sub subscription) { + sub.onChange(s.ctxBuf) + if sub.hasDep() { + sub.getDep().onChange(s.ctxBuf) + } + }) + }) +} + +func (s *spaceSubscriptions) onChangeWithinContext(entries []*entry, proc func(ctxBuf *opCtx)) time.Duration { st := time.Now() s.ctxBuf.reset() s.ctxBuf.entries = entries - s.iterateSubscriptions(func(sub subscription) { - sub.onChange(s.ctxBuf) - subCount++ - if sub.hasDep() { - sub.getDep().onChange(s.ctxBuf) - depCount++ - } - }) - handleTime := time.Since(st) + + proc(s.ctxBuf) // Reset output buffer for subId := range s.ctxBuf.outputs { @@ -608,7 +826,7 @@ func (s *service) onChange(entries []*entry) time.Duration { if id == defaultOutput { s.eventSender.Broadcast(&pb.Event{Messages: msgs}) } else { - err := s.customOutput[id].Add(context.TODO(), msgs...) + err := s.customOutput[id].add(msgs...) if err != nil && !errors.Is(err, mb2.ErrClosed) { log.With("subId", id, "error", err).Errorf("push to output") } @@ -616,12 +834,10 @@ func (s *service) onChange(entries []*entry) time.Duration { } } - log.Debugf("handle %d entries; %v(handle:%v;genEvents:%v); cacheSize: %d; subCount:%d; subDepCount:%d", len(entries), dur, handleTime, dur-handleTime, len(s.cache.entries), subCount, depCount) - return dur } -func (s *service) filtersFromSource(sources []string) (database.Filter, error) { +func (s *spaceSubscriptions) filtersFromSource(spaceId string, sources []string) (database.Filter, error) { var relTypeFilter database.FiltersOr var ( relKeys []string @@ -667,9 +883,9 @@ func (s *service) filtersFromSource(sources []string) (database.Filter, error) { return relTypeFilter, nil } -func (s *service) depIdsFromFilter(filters []*model.BlockContentDataviewFilter) (depIds []string) { +func (s *spaceSubscriptions) depIdsFromFilter(spaceId string, filters []*model.BlockContentDataviewFilter) (depIds []string) { for _, f := range filters { - if s.ds.isRelationObject(f.RelationKey) { + if s.ds.isRelationObject(spaceId, f.RelationKey) { for _, id := range pbtypes.GetStringListValue(f.Value) { if slice.FindPos(depIds, id) == -1 && id != "" { depIds = append(depIds, id) @@ -680,7 +896,7 @@ func (s *service) depIdsFromFilter(filters []*model.BlockContentDataviewFilter) return } -func (s *service) Close(ctx context.Context) (err error) { +func (s *spaceSubscriptions) Close(ctx context.Context) (err error) { s.m.Lock() defer s.m.Unlock() s.recBatch.Close() diff --git a/core/subscription/service_test.go b/core/subscription/service_test.go index b1d9c15dc3..655fc871d6 100644 --- a/core/subscription/service_test.go +++ b/core/subscription/service_test.go @@ -4,51 +4,59 @@ import ( "context" "fmt" "testing" + "time" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) +const testSpaceId = "space1" + func TestService_Search(t *testing.T) { var newSub = func(fx *fixture, subId string) { - fx.store.EXPECT().QueryRaw(gomock.Any(), 0, 0).Return( - []database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("one"), - "author": pbtypes.StringList([]string{"author1"}), - }}}, - }, - nil, - ) - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyAuthor.String()).Return(model.RelationFormat_object, nil).AnyTimes() - - fx.store.EXPECT().QueryByID([]string{"author1"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("author1"), - "name": pbtypes.String("author1"), - }}}, - }, nil).AnyTimes() + + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("one"), + bundle.RelationKeyAuthor: pbtypes.StringList([]string{"author1"}), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyAuthor.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + // dep + { + bundle.RelationKeyId: pbtypes.String("author1"), + bundle.RelationKeyName: pbtypes.String("author1"), + }, + }) resp, err := fx.Search(SubscribeRequest{ - SubId: subId, - Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyAuthor.String()}, + SpaceId: testSpaceId, + SubId: subId, + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyAuthor.String()}, }) require.NoError(t, err) - assert.Len(t, resp.Records, 1) + assert.Len(t, resp.Records, 4) assert.Len(t, resp.Dependencies, 1) } @@ -59,18 +67,24 @@ func TestService_Search(t *testing.T) { newSub(fx, "test") - fx.store.EXPECT().QueryByID([]string{"author2", "author3"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("author2"), - "name": pbtypes.String("author2"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("author3"), - "name": pbtypes.String("author3"), - }}}, - }, nil) + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("author2"), + bundle.RelationKeyName: pbtypes.String("author2"), + }, + { + bundle.RelationKeyId: pbtypes.String("author3"), + bundle.RelationKeyName: pbtypes.String("author3"), + }, + }) + + spaceSub, err := fx.getSpaceSubscriptions(testSpaceId) + require.NoError(t, err) - fx.Service.(*service).onChange([]*entry{ + // Wait enough time to flush pending updates to subscriptions handler + time.Sleep(batchTime + time.Millisecond) + + spaceSub.onChange([]*entry{ {id: "1", data: &types.Struct{Fields: map[string]*types.Value{ "id": pbtypes.String("1"), "name": pbtypes.String("one"), @@ -78,40 +92,37 @@ func TestService_Search(t *testing.T) { }}}, }) - require.Len(t, fx.Service.(*service).cache.entries, 3) - assert.Len(t, fx.Service.(*service).cache.entries["1"].SubIds(), 1) - assert.Len(t, fx.Service.(*service).cache.entries["author2"].SubIds(), 1) - assert.Len(t, fx.Service.(*service).cache.entries["author3"].SubIds(), 1) + assert.Equal(t, []string{"test"}, spaceSub.cache.entries["1"].SubIds()) + assert.Equal(t, []string{"test", "test/dep"}, spaceSub.cache.entries["author2"].SubIds()) + assert.Equal(t, []string{"test", "test/dep"}, spaceSub.cache.entries["author3"].SubIds()) fx.events = fx.events[:0] - fx.Service.(*service).onChange([]*entry{ + spaceSub.onChange([]*entry{ {id: "1", data: &types.Struct{Fields: map[string]*types.Value{ "id": pbtypes.String("1"), "name": pbtypes.String("one"), }}}, }) - assert.Len(t, fx.Service.(*service).cache.entries, 1) - assert.NoError(t, fx.Unsubscribe("test")) - assert.Len(t, fx.Service.(*service).cache.entries, 0) + assert.Len(t, spaceSub.cache.entries, 0) }) t.Run("search with filters: one filter None", func(t *testing.T) { fx := newFixtureWithRealObjectStore(t) defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() source := "source" - spaceID := "spaceId" relationKey := "key" option1 := "option1" option2 := "option2" - err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx) + err := addTestObjects(t, source, relationKey, option1, option2, testSpaceId, fx) require.NoError(t, err) resp, err := fx.Search(SubscribeRequest{ - Keys: []string{bundle.RelationKeyId.String()}, + SpaceId: testSpaceId, + Keys: []string{bundle.RelationKeyId.String()}, Filters: []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_No, @@ -133,16 +144,17 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() source := "source" - spaceID := "spaceId" + relationKey := "key" option1 := "option1" option2 := "option2" - err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx) + err := addTestObjects(t, source, relationKey, option1, option2, testSpaceId, fx) require.NoError(t, err) resp, err := fx.Search(SubscribeRequest{ - Keys: []string{bundle.RelationKeyId.String()}, + SpaceId: testSpaceId, + Keys: []string{bundle.RelationKeyId.String()}, Filters: []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_No, @@ -169,16 +181,17 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() source := "source" - spaceID := "spaceId" + relationKey := "key" option1 := "option1" option2 := "option2" - err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx) + err := addTestObjects(t, source, relationKey, option1, option2, testSpaceId, fx) require.NoError(t, err) resp, err := fx.Search(SubscribeRequest{ - Keys: []string{bundle.RelationKeyId.String()}, + SpaceId: testSpaceId, + Keys: []string{bundle.RelationKeyId.String()}, Filters: []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -210,16 +223,17 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() source := "source" - spaceID := "spaceId" + relationKey := "key" option1 := "option1" option2 := "option2" - err := addTestObjects(t, source, relationKey, option1, option2, spaceID, fx) + err := addTestObjects(t, source, relationKey, option1, option2, testSpaceId, fx) require.NoError(t, err) resp, err := fx.Search(SubscribeRequest{ - Keys: []string{bundle.RelationKeyId.String()}, + SpaceId: testSpaceId, + Keys: []string{bundle.RelationKeyId.String()}, Filters: []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_Or, @@ -253,8 +267,6 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - spaceID := "spaceId" - option1 := "option1" option2 := "option2" option3 := "option3" @@ -262,9 +274,10 @@ func TestService_Search(t *testing.T) { tag1 := "work" tag2 := "university" - addTestObjectsForNestedFilters(t, fx, spaceID, option1, option2, option3, tag1, tag2) + addTestObjectsForNestedFilters(t, fx, testSpaceId, option1, option2, option3, tag1, tag2) resp, err := fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, Keys: []string{bundle.RelationKeyId.String()}, Filters: prepareNestedFiltersWithOperator(model.BlockContentDataviewFilter_And, option1, option2, tag1), NoDepSubscription: true, @@ -278,8 +291,6 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - spaceID := "spaceId" - option1 := "option1" option2 := "option2" option3 := "option3" @@ -287,9 +298,10 @@ func TestService_Search(t *testing.T) { tag1 := "work" tag2 := "university" - addTestObjectsForNestedFilters(t, fx, spaceID, option1, option2, option3, tag1, tag2) + addTestObjectsForNestedFilters(t, fx, testSpaceId, option1, option2, option3, tag1, tag2) resp, err := fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, Keys: []string{bundle.RelationKeyId.String()}, Filters: prepareNestedFiltersWithOperator(model.BlockContentDataviewFilter_Or, option1, option2, tag1), NoDepSubscription: true, @@ -307,15 +319,16 @@ func TestService_Search(t *testing.T) { newSub(fx, "test") - require.Len(t, fx.Service.(*service).cache.entries, 2) - assert.Equal(t, []string{"test"}, fx.Service.(*service).cache.entries["1"].SubIds()) - assert.Equal(t, []string{"test/dep"}, fx.Service.(*service).cache.entries["author1"].SubIds()) + spaceSub, err := fx.getSpaceSubscriptions(testSpaceId) + require.NoError(t, err) + + assert.Equal(t, []string{"test"}, spaceSub.cache.entries["1"].SubIds()) + assert.Equal(t, []string{"test", "test/dep"}, spaceSub.cache.entries["author1"].SubIds()) newSub(fx, "test1") - require.Len(t, fx.Service.(*service).cache.entries, 2) - assert.Len(t, fx.Service.(*service).cache.entries["1"].SubIds(), 2) - assert.Len(t, fx.Service.(*service).cache.entries["author1"].SubIds(), 2) + assert.Equal(t, []string{"test", "test1"}, spaceSub.cache.entries["1"].SubIds()) + assert.Equal(t, []string{"test", "test/dep", "test1", "test1/dep"}, spaceSub.cache.entries["author1"].SubIds()) }) t.Run("filter deps", func(t *testing.T) { @@ -323,36 +336,42 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - fx.store.EXPECT().QueryRaw(gomock.Any(), 0, 0).Return( - []database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("one"), - }}}, - }, - nil, - ) - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyAuthor.String()).Return(model.RelationFormat_object, nil).AnyTimes() - - fx.store.EXPECT().QueryByID([]string{"force1", "force2"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("force1"), - "name": pbtypes.String("force1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("force2"), - "name": pbtypes.String("force2"), - }}}, - }, nil) + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("one"), + bundle.RelationKeyAuthor: pbtypes.StringList([]string{"force1"}), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyAuthor.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + // dep + { + bundle.RelationKeyId: pbtypes.String("force1"), + bundle.RelationKeyName: pbtypes.String("force1"), + }, + { + bundle.RelationKeyId: pbtypes.String("force2"), + bundle.RelationKeyName: pbtypes.String("force2"), + }, + }) var resp, err = fx.Search(SubscribeRequest{ - SubId: "subId", - Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyAuthor.String()}, + SpaceId: testSpaceId, + SubId: "subId", + Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyAuthor.String()}, Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyAuthor.String(), - Condition: model.BlockContentDataviewFilter_Equal, + Condition: model.BlockContentDataviewFilter_In, Value: pbtypes.StringList([]string{"force1", "force2"}), }, }, @@ -368,27 +387,29 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - fx.store.EXPECT().QueryRaw(gomock.Any(), 0, 0).Return( - []database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("3"), - "name": pbtypes.String("3"), - }}}, - }, - nil, - ) - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + { + bundle.RelationKeyId: pbtypes.String("3"), + bundle.RelationKeyName: pbtypes.String("3"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }) resp, err := fx.Search(SubscribeRequest{ - SubId: "test", + SpaceId: testSpaceId, + SubId: "test", Sorts: []*model.BlockContentDataviewSort{ { RelationKey: "name", @@ -404,7 +425,10 @@ func TestService_Search(t *testing.T) { assert.Equal(t, "3", pbtypes.GetString(resp.Records[0], "id")) assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], "id")) - fx.Service.(*service).onChange([]*entry{ + spaceSub, err := fx.getSpaceSubscriptions(testSpaceId) + require.NoError(t, err) + + spaceSub.onChange([]*entry{ {id: "1", data: &types.Struct{Fields: map[string]*types.Value{ "id": pbtypes.String("1"), "name": pbtypes.String("4"), @@ -416,7 +440,7 @@ func TestService_Search(t *testing.T) { assert.NotEmpty(t, fx.events[0].Messages[1].GetSubscriptionAdd()) assert.NotEmpty(t, fx.events[0].Messages[2].GetSubscriptionRemove()) - fx.Service.(*service).onChange([]*entry{ + spaceSub.onChange([]*entry{ {id: "2", data: &types.Struct{Fields: map[string]*types.Value{ "id": pbtypes.String("2"), "name": pbtypes.String("6"), @@ -432,31 +456,35 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - fx.store.EXPECT().QueryRaw(gomock.Any(), 0, 0).Return( - []database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("3"), - "name": pbtypes.String("3"), - }}}, - }, - nil, - ) - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + { + bundle.RelationKeyId: pbtypes.String("3"), + bundle.RelationKeyName: pbtypes.String("3"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }) resp, err := fx.Search(SubscribeRequest{ - SubId: "test", + SpaceId: testSpaceId, + SubId: "test", Sorts: []*model.BlockContentDataviewSort{ { - RelationKey: "name", - Type: model.BlockContentDataviewSort_Asc, + RelationKey: "name", + Type: model.BlockContentDataviewSort_Asc, + EmptyPlacement: model.BlockContentDataviewSort_End, }, }, Limit: 2, @@ -468,7 +496,10 @@ func TestService_Search(t *testing.T) { assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], "id")) assert.Equal(t, "2", pbtypes.GetString(resp.Records[1], "id")) - fx.Service.(*service).onChange([]*entry{ + spaceSub, err := fx.getSpaceSubscriptions(testSpaceId) + require.NoError(t, err) + + spaceSub.onChange([]*entry{ { id: "2", data: &types.Struct{ @@ -495,6 +526,7 @@ func TestService_Search(t *testing.T) { subscriptionID := "subId" fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return(nil, nil, fmt.Errorf("error")) var resp, err = fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: "subId", CollectionId: collectionID, }) @@ -512,6 +544,7 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return(nil, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() var resp, err = fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, CollectionId: collectionID, }) @@ -533,21 +566,29 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2"}, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() - fx.store.EXPECT().QueryByID([]string{"1", "2"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - }, nil) - - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyId.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }) var resp, err = fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, CollectionId: collectionID, @@ -573,25 +614,33 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2", "3"}, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() - fx.store.EXPECT().QueryByID([]string{"1", "2", "3"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("3"), - "name": pbtypes.String("3"), - }}}, - }, nil) - - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + { + bundle.RelationKeyId: pbtypes.String("3"), + bundle.RelationKeyName: pbtypes.String("3"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyId.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }) var resp, err = fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, CollectionId: collectionID, @@ -624,25 +673,34 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2", "3"}, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() - fx.store.EXPECT().QueryByID([]string{"1", "2", "3"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("3"), - "name": pbtypes.String("3"), - }}}, - }, nil) - - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + { + bundle.RelationKeyId: pbtypes.String("3"), + bundle.RelationKeyName: pbtypes.String("3"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyId.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }) var resp, err = fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, CollectionId: collectionID, @@ -667,22 +725,33 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1"}, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() - fx.store.EXPECT().QueryByID([]string{"1"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - testRelationKey: pbtypes.String("2"), - }}}, - }, nil) - - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + domain.RelationKey(testRelationKey): pbtypes.String("2"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(testRelationKey), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + }) - fx.store.EXPECT().GetRelationFormatByKey(testRelationKey).Return(model.RelationFormat_object, nil).AnyTimes() + s, err := fx.getSpaceSubscriptions(testSpaceId) + require.NoError(t, err) - s := fx.Service.(*service) s.ds = newDependencyService(s) - var resp, err = fx.Search(SubscribeRequest{ + resp, err := fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String(), testRelationKey}, CollectionId: collectionID, @@ -708,30 +777,37 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1"}, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() - fx.store.EXPECT().QueryByID([]string{"1"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - testRelationKey: pbtypes.String("2"), - }}}, - }, nil) - - // dependency - fx.store.EXPECT().QueryByID([]string{"2"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - }, nil) - - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - - fx.store.EXPECT().GetRelationFormatByKey(testRelationKey).Return(model.RelationFormat_object, nil).AnyTimes() + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + domain.RelationKey(testRelationKey): pbtypes.StringList([]string{"2"}), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(testRelationKey), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_object)), + }, + // deps + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + }) - s := fx.Service.(*service) + s, err := fx.getSpaceSubscriptions(testSpaceId) + require.NoError(t, err) s.ds = newDependencyService(s) - var resp, err = fx.Search(SubscribeRequest{ + resp, err := fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String(), testRelationKey}, CollectionId: collectionID, @@ -747,6 +823,7 @@ func TestService_Search(t *testing.T) { assert.Equal(t, "2", pbtypes.GetString(resp.Dependencies[0], bundle.RelationKeyName.String())) assert.Equal(t, "2", pbtypes.GetString(resp.Dependencies[0], bundle.RelationKeyId.String())) }) + t.Run("collection: collection has 3 objects, but limit = 2 - return 2 objects in response", func(t *testing.T) { fx := newFixture(t) defer fx.a.Close(context.Background()) @@ -758,25 +835,34 @@ func TestService_Search(t *testing.T) { fx.collectionService.EXPECT().SubscribeForCollection(collectionID, subscriptionID).Return([]string{"1", "2", "3"}, nil, nil) fx.collectionService.EXPECT().UnsubscribeFromCollection(collectionID, subscriptionID).Return() - fx.store.EXPECT().QueryByID([]string{"1", "2", "3"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("1"), - "name": pbtypes.String("1"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("2"), - "name": pbtypes.String("2"), - }}}, - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("3"), - "name": pbtypes.String("3"), - }}}, - }, nil) - - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyName.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() - fx.store.EXPECT().GetRelationFormatByKey(bundle.RelationKeyId.String()).Return(model.RelationFormat_shorttext, nil).AnyTimes() + fx.store.AddObjects(t, testSpaceId, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + { + bundle.RelationKeyId: pbtypes.String("3"), + bundle.RelationKeyName: pbtypes.String("3"), + }, + // relations + { + bundle.RelationKeyId: pbtypes.String("rel1"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyName.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + { + bundle.RelationKeyId: pbtypes.String("rel2"), + bundle.RelationKeyRelationKey: pbtypes.String(bundle.RelationKeyId.String()), + bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), + }, + }) var resp, err = fx.Search(SubscribeRequest{ + SpaceId: testSpaceId, SubId: subscriptionID, Keys: []string{bundle.RelationKeyName.String(), bundle.RelationKeyId.String()}, CollectionId: collectionID, @@ -795,7 +881,7 @@ func TestService_Search(t *testing.T) { fx := newFixtureWithRealObjectStore(t) source := "source" - spaceID := "spaceId" + relationKey := "key" subID := "subId" collectionID := "collectionId" @@ -811,37 +897,37 @@ func TestService_Search(t *testing.T) { relationUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(relationUniqueKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_tag)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), }, { bundle.RelationKeyId: pbtypes.String(source), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), }, { bundle.RelationKeyId: pbtypes.String("1"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relationOption)), }, { bundle.RelationKeyId: pbtypes.String("2"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relationOption)), }, }) // when - groups, err := fx.SubscribeGroups(nil, pb.RpcObjectGroupsSubscribeRequest{ - SpaceId: spaceID, + groups, err := fx.SubscribeGroups(pb.RpcObjectGroupsSubscribeRequest{ + SpaceId: testSpaceId, RelationKey: relationKey, Source: []string{source}, SubId: subID, @@ -870,7 +956,7 @@ func TestService_Search(t *testing.T) { fx := newFixtureWithRealObjectStore(t) source := "source" - spaceID := "spaceId" + relationKey := "key" subID := "subId" collectionID := "collectionId" @@ -886,25 +972,25 @@ func TestService_Search(t *testing.T) { relationUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(relationUniqueKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_tag)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), }, { bundle.RelationKeyId: pbtypes.String(source), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), }, }) // when - groups, err := fx.SubscribeGroups(nil, pb.RpcObjectGroupsSubscribeRequest{ - SpaceId: spaceID, + groups, err := fx.SubscribeGroups(pb.RpcObjectGroupsSubscribeRequest{ + SpaceId: testSpaceId, RelationKey: relationKey, Source: []string{source}, SubId: subID, @@ -925,7 +1011,7 @@ func TestService_Search(t *testing.T) { fx := newFixtureWithRealObjectStore(t) source := "source" - spaceID := "spaceId" + relationKey := "key" defer fx.a.Close(context.Background()) @@ -936,30 +1022,30 @@ func TestService_Search(t *testing.T) { relationUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(relationUniqueKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_status)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), }, { bundle.RelationKeyId: pbtypes.String(source), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), }, { bundle.RelationKeyId: pbtypes.String("1"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relationOption)), bundle.RelationKeyName: pbtypes.String("Done"), }, { bundle.RelationKeyId: pbtypes.String("2"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationKey: pbtypes.String(relationKey), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relationOption)), bundle.RelationKeyName: pbtypes.String("Not started"), @@ -967,8 +1053,8 @@ func TestService_Search(t *testing.T) { }) // when - groups, err := fx.SubscribeGroups(nil, pb.RpcObjectGroupsSubscribeRequest{ - SpaceId: spaceID, + groups, err := fx.SubscribeGroups(pb.RpcObjectGroupsSubscribeRequest{ + SpaceId: testSpaceId, RelationKey: relationKey, Source: []string{source}, }) @@ -993,7 +1079,7 @@ func TestService_Search(t *testing.T) { fx := newFixtureWithRealObjectStore(t) source := "source" - spaceID := "spaceId" + relationKey := "key" defer fx.a.Close(context.Background()) @@ -1004,25 +1090,25 @@ func TestService_Search(t *testing.T) { relationUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(relationUniqueKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_status)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), }, { bundle.RelationKeyId: pbtypes.String(source), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), }, }) // when - groups, err := fx.SubscribeGroups(nil, pb.RpcObjectGroupsSubscribeRequest{ - SpaceId: spaceID, + groups, err := fx.SubscribeGroups(pb.RpcObjectGroupsSubscribeRequest{ + SpaceId: testSpaceId, RelationKey: relationKey, Source: []string{source}, }) @@ -1041,7 +1127,7 @@ func TestService_Search(t *testing.T) { fx := newFixtureWithRealObjectStore(t) source := "source" - spaceID := "spaceId" + relationKey := "key" defer fx.a.Close(context.Background()) @@ -1052,25 +1138,25 @@ func TestService_Search(t *testing.T) { relationUniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, relationKey) assert.Nil(t, err) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(relationKey), bundle.RelationKeyUniqueKey: pbtypes.String(relationUniqueKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_checkbox)), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_relation)), }, { bundle.RelationKeyId: pbtypes.String(source), bundle.RelationKeyUniqueKey: pbtypes.String(objectTypeKey.Marshal()), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_objectType)), }, }) // when - groups, err := fx.SubscribeGroups(nil, pb.RpcObjectGroupsSubscribeRequest{ - SpaceId: spaceID, + groups, err := fx.SubscribeGroups(pb.RpcObjectGroupsSubscribeRequest{ + SpaceId: testSpaceId, RelationKey: relationKey, Source: []string{source}, }) @@ -1093,13 +1179,14 @@ func TestService_Search(t *testing.T) { id := "id" defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - fx.store.AddObjects(t, []objectstore.TestObject{{bundle.RelationKeyId: pbtypes.String(id), bundle.RelationKeyName: pbtypes.String("name")}}) + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{{bundle.RelationKeyId: pbtypes.String(id), bundle.RelationKeyName: pbtypes.String("name")}}) // when sub, err := fx.SubscribeIdsReq(pb.RpcObjectSubscribeIdsRequest{ - Ids: []string{id}, - SubId: "subID", - Keys: []string{bundle.RelationKeyId.String()}, + SpaceId: testSpaceId, + Ids: []string{id}, + SubId: "subID", + Keys: []string{bundle.RelationKeyId.String()}, }) // then @@ -1119,7 +1206,7 @@ func TestService_Search(t *testing.T) { defer fx.a.Close(context.Background()) defer fx.ctrl.Finish() - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String(id), bundle.RelationKeyName: pbtypes.String(relationValue), @@ -1128,8 +1215,9 @@ func TestService_Search(t *testing.T) { // when sub, err := fx.SubscribeIdsReq(pb.RpcObjectSubscribeIdsRequest{ - Ids: []string{id}, - Keys: []string{bundle.RelationKeyName.String()}, + SpaceId: testSpaceId, + Ids: []string{id}, + Keys: []string{bundle.RelationKeyName.String()}, }) // then @@ -1150,7 +1238,8 @@ func TestService_Search(t *testing.T) { // when sub, err := fx.SubscribeIdsReq(pb.RpcObjectSubscribeIdsRequest{ - Ids: []string{id}, + SpaceId: testSpaceId, + Ids: []string{id}, }) // then @@ -1161,13 +1250,13 @@ func TestService_Search(t *testing.T) { }) } -func addTestObjects(t *testing.T, source, relationKey, option1, option2, spaceID string, fx *fixtureRealStore) error { +func addTestObjects(t *testing.T, source, relationKey, option1, option2, testSpaceId string, fx *fixtureRealStore) error { objectTypeKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeObjectType, source) assert.Nil(t, err) - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("1"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), domain.RelationKey(relationKey): pbtypes.String(option1), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)), bundle.RelationKeyName: pbtypes.String("Object 1"), @@ -1175,7 +1264,7 @@ func addTestObjects(t *testing.T, source, relationKey, option1, option2, spaceID }, { bundle.RelationKeyId: pbtypes.String("2"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), domain.RelationKey(relationKey): pbtypes.String(option2), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)), bundle.RelationKeyName: pbtypes.String("Object 2"), @@ -1185,11 +1274,11 @@ func addTestObjects(t *testing.T, source, relationKey, option1, option2, spaceID return err } -func addTestObjectsForNestedFilters(t *testing.T, fx *fixtureRealStore, spaceID, option1, option2, option3, tag1, tag2 string) { - fx.store.AddObjects(t, []objectstore.TestObject{ +func addTestObjectsForNestedFilters(t *testing.T, fx *fixtureRealStore, testSpaceId, option1, option2, option3, tag1, tag2 string) { + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("1"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyStatus: pbtypes.String(option1), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)), bundle.RelationKeyName: pbtypes.String("Object 1"), @@ -1199,7 +1288,7 @@ func addTestObjectsForNestedFilters(t *testing.T, fx *fixtureRealStore, spaceID, }, { bundle.RelationKeyId: pbtypes.String("2"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyStatus: pbtypes.String(option3), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)), bundle.RelationKeyName: pbtypes.String("Object 2"), @@ -1209,7 +1298,7 @@ func addTestObjectsForNestedFilters(t *testing.T, fx *fixtureRealStore, spaceID, }, { bundle.RelationKeyId: pbtypes.String("3"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyStatus: pbtypes.String(option2), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)), bundle.RelationKeyName: pbtypes.String("Object 3"), @@ -1219,7 +1308,7 @@ func addTestObjectsForNestedFilters(t *testing.T, fx *fixtureRealStore, spaceID, }, { bundle.RelationKeyId: pbtypes.String("4"), - bundle.RelationKeySpaceId: pbtypes.String(spaceID), + bundle.RelationKeySpaceId: pbtypes.String(testSpaceId), bundle.RelationKeyStatus: pbtypes.String(option1), bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_basic)), bundle.RelationKeyName: pbtypes.String("Object 4"), @@ -1307,7 +1396,7 @@ func xTestNestedSubscription(t *testing.T) { t.Run("update nested object, so it's not satisfying filter anymore", func(t *testing.T) { fx := testCreateSubscriptionWithNestedFilter(t) - err := fx.store.UpdateObjectDetails(context.Background(), "assignee1", &types.Struct{ + err := fx.store.SpaceIndex(testSpaceId).UpdateObjectDetails(context.Background(), "assignee1", &types.Struct{ Fields: map[string]*types.Value{ "id": pbtypes.String("assignee1"), "name": pbtypes.String("John Doe"), @@ -1345,7 +1434,7 @@ func xTestNestedSubscription(t *testing.T) { t.Run("update parent object relation so no nested objects satisfy filter anymore", func(t *testing.T) { fx := testCreateSubscriptionWithNestedFilter(t) - err := fx.store.UpdateObjectDetails(context.Background(), "task1", &types.Struct{ + err := fx.store.SpaceIndex(testSpaceId).UpdateObjectDetails(context.Background(), "task1", &types.Struct{ Fields: map[string]*types.Value{ "id": pbtypes.String("task1"), "assignee": pbtypes.String("assignee2"), @@ -1359,7 +1448,8 @@ func testCreateSubscriptionWithNestedFilter(t *testing.T) *fixtureRealStore { fx := newFixtureWithRealObjectStore(t) // fx.store.EXPECT().GetRelationFormatByKey(mock.Anything).Return(&model.Relation{}, nil) resp, err := fx.Search(SubscribeRequest{ - SubId: "test", + SpaceId: testSpaceId, + SubId: "test", Filters: []*model.BlockContentDataviewFilter{ { RelationKey: "assignee.name", @@ -1374,7 +1464,7 @@ func testCreateSubscriptionWithNestedFilter(t *testing.T) *fixtureRealStore { require.Empty(t, resp.Records) t.Run("add nested object", func(t *testing.T) { - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { "id": pbtypes.String("assignee1"), "name": pbtypes.String("Joe Doe"), @@ -1409,7 +1499,7 @@ func testCreateSubscriptionWithNestedFilter(t *testing.T) *fixtureRealStore { }) t.Run("add object satisfying nested filter", func(t *testing.T) { - fx.store.AddObjects(t, []objectstore.TestObject{ + fx.store.AddObjects(t, testSpaceId, []objectstore.TestObject{ { "id": pbtypes.String("task1"), "assignee": pbtypes.String("assignee1"), diff --git a/core/subscription/simple.go b/core/subscription/simple.go index c46ce4d0d4..8e1d576f84 100644 --- a/core/subscription/simple.go +++ b/core/subscription/simple.go @@ -6,11 +6,12 @@ import ( "github.com/anyproto/anytype-heart/util/pbtypes" ) -func (s *service) newSimpleSub(id string, keys []string, isDep bool) *simpleSub { +func (s *spaceSubscriptions) newSimpleSub(id string, spaceId string, keys []string, isDep bool) *simpleSub { sub := &simpleSub{ - id: id, - keys: keys, - cache: s.cache, + id: id, + spaceId: spaceId, + keys: keys, + cache: s.cache, } if !isDep { sub.ds = s.ds @@ -20,6 +21,7 @@ func (s *service) newSimpleSub(id string, keys []string, isDep bool) *simpleSub type simpleSub struct { id string + spaceId string set map[string]struct{} keys []string forceIds []string @@ -40,9 +42,9 @@ func (s *simpleSub) init(entries []*entry) (err error) { e.SetSub(s.id, true, false) } if s.ds != nil { - s.depKeys = s.ds.depKeys(s.keys) + s.depKeys = s.ds.depKeys(s.spaceId, s.keys) if len(s.depKeys) > 0 { - s.depSub = s.ds.makeSubscriptionByEntries(s.id+"/dep", entries, s.getActiveEntries(), s.keys, s.depKeys, nil) + s.depSub = s.ds.makeSubscriptionByEntries(s.id+"/dep", s.spaceId, entries, s.getActiveEntries(), s.keys, s.depKeys, nil) } } return @@ -110,7 +112,7 @@ func (s *simpleSub) onChange(ctx *opCtx) { } } if changed && s.depSub != nil { - s.ds.refillSubscription(ctx, s.depSub, s.getActiveEntries(), s.depKeys) + s.ds.refillSubscription(s.spaceId, ctx, s.depSub, s.getActiveEntries(), s.depKeys) } } diff --git a/core/subscription/sorted.go b/core/subscription/sorted.go index 1c39fc611f..4a102f3323 100644 --- a/core/subscription/sorted.go +++ b/core/subscription/sorted.go @@ -7,7 +7,7 @@ import ( "github.com/huandu/skiplist" "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -17,9 +17,10 @@ var ( ErrNoRecords = errors.New("no records with given offset") ) -func (s *service) newSortedSub(id string, keys []string, filter database.Filter, order database.Order, limit, offset int) *sortedSub { +func (s *spaceSubscriptions) newSortedSub(id string, spaceId string, keys []string, filter database.Filter, order database.Order, limit, offset int) *sortedSub { sub := &sortedSub{ id: id, + spaceId: spaceId, keys: keys, filter: filter, order: order, @@ -33,10 +34,11 @@ func (s *service) newSortedSub(id string, keys []string, filter database.Filter, } type sortedSub struct { - id string - keys []string - filter database.Filter - order database.Order + id string + spaceId string + keys []string + filter database.Filter + order database.Order afterId, beforeId string limit, offset int @@ -59,7 +61,7 @@ type sortedSub struct { ds *dependencyService // for nested subscriptions - objectStore objectstore.ObjectStore + objectStore spaceindex.Store // parent is used to run onChange callback when any child subscriptions receive changes parent *sortedSub parentFilter *database.FilterNestedIn @@ -133,9 +135,9 @@ func (s *sortedSub) init(entries []*entry) (err error) { s.compCountBefore.total = s.skl.Len() if s.ds != nil && !s.disableDep { - s.depKeys = s.ds.depKeys(s.keys) + s.depKeys = s.ds.depKeys(s.spaceId, s.keys) if len(s.depKeys) > 0 || len(s.forceSubIds) > 0 { - s.depSub = s.ds.makeSubscriptionByEntries(s.id+"/dep", entries, activeEntries, s.keys, s.depKeys, s.forceSubIds) + s.depSub = s.ds.makeSubscriptionByEntries(s.id+"/dep", s.spaceId, entries, activeEntries, s.keys, s.depKeys, s.forceSubIds) } } return nil @@ -172,7 +174,7 @@ func (s *sortedSub) onChange(ctx *opCtx) { } wasAddOrRemove, ids := s.diff.diff(ctx, s.id, s.keys) - s.ds.depEntriesByEntries(ctx, ids) + s.ds.depEntriesByEntries(ctx, s.spaceId, ids) hasChanges := false for _, e := range ctx.entries { @@ -188,7 +190,7 @@ func (s *sortedSub) onChange(ctx *opCtx) { } if (wasAddOrRemove || hasChanges) && s.depSub != nil { - s.ds.refillSubscription(ctx, s.depSub, s.activeEntriesBuf, s.depKeys) + s.ds.refillSubscription(s.spaceId, ctx, s.depSub, s.activeEntriesBuf, s.depKeys) } if s.parent != nil { diff --git a/core/subscription/sorted_test.go b/core/subscription/sorted_test.go index 3fe63ea015..62bf5a3704 100644 --- a/core/subscription/sorted_test.go +++ b/core/subscription/sorted_test.go @@ -6,13 +6,13 @@ import ( "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.uber.org/mock/gomock" "github.com/anyproto/anytype-heart/pb" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" - "github.com/anyproto/anytype-heart/util/testMock" ) func TestSubscription_Add(t *testing.T) { @@ -52,15 +52,14 @@ func TestSubscription_Add(t *testing.T) { func TestSubscription_Remove(t *testing.T) { newSub := func() *sortedSub { - ctrl := gomock.NewController(t) - store := testMock.NewMockObjectStore(ctrl) - store.EXPECT().QueryByID([]string{"id7"}).Return([]database.Record{ - {Details: &types.Struct{Fields: map[string]*types.Value{ - "id": pbtypes.String("id7"), - "name": pbtypes.String("id7"), - }}}, - }, nil).AnyTimes() - s := service{ + store := spaceindex.NewStoreFixture(t) + store.AddObjects(t, []spaceindex.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("id7"), + bundle.RelationKeyName: pbtypes.String("id7"), + }, + }) + s := spaceSubscriptions{ cache: newCache(), objectStore: store, } diff --git a/core/syncstatus/detailsupdater/updater.go b/core/syncstatus/detailsupdater/updater.go index 575c650d36..4fbcd63ddc 100644 --- a/core/syncstatus/detailsupdater/updater.go +++ b/core/syncstatus/detailsupdater/updater.go @@ -202,7 +202,7 @@ func (u *syncStatusUpdater) updateObjectDetails(syncStatusDetails *syncStatusDet } defer u.spaceSyncStatus.Refresh(syncStatusDetails.spaceId) err = spc.DoLockedIfNotExists(objectId, func() error { - return u.objectStore.ModifyObjectDetails(objectId, func(details *types.Struct) (*types.Struct, bool, error) { + return u.objectStore.SpaceIndex(syncStatusDetails.spaceId).ModifyObjectDetails(objectId, func(details *types.Struct) (*types.Struct, bool, error) { if details == nil || details.Fields == nil { details = &types.Struct{Fields: map[string]*types.Value{}} } diff --git a/core/syncstatus/detailsupdater/updater_test.go b/core/syncstatus/detailsupdater/updater_test.go index 9becf1d7bb..2a42b238f5 100644 --- a/core/syncstatus/detailsupdater/updater_test.go +++ b/core/syncstatus/detailsupdater/updater_test.go @@ -16,7 +16,7 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" "github.com/anyproto/anytype-heart/core/block/editor/state" - domain "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/subscription" "github.com/anyproto/anytype-heart/core/syncstatus/detailsupdater/mock_detailsupdater" "github.com/anyproto/anytype-heart/core/syncstatus/filesyncstatus" @@ -125,7 +125,7 @@ func TestSyncStatusUpdater_UpdateDetails(t *testing.T) { fx := newUpdateDetailsFixture(t) updTester := newUpdateTester(t, 1, 1) - fx.subscriptionService.StoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.subscriptionService.StoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeySpaceId: pbtypes.String("space1"), @@ -139,7 +139,7 @@ func TestSyncStatusUpdater_UpdateDetails(t *testing.T) { err := proc() require.NoError(t, err) - details, err := fx.objectStore.GetDetails(objectId) + details, err := fx.objectStore.SpaceIndex("space1").GetDetails(objectId) require.NoError(t, err) assert.True(t, pbtypes.GetInt64(details.Details, bundle.RelationKeySyncStatus.String()) == int64(domain.ObjectSyncStatusError)) @@ -223,7 +223,7 @@ func TestSyncStatusUpdater_UpdateSpaceDetails(t *testing.T) { fx := newUpdateDetailsFixture(t) updTester := newUpdateTester(t, 3, 3) - fx.subscriptionService.StoreFixture.AddObjects(t, []objectstore.TestObject{ + fx.subscriptionService.StoreFixture.AddObjects(t, "space1", []objectstore.TestObject{ { bundle.RelationKeyId: pbtypes.String("id1"), bundle.RelationKeySpaceId: pbtypes.String("space1"), diff --git a/core/syncstatus/objectsyncstatus/syncstatus.go b/core/syncstatus/objectsyncstatus/syncstatus.go index 5c85c19e9e..a05873e80e 100644 --- a/core/syncstatus/objectsyncstatus/syncstatus.go +++ b/core/syncstatus/objectsyncstatus/syncstatus.go @@ -8,6 +8,7 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/spacestate" + "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/nodeconf" @@ -66,10 +67,11 @@ type syncStatusService struct { sync.Mutex periodicSync periodicsync.PeriodicSync - spaceId string - synced []string - tempSynced map[string]struct{} - treeHeads map[string]treeHeadsEntry + spaceId string + spaceSettingsId string + synced []string + tempSynced map[string]struct{} + treeHeads map[string]treeHeadsEntry updateIntervalSecs int updateTimeout time.Duration @@ -87,10 +89,12 @@ func NewSyncStatusService() StatusService { } func (s *syncStatusService) Init(a *app.App) (err error) { - sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState) + sharedState := app.MustComponent[*spacestate.SpaceState](a) + spaceStorage := app.MustComponent[spacestorage.SpaceStorage](a) s.updateIntervalSecs = syncUpdateInterval s.updateTimeout = syncTimeout s.spaceId = sharedState.SpaceId + s.spaceSettingsId = spaceStorage.SpaceSettingsId() s.periodicSync = periodicsync.NewPeriodicSync( s.updateIntervalSecs, s.updateTimeout, @@ -115,6 +119,7 @@ func (s *syncStatusService) HeadsChange(treeId string, heads []string) { s.Lock() s.addTreeHead(treeId, heads, StatusNotSynced) s.Unlock() + s.updateDetails(treeId, domain.ObjectSyncStatusSyncing) } @@ -224,5 +229,7 @@ func (s *syncStatusService) isSenderResponsible(senderId string) bool { } func (s *syncStatusService) updateDetails(treeId string, status domain.ObjectSyncStatus) { - s.syncDetailsUpdater.UpdateDetails(treeId, status, s.spaceId) + if treeId != s.spaceSettingsId { + s.syncDetailsUpdater.UpdateDetails(treeId, status, s.spaceId) + } } diff --git a/core/syncstatus/objectsyncstatus/syncstatus_test.go b/core/syncstatus/objectsyncstatus/syncstatus_test.go index a1da2c8b60..24307b6cd3 100644 --- a/core/syncstatus/objectsyncstatus/syncstatus_test.go +++ b/core/syncstatus/objectsyncstatus/syncstatus_test.go @@ -19,6 +19,10 @@ import ( "github.com/anyproto/anytype-heart/tests/testutil" ) +const ( + testSpaceSettingsId = "testSpaceSettingsId" +) + func Test_UseCases(t *testing.T) { t.Run("HeadsChange: new object", func(t *testing.T) { s := newFixture(t, "spaceId") @@ -86,6 +90,14 @@ func Test_UseCases(t *testing.T) { assert.Equal(t, s.synced, []string{"id"}) }) + t.Run("HeadsChange: settings object is changed", func(t *testing.T) { + s := newFixture(t, "spaceId") + + s.HeadsChange(testSpaceSettingsId, []string{"head1", "head2"}) + + assert.NotNil(t, s.treeHeads[testSpaceSettingsId]) + assert.Equal(t, []string{"head1", "head2"}, s.treeHeads[testSpaceSettingsId].heads) + }) } func TestSyncStatusService_Run(t *testing.T) { @@ -162,6 +174,8 @@ func newFixture(t *testing.T, spaceId string) *fixture { ctrl := gomock.NewController(t) service := mock_nodeconf.NewMockService(ctrl) storage := mock_spacestorage.NewMockSpaceStorage(ctrl) + storage.EXPECT().SpaceSettingsId().Return(testSpaceSettingsId) + spaceState := &spacestate.SpaceState{SpaceId: spaceId} config := &config.Config{} detailsUpdater := mock_objectsyncstatus.NewMockUpdater(t) diff --git a/core/syncstatus/spacesyncstatus/spacestatus_test.go b/core/syncstatus/spacesyncstatus/spacestatus_test.go index a1fa9024e4..f6bd4eebe4 100644 --- a/core/syncstatus/spacesyncstatus/spacestatus_test.go +++ b/core/syncstatus/spacesyncstatus/spacestatus_test.go @@ -166,7 +166,7 @@ func Test(t *testing.T) { t.Run("objects syncing", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.Online) @@ -197,7 +197,7 @@ func Test(t *testing.T) { fx := newFixture(t, func(fx *fixture) { fx.spaceSyncStatus.loopInterval = 10 * time.Millisecond objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.Online) @@ -229,7 +229,7 @@ func Test(t *testing.T) { t.Run("local only", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_LocalOnly) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.eventSender.EXPECT().Broadcast(&pb.Event{ @@ -249,7 +249,7 @@ func Test(t *testing.T) { t.Run("size exceeded", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.Online) @@ -280,7 +280,7 @@ func Test(t *testing.T) { t.Run("connection error", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.ConnectionError) @@ -311,7 +311,7 @@ func Test(t *testing.T) { t.Run("network incompatible", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.ConnectionError) @@ -343,7 +343,7 @@ func Test(t *testing.T) { fx := newFixture(t, func(fx *fixture) { fx.spaceSyncStatus.loopInterval = 10 * time.Millisecond objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.Online) @@ -415,7 +415,7 @@ func Test(t *testing.T) { t.Run("hook new session", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_DefaultConfig) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.nodeStatus.EXPECT().GetNodeStatus("spaceId").Return(nodestatus.ConnectionError) @@ -460,7 +460,7 @@ func Test(t *testing.T) { t.Run("hook new session local only", func(t *testing.T) { fx := newFixture(t, func(fx *fixture) { objs := genSyncingObjects(10, 100, "spaceId") - fx.objectStore.AddObjects(t, objs) + fx.objectStore.AddObjects(t, "spaceId", objs) fx.networkConfig.EXPECT().GetNetworkMode().Return(pb.RpcAccount_LocalOnly) fx.spaceIdGetter.EXPECT().AllSpaceIds().Return([]string{"spaceId"}) fx.eventSender.EXPECT().Broadcast(&pb.Event{ diff --git a/core/syncstatus/syncsubscriptions/syncingobjects.go b/core/syncstatus/syncsubscriptions/syncingobjects.go index ec88fe9768..1f9b218189 100644 --- a/core/syncstatus/syncsubscriptions/syncingobjects.go +++ b/core/syncstatus/syncsubscriptions/syncingobjects.go @@ -5,6 +5,7 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/core/subscription/objectsubscription" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" @@ -12,7 +13,7 @@ import ( ) type syncingObjects struct { - objectSubscription *ObjectSubscription[struct{}] + objectSubscription *objectsubscription.ObjectSubscription[struct{}] service subscription.Service spaceId string } @@ -26,6 +27,7 @@ func newSyncingObjects(spaceId string, service subscription.Service) *syncingObj func (s *syncingObjects) Run() error { objectReq := subscription.SubscribeRequest{ + SpaceId: s.spaceId, SubId: fmt.Sprintf("spacestatus.objects.%s", s.spaceId), Internal: true, NoDepSubscription: true, @@ -43,7 +45,7 @@ func (s *syncingObjects) Run() error { }, }, } - s.objectSubscription = NewIdSubscription(s.service, objectReq) + s.objectSubscription = objectsubscription.NewIdSubscription(s.service, objectReq) errObjects := s.objectSubscription.Run() if errObjects != nil { return fmt.Errorf("error running syncing objects: %w", errObjects) @@ -55,7 +57,7 @@ func (s *syncingObjects) Close() { s.objectSubscription.Close() } -func (s *syncingObjects) GetObjectSubscription() *ObjectSubscription[struct{}] { +func (s *syncingObjects) GetObjectSubscription() *objectsubscription.ObjectSubscription[struct{}] { return s.objectSubscription } diff --git a/core/syncstatus/syncsubscriptions/syncingobjects_test.go b/core/syncstatus/syncsubscriptions/syncingobjects_test.go index a7b5991408..69e055e468 100644 --- a/core/syncstatus/syncsubscriptions/syncingobjects_test.go +++ b/core/syncstatus/syncsubscriptions/syncingobjects_test.go @@ -6,15 +6,38 @@ import ( "github.com/stretchr/testify/require" "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/core/subscription/objectsubscription" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/util/pbtypes" ) func TestCount(t *testing.T) { - objSubscription := NewIdSubscription(nil, subscription.SubscribeRequest{}) - objSubscription.sub = map[string]*entry[struct{}]{ - "1": newEmptyEntry[struct{}](), - "2": newEmptyEntry[struct{}](), - "4": newEmptyEntry[struct{}](), - } + spaceId := "space1" + subService := subscription.NewInternalTestService(t) + subService.AddObjects(t, spaceId, []objectstore.TestObject{ + { + bundle.RelationKeyId: pbtypes.String("1"), + bundle.RelationKeyName: pbtypes.String("1"), + }, + { + bundle.RelationKeyId: pbtypes.String("2"), + bundle.RelationKeyName: pbtypes.String("2"), + }, + { + bundle.RelationKeyId: pbtypes.String("4"), + bundle.RelationKeyName: pbtypes.String("4"), + }, + }) + + objSubscription := objectsubscription.NewIdSubscription(subService, subscription.SubscribeRequest{ + SpaceId: spaceId, + Keys: []string{bundle.RelationKeyId.String()}, + }) + err := objSubscription.Run() + require.NoError(t, err) + defer objSubscription.Close() + syncing := &syncingObjects{ objectSubscription: objSubscription, } diff --git a/core/syncstatus/syncsubscriptions/syncsubscriptions.go b/core/syncstatus/syncsubscriptions/syncsubscriptions.go index 50a199a8f1..660a7764b4 100644 --- a/core/syncstatus/syncsubscriptions/syncsubscriptions.go +++ b/core/syncstatus/syncsubscriptions/syncsubscriptions.go @@ -8,6 +8,7 @@ import ( "github.com/samber/lo" "github.com/anyproto/anytype-heart/core/subscription" + "github.com/anyproto/anytype-heart/core/subscription/objectsubscription" ) const CName = "client.syncstatus.syncsubscriptions" @@ -15,7 +16,7 @@ const CName = "client.syncstatus.syncsubscriptions" type SyncSubscription interface { Run() error Close() - GetObjectSubscription() *ObjectSubscription[struct{}] + GetObjectSubscription() *objectsubscription.ObjectSubscription[struct{}] SyncingObjectsCount(missing []string) int } diff --git a/core/syncstatus/syncsubscriptions/syncsubscriptions_test.go b/core/syncstatus/syncsubscriptions/syncsubscriptions_test.go index 7d8fe23652..f854950c08 100644 --- a/core/syncstatus/syncsubscriptions/syncsubscriptions_test.go +++ b/core/syncstatus/syncsubscriptions/syncsubscriptions_test.go @@ -40,7 +40,7 @@ func TestSyncSubscriptions(t *testing.T) { for i := 0; i < 10; i++ { objects = append(objects, genObject(domain.ObjectSyncStatusSynced, "spaceId")) } - testSubs.AddObjects(t, objects) + testSubs.AddObjects(t, "spaceId", objects) subs := New() subs.(*syncSubscriptions).service = testSubs err := subs.Run(context.Background()) @@ -58,7 +58,7 @@ func TestSyncSubscriptions(t *testing.T) { require.Empty(t, objs) for i := 0; i < 10; i++ { objects[i][bundle.RelationKeySyncStatus] = pbtypes.Int64(int64(domain.ObjectSyncStatusSynced)) - testSubs.AddObjects(t, []objectstore.TestObject{objects[i]}) + testSubs.AddObjects(t, "spaceId", []objectstore.TestObject{objects[i]}) } time.Sleep(100 * time.Millisecond) syncCnt = spaceSub.SyncingObjectsCount([]string{"1", "2"}) diff --git a/core/workspace.go b/core/workspace.go index 0775e8f676..d20cf2e9f3 100644 --- a/core/workspace.go +++ b/core/workspace.go @@ -47,8 +47,7 @@ func (mw *Middleware) WorkspaceOpen(cctx context.Context, req *pb.RpcWorkspaceOp } return m } - // TODO: [MR] this should probably be related only to account - info, err := getService[account.Service](mw).GetInfo(cctx, req.SpaceId) + info, err := getService[account.Service](mw).GetSpaceInfo(cctx, req.SpaceId) if err != nil { return response(info, pb.RpcWorkspaceOpenResponseError_UNKNOWN_ERROR, err) } diff --git a/docs/Build.md b/docs/Build.md index 5316a128bc..b8686c5a3c 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -5,6 +5,12 @@ ### Install local deps +#### Update tantivy +Update the tantivy version in go.mod and run: +``` +make download-tantivy-all-force +``` + #### Mac As of 16.01.23 last protobuf version (21.12) broke the JS plugin support, so you can use the v3 branch: ``` diff --git a/docs/proto.md b/docs/proto.md index 0df83808f6..3c95d8e20b 100644 --- a/docs/proto.md +++ b/docs/proto.md @@ -36,6 +36,14 @@ - [Change.StoreSliceUpdate.Add](#anytype-Change-StoreSliceUpdate-Add) - [Change.StoreSliceUpdate.Move](#anytype-Change-StoreSliceUpdate-Move) - [Change.StoreSliceUpdate.Remove](#anytype-Change-StoreSliceUpdate-Remove) + - [DocumentCreate](#anytype-DocumentCreate) + - [DocumentDelete](#anytype-DocumentDelete) + - [DocumentModify](#anytype-DocumentModify) + - [KeyModify](#anytype-KeyModify) + - [StoreChange](#anytype-StoreChange) + - [StoreChangeContent](#anytype-StoreChangeContent) + + - [ModifyOp](#anytype-ModifyOp) - [pb/protos/commands.proto](#pb_protos_commands-proto) - [Empty](#anytype-Empty) @@ -560,6 +568,11 @@ - [Rpc.Debug.AccountSelectTrace.Request](#anytype-Rpc-Debug-AccountSelectTrace-Request) - [Rpc.Debug.AccountSelectTrace.Response](#anytype-Rpc-Debug-AccountSelectTrace-Response) - [Rpc.Debug.AccountSelectTrace.Response.Error](#anytype-Rpc-Debug-AccountSelectTrace-Response-Error) + - [Rpc.Debug.AnystoreObjectChanges](#anytype-Rpc-Debug-AnystoreObjectChanges) + - [Rpc.Debug.AnystoreObjectChanges.Request](#anytype-Rpc-Debug-AnystoreObjectChanges-Request) + - [Rpc.Debug.AnystoreObjectChanges.Response](#anytype-Rpc-Debug-AnystoreObjectChanges-Response) + - [Rpc.Debug.AnystoreObjectChanges.Response.Change](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Change) + - [Rpc.Debug.AnystoreObjectChanges.Response.Error](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Error) - [Rpc.Debug.ExportLocalstore](#anytype-Rpc-Debug-ExportLocalstore) - [Rpc.Debug.ExportLocalstore.Request](#anytype-Rpc-Debug-ExportLocalstore-Request) - [Rpc.Debug.ExportLocalstore.Response](#anytype-Rpc-Debug-ExportLocalstore-Response) @@ -825,6 +838,14 @@ - [Rpc.Object.CreateSet.Request](#anytype-Rpc-Object-CreateSet-Request) - [Rpc.Object.CreateSet.Response](#anytype-Rpc-Object-CreateSet-Response) - [Rpc.Object.CreateSet.Response.Error](#anytype-Rpc-Object-CreateSet-Response-Error) + - [Rpc.Object.CrossSpaceSearchSubscribe](#anytype-Rpc-Object-CrossSpaceSearchSubscribe) + - [Rpc.Object.CrossSpaceSearchSubscribe.Request](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Request) + - [Rpc.Object.CrossSpaceSearchSubscribe.Response](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Response) + - [Rpc.Object.CrossSpaceSearchSubscribe.Response.Error](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Response-Error) + - [Rpc.Object.CrossSpaceSearchUnsubscribe](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe) + - [Rpc.Object.CrossSpaceSearchUnsubscribe.Request](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Request) + - [Rpc.Object.CrossSpaceSearchUnsubscribe.Response](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Response) + - [Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Response-Error) - [Rpc.Object.Duplicate](#anytype-Rpc-Object-Duplicate) - [Rpc.Object.Duplicate.Request](#anytype-Rpc-Object-Duplicate-Request) - [Rpc.Object.Duplicate.Response](#anytype-Rpc-Object-Duplicate-Response) @@ -1326,6 +1347,8 @@ - [Rpc.Chat.ToggleMessageReaction.Response.Error.Code](#anytype-Rpc-Chat-ToggleMessageReaction-Response-Error-Code) - [Rpc.Chat.Unsubscribe.Response.Error.Code](#anytype-Rpc-Chat-Unsubscribe-Response-Error-Code) - [Rpc.Debug.AccountSelectTrace.Response.Error.Code](#anytype-Rpc-Debug-AccountSelectTrace-Response-Error-Code) + - [Rpc.Debug.AnystoreObjectChanges.Request.OrderBy](#anytype-Rpc-Debug-AnystoreObjectChanges-Request-OrderBy) + - [Rpc.Debug.AnystoreObjectChanges.Response.Error.Code](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Error-Code) - [Rpc.Debug.ExportLocalstore.Response.Error.Code](#anytype-Rpc-Debug-ExportLocalstore-Response-Error-Code) - [Rpc.Debug.OpenedObjects.Response.Error.Code](#anytype-Rpc-Debug-OpenedObjects-Response-Error-Code) - [Rpc.Debug.Ping.Response.Error.Code](#anytype-Rpc-Debug-Ping-Response-Error-Code) @@ -1390,6 +1413,8 @@ - [Rpc.Object.CreateRelation.Response.Error.Code](#anytype-Rpc-Object-CreateRelation-Response-Error-Code) - [Rpc.Object.CreateRelationOption.Response.Error.Code](#anytype-Rpc-Object-CreateRelationOption-Response-Error-Code) - [Rpc.Object.CreateSet.Response.Error.Code](#anytype-Rpc-Object-CreateSet-Response-Error-Code) + - [Rpc.Object.CrossSpaceSearchSubscribe.Response.Error.Code](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Response-Error-Code) + - [Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error.Code](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Response-Error-Code) - [Rpc.Object.Duplicate.Response.Error.Code](#anytype-Rpc-Object-Duplicate-Response-Error-Code) - [Rpc.Object.Graph.Edge.Type](#anytype-Rpc-Object-Graph-Edge-Type) - [Rpc.Object.Graph.Response.Error.Code](#anytype-Rpc-Object-Graph-Response-Error-Code) @@ -1947,12 +1972,13 @@ | ObjectCreate | [Rpc.Object.Create.Request](#anytype-Rpc-Object-Create-Request) | [Rpc.Object.Create.Response](#anytype-Rpc-Object-Create-Response) | ObjectCreate just creates the new page, without adding the link to it from some other page | | ObjectCreateBookmark | [Rpc.Object.CreateBookmark.Request](#anytype-Rpc-Object-CreateBookmark-Request) | [Rpc.Object.CreateBookmark.Response](#anytype-Rpc-Object-CreateBookmark-Response) | | | ObjectCreateFromUrl | [Rpc.Object.CreateFromUrl.Request](#anytype-Rpc-Object-CreateFromUrl-Request) | [Rpc.Object.CreateFromUrl.Response](#anytype-Rpc-Object-CreateFromUrl-Response) | | -| ObjectChatAdd | [Rpc.Object.ChatAdd.Request](#anytype-Rpc-Object-ChatAdd-Request) | [Rpc.Object.ChatAdd.Response](#anytype-Rpc-Object-ChatAdd-Response) | | | ObjectCreateSet | [Rpc.Object.CreateSet.Request](#anytype-Rpc-Object-CreateSet-Request) | [Rpc.Object.CreateSet.Response](#anytype-Rpc-Object-CreateSet-Response) | ObjectCreateSet just creates the new set, without adding the link to it from some other page | | ObjectGraph | [Rpc.Object.Graph.Request](#anytype-Rpc-Object-Graph-Request) | [Rpc.Object.Graph.Response](#anytype-Rpc-Object-Graph-Response) | | | ObjectSearch | [Rpc.Object.Search.Request](#anytype-Rpc-Object-Search-Request) | [Rpc.Object.Search.Response](#anytype-Rpc-Object-Search-Response) | | | ObjectSearchWithMeta | [Rpc.Object.SearchWithMeta.Request](#anytype-Rpc-Object-SearchWithMeta-Request) | [Rpc.Object.SearchWithMeta.Response](#anytype-Rpc-Object-SearchWithMeta-Response) | | | ObjectSearchSubscribe | [Rpc.Object.SearchSubscribe.Request](#anytype-Rpc-Object-SearchSubscribe-Request) | [Rpc.Object.SearchSubscribe.Response](#anytype-Rpc-Object-SearchSubscribe-Response) | | +| ObjectCrossSpaceSearchSubscribe | [Rpc.Object.CrossSpaceSearchSubscribe.Request](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Request) | [Rpc.Object.CrossSpaceSearchSubscribe.Response](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Response) | | +| ObjectCrossSpaceSearchUnsubscribe | [Rpc.Object.CrossSpaceSearchUnsubscribe.Request](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Request) | [Rpc.Object.CrossSpaceSearchUnsubscribe.Response](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Response) | | | ObjectSubscribeIds | [Rpc.Object.SubscribeIds.Request](#anytype-Rpc-Object-SubscribeIds-Request) | [Rpc.Object.SubscribeIds.Response](#anytype-Rpc-Object-SubscribeIds-Response) | | | ObjectGroupsSubscribe | [Rpc.Object.GroupsSubscribe.Request](#anytype-Rpc-Object-GroupsSubscribe-Request) | [Rpc.Object.GroupsSubscribe.Response](#anytype-Rpc-Object-GroupsSubscribe-Response) | | | ObjectSearchUnsubscribe | [Rpc.Object.SearchUnsubscribe.Request](#anytype-Rpc-Object-SearchUnsubscribe-Request) | [Rpc.Object.SearchUnsubscribe.Response](#anytype-Rpc-Object-SearchUnsubscribe-Response) | | @@ -2126,6 +2152,7 @@ | DebugOpenedObjects | [Rpc.Debug.OpenedObjects.Request](#anytype-Rpc-Debug-OpenedObjects-Request) | [Rpc.Debug.OpenedObjects.Response](#anytype-Rpc-Debug-OpenedObjects-Response) | | | DebugRunProfiler | [Rpc.Debug.RunProfiler.Request](#anytype-Rpc-Debug-RunProfiler-Request) | [Rpc.Debug.RunProfiler.Response](#anytype-Rpc-Debug-RunProfiler-Response) | | | DebugAccountSelectTrace | [Rpc.Debug.AccountSelectTrace.Request](#anytype-Rpc-Debug-AccountSelectTrace-Request) | [Rpc.Debug.AccountSelectTrace.Response](#anytype-Rpc-Debug-AccountSelectTrace-Response) | | +| DebugAnystoreObjectChanges | [Rpc.Debug.AnystoreObjectChanges.Request](#anytype-Rpc-Debug-AnystoreObjectChanges-Request) | [Rpc.Debug.AnystoreObjectChanges.Response](#anytype-Rpc-Debug-AnystoreObjectChanges-Response) | | | MetricsSetParameters | [Rpc.Metrics.SetParameters.Request](#anytype-Rpc-Metrics-SetParameters-Request) | [Rpc.Metrics.SetParameters.Response](#anytype-Rpc-Metrics-SetParameters-Response) | | | ListenSessionEvents | [StreamRequest](#anytype-StreamRequest) | [Event](#anytype-Event) stream | used only for lib-server via grpc | | NotificationList | [Rpc.Notification.List.Request](#anytype-Rpc-Notification-List-Request) | [Rpc.Notification.List.Response](#anytype-Rpc-Notification-List-Response) | | @@ -2148,7 +2175,7 @@ | DeviceSetName | [Rpc.Device.SetName.Request](#anytype-Rpc-Device-SetName-Request) | [Rpc.Device.SetName.Response](#anytype-Rpc-Device-SetName-Response) | | | DeviceList | [Rpc.Device.List.Request](#anytype-Rpc-Device-List-Request) | [Rpc.Device.List.Response](#anytype-Rpc-Device-List-Response) | | | DeviceNetworkStateSet | [Rpc.Device.NetworkState.Set.Request](#anytype-Rpc-Device-NetworkState-Set-Request) | [Rpc.Device.NetworkState.Set.Response](#anytype-Rpc-Device-NetworkState-Set-Response) | | -| ChatAddMessage | [Rpc.Chat.AddMessage.Request](#anytype-Rpc-Chat-AddMessage-Request) | [Rpc.Chat.AddMessage.Response](#anytype-Rpc-Chat-AddMessage-Response) | Chats dummy impl | +| ChatAddMessage | [Rpc.Chat.AddMessage.Request](#anytype-Rpc-Chat-AddMessage-Request) | [Rpc.Chat.AddMessage.Response](#anytype-Rpc-Chat-AddMessage-Response) | Chats | | ChatEditMessageContent | [Rpc.Chat.EditMessageContent.Request](#anytype-Rpc-Chat-EditMessageContent-Request) | [Rpc.Chat.EditMessageContent.Response](#anytype-Rpc-Chat-EditMessageContent-Response) | | | ChatToggleMessageReaction | [Rpc.Chat.ToggleMessageReaction.Request](#anytype-Rpc-Chat-ToggleMessageReaction-Request) | [Rpc.Chat.ToggleMessageReaction.Response](#anytype-Rpc-Chat-ToggleMessageReaction-Response) | | | ChatDeleteMessage | [Rpc.Chat.DeleteMessage.Request](#anytype-Rpc-Chat-DeleteMessage-Request) | [Rpc.Chat.DeleteMessage.Response](#anytype-Rpc-Chat-DeleteMessage-Response) | | @@ -2156,6 +2183,7 @@ | ChatGetMessagesByIds | [Rpc.Chat.GetMessagesByIds.Request](#anytype-Rpc-Chat-GetMessagesByIds-Request) | [Rpc.Chat.GetMessagesByIds.Response](#anytype-Rpc-Chat-GetMessagesByIds-Response) | | | ChatSubscribeLastMessages | [Rpc.Chat.SubscribeLastMessages.Request](#anytype-Rpc-Chat-SubscribeLastMessages-Request) | [Rpc.Chat.SubscribeLastMessages.Response](#anytype-Rpc-Chat-SubscribeLastMessages-Response) | | | ChatUnsubscribe | [Rpc.Chat.Unsubscribe.Request](#anytype-Rpc-Chat-Unsubscribe-Request) | [Rpc.Chat.Unsubscribe.Response](#anytype-Rpc-Chat-Unsubscribe-Response) | | +| ObjectChatAdd | [Rpc.Object.ChatAdd.Request](#anytype-Rpc-Object-ChatAdd-Request) | [Rpc.Object.ChatAdd.Response](#anytype-Rpc-Object-ChatAdd-Response) | | @@ -2650,8 +2678,122 @@ the element of change tree used to store and internal apply smartBlock history + + + +### DocumentCreate + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| collection | [string](#string) | | | +| documentId | [string](#string) | | | +| value | [string](#string) | | json | + + + + + + + + +### DocumentDelete + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| collection | [string](#string) | | | +| documentId | [string](#string) | | | + + + + + + + + +### DocumentModify + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| collection | [string](#string) | | | +| documentId | [string](#string) | | | +| keys | [KeyModify](#anytype-KeyModify) | repeated | | + + + + + + + + +### KeyModify + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| keyPath | [string](#string) | repeated | key path; example: [user, email] | +| modifyOp | [ModifyOp](#anytype-ModifyOp) | | modify op: set, unset, inc, etc. | +| modifyValue | [string](#string) | | json value; example: '"new@email.com"' | + + + + + + + + +### StoreChange + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| changeSet | [StoreChangeContent](#anytype-StoreChangeContent) | repeated | | + + + + + + + + +### StoreChangeContent + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| create | [DocumentCreate](#anytype-DocumentCreate) | | | +| modify | [DocumentModify](#anytype-DocumentModify) | | | +| delete | [DocumentDelete](#anytype-DocumentDelete) | | | + + + + + + + + +### ModifyOp + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| Set | 0 | | +| Unset | 1 | | +| Inc | 2 | | +| AddToSet | 3 | | +| Pull | 4 | | + + @@ -10266,6 +10408,83 @@ Get marks list in the selected range in text block. + + +### Rpc.Debug.AnystoreObjectChanges + + + + + + + + + +### Rpc.Debug.AnystoreObjectChanges.Request + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| objectId | [string](#string) | | | +| orderBy | [Rpc.Debug.AnystoreObjectChanges.Request.OrderBy](#anytype-Rpc-Debug-AnystoreObjectChanges-Request-OrderBy) | | | + + + + + + + + +### Rpc.Debug.AnystoreObjectChanges.Response + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| error | [Rpc.Debug.AnystoreObjectChanges.Response.Error](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Error) | | | +| changes | [Rpc.Debug.AnystoreObjectChanges.Response.Change](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Change) | repeated | | +| wrongOrder | [bool](#bool) | | | + + + + + + + + +### Rpc.Debug.AnystoreObjectChanges.Response.Change + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| changeId | [string](#string) | | | +| orderId | [string](#string) | | | +| error | [string](#string) | | | +| change | [google.protobuf.Struct](#google-protobuf-Struct) | | | + + + + + + + + +### Rpc.Debug.AnystoreObjectChanges.Response.Error + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| code | [Rpc.Debug.AnystoreObjectChanges.Response.Error.Code](#anytype-Rpc-Debug-AnystoreObjectChanges-Response-Error-Code) | | | +| description | [string](#string) | | | + + + + + + ### Rpc.Debug.ExportLocalstore @@ -12441,6 +12660,8 @@ can be called multiple times but with some timeout (N seconds) between calls | ----- | ---- | ----- | ----------- | | email | [string](#string) | | | | subscribeToNewsletter | [bool](#bool) | | | +| insiderTipsAndTutorials | [bool](#bool) | | | +| isOnboardingList | [bool](#bool) | | if we are coming from the onboarding list | @@ -13656,6 +13877,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | templateId | [string](#string) | | | | spaceId | [string](#string) | | | | objectTypeUniqueKey | [string](#string) | | | +| withChat | [bool](#bool) | | | @@ -13716,6 +13938,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | ----- | ---- | ----- | ----------- | | details | [google.protobuf.Struct](#google-protobuf-Struct) | | | | spaceId | [string](#string) | | | +| withChat | [bool](#bool) | | | @@ -13778,6 +14001,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | url | [string](#string) | | | | details | [google.protobuf.Struct](#google-protobuf-Struct) | | | | addPageContent | [bool](#bool) | | | +| withChat | [bool](#bool) | | | @@ -13795,6 +14019,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | error | [Rpc.Object.CreateFromUrl.Response.Error](#anytype-Rpc-Object-CreateFromUrl-Response-Error) | | | | objectId | [string](#string) | | | | details | [google.protobuf.Struct](#google-protobuf-Struct) | | | +| chatId | [string](#string) | | | @@ -14019,6 +14244,7 @@ Get the info for page alongside with info for all inbound and outbound links fro | templateId | [string](#string) | | optional template id for creating from template | | internalFlags | [model.InternalFlag](#anytype-model-InternalFlag) | repeated | | | spaceId | [string](#string) | | | +| withChat | [bool](#bool) | | | @@ -14059,6 +14285,128 @@ Get the info for page alongside with info for all inbound and outbound links fro + + +### Rpc.Object.CrossSpaceSearchSubscribe + + + + + + + + + +### Rpc.Object.CrossSpaceSearchSubscribe.Request + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| subId | [string](#string) | | (optional) subscription identifier client can provide some string or middleware will generate it automatically if subId is already registered on middleware, the new query will replace previous subscription | +| filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | filters | +| sorts | [model.Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | sorts | +| keys | [string](#string) | repeated | (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent | +| source | [string](#string) | repeated | | +| noDepSubscription | [bool](#bool) | | disable dependent subscription | +| collectionId | [string](#string) | | | + + + + + + + + +### Rpc.Object.CrossSpaceSearchSubscribe.Response + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| error | [Rpc.Object.CrossSpaceSearchSubscribe.Response.Error](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Response-Error) | | | +| records | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | +| dependencies | [google.protobuf.Struct](#google-protobuf-Struct) | repeated | | +| subId | [string](#string) | | | +| counters | [Event.Object.Subscription.Counters](#anytype-Event-Object-Subscription-Counters) | | | + + + + + + + + +### Rpc.Object.CrossSpaceSearchSubscribe.Response.Error + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| code | [Rpc.Object.CrossSpaceSearchSubscribe.Response.Error.Code](#anytype-Rpc-Object-CrossSpaceSearchSubscribe-Response-Error-Code) | | | +| description | [string](#string) | | | + + + + + + + + +### Rpc.Object.CrossSpaceSearchUnsubscribe + + + + + + + + + +### Rpc.Object.CrossSpaceSearchUnsubscribe.Request + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| subId | [string](#string) | | | + + + + + + + + +### Rpc.Object.CrossSpaceSearchUnsubscribe.Response + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| error | [Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Response-Error) | | | + + + + + + + + +### Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| code | [Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error.Code](#anytype-Rpc-Object-CrossSpaceSearchUnsubscribe-Response-Error-Code) | | | +| description | [string](#string) | | | + + + + + + ### Rpc.Object.Duplicate @@ -15403,6 +15751,7 @@ deprecated in favor of SearchWithMeta | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| spaceId | [string](#string) | | | | filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | | | sorts | [model.Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | | | fullText | [string](#string) | | | @@ -15468,6 +15817,7 @@ DEPRECATED, GO-1926 | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| spaceId | [string](#string) | | | | subId | [string](#string) | | (optional) subscription identifier client can provide some string or middleware will generate it automatically if subId is already registered on middleware, the new query will replace previous subscription | | filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | filters | | sorts | [model.Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | sorts | @@ -15477,7 +15827,6 @@ DEPRECATED, GO-1926 | | afterId | [string](#string) | | (optional) pagination: middleware will return results after given id | | beforeId | [string](#string) | | (optional) pagination: middleware will return results before given id | | source | [string](#string) | repeated | | -| ignoreWorkspace | [string](#string) | | | | noDepSubscription | [bool](#bool) | | disable dependent subscription | | collectionId | [string](#string) | | | @@ -15595,6 +15944,7 @@ DEPRECATED, GO-1926 | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| spaceId | [string](#string) | | | | filters | [model.Block.Content.Dataview.Filter](#anytype-model-Block-Content-Dataview-Filter) | repeated | | | sorts | [model.Block.Content.Dataview.Sort](#anytype-model-Block-Content-Dataview-Sort) | repeated | | | fullText | [string](#string) | | | @@ -16244,10 +16594,10 @@ DEPRECATED, GO-1926 | | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | +| spaceId | [string](#string) | | | | subId | [string](#string) | | (optional) subscription identifier client can provide some string or middleware will generate it automatically if subId is already registered on middleware, the new query will replace previous subscription | | ids | [string](#string) | repeated | ids for subscribe | | keys | [string](#string) | repeated | sorts (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent | -| ignoreWorkspace | [string](#string) | | | | noDepSubscription | [bool](#bool) | | disable dependent subscription | @@ -21206,6 +21556,31 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er + + +### Rpc.Debug.AnystoreObjectChanges.Request.OrderBy + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ORDER_ID | 0 | | +| ITERATION_ORDER | 1 | | + + + + + +### Rpc.Debug.AnystoreObjectChanges.Response.Error.Code + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| NULL | 0 | | +| UNKNOWN_ERROR | 1 | | +| BAD_INPUT | 2 | | + + + ### Rpc.Debug.ExportLocalstore.Response.Error.Code @@ -22126,6 +22501,32 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er + + +### Rpc.Object.CrossSpaceSearchSubscribe.Response.Error.Code + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| NULL | 0 | | +| UNKNOWN_ERROR | 1 | | +| BAD_INPUT | 2 | ... | + + + + + +### Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error.Code + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| NULL | 0 | | +| UNKNOWN_ERROR | 1 | | +| BAD_INPUT | 2 | ... | + + + ### Rpc.Object.Duplicate.Response.Error.Code @@ -28542,7 +28943,7 @@ default dictionary with unique values to choose for select/multiSelect format | | description | [string](#string) | | | | scope | [Relation.Scope](#anytype-model-Relation-Scope) | | on-store fields, injected only locally -scope from which this relation have been aggregated | +deprecated, to be removed | | creator | [string](#string) | | creator profile id | | revision | [int64](#int64) | | revision of system relation. Used to check if we should change relation content or not | @@ -29632,6 +30033,7 @@ RelationFormat describes how the underlying data is stored in the google.protobu | DevicesObject | 536 | | | ChatObject | 537 | Container for any-store based chats | | ChatDerivedObject | 544 | Any-store based object for chat | +| AccountObject | 545 | Container for account data in tech space | diff --git a/go.mod b/go.mod index 92c1dd21e9..1313365061 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,18 @@ module github.com/anyproto/anytype-heart -go 1.22 +go 1.22.0 require ( github.com/JohannesKaufmann/html-to-markdown v1.4.0 github.com/PuerkitoBio/goquery v1.9.2 github.com/VividCortex/ewma v1.2.0 github.com/adrium/goheif v0.0.0-20230113233934-ca402e77a786 - github.com/anyproto/any-store v0.0.6 - github.com/anyproto/any-sync v0.4.30 + github.com/anyproto/any-store v0.1.1 + github.com/anyproto/any-sync v0.5.5 github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438 - github.com/anyproto/tantivy-go v0.1.0 + github.com/anyproto/lexid v0.0.2 + github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5 + github.com/anyproto/tantivy-go v0.1.3 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/avast/retry-go/v4 v4.6.0 github.com/blevesearch/bleve/v2 v2.3.10 @@ -58,7 +60,7 @@ require ( github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e github.com/kelseyhightower/envconfig v1.4.0 github.com/klauspost/compress v1.17.11 - github.com/libp2p/go-libp2p v0.35.1 + github.com/libp2p/go-libp2p v0.36.5 github.com/libp2p/zeroconf/v2 v2.2.0 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/magiconair/properties v1.8.7 @@ -95,7 +97,7 @@ require ( go.uber.org/mock v0.5.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/image v0.21.0 golang.org/x/mobile v0.0.0-20240806205939-81131f6468ab golang.org/x/net v0.30.0 @@ -105,6 +107,7 @@ require ( gopkg.in/Graylog2/go-gelf.v2 v2.0.0-20180125164251-1832d8546a9f gopkg.in/yaml.v3 v3.0.1 storj.io/drpc v0.0.34 + zombiezen.com/go/sqlite v1.4.0 ) @@ -161,11 +164,11 @@ require ( github.com/fogleman/gg v1.3.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-errors/errors v1.4.2 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-shiori/dom v0.0.0-20210627111528-4e4722cd0d65 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/googleapis v1.3.1 // indirect @@ -176,7 +179,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v1.12.1 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c // indirect github.com/gorilla/css v1.0.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect @@ -202,12 +205,12 @@ require ( github.com/jbenet/goprocess v0.1.4 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -224,7 +227,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-proto-validators v0.3.2 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/onsi/ginkgo/v2 v2.17.1 // indirect + github.com/onsi/ginkgo/v2 v2.19.1 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -234,7 +237,7 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/pseudomuto/protokit v0.2.1 // indirect - github.com/quic-go/quic-go v0.46.0 // indirect + github.com/quic-go/quic-go v0.47.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rs/cors v1.7.0 // indirect github.com/rs/zerolog v1.29.0 // indirect @@ -263,24 +266,23 @@ require ( go.opentelemetry.io/otel v1.14.0 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect golang.org/x/crypto v0.28.0 // indirect - golang.org/x/mod v0.20.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect - golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.24.0 // indirect + golang.org/x/time v0.6.0 // indirect + golang.org/x/tools v0.26.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - lukechampine.com/blake3 v1.2.1 // indirect - modernc.org/libc v1.60.1 // indirect + lukechampine.com/blake3 v1.3.0 // indirect + modernc.org/libc v1.61.0 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect - modernc.org/sqlite v1.32.0 // indirect + modernc.org/sqlite v1.33.1 // indirect nhooyr.io/websocket v1.8.7 // indirect - zombiezen.com/go/sqlite v1.3.0 // indirect ) replace github.com/dgraph-io/badger/v4 => github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580 diff --git a/go.sum b/go.sum index 969b8b7a92..59b006c90d 100644 --- a/go.sum +++ b/go.sum @@ -83,10 +83,10 @@ github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxB github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= -github.com/anyproto/any-store v0.0.6 h1:FOBtNL6osrlzBu4wmiFqKZOa8pkL5Ena2LfVser8nig= -github.com/anyproto/any-store v0.0.6/go.mod h1:MA3sSqRXIp0h9bC2LnMuDGVEFGB3BkI/UuWNCleGHMs= -github.com/anyproto/any-sync v0.4.30 h1:2nnoVQF9WiBIw8pzwuOubwqf7a+xvZPDkXHmykTPi0k= -github.com/anyproto/any-sync v0.4.30/go.mod h1:YjwTdTRL6b6GuutJNboJJ1M5D/kkdeSf9qF5xP6wG7Y= +github.com/anyproto/any-store v0.1.1 h1:dZJt/ELKHzP0P6G3mT/Ch6CnX0pSHTAGpZYuBPCw2hA= +github.com/anyproto/any-store v0.1.1/go.mod h1:SDlN2AzysAfs8CDd28rrs6boUUtf5H/ydCvwmj+EbsE= +github.com/anyproto/any-sync v0.5.5 h1:StWApo7eE9dzWw/PtGkEayEsrO7dbFid0dDRsq3DVio= +github.com/anyproto/any-sync v0.5.5/go.mod h1:jXPhT2kjMVIPKEJZ/mW3NTP5j4Xsg4J5cp/ILGc/60A= github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580 h1:Ba80IlCCxkZ9H1GF+7vFu/TSpPvbpDCxXJ5ogc4euYc= github.com/anyproto/badger/v4 v4.2.1-0.20240110160636-80743fa3d580/go.mod h1:T/uWAYxrXdaXw64ihI++9RMbKTCpKd/yE9+saARew7k= github.com/anyproto/go-chash v0.1.0 h1:I9meTPjXFRfXZHRJzjOHC/XF7Q5vzysKkiT/grsogXY= @@ -105,12 +105,16 @@ github.com/anyproto/go-slip21 v1.0.0 h1:CI7lUqTIwmPOEGVAj4jyNLoICvueh++0U2HoAi3m github.com/anyproto/go-slip21 v1.0.0/go.mod h1:gbIJt7HAdr5DuT4f2pFTKCBSUWYsm/fysHBNqgsuxT0= github.com/anyproto/html-to-markdown v0.0.0-20231025221133-830bf0a6f139 h1:Wp9z0Q2kAstznWUmTZyOb9UgpVmUgYt1LXRvK/cg10E= github.com/anyproto/html-to-markdown v0.0.0-20231025221133-830bf0a6f139/go.mod h1:1zaDDQVWTRwNksmTUTkcVXqgNF28YHiEUIm8FL9Z+II= +github.com/anyproto/lexid v0.0.2 h1:sYMbqBEOwAK+0JlX360oPPCqV4b2N7NtVhvT4gZD+5w= +github.com/anyproto/lexid v0.0.2/go.mod h1:2RfpYiZkgoNmSDklXdwCCwGlso1FIp9Te8ZtoF3/Ehg= github.com/anyproto/protobuf v1.3.3-0.20240201225420-6e325cf0ac38 h1:80jke82/c+bNQQpnx4VO3Mi/lAxARyyfUpZvFaPxdzE= github.com/anyproto/protobuf v1.3.3-0.20240201225420-6e325cf0ac38/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5 h1:aY7tBzQ+z8Hr/v8vOL4/EaKwPZx+J/ClZ1WuD6sqPvE= +github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5/go.mod h1:5+PHE01DgsDPkralb8MYmGg2sPQahsqEJ9ue7ciDHKg= github.com/anyproto/ristretto v0.1.2-0.20240221153107-2b23839cc50c h1:GicoaTUyB2mtCIl3YMrO0OzysqRT5GA4vuvDsqEkhSM= github.com/anyproto/ristretto v0.1.2-0.20240221153107-2b23839cc50c/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/anyproto/tantivy-go v0.1.0 h1:5SuItuJnYAEK9U6cfxPnwFUXGboURIwF4JAp7s46rII= -github.com/anyproto/tantivy-go v0.1.0/go.mod h1:Pl0zaeEX7dkVDTDKROzlLlGCVjbZHjyPrZloFuVEASc= +github.com/anyproto/tantivy-go v0.1.3 h1:kAaRiHNtoi3o6+FdQCBaUds21GWmZnrIje4eYU+01S0= +github.com/anyproto/tantivy-go v0.1.3/go.mod h1:Pl0zaeEX7dkVDTDKROzlLlGCVjbZHjyPrZloFuVEASc= github.com/anyproto/zeroconf/v2 v2.2.1-0.20240228113933-f90a5cc4439d h1:5bj7nX/AS8sxGpTIrapE7PC4oPlhkHMwMqXlJbUHBlg= github.com/anyproto/zeroconf/v2 v2.2.1-0.20240228113933-f90a5cc4439d/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -358,8 +362,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= @@ -378,22 +382,19 @@ github.com/go-shiori/go-readability v0.0.0-20220215145315-dd6828d2f09b h1:yrGomo github.com/go-shiori/go-readability v0.0.0-20220215145315-dd6828d2f09b/go.mod h1:LTRGsNyO3/Y6u3ERbz17OiXy2qO1Y+/8QjXpg2ViyEY= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= -github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= -github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gobwas/ws v1.2.1 h1:F2aeBZrm2NDsc7vbovKrWSogd4wvfAxg0FQ89/iqOTk= -github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-graphviz v0.1.3 h1:Pkt8y4FBnBNI9tfSobpoN5qy1qMNqRXPQYvLhaSUasY= github.com/goccy/go-graphviz v0.1.3/go.mod h1:pMYpbAqJT10V8dzV1JN/g/wUlG/0imKPzn3ZsrchGCI= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -490,8 +491,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= -github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -513,8 +514,8 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= @@ -760,8 +761,8 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -802,8 +803,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw= github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o= github.com/libp2p/go-libp2p v0.13.0/go.mod h1:pM0beYdACRfHO1WcJlp65WXyG2A6NqYM+t2DTVAJxMo= -github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= -github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= +github.com/libp2p/go-libp2p v0.36.5 h1:DoABsaHO0VXwH6pwCs2F6XKAXWYjFMO4HFBoVxTnF9g= +github.com/libp2p/go-libp2p v0.36.5/go.mod h1:CpszAtXxHYOcyvB7K8rSHgnNlh21eKjYbEfLoMerbEI= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= @@ -1002,8 +1003,8 @@ github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= @@ -1121,14 +1122,14 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= +github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb h1:JF9kOhBBk4WPF7luXFu5yR+WgaFm9L/KiHJHhU9vDwA= github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -1165,12 +1166,12 @@ github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= -github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -1181,22 +1182,22 @@ github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= +github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.40 h1:Wtfi6AZMQg+624cvCXUuSmrKWepSB7zfgYDOYqsSOVU= -github.com/pion/webrtc/v3 v3.2.40/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -1252,10 +1253,10 @@ github.com/pseudomuto/protoc-gen-doc v1.5.1 h1:Ah259kcrio7Ix1Rhb6u8FCaOkzf9qRBqX github.com/pseudomuto/protoc-gen-doc v1.5.1/go.mod h1:XpMKYg6zkcpgfpCfQ8GcWBDRtRxOmMR5w7pz4Xo+dYM= github.com/pseudomuto/protokit v0.2.1 h1:kCYpE3thoR6Esm0CUvd5xbrDTOZPvQPTDeyXpZfrJdk= github.com/pseudomuto/protokit v0.2.1/go.mod h1:gt7N5Rz2flBzYafvaxyIxMZC0TTF5jDZfRnw25hAAyo= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= -github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.47.0 h1:yXs3v7r2bm1wmPTYNLKAAJTHMYkPEsfYJmTazXrCZ7Y= +github.com/quic-go/quic-go v0.47.0/go.mod h1:3bCapYsJvXGZcipOHuu7plYtaV6tnF+z7wIFsU0WK9E= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1417,6 +1418,8 @@ github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvX github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1537,8 +1540,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= -golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1571,8 +1574,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1785,8 +1788,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1849,8 +1852,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2012,8 +2015,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= @@ -2022,8 +2025,8 @@ modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= modernc.org/gc/v2 v2.5.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= -modernc.org/libc v1.60.1 h1:at373l8IFRTkJIkAU85BIuUoBM4T1b51ds0E1ovPG2s= -modernc.org/libc v1.60.1/go.mod h1:xJuobKuNxKH3RUatS7GjR+suWj+5c2K7bi4m/S5arOY= +modernc.org/libc v1.61.0 h1:eGFcvWpqlnoGwzZeZe3PWJkkKbM/3SUGyk1DVZQ0TpE= +modernc.org/libc v1.61.0/go.mod h1:DvxVX89wtGTu+r72MLGhygpfi3aUGgZRdAYGCAVVud0= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -2032,8 +2035,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= -modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM= +modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= @@ -2049,5 +2052,5 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= storj.io/drpc v0.0.34 h1:q9zlQKfJ5A7x8NQNFk8x7eKUF78FMhmAbZLnFK+og7I= storj.io/drpc v0.0.34/go.mod h1:Y9LZaa8esL1PW2IDMqJE7CFSNq7d5bQ3RI7mGPtmKMg= -zombiezen.com/go/sqlite v1.3.0 h1:98g1gnCm+CNz6AuQHu0gqyw7gR2WU3O3PJufDOStpUs= -zombiezen.com/go/sqlite v1.3.0/go.mod h1:yRl27//s/9aXU3RWs8uFQwjkTG9gYNGEls6+6SvrclY= +zombiezen.com/go/sqlite v1.4.0 h1:N1s3RIljwtp4541Y8rM880qgGIgq3fTD2yks1xftnKU= +zombiezen.com/go/sqlite v1.4.0/go.mod h1:0w9F1DN9IZj9AcLS9YDKMboubCACkwYCGkzoy3eG5ik= diff --git a/metrics/anymetry/client.go b/metrics/anymetry/client.go index 8af9ca572a..09cf2943ae 100644 --- a/metrics/anymetry/client.go +++ b/metrics/anymetry/client.go @@ -97,6 +97,10 @@ func (c *Client) SendEvents(amplEvents []Event, info AppInfoProvider) error { amIndex++ } + if amIndex == 0 { + return nil + } + reqJSON.Set("events", events) evJSON := reqJSON.MarshalTo(nil) diff --git a/metrics/client.go b/metrics/client.go index d6ad30ca79..062dc9c9c0 100644 --- a/metrics/client.go +++ b/metrics/client.go @@ -132,9 +132,6 @@ func (c *client) sendNextBatch(info anymetry.AppInfoProvider, batcher *mb.MB[any err = c.telemetry.SendEvents(msgs, info) if err != nil { - clientMetricsLog. - With("unsent messages", len(msgs)+clientBatcher.Len()). - Error("failed to send messages") if batcher != nil { _ = batcher.TryAdd(msgs...) //nolint:errcheck } diff --git a/pb/changes.pb.go b/pb/changes.pb.go index 9f3f959729..0b240e616c 100644 --- a/pb/changes.pb.go +++ b/pb/changes.pb.go @@ -24,6 +24,40 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type ModifyOp int32 + +const ( + ModifyOp_Set ModifyOp = 0 + ModifyOp_Unset ModifyOp = 1 + ModifyOp_Inc ModifyOp = 2 + ModifyOp_AddToSet ModifyOp = 3 + ModifyOp_Pull ModifyOp = 4 +) + +var ModifyOp_name = map[int32]string{ + 0: "Set", + 1: "Unset", + 2: "Inc", + 3: "AddToSet", + 4: "Pull", +} + +var ModifyOp_value = map[string]int32{ + "Set": 0, + "Unset": 1, + "Inc": 2, + "AddToSet": 3, + "Pull": 4, +} + +func (x ModifyOp) String() string { + return proto.EnumName(ModifyOp_name, int32(x)) +} + +func (ModifyOp) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{0} +} + // the element of change tree used to store and internal apply smartBlock history type Change struct { // ids of previous changes @@ -1753,7 +1787,386 @@ func (m *ChangeDeviceUpdate) GetName() string { return "" } +type StoreChange struct { + ChangeSet []*StoreChangeContent `protobuf:"bytes,1,rep,name=changeSet,proto3" json:"changeSet,omitempty"` +} + +func (m *StoreChange) Reset() { *m = StoreChange{} } +func (m *StoreChange) String() string { return proto.CompactTextString(m) } +func (*StoreChange) ProtoMessage() {} +func (*StoreChange) Descriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{1} +} +func (m *StoreChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StoreChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StoreChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StoreChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_StoreChange.Merge(m, src) +} +func (m *StoreChange) XXX_Size() int { + return m.Size() +} +func (m *StoreChange) XXX_DiscardUnknown() { + xxx_messageInfo_StoreChange.DiscardUnknown(m) +} + +var xxx_messageInfo_StoreChange proto.InternalMessageInfo + +func (m *StoreChange) GetChangeSet() []*StoreChangeContent { + if m != nil { + return m.ChangeSet + } + return nil +} + +type StoreChangeContent struct { + // Types that are valid to be assigned to Change: + // *StoreChangeContentChangeOfCreate + // *StoreChangeContentChangeOfModify + // *StoreChangeContentChangeOfDelete + Change IsStoreChangeContentChange `protobuf_oneof:"change"` +} + +func (m *StoreChangeContent) Reset() { *m = StoreChangeContent{} } +func (m *StoreChangeContent) String() string { return proto.CompactTextString(m) } +func (*StoreChangeContent) ProtoMessage() {} +func (*StoreChangeContent) Descriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{2} +} +func (m *StoreChangeContent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StoreChangeContent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StoreChangeContent.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *StoreChangeContent) XXX_Merge(src proto.Message) { + xxx_messageInfo_StoreChangeContent.Merge(m, src) +} +func (m *StoreChangeContent) XXX_Size() int { + return m.Size() +} +func (m *StoreChangeContent) XXX_DiscardUnknown() { + xxx_messageInfo_StoreChangeContent.DiscardUnknown(m) +} + +var xxx_messageInfo_StoreChangeContent proto.InternalMessageInfo + +type IsStoreChangeContentChange interface { + IsStoreChangeContentChange() + MarshalTo([]byte) (int, error) + Size() int +} + +type StoreChangeContentChangeOfCreate struct { + Create *DocumentCreate `protobuf:"bytes,1,opt,name=create,proto3,oneof" json:"create,omitempty"` +} +type StoreChangeContentChangeOfModify struct { + Modify *DocumentModify `protobuf:"bytes,2,opt,name=modify,proto3,oneof" json:"modify,omitempty"` +} +type StoreChangeContentChangeOfDelete struct { + Delete *DocumentDelete `protobuf:"bytes,3,opt,name=delete,proto3,oneof" json:"delete,omitempty"` +} + +func (*StoreChangeContentChangeOfCreate) IsStoreChangeContentChange() {} +func (*StoreChangeContentChangeOfModify) IsStoreChangeContentChange() {} +func (*StoreChangeContentChangeOfDelete) IsStoreChangeContentChange() {} + +func (m *StoreChangeContent) GetChange() IsStoreChangeContentChange { + if m != nil { + return m.Change + } + return nil +} + +func (m *StoreChangeContent) GetCreate() *DocumentCreate { + if x, ok := m.GetChange().(*StoreChangeContentChangeOfCreate); ok { + return x.Create + } + return nil +} + +func (m *StoreChangeContent) GetModify() *DocumentModify { + if x, ok := m.GetChange().(*StoreChangeContentChangeOfModify); ok { + return x.Modify + } + return nil +} + +func (m *StoreChangeContent) GetDelete() *DocumentDelete { + if x, ok := m.GetChange().(*StoreChangeContentChangeOfDelete); ok { + return x.Delete + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*StoreChangeContent) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*StoreChangeContentChangeOfCreate)(nil), + (*StoreChangeContentChangeOfModify)(nil), + (*StoreChangeContentChangeOfDelete)(nil), + } +} + +type DocumentCreate struct { + Collection string `protobuf:"bytes,1,opt,name=collection,proto3" json:"collection,omitempty"` + DocumentId string `protobuf:"bytes,2,opt,name=documentId,proto3" json:"documentId,omitempty"` + // json + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (m *DocumentCreate) Reset() { *m = DocumentCreate{} } +func (m *DocumentCreate) String() string { return proto.CompactTextString(m) } +func (*DocumentCreate) ProtoMessage() {} +func (*DocumentCreate) Descriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{3} +} +func (m *DocumentCreate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DocumentCreate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DocumentCreate.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DocumentCreate) XXX_Merge(src proto.Message) { + xxx_messageInfo_DocumentCreate.Merge(m, src) +} +func (m *DocumentCreate) XXX_Size() int { + return m.Size() +} +func (m *DocumentCreate) XXX_DiscardUnknown() { + xxx_messageInfo_DocumentCreate.DiscardUnknown(m) +} + +var xxx_messageInfo_DocumentCreate proto.InternalMessageInfo + +func (m *DocumentCreate) GetCollection() string { + if m != nil { + return m.Collection + } + return "" +} + +func (m *DocumentCreate) GetDocumentId() string { + if m != nil { + return m.DocumentId + } + return "" +} + +func (m *DocumentCreate) GetValue() string { + if m != nil { + return m.Value + } + return "" +} + +type DocumentModify struct { + Collection string `protobuf:"bytes,1,opt,name=collection,proto3" json:"collection,omitempty"` + DocumentId string `protobuf:"bytes,2,opt,name=documentId,proto3" json:"documentId,omitempty"` + Keys []*KeyModify `protobuf:"bytes,4,rep,name=keys,proto3" json:"keys,omitempty"` +} + +func (m *DocumentModify) Reset() { *m = DocumentModify{} } +func (m *DocumentModify) String() string { return proto.CompactTextString(m) } +func (*DocumentModify) ProtoMessage() {} +func (*DocumentModify) Descriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{4} +} +func (m *DocumentModify) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DocumentModify) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DocumentModify.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DocumentModify) XXX_Merge(src proto.Message) { + xxx_messageInfo_DocumentModify.Merge(m, src) +} +func (m *DocumentModify) XXX_Size() int { + return m.Size() +} +func (m *DocumentModify) XXX_DiscardUnknown() { + xxx_messageInfo_DocumentModify.DiscardUnknown(m) +} + +var xxx_messageInfo_DocumentModify proto.InternalMessageInfo + +func (m *DocumentModify) GetCollection() string { + if m != nil { + return m.Collection + } + return "" +} + +func (m *DocumentModify) GetDocumentId() string { + if m != nil { + return m.DocumentId + } + return "" +} + +func (m *DocumentModify) GetKeys() []*KeyModify { + if m != nil { + return m.Keys + } + return nil +} + +type KeyModify struct { + // key path; example: [user, email] + KeyPath []string `protobuf:"bytes,1,rep,name=keyPath,proto3" json:"keyPath,omitempty"` + // modify op: set, unset, inc, etc. + ModifyOp ModifyOp `protobuf:"varint,3,opt,name=modifyOp,proto3,enum=anytype.ModifyOp" json:"modifyOp,omitempty"` + // json value; example: '"new@email.com"' + ModifyValue string `protobuf:"bytes,4,opt,name=modifyValue,proto3" json:"modifyValue,omitempty"` +} + +func (m *KeyModify) Reset() { *m = KeyModify{} } +func (m *KeyModify) String() string { return proto.CompactTextString(m) } +func (*KeyModify) ProtoMessage() {} +func (*KeyModify) Descriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{5} +} +func (m *KeyModify) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *KeyModify) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_KeyModify.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *KeyModify) XXX_Merge(src proto.Message) { + xxx_messageInfo_KeyModify.Merge(m, src) +} +func (m *KeyModify) XXX_Size() int { + return m.Size() +} +func (m *KeyModify) XXX_DiscardUnknown() { + xxx_messageInfo_KeyModify.DiscardUnknown(m) +} + +var xxx_messageInfo_KeyModify proto.InternalMessageInfo + +func (m *KeyModify) GetKeyPath() []string { + if m != nil { + return m.KeyPath + } + return nil +} + +func (m *KeyModify) GetModifyOp() ModifyOp { + if m != nil { + return m.ModifyOp + } + return ModifyOp_Set +} + +func (m *KeyModify) GetModifyValue() string { + if m != nil { + return m.ModifyValue + } + return "" +} + +type DocumentDelete struct { + Collection string `protobuf:"bytes,1,opt,name=collection,proto3" json:"collection,omitempty"` + DocumentId string `protobuf:"bytes,2,opt,name=documentId,proto3" json:"documentId,omitempty"` +} + +func (m *DocumentDelete) Reset() { *m = DocumentDelete{} } +func (m *DocumentDelete) String() string { return proto.CompactTextString(m) } +func (*DocumentDelete) ProtoMessage() {} +func (*DocumentDelete) Descriptor() ([]byte, []int) { + return fileDescriptor_2b02bba284ea1e46, []int{6} +} +func (m *DocumentDelete) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DocumentDelete) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DocumentDelete.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DocumentDelete) XXX_Merge(src proto.Message) { + xxx_messageInfo_DocumentDelete.Merge(m, src) +} +func (m *DocumentDelete) XXX_Size() int { + return m.Size() +} +func (m *DocumentDelete) XXX_DiscardUnknown() { + xxx_messageInfo_DocumentDelete.DiscardUnknown(m) +} + +var xxx_messageInfo_DocumentDelete proto.InternalMessageInfo + +func (m *DocumentDelete) GetCollection() string { + if m != nil { + return m.Collection + } + return "" +} + +func (m *DocumentDelete) GetDocumentId() string { + if m != nil { + return m.DocumentId + } + return "" +} + func init() { + proto.RegisterEnum("anytype.ModifyOp", ModifyOp_name, ModifyOp_value) proto.RegisterType((*Change)(nil), "anytype.Change") proto.RegisterType((*ChangeSnapshot)(nil), "anytype.Change.Snapshot") proto.RegisterMapType((map[string]string)(nil), "anytype.Change.Snapshot.LogHeadsEntry") @@ -1783,100 +2196,121 @@ func init() { proto.RegisterType((*ChangeNotificationUpdate)(nil), "anytype.Change.NotificationUpdate") proto.RegisterType((*ChangeDeviceAdd)(nil), "anytype.Change.DeviceAdd") proto.RegisterType((*ChangeDeviceUpdate)(nil), "anytype.Change.DeviceUpdate") + proto.RegisterType((*StoreChange)(nil), "anytype.StoreChange") + proto.RegisterType((*StoreChangeContent)(nil), "anytype.StoreChangeContent") + proto.RegisterType((*DocumentCreate)(nil), "anytype.DocumentCreate") + proto.RegisterType((*DocumentModify)(nil), "anytype.DocumentModify") + proto.RegisterType((*KeyModify)(nil), "anytype.KeyModify") + proto.RegisterType((*DocumentDelete)(nil), "anytype.DocumentDelete") } func init() { proto.RegisterFile("pb/protos/changes.proto", fileDescriptor_2b02bba284ea1e46) } var fileDescriptor_2b02bba284ea1e46 = []byte{ - // 1397 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0x4d, 0x93, 0xd3, 0x46, - 0x13, 0xb6, 0x6c, 0xe3, 0x8f, 0xd6, 0xae, 0x5f, 0xbf, 0x53, 0x14, 0x08, 0xed, 0xc6, 0x38, 0x04, - 0x12, 0x57, 0x42, 0xb4, 0x85, 0x37, 0x45, 0xf8, 0x48, 0x42, 0x61, 0x20, 0xe5, 0x05, 0x16, 0xa8, - 0x31, 0xe4, 0x90, 0x0b, 0x91, 0xad, 0x59, 0x5b, 0xac, 0x2c, 0x29, 0xd2, 0xd8, 0x55, 0x3e, 0xe6, - 0x17, 0x24, 0x95, 0xff, 0x94, 0xaa, 0x1c, 0x39, 0xe6, 0x98, 0x82, 0x7b, 0x7e, 0x41, 0x0e, 0xa9, - 0x19, 0xcd, 0xe8, 0xcb, 0xf2, 0x2e, 0x1c, 0x92, 0x8b, 0x4b, 0x3d, 0xf3, 0x3c, 0xcf, 0x74, 0xf7, - 0xcc, 0x74, 0x8f, 0xe1, 0xbc, 0x3f, 0xde, 0xf3, 0x03, 0x8f, 0x7a, 0xe1, 0xde, 0x64, 0x66, 0xba, - 0x53, 0x12, 0x1a, 0xdc, 0x44, 0x75, 0xd3, 0x5d, 0xd1, 0x95, 0x4f, 0xf4, 0xcb, 0xfe, 0xf1, 0x74, - 0xcf, 0xb1, 0xc7, 0x7b, 0xfe, 0x78, 0x6f, 0xee, 0x59, 0xc4, 0x91, 0x78, 0x6e, 0x08, 0xb8, 0x7e, - 0x2e, 0xd1, 0x21, 0x4b, 0xe2, 0x52, 0x39, 0xbe, 0x3b, 0xf5, 0xbc, 0xa9, 0x43, 0xa2, 0xb9, 0xf1, - 0xe2, 0x68, 0x2f, 0xa4, 0xc1, 0x62, 0x42, 0xa3, 0xd9, 0x4b, 0x3f, 0x5d, 0x84, 0xda, 0x3d, 0xbe, - 0x2c, 0xfa, 0x10, 0xb6, 0xfc, 0x80, 0x2c, 0x6d, 0x6f, 0x11, 0xbe, 0xb4, 0xad, 0x50, 0x53, 0xba, - 0x95, 0x5e, 0x13, 0xab, 0x72, 0xec, 0xc0, 0x0a, 0x51, 0x0f, 0xda, 0x8e, 0x19, 0xd2, 0x97, 0xa1, - 0x6b, 0xfa, 0xe1, 0xcc, 0xa3, 0x2f, 0x6d, 0x4b, 0x2b, 0x77, 0x95, 0x5e, 0x13, 0xb7, 0xd8, 0xf8, - 0x48, 0x0c, 0x1f, 0x58, 0xe8, 0x53, 0xf8, 0x7f, 0x2c, 0x36, 0x27, 0xd4, 0xe4, 0x8a, 0x67, 0xb8, - 0xe2, 0xff, 0xe4, 0xc4, 0x21, 0xa1, 0x26, 0x53, 0xbd, 0x06, 0xf5, 0x89, 0xe7, 0x52, 0xe2, 0x52, - 0xad, 0xd2, 0xad, 0xf4, 0xd4, 0xfe, 0x79, 0x43, 0x84, 0x6e, 0x44, 0xae, 0x19, 0xf7, 0xa2, 0x69, - 0x2c, 0x71, 0xe8, 0x0b, 0x68, 0x48, 0x1f, 0xb4, 0x6a, 0x57, 0xe9, 0xa9, 0x7d, 0x2d, 0xcf, 0x91, - 0xce, 0xe0, 0x18, 0xc9, 0x58, 0x47, 0xb6, 0x43, 0x1e, 0x91, 0x55, 0xa8, 0xd5, 0xf8, 0x4a, 0x6b, - 0xac, 0x6f, 0xc5, 0x3c, 0x8e, 0x91, 0x68, 0x17, 0x9a, 0xd4, 0x9e, 0x93, 0x90, 0x9a, 0x73, 0x5f, - 0xab, 0x77, 0x95, 0x5e, 0x05, 0x27, 0x03, 0x48, 0x83, 0xfa, 0x92, 0x04, 0xa1, 0xed, 0xb9, 0x5a, - 0xa3, 0xab, 0xf4, 0xb6, 0xb1, 0x34, 0xf5, 0xbf, 0x15, 0x68, 0x48, 0x27, 0xd0, 0x00, 0x1a, 0x8e, - 0x37, 0x1d, 0x12, 0x53, 0x24, 0x56, 0xed, 0x7f, 0xbc, 0xc9, 0x61, 0xe3, 0xb1, 0x00, 0x3e, 0x70, - 0x69, 0xb0, 0xc2, 0x31, 0x0f, 0xdd, 0x84, 0xaa, 0x65, 0x52, 0x93, 0x67, 0x5c, 0xed, 0x5f, 0x89, - 0xf9, 0xfc, 0x18, 0x18, 0xa3, 0xb9, 0x19, 0xd0, 0x81, 0xe3, 0x4d, 0x8e, 0xa5, 0xd0, 0xc0, 0x0c, - 0x09, 0xe6, 0x94, 0x4c, 0xe4, 0x95, 0x77, 0x8d, 0x5c, 0xbf, 0x0d, 0xdb, 0x19, 0x5f, 0x50, 0x1b, - 0x2a, 0xc7, 0x64, 0xa5, 0x29, 0x7c, 0xcb, 0xd9, 0x27, 0x3a, 0x0b, 0x67, 0x96, 0xa6, 0xb3, 0x20, - 0xe2, 0x18, 0x44, 0xc6, 0xad, 0xf2, 0x0d, 0x45, 0xff, 0x59, 0x81, 0x86, 0xd4, 0x44, 0x08, 0xaa, - 0x33, 0x33, 0x9c, 0x09, 0x26, 0xff, 0x46, 0xd7, 0xa1, 0x7a, 0xcc, 0xfc, 0x29, 0x73, 0x7f, 0x2e, - 0x6d, 0xf2, 0xc7, 0x60, 0x3f, 0x51, 0x2a, 0x38, 0x5e, 0xff, 0x12, 0x9a, 0xf1, 0xd0, 0x7b, 0x79, - 0xf4, 0x9b, 0x0a, 0x75, 0x71, 0x92, 0xd0, 0x1d, 0x50, 0xc7, 0x2c, 0x57, 0xf7, 0x02, 0x62, 0x52, - 0xc2, 0xf9, 0x6a, 0x7f, 0x27, 0xef, 0xc3, 0x20, 0x81, 0x0c, 0x4b, 0x38, 0xcd, 0x88, 0x05, 0x5e, - 0xf8, 0x16, 0x13, 0x28, 0x9f, 0x20, 0x10, 0x41, 0x62, 0x81, 0xc8, 0x8c, 0x05, 0x30, 0x99, 0x7b, - 0x4b, 0xa2, 0x55, 0x4e, 0x10, 0x88, 0x20, 0xb1, 0x40, 0x64, 0xa2, 0x9b, 0xd0, 0xe4, 0xe6, 0x21, - 0xa3, 0x47, 0x97, 0xe0, 0x42, 0x21, 0xfd, 0x30, 0x22, 0x27, 0x68, 0x34, 0x84, 0x16, 0x37, 0xee, - 0x2f, 0x7c, 0xc7, 0x9e, 0x30, 0xff, 0xcf, 0x70, 0x7e, 0xa7, 0x90, 0x1f, 0xa3, 0x86, 0x25, 0x9c, - 0xe3, 0xb1, 0x28, 0x02, 0xe2, 0x98, 0xd4, 0xf6, 0xdc, 0xbb, 0x96, 0xa5, 0xf5, 0x8b, 0xa3, 0xc0, - 0x09, 0x84, 0x45, 0x91, 0x62, 0x30, 0x57, 0xa4, 0x29, 0x32, 0xb1, 0x5f, 0xec, 0x0a, 0xce, 0xa0, - 0x98, 0x2b, 0x59, 0x1e, 0xfa, 0x0a, 0xc0, 0x22, 0xd4, 0xb4, 0x9d, 0x70, 0x44, 0xa8, 0x66, 0x71, - 0x15, 0x3d, 0xaf, 0x72, 0x3f, 0x46, 0x0c, 0x4b, 0x38, 0x85, 0x47, 0x03, 0xd8, 0x12, 0xd6, 0x0b, - 0x37, 0x24, 0x54, 0x23, 0x9c, 0xbf, 0xbb, 0x81, 0xcf, 0x31, 0xc3, 0x12, 0xce, 0x70, 0xd0, 0x03, - 0xd8, 0xf6, 0xc6, 0xaf, 0xc8, 0x84, 0x3e, 0x5f, 0xf9, 0x84, 0xa5, 0xc3, 0xe6, 0x22, 0x1f, 0xe4, - 0x45, 0x9e, 0xa6, 0x41, 0xc3, 0x12, 0xce, 0xb2, 0xd0, 0x13, 0x68, 0x27, 0x03, 0x22, 0x29, 0xaf, - 0xb8, 0x52, 0x77, 0xb3, 0x52, 0x9c, 0x96, 0x35, 0x2e, 0xdb, 0xa3, 0x90, 0x7a, 0x01, 0xbb, 0x4d, - 0x2c, 0x33, 0xc7, 0xc5, 0x7b, 0x34, 0x4a, 0x20, 0x6c, 0x8f, 0x52, 0x0c, 0x16, 0x97, 0x34, 0xa3, - 0xe4, 0x38, 0xc5, 0x71, 0x8d, 0xd2, 0x20, 0x16, 0x57, 0x86, 0xc5, 0xe2, 0xe2, 0x03, 0x23, 0xc7, - 0x9e, 0x10, 0x71, 0x6f, 0xe6, 0xc5, 0x71, 0x8d, 0x72, 0x38, 0x16, 0x57, 0x9e, 0x8b, 0x3c, 0xd8, - 0xf1, 0x02, 0x7b, 0x6a, 0xbb, 0xa6, 0x13, 0x5d, 0x4a, 0xeb, 0xb9, 0x2c, 0xcb, 0x2c, 0x4e, 0x97, - 0x4b, 0x7f, 0xb6, 0x96, 0xb2, 0xcd, 0x94, 0x61, 0x09, 0x9f, 0xa4, 0xc8, 0x13, 0x49, 0x28, 0x2b, - 0x4c, 0x07, 0xee, 0x91, 0xa7, 0x79, 0x1b, 0x12, 0x99, 0x40, 0x78, 0x22, 0x13, 0x13, 0x3d, 0x07, - 0xe4, 0x7a, 0xd4, 0x3e, 0x62, 0x77, 0xc7, 0xf6, 0x5c, 0x51, 0x7c, 0x7c, 0xae, 0xb3, 0x56, 0x00, - 0x9f, 0xac, 0x21, 0x87, 0x25, 0x5c, 0xc0, 0xcf, 0xab, 0x8a, 0xcc, 0xfe, 0x78, 0xba, 0x6a, 0x9c, - 0xdb, 0x02, 0x3e, 0x2b, 0x2f, 0x16, 0x59, 0xda, 0x13, 0x7e, 0x90, 0x83, 0xe2, 0xf2, 0x72, 0x5f, - 0x02, 0x58, 0x79, 0x89, 0xd1, 0xd1, 0x5d, 0x5a, 0x26, 0x9b, 0x1c, 0x6e, 0xba, 0x4b, 0xcb, 0xf4, - 0x06, 0x67, 0x38, 0x83, 0xba, 0x28, 0xe3, 0x0f, 0xab, 0x8d, 0xa3, 0xf6, 0xf4, 0x61, 0xb5, 0x31, - 0x6d, 0xcf, 0x1e, 0x56, 0x1b, 0xb3, 0xb6, 0xad, 0xff, 0xaa, 0x80, 0x9a, 0xaa, 0xcc, 0x48, 0x87, - 0x06, 0x35, 0x83, 0x29, 0xa1, 0x07, 0x96, 0x68, 0x04, 0xb1, 0x8d, 0x6e, 0x42, 0xc3, 0xf7, 0x42, - 0x9b, 0xc5, 0xc5, 0x6b, 0x74, 0x2b, 0x75, 0x6a, 0xa3, 0xbe, 0xc9, 0x95, 0x8c, 0x67, 0x02, 0x84, - 0x63, 0x38, 0xba, 0x0a, 0x35, 0x5e, 0xec, 0x64, 0xc7, 0x3c, 0x5b, 0x44, 0xc4, 0x02, 0xa3, 0x7f, - 0x2d, 0x7c, 0x12, 0xd9, 0x33, 0xa0, 0x16, 0xbd, 0xc2, 0x44, 0x7b, 0x3b, 0x17, 0x93, 0x1f, 0xb0, - 0x61, 0xe3, 0x90, 0x84, 0xa1, 0x39, 0x25, 0x58, 0xa0, 0xf4, 0x8b, 0x82, 0x2e, 0xae, 0x6c, 0x1b, - 0x2a, 0xc9, 0x13, 0x8c, 0x7d, 0xea, 0x14, 0x9a, 0x71, 0x31, 0xff, 0xb7, 0x22, 0x16, 0xab, 0x56, - 0x92, 0x55, 0x57, 0xd0, 0xca, 0xb6, 0x80, 0xff, 0x6e, 0xe9, 0xc7, 0x00, 0x49, 0xb1, 0x2e, 0xe8, - 0xf3, 0x57, 0xd3, 0x7d, 0x9e, 0x25, 0x38, 0x7a, 0xe7, 0x1a, 0xf2, 0x9d, 0x6b, 0x7c, 0xc7, 0x66, - 0x45, 0xff, 0xd7, 0xbb, 0xb0, 0x95, 0x2e, 0xdd, 0xeb, 0x7a, 0xfa, 0x33, 0x50, 0x53, 0x6d, 0x0a, - 0xdd, 0x85, 0x6d, 0xd9, 0x5f, 0x1e, 0xdb, 0xee, 0xb1, 0x7c, 0xb5, 0xed, 0xe4, 0x02, 0xc2, 0x29, - 0x0c, 0xce, 0x32, 0xf4, 0x3e, 0xb4, 0xb2, 0x4d, 0x0b, 0x75, 0x93, 0x6e, 0xf9, 0x88, 0xaf, 0xce, - 0x5f, 0xd8, 0xa9, 0x21, 0x7d, 0x1f, 0xb6, 0x33, 0xdd, 0x81, 0x39, 0xba, 0x08, 0x1c, 0xe9, 0xe8, - 0x22, 0x70, 0xa4, 0xeb, 0xe5, 0xc4, 0xf5, 0xeb, 0xd0, 0xce, 0x37, 0x82, 0x77, 0xe2, 0x3d, 0x05, - 0x35, 0x55, 0xf5, 0xd9, 0x23, 0xcd, 0x37, 0xe9, 0x4c, 0xb8, 0xc5, 0xbf, 0xdf, 0x33, 0xcb, 0x1f, - 0xc1, 0x76, 0xa6, 0x07, 0x14, 0x49, 0xea, 0x7f, 0x95, 0xa1, 0x9d, 0xaf, 0xef, 0x05, 0xfb, 0x7b, - 0x03, 0x2a, 0xa6, 0x65, 0x89, 0x75, 0x2f, 0x9f, 0xd6, 0x20, 0x8c, 0xa8, 0x08, 0x31, 0x0a, 0xba, - 0x0b, 0xb5, 0x20, 0xfd, 0xa8, 0xfa, 0xe4, 0x54, 0x72, 0xdc, 0x3c, 0x05, 0x11, 0xdd, 0x86, 0xea, - 0x3c, 0x79, 0x56, 0x5d, 0x39, 0x55, 0x40, 0x3c, 0xb1, 0x38, 0x49, 0xbf, 0x06, 0x15, 0xb6, 0x73, - 0x1a, 0xd4, 0xcd, 0x23, 0x4a, 0x82, 0xf8, 0xa2, 0x48, 0x53, 0x1e, 0xf6, 0x72, 0x72, 0xd8, 0x75, - 0xa8, 0x6d, 0xbc, 0xf9, 0x7d, 0xa8, 0xf2, 0x4b, 0xff, 0x1e, 0x7a, 0x03, 0x15, 0x9a, 0x9e, 0x4f, - 0x02, 0x7e, 0xac, 0xf4, 0xcf, 0x61, 0xe7, 0x84, 0xa6, 0x87, 0x5a, 0x50, 0xa6, 0x21, 0x97, 0xac, - 0xe0, 0x32, 0x0d, 0xf5, 0x01, 0xa8, 0xa9, 0x16, 0x86, 0xf6, 0xa3, 0xbf, 0x0e, 0xbc, 0xe3, 0x45, - 0xcf, 0xe4, 0xf3, 0xb9, 0x3b, 0x20, 0xa1, 0x38, 0x06, 0xea, 0x2f, 0x00, 0xad, 0xb7, 0x2f, 0x74, - 0x07, 0xb6, 0xd2, 0x8d, 0x66, 0xed, 0xd5, 0x1d, 0xc9, 0xa5, 0x89, 0x38, 0x43, 0xd0, 0x7f, 0xc8, - 0xca, 0x8a, 0xb3, 0xd3, 0x82, 0xb2, 0x2d, 0x73, 0x52, 0xb6, 0x2d, 0x74, 0x0b, 0x6a, 0x21, 0x35, - 0xe9, 0x22, 0x14, 0x45, 0xe8, 0xd2, 0x09, 0x0b, 0x18, 0x23, 0x8e, 0xc4, 0x82, 0xa1, 0x7f, 0x03, - 0xcd, 0xb8, 0xa9, 0xa1, 0x6b, 0x50, 0x8b, 0x7a, 0x92, 0xf0, 0xf4, 0x42, 0x4e, 0x28, 0x42, 0xf2, - 0xd0, 0x05, 0x50, 0xef, 0xb3, 0x3a, 0x93, 0xb4, 0xb1, 0x35, 0xdf, 0x10, 0x54, 0x5d, 0x73, 0x2e, - 0xff, 0x9c, 0xf0, 0xef, 0xc1, 0xee, 0xef, 0x6f, 0x3a, 0xca, 0xeb, 0x37, 0x1d, 0xe5, 0xcf, 0x37, - 0x1d, 0xe5, 0x97, 0xb7, 0x9d, 0xd2, 0xeb, 0xb7, 0x9d, 0xd2, 0x1f, 0x6f, 0x3b, 0xa5, 0xef, 0xcb, - 0xfe, 0x78, 0x5c, 0xe3, 0x57, 0x6d, 0xff, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x63, 0xdb, 0x9a, - 0x94, 0x28, 0x10, 0x00, 0x00, + // 1643 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdd, 0x72, 0x13, 0x47, + 0x16, 0xd6, 0x9f, 0xa5, 0xd1, 0x91, 0xad, 0x15, 0x5d, 0x14, 0x0c, 0x63, 0xaf, 0xd0, 0x6a, 0x81, + 0x75, 0xb1, 0x20, 0x17, 0xf2, 0x16, 0x8b, 0x61, 0x77, 0x29, 0x0b, 0xb3, 0x25, 0x03, 0x06, 0x57, + 0xcb, 0xec, 0xc5, 0xde, 0x90, 0x91, 0xa6, 0x25, 0x0f, 0x1e, 0xcd, 0x4c, 0x66, 0x5a, 0xaa, 0xe8, + 0x32, 0x4f, 0x90, 0x54, 0x5e, 0x26, 0x4f, 0x90, 0xaa, 0x5c, 0x72, 0x99, 0xcb, 0x14, 0xdc, 0xe7, + 0x09, 0x72, 0x91, 0xea, 0xbf, 0xf9, 0xd1, 0x8f, 0x0d, 0x45, 0x25, 0x37, 0xaa, 0xe9, 0xee, 0xef, + 0xfb, 0xfa, 0x9c, 0xd3, 0xdd, 0xe7, 0x74, 0x0b, 0xae, 0xfa, 0xfd, 0x1d, 0x3f, 0xf0, 0xa8, 0x17, + 0xee, 0x0c, 0x4e, 0x4d, 0x77, 0x44, 0xc2, 0x16, 0x6f, 0xa2, 0x92, 0xe9, 0xce, 0xe8, 0xcc, 0x27, + 0xc6, 0x0d, 0xff, 0x6c, 0xb4, 0xe3, 0xd8, 0xfd, 0x1d, 0xbf, 0xbf, 0x33, 0xf6, 0x2c, 0xe2, 0x28, + 0x3c, 0x6f, 0x48, 0xb8, 0x71, 0x25, 0xd6, 0x21, 0x53, 0xe2, 0x52, 0xd5, 0xbf, 0x35, 0xf2, 0xbc, + 0x91, 0x43, 0xc4, 0x58, 0x7f, 0x32, 0xdc, 0x09, 0x69, 0x30, 0x19, 0x50, 0x31, 0xda, 0xfc, 0xfa, + 0x3a, 0x14, 0x9f, 0xf0, 0x69, 0xd1, 0x5f, 0x60, 0xdd, 0x0f, 0xc8, 0xd4, 0xf6, 0x26, 0xe1, 0x1b, + 0xdb, 0x0a, 0xf5, 0x6c, 0x23, 0xbf, 0x5d, 0xc6, 0x15, 0xd5, 0x77, 0x68, 0x85, 0x68, 0x1b, 0x6a, + 0x8e, 0x19, 0xd2, 0x37, 0xa1, 0x6b, 0xfa, 0xe1, 0xa9, 0x47, 0xdf, 0xd8, 0x96, 0x9e, 0x6b, 0x64, + 0xb7, 0xcb, 0xb8, 0xca, 0xfa, 0x7b, 0xb2, 0xfb, 0xd0, 0x42, 0xb7, 0xe1, 0x52, 0x24, 0x36, 0x26, + 0xd4, 0xe4, 0x8a, 0x6b, 0x5c, 0xf1, 0x4f, 0x6a, 0xe0, 0x88, 0x50, 0x93, 0xa9, 0xde, 0x83, 0xd2, + 0xc0, 0x73, 0x29, 0x71, 0xa9, 0x9e, 0x6f, 0xe4, 0xb7, 0x2b, 0xed, 0xab, 0x2d, 0xe9, 0x7a, 0x4b, + 0x98, 0xd6, 0x7a, 0x22, 0x86, 0xb1, 0xc2, 0xa1, 0x7f, 0x80, 0xa6, 0x6c, 0xd0, 0x0b, 0x8d, 0xec, + 0x76, 0xa5, 0xad, 0xcf, 0x73, 0x94, 0x31, 0x38, 0x42, 0x32, 0xd6, 0xd0, 0x76, 0xc8, 0x73, 0x32, + 0x0b, 0xf5, 0x22, 0x9f, 0x69, 0x81, 0xf5, 0x5f, 0x39, 0x8e, 0x23, 0x24, 0xda, 0x82, 0x32, 0xb5, + 0xc7, 0x24, 0xa4, 0xe6, 0xd8, 0xd7, 0x4b, 0x8d, 0xec, 0x76, 0x1e, 0xc7, 0x1d, 0x48, 0x87, 0xd2, + 0x94, 0x04, 0xa1, 0xed, 0xb9, 0xba, 0xd6, 0xc8, 0x6e, 0x6f, 0x60, 0xd5, 0x34, 0x7e, 0xcd, 0x82, + 0xa6, 0x8c, 0x40, 0x1d, 0xd0, 0x1c, 0x6f, 0xd4, 0x25, 0xa6, 0x0c, 0x6c, 0xa5, 0x7d, 0x6b, 0x95, + 0xc1, 0xad, 0x17, 0x12, 0xf8, 0xd4, 0xa5, 0xc1, 0x0c, 0x47, 0x3c, 0xb4, 0x07, 0x05, 0xcb, 0xa4, + 0x26, 0x8f, 0x78, 0xa5, 0x7d, 0x33, 0xe2, 0xf3, 0x6d, 0xd0, 0xea, 0x8d, 0xcd, 0x80, 0x76, 0x1c, + 0x6f, 0x70, 0xa6, 0x84, 0x3a, 0x66, 0x48, 0x30, 0xa7, 0xa4, 0x3c, 0xcf, 0x7f, 0xac, 0xe7, 0xc6, + 0x23, 0xd8, 0x48, 0xd9, 0x82, 0x6a, 0x90, 0x3f, 0x23, 0x33, 0x3d, 0xcb, 0x97, 0x9c, 0x7d, 0xa2, + 0xcb, 0xb0, 0x36, 0x35, 0x9d, 0x09, 0x91, 0xdb, 0x40, 0x34, 0x1e, 0xe6, 0x1e, 0x64, 0x8d, 0x6f, + 0xb2, 0xa0, 0x29, 0x4d, 0x84, 0xa0, 0x70, 0x6a, 0x86, 0xa7, 0x92, 0xc9, 0xbf, 0xd1, 0x7d, 0x28, + 0x9c, 0x31, 0x7b, 0x72, 0xdc, 0x9e, 0xe6, 0x2a, 0x7b, 0x5a, 0xec, 0x47, 0x84, 0x82, 0xe3, 0x8d, + 0x7f, 0x42, 0x39, 0xea, 0xfa, 0x24, 0x8b, 0x7e, 0xa8, 0x40, 0x49, 0xee, 0x24, 0xf4, 0x18, 0x2a, + 0x7d, 0x16, 0xab, 0x27, 0x01, 0x31, 0x29, 0xe1, 0xfc, 0x4a, 0x7b, 0x73, 0xde, 0x86, 0x4e, 0x0c, + 0xe9, 0x66, 0x70, 0x92, 0x11, 0x09, 0xbc, 0xf6, 0x2d, 0x26, 0x90, 0x3b, 0x47, 0x40, 0x40, 0x22, + 0x01, 0xd1, 0x8c, 0x04, 0x30, 0x19, 0x7b, 0x53, 0xa2, 0xe7, 0xcf, 0x11, 0x10, 0x90, 0x48, 0x40, + 0x34, 0xd1, 0x1e, 0x94, 0x79, 0xf3, 0x88, 0xd1, 0xc5, 0x21, 0xb8, 0xb6, 0x94, 0x7e, 0x24, 0xc8, + 0x31, 0x1a, 0x75, 0xa1, 0xca, 0x1b, 0x07, 0x13, 0xdf, 0xb1, 0x07, 0xcc, 0xfe, 0x35, 0xce, 0xaf, + 0x2f, 0xe5, 0x47, 0xa8, 0x6e, 0x06, 0xcf, 0xf1, 0x98, 0x17, 0x01, 0x71, 0x4c, 0x6a, 0x7b, 0xee, + 0xbe, 0x65, 0xe9, 0xed, 0xe5, 0x5e, 0xe0, 0x18, 0xc2, 0xbc, 0x48, 0x30, 0x98, 0x29, 0xaa, 0x29, + 0x23, 0xb1, 0xbb, 0xdc, 0x14, 0x9c, 0x42, 0x31, 0x53, 0xd2, 0x3c, 0xf4, 0x2f, 0x00, 0x8b, 0x50, + 0xd3, 0x76, 0xc2, 0x1e, 0xa1, 0xba, 0xc5, 0x55, 0x8c, 0x79, 0x95, 0x83, 0x08, 0xd1, 0xcd, 0xe0, + 0x04, 0x1e, 0x75, 0x60, 0x5d, 0xb6, 0x5e, 0xbb, 0x21, 0xa1, 0x3a, 0xe1, 0xfc, 0xad, 0x15, 0x7c, + 0x8e, 0xe9, 0x66, 0x70, 0x8a, 0x83, 0x9e, 0xc2, 0x86, 0xd7, 0x7f, 0x4b, 0x06, 0xf4, 0x64, 0xe6, + 0x13, 0x16, 0x0e, 0x9b, 0x8b, 0xfc, 0x79, 0x5e, 0xe4, 0x55, 0x12, 0xd4, 0xcd, 0xe0, 0x34, 0x0b, + 0xbd, 0x84, 0x5a, 0xdc, 0x21, 0x83, 0xf2, 0x96, 0x2b, 0x35, 0x56, 0x2b, 0x45, 0x61, 0x59, 0xe0, + 0xb2, 0x35, 0x0a, 0xa9, 0x17, 0xb0, 0xd3, 0xc4, 0x22, 0x73, 0xb6, 0x7c, 0x8d, 0x7a, 0x31, 0x84, + 0xad, 0x51, 0x82, 0xc1, 0xfc, 0x52, 0x4d, 0x11, 0x1c, 0x67, 0xb9, 0x5f, 0xbd, 0x24, 0x88, 0xf9, + 0x95, 0x62, 0x31, 0xbf, 0x78, 0x47, 0xcf, 0xb1, 0x07, 0x44, 0x9e, 0x9b, 0xf1, 0x72, 0xbf, 0x7a, + 0x73, 0x38, 0xe6, 0xd7, 0x3c, 0x17, 0x79, 0xb0, 0xe9, 0x05, 0xf6, 0xc8, 0x76, 0x4d, 0x47, 0x1c, + 0x4a, 0xeb, 0x44, 0xa5, 0x65, 0xe6, 0xa7, 0xcb, 0xa5, 0xff, 0xbe, 0x10, 0xb2, 0xd5, 0x94, 0x6e, + 0x06, 0x9f, 0xa7, 0xc8, 0x03, 0x49, 0x28, 0x4b, 0x4c, 0x87, 0xee, 0xd0, 0xd3, 0xbd, 0x15, 0x81, + 0x8c, 0x21, 0x3c, 0x90, 0x71, 0x13, 0x9d, 0x00, 0x72, 0x3d, 0x6a, 0x0f, 0xd9, 0xd9, 0xb1, 0x3d, + 0x57, 0x26, 0x1f, 0x9f, 0xeb, 0x2c, 0x24, 0xc0, 0x97, 0x0b, 0xc8, 0x6e, 0x06, 0x2f, 0xe1, 0xcf, + 0xab, 0xca, 0xc8, 0x7e, 0x79, 0xb1, 0x6a, 0x14, 0xdb, 0x25, 0x7c, 0x96, 0x5e, 0x2c, 0x32, 0xb5, + 0x07, 0x7c, 0x23, 0x07, 0xcb, 0xd3, 0xcb, 0x81, 0x02, 0xb0, 0xf4, 0x12, 0xa1, 0xc5, 0x59, 0x9a, + 0xc6, 0x8b, 0x1c, 0xae, 0x3a, 0x4b, 0xd3, 0xe4, 0x02, 0xa7, 0x38, 0x9d, 0x92, 0x4c, 0xe3, 0xcf, + 0x0a, 0xda, 0xb0, 0x36, 0x7a, 0x56, 0xd0, 0x46, 0xb5, 0xd3, 0x67, 0x05, 0xed, 0xb4, 0x66, 0x1b, + 0xdf, 0x65, 0xa1, 0x92, 0xc8, 0xcc, 0xc8, 0x00, 0x8d, 0x9a, 0xc1, 0x88, 0xd0, 0x43, 0x4b, 0x16, + 0x82, 0xa8, 0x8d, 0xf6, 0x40, 0xf3, 0xbd, 0xd0, 0x66, 0x7e, 0xf1, 0x1c, 0x5d, 0x4d, 0xec, 0x5a, + 0x51, 0x37, 0xb9, 0x52, 0xeb, 0x58, 0x82, 0x70, 0x04, 0x47, 0x77, 0xa0, 0xc8, 0x93, 0x9d, 0xaa, + 0x98, 0x97, 0x97, 0x11, 0xb1, 0xc4, 0x18, 0xff, 0x96, 0x36, 0xc9, 0xe8, 0xb5, 0xa0, 0x28, 0x6e, + 0x61, 0xb2, 0xbc, 0x5d, 0x89, 0xc8, 0x4f, 0x59, 0x77, 0xeb, 0x88, 0x84, 0xa1, 0x39, 0x22, 0x58, + 0xa2, 0x8c, 0xeb, 0x92, 0x2e, 0x8f, 0x6c, 0x0d, 0xf2, 0xf1, 0x15, 0x8c, 0x7d, 0x1a, 0x14, 0xca, + 0x51, 0x32, 0xff, 0xbd, 0x3c, 0x96, 0xb3, 0xe6, 0xe3, 0x59, 0x67, 0x50, 0x4d, 0x97, 0x80, 0x3f, + 0x6e, 0xea, 0x17, 0x00, 0x71, 0xb2, 0x5e, 0x52, 0xe7, 0xef, 0x24, 0xeb, 0x3c, 0x0b, 0xb0, 0xb8, + 0xe7, 0xb6, 0xd4, 0x3d, 0xb7, 0xf5, 0x3f, 0x36, 0x2a, 0xeb, 0xbf, 0xd1, 0x80, 0xf5, 0x64, 0xea, + 0x5e, 0xd4, 0x33, 0x8e, 0xa1, 0x92, 0x28, 0x53, 0x68, 0x1f, 0x36, 0x54, 0x7d, 0x79, 0x61, 0xbb, + 0x67, 0xea, 0xd6, 0xb6, 0x39, 0xe7, 0x10, 0x4e, 0x60, 0x70, 0x9a, 0x61, 0xb4, 0xa1, 0x9a, 0x2e, + 0x5a, 0xa8, 0x11, 0x57, 0xcb, 0xe7, 0x7c, 0x76, 0x7e, 0xc3, 0x4e, 0x74, 0x19, 0xbb, 0xb0, 0x91, + 0xaa, 0x0e, 0xcc, 0xd0, 0x49, 0xe0, 0x28, 0x43, 0x27, 0x81, 0xa3, 0x4c, 0xcf, 0xc5, 0xa6, 0xdf, + 0x87, 0xda, 0x7c, 0x21, 0xf8, 0x28, 0xde, 0x2b, 0xa8, 0x24, 0xb2, 0x3e, 0xbb, 0xa4, 0xf9, 0x26, + 0x3d, 0x95, 0x66, 0xf1, 0xef, 0x4f, 0x8c, 0xf2, 0x5f, 0x61, 0x23, 0x55, 0x03, 0x96, 0x49, 0x1a, + 0xbf, 0xe4, 0xa0, 0x36, 0x9f, 0xdf, 0x97, 0xac, 0xef, 0x03, 0xc8, 0x9b, 0x96, 0x25, 0xe7, 0xbd, + 0x71, 0x51, 0x81, 0x68, 0x89, 0x24, 0xc4, 0x28, 0x68, 0x1f, 0x8a, 0x41, 0xf2, 0x52, 0xf5, 0xb7, + 0x0b, 0xc9, 0x51, 0xf1, 0x94, 0x44, 0xf4, 0x08, 0x0a, 0xe3, 0xf8, 0x5a, 0x75, 0xf3, 0x42, 0x01, + 0x79, 0xc5, 0xe2, 0x24, 0xe3, 0x1e, 0xe4, 0xd9, 0xca, 0xe9, 0x50, 0x32, 0x87, 0x94, 0x04, 0xd1, + 0x41, 0x51, 0x4d, 0xb5, 0xd9, 0x73, 0xf1, 0x66, 0x37, 0xa0, 0xb8, 0xf2, 0xe4, 0xb7, 0xa1, 0xc0, + 0x0f, 0xfd, 0x27, 0xe8, 0x75, 0x2a, 0x50, 0xf6, 0x7c, 0x12, 0xf0, 0x6d, 0x65, 0xdc, 0x85, 0xcd, + 0x73, 0x8a, 0x1e, 0xaa, 0x42, 0x8e, 0x86, 0x5c, 0x32, 0x8f, 0x73, 0x34, 0x34, 0x3a, 0x50, 0x49, + 0x94, 0x30, 0xb4, 0x2b, 0x9e, 0x0e, 0xbc, 0xe2, 0x89, 0x6b, 0xf2, 0xd5, 0xb9, 0x33, 0xa0, 0xa0, + 0x38, 0x02, 0x1a, 0xaf, 0x01, 0x2d, 0x96, 0x2f, 0xf4, 0x18, 0xd6, 0x93, 0x85, 0x66, 0xe1, 0xd6, + 0x2d, 0xe4, 0x92, 0x44, 0x9c, 0x22, 0x18, 0x5f, 0xa4, 0x65, 0xe5, 0xde, 0xa9, 0x42, 0xce, 0x56, + 0x31, 0xc9, 0xd9, 0x16, 0x7a, 0x08, 0xc5, 0x90, 0x9a, 0x74, 0x12, 0xca, 0x24, 0xd4, 0x3c, 0x67, + 0x82, 0x56, 0x8f, 0x23, 0xb1, 0x64, 0x18, 0xff, 0x81, 0x72, 0x54, 0xd4, 0xd0, 0x3d, 0x28, 0x8a, + 0x9a, 0x24, 0x2d, 0xbd, 0x36, 0x27, 0x24, 0x90, 0xdc, 0x75, 0x09, 0x34, 0xda, 0x2c, 0xcf, 0xc4, + 0x65, 0x6c, 0xc1, 0x36, 0x04, 0x05, 0xd7, 0x1c, 0xab, 0xc7, 0x09, 0xff, 0x6e, 0x76, 0xe5, 0x31, + 0x94, 0xef, 0xf0, 0x3d, 0x28, 0x8b, 0x3f, 0x02, 0xd8, 0x25, 0x66, 0x3e, 0xeb, 0x24, 0x80, 0xea, + 0x51, 0x1c, 0xa3, 0x9b, 0xdf, 0x67, 0x01, 0x2d, 0x22, 0x98, 0x1f, 0x83, 0xe4, 0x3b, 0x27, 0x5e, + 0xc0, 0x03, 0x6f, 0x30, 0x19, 0x13, 0x97, 0x46, 0xf7, 0x0b, 0x09, 0x64, 0x94, 0xb1, 0x67, 0xd9, + 0xc3, 0x99, 0x3c, 0x80, 0x8b, 0x94, 0x23, 0x3e, 0xcc, 0x28, 0x02, 0x28, 0xa2, 0xe5, 0x10, 0xaa, + 0x8e, 0xdd, 0x22, 0xe5, 0x80, 0x0f, 0x33, 0x8a, 0x00, 0x76, 0x34, 0x28, 0x0a, 0xe3, 0x9b, 0x43, + 0xa8, 0xa6, 0x6d, 0x41, 0x75, 0x80, 0x81, 0xe7, 0x38, 0x64, 0x10, 0x6d, 0x95, 0x32, 0x4e, 0xf4, + 0xb0, 0x71, 0x4b, 0x32, 0x0e, 0xd5, 0xbf, 0x10, 0x89, 0x9e, 0xf8, 0x1d, 0x98, 0x4f, 0xbc, 0x03, + 0x9b, 0x5f, 0xc5, 0xf3, 0x08, 0x07, 0x3e, 0x7b, 0x9e, 0x5b, 0xf2, 0x19, 0x5b, 0xe0, 0x2b, 0x85, + 0x22, 0xa7, 0x9f, 0x93, 0x99, 0x98, 0x41, 0x3c, 0x5b, 0x9b, 0x53, 0xfe, 0x6c, 0x95, 0x93, 0xea, + 0x50, 0x3a, 0x23, 0xb3, 0xe3, 0x38, 0x35, 0xaa, 0x26, 0xba, 0x0b, 0x9a, 0x88, 0xe7, 0x2b, 0x9f, + 0x5b, 0x5e, 0x6d, 0x5f, 0x8a, 0x24, 0x8f, 0xe4, 0x00, 0x8e, 0x20, 0xac, 0xa2, 0x88, 0x6f, 0x9e, + 0x87, 0x79, 0xbe, 0x2a, 0xe3, 0x64, 0x57, 0xf3, 0x38, 0xf6, 0x58, 0xc4, 0xff, 0x73, 0x3d, 0xbe, + 0xfd, 0x18, 0x34, 0x65, 0x09, 0x2a, 0x41, 0xbe, 0x47, 0x68, 0x2d, 0x83, 0xca, 0xb0, 0xc6, 0x53, + 0x7e, 0x2d, 0xcb, 0xfa, 0x0e, 0xdd, 0x41, 0x2d, 0x87, 0xd6, 0x41, 0xdb, 0xb7, 0xac, 0x13, 0x8f, + 0x21, 0xf2, 0x48, 0x83, 0xc2, 0xf1, 0xc4, 0x71, 0x6a, 0x85, 0xce, 0xd6, 0x8f, 0xef, 0xeb, 0xd9, + 0x77, 0xef, 0xeb, 0xd9, 0x9f, 0xdf, 0xd7, 0xb3, 0xdf, 0x7e, 0xa8, 0x67, 0xde, 0x7d, 0xa8, 0x67, + 0x7e, 0xfa, 0x50, 0xcf, 0xfc, 0x3f, 0xe7, 0xf7, 0xfb, 0x45, 0x5e, 0x5b, 0x76, 0x7f, 0x0b, 0x00, + 0x00, 0xff, 0xff, 0x75, 0x94, 0x4e, 0xf1, 0x19, 0x13, 0x00, 0x00, } func (m *Change) Marshal() (dAtA []byte, err error) { @@ -3490,24 +3924,332 @@ func (m *ChangeDeviceUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintChanges(dAtA []byte, offset int, v uint64) int { - offset -= sovChanges(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *StoreChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Change) Size() (n int) { - if m == nil { - return 0 - } + +func (m *StoreChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoreChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.PreviousIds) > 0 { + if len(m.ChangeSet) > 0 { + for iNdEx := len(m.ChangeSet) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ChangeSet[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChanges(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *StoreChangeContent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StoreChangeContent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoreChangeContent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Change != nil { + { + size := m.Change.Size() + i -= size + if _, err := m.Change.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *StoreChangeContentChangeOfCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoreChangeContentChangeOfCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Create != nil { + { + size, err := m.Create.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChanges(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *StoreChangeContentChangeOfModify) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoreChangeContentChangeOfModify) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Modify != nil { + { + size, err := m.Modify.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChanges(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *StoreChangeContentChangeOfDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoreChangeContentChangeOfDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Delete != nil { + { + size, err := m.Delete.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChanges(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *DocumentCreate) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DocumentCreate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DocumentCreate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintChanges(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x1a + } + if len(m.DocumentId) > 0 { + i -= len(m.DocumentId) + copy(dAtA[i:], m.DocumentId) + i = encodeVarintChanges(dAtA, i, uint64(len(m.DocumentId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Collection) > 0 { + i -= len(m.Collection) + copy(dAtA[i:], m.Collection) + i = encodeVarintChanges(dAtA, i, uint64(len(m.Collection))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DocumentModify) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DocumentModify) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DocumentModify) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Keys) > 0 { + for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Keys[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintChanges(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.DocumentId) > 0 { + i -= len(m.DocumentId) + copy(dAtA[i:], m.DocumentId) + i = encodeVarintChanges(dAtA, i, uint64(len(m.DocumentId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Collection) > 0 { + i -= len(m.Collection) + copy(dAtA[i:], m.Collection) + i = encodeVarintChanges(dAtA, i, uint64(len(m.Collection))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *KeyModify) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KeyModify) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *KeyModify) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ModifyValue) > 0 { + i -= len(m.ModifyValue) + copy(dAtA[i:], m.ModifyValue) + i = encodeVarintChanges(dAtA, i, uint64(len(m.ModifyValue))) + i-- + dAtA[i] = 0x22 + } + if m.ModifyOp != 0 { + i = encodeVarintChanges(dAtA, i, uint64(m.ModifyOp)) + i-- + dAtA[i] = 0x18 + } + if len(m.KeyPath) > 0 { + for iNdEx := len(m.KeyPath) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.KeyPath[iNdEx]) + copy(dAtA[i:], m.KeyPath[iNdEx]) + i = encodeVarintChanges(dAtA, i, uint64(len(m.KeyPath[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *DocumentDelete) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DocumentDelete) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DocumentDelete) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DocumentId) > 0 { + i -= len(m.DocumentId) + copy(dAtA[i:], m.DocumentId) + i = encodeVarintChanges(dAtA, i, uint64(len(m.DocumentId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Collection) > 0 { + i -= len(m.Collection) + copy(dAtA[i:], m.Collection) + i = encodeVarintChanges(dAtA, i, uint64(len(m.Collection))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintChanges(dAtA []byte, offset int, v uint64) int { + offset -= sovChanges(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Change) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.PreviousIds) > 0 { for _, s := range m.PreviousIds { l = len(s) n += 1 + l + sovChanges(uint64(l)) @@ -4261,16 +5003,162 @@ func (m *ChangeDeviceUpdate) Size() (n int) { return n } -func sovChanges(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 +func (m *StoreChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ChangeSet) > 0 { + for _, e := range m.ChangeSet { + l = e.Size() + n += 1 + l + sovChanges(uint64(l)) + } + } + return n } -func sozChanges(x uint64) (n int) { - return sovChanges(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + +func (m *StoreChangeContent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Change != nil { + n += m.Change.Size() + } + return n } -func (m *Change) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { + +func (m *StoreChangeContentChangeOfCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Create != nil { + l = m.Create.Size() + n += 1 + l + sovChanges(uint64(l)) + } + return n +} +func (m *StoreChangeContentChangeOfModify) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Modify != nil { + l = m.Modify.Size() + n += 1 + l + sovChanges(uint64(l)) + } + return n +} +func (m *StoreChangeContentChangeOfDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Delete != nil { + l = m.Delete.Size() + n += 1 + l + sovChanges(uint64(l)) + } + return n +} +func (m *DocumentCreate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Collection) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + l = len(m.DocumentId) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + return n +} + +func (m *DocumentModify) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Collection) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + l = len(m.DocumentId) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + if len(m.Keys) > 0 { + for _, e := range m.Keys { + l = e.Size() + n += 1 + l + sovChanges(uint64(l)) + } + } + return n +} + +func (m *KeyModify) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.KeyPath) > 0 { + for _, s := range m.KeyPath { + l = len(s) + n += 1 + l + sovChanges(uint64(l)) + } + } + if m.ModifyOp != 0 { + n += 1 + sovChanges(uint64(m.ModifyOp)) + } + l = len(m.ModifyValue) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + return n +} + +func (m *DocumentDelete) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Collection) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + l = len(m.DocumentId) + if l > 0 { + n += 1 + l + sovChanges(uint64(l)) + } + return n +} + +func sovChanges(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozChanges(x uint64) (n int) { + return sovChanges(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Change) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { preIndex := iNdEx var wire uint64 for shift := uint(0); ; shift += 7 { @@ -8161,6 +9049,786 @@ func (m *ChangeDeviceUpdate) Unmarshal(dAtA []byte) error { } return nil } +func (m *StoreChange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StoreChange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoreChange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChangeSet", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChangeSet = append(m.ChangeSet, &StoreChangeContent{}) + if err := m.ChangeSet[len(m.ChangeSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StoreChangeContent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StoreChangeContent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoreChangeContent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Create", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &DocumentCreate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Change = &StoreChangeContentChangeOfCreate{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Modify", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &DocumentModify{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Change = &StoreChangeContentChangeOfModify{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Delete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &DocumentDelete{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Change = &StoreChangeContentChangeOfDelete{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DocumentCreate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DocumentCreate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DocumentCreate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Collection", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Collection = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DocumentId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DocumentId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DocumentModify) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DocumentModify: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DocumentModify: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Collection", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Collection = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DocumentId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DocumentId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, &KeyModify{}) + if err := m.Keys[len(m.Keys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KeyModify) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KeyModify: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KeyModify: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyPath = append(m.KeyPath, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ModifyOp", wireType) + } + m.ModifyOp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ModifyOp |= ModifyOp(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ModifyValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ModifyValue = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DocumentDelete) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DocumentDelete: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DocumentDelete: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Collection", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Collection = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DocumentId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowChanges + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthChanges + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthChanges + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DocumentId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipChanges(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthChanges + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipChanges(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/pb/commands.pb.go b/pb/commands.pb.go index c76f1be73a..c3f695faf2 100644 --- a/pb/commands.pb.go +++ b/pb/commands.pb.go @@ -2456,6 +2456,62 @@ func (RpcObjectSearchSubscribeResponseErrorCode) EnumDescriptor() ([]byte, []int return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 20, 1, 0, 0} } +type RpcObjectCrossSpaceSearchSubscribeResponseErrorCode int32 + +const ( + RpcObjectCrossSpaceSearchSubscribeResponseError_NULL RpcObjectCrossSpaceSearchSubscribeResponseErrorCode = 0 + RpcObjectCrossSpaceSearchSubscribeResponseError_UNKNOWN_ERROR RpcObjectCrossSpaceSearchSubscribeResponseErrorCode = 1 + RpcObjectCrossSpaceSearchSubscribeResponseError_BAD_INPUT RpcObjectCrossSpaceSearchSubscribeResponseErrorCode = 2 +) + +var RpcObjectCrossSpaceSearchSubscribeResponseErrorCode_name = map[int32]string{ + 0: "NULL", + 1: "UNKNOWN_ERROR", + 2: "BAD_INPUT", +} + +var RpcObjectCrossSpaceSearchSubscribeResponseErrorCode_value = map[string]int32{ + "NULL": 0, + "UNKNOWN_ERROR": 1, + "BAD_INPUT": 2, +} + +func (x RpcObjectCrossSpaceSearchSubscribeResponseErrorCode) String() string { + return proto.EnumName(RpcObjectCrossSpaceSearchSubscribeResponseErrorCode_name, int32(x)) +} + +func (RpcObjectCrossSpaceSearchSubscribeResponseErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 1, 0, 0} +} + +type RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode int32 + +const ( + RpcObjectCrossSpaceSearchUnsubscribeResponseError_NULL RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode = 0 + RpcObjectCrossSpaceSearchUnsubscribeResponseError_UNKNOWN_ERROR RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode = 1 + RpcObjectCrossSpaceSearchUnsubscribeResponseError_BAD_INPUT RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode = 2 +) + +var RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode_name = map[int32]string{ + 0: "NULL", + 1: "UNKNOWN_ERROR", + 2: "BAD_INPUT", +} + +var RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode_value = map[string]int32{ + "NULL": 0, + "UNKNOWN_ERROR": 1, + "BAD_INPUT": 2, +} + +func (x RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode) String() string { + return proto.EnumName(RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode_name, int32(x)) +} + +func (RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 1, 0, 0} +} + type RpcObjectGroupsSubscribeResponseErrorCode int32 const ( @@ -2481,7 +2537,7 @@ func (x RpcObjectGroupsSubscribeResponseErrorCode) String() string { } func (RpcObjectGroupsSubscribeResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 1, 0, 0} } type RpcObjectSubscribeIdsResponseErrorCode int32 @@ -2509,7 +2565,7 @@ func (x RpcObjectSubscribeIdsResponseErrorCode) String() string { } func (RpcObjectSubscribeIdsResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 1, 0, 0} } type RpcObjectSearchUnsubscribeResponseErrorCode int32 @@ -2537,7 +2593,7 @@ func (x RpcObjectSearchUnsubscribeResponseErrorCode) String() string { } func (RpcObjectSearchUnsubscribeResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 1, 0, 0} } type RpcObjectSetLayoutResponseErrorCode int32 @@ -2565,7 +2621,7 @@ func (x RpcObjectSetLayoutResponseErrorCode) String() string { } func (RpcObjectSetLayoutResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 1, 0, 0} } type RpcObjectSetIsFavoriteResponseErrorCode int32 @@ -2593,7 +2649,7 @@ func (x RpcObjectSetIsFavoriteResponseErrorCode) String() string { } func (RpcObjectSetIsFavoriteResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 1, 0, 0} } type RpcObjectSetIsArchivedResponseErrorCode int32 @@ -2621,7 +2677,7 @@ func (x RpcObjectSetIsArchivedResponseErrorCode) String() string { } func (RpcObjectSetIsArchivedResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 1, 0, 0} } type RpcObjectSetSourceResponseErrorCode int32 @@ -2649,7 +2705,7 @@ func (x RpcObjectSetSourceResponseErrorCode) String() string { } func (RpcObjectSetSourceResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 1, 0, 0} } type RpcObjectWorkspaceSetDashboardResponseErrorCode int32 @@ -2677,7 +2733,7 @@ func (x RpcObjectWorkspaceSetDashboardResponseErrorCode) String() string { } func (RpcObjectWorkspaceSetDashboardResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 1, 0, 0} } type RpcObjectSetObjectTypeResponseErrorCode int32 @@ -2705,7 +2761,7 @@ func (x RpcObjectSetObjectTypeResponseErrorCode) String() string { } func (RpcObjectSetObjectTypeResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 1, 0, 0} } type RpcObjectSetInternalFlagsResponseErrorCode int32 @@ -2733,7 +2789,7 @@ func (x RpcObjectSetInternalFlagsResponseErrorCode) String() string { } func (RpcObjectSetInternalFlagsResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 1, 0, 0} } type RpcObjectSetDetailsResponseErrorCode int32 @@ -2761,7 +2817,7 @@ func (x RpcObjectSetDetailsResponseErrorCode) String() string { } func (RpcObjectSetDetailsResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 1, 0, 0} } type RpcObjectToSetResponseErrorCode int32 @@ -2789,7 +2845,7 @@ func (x RpcObjectToSetResponseErrorCode) String() string { } func (RpcObjectToSetResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 34, 1, 0, 0} } type RpcObjectToCollectionResponseErrorCode int32 @@ -2817,7 +2873,7 @@ func (x RpcObjectToCollectionResponseErrorCode) String() string { } func (RpcObjectToCollectionResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 1, 0, 0} } type RpcObjectUndoResponseErrorCode int32 @@ -2848,7 +2904,7 @@ func (x RpcObjectUndoResponseErrorCode) String() string { } func (RpcObjectUndoResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 1, 0, 0} } type RpcObjectRedoResponseErrorCode int32 @@ -2879,7 +2935,7 @@ func (x RpcObjectRedoResponseErrorCode) String() string { } func (RpcObjectRedoResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 36, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 1, 0, 0} } type RpcObjectListDuplicateResponseErrorCode int32 @@ -2907,7 +2963,7 @@ func (x RpcObjectListDuplicateResponseErrorCode) String() string { } func (RpcObjectListDuplicateResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 1, 0, 0} } type RpcObjectListDeleteResponseErrorCode int32 @@ -2935,7 +2991,7 @@ func (x RpcObjectListDeleteResponseErrorCode) String() string { } func (RpcObjectListDeleteResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 1, 0, 0} } type RpcObjectListSetIsArchivedResponseErrorCode int32 @@ -2963,7 +3019,7 @@ func (x RpcObjectListSetIsArchivedResponseErrorCode) String() string { } func (RpcObjectListSetIsArchivedResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 1, 0, 0} } type RpcObjectListSetIsFavoriteResponseErrorCode int32 @@ -2991,7 +3047,7 @@ func (x RpcObjectListSetIsFavoriteResponseErrorCode) String() string { } func (RpcObjectListSetIsFavoriteResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 1, 0, 0} } type RpcObjectListSetObjectTypeResponseErrorCode int32 @@ -3019,7 +3075,7 @@ func (x RpcObjectListSetObjectTypeResponseErrorCode) String() string { } func (RpcObjectListSetObjectTypeResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 1, 0, 0} } type RpcObjectListSetDetailsResponseErrorCode int32 @@ -3047,7 +3103,7 @@ func (x RpcObjectListSetDetailsResponseErrorCode) String() string { } func (RpcObjectListSetDetailsResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 1, 0, 0} } type RpcObjectListModifyDetailValuesResponseErrorCode int32 @@ -3075,7 +3131,7 @@ func (x RpcObjectListModifyDetailValuesResponseErrorCode) String() string { } func (RpcObjectListModifyDetailValuesResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 1, 0, 0} } type RpcObjectApplyTemplateResponseErrorCode int32 @@ -3103,7 +3159,7 @@ func (x RpcObjectApplyTemplateResponseErrorCode) String() string { } func (RpcObjectApplyTemplateResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 1, 0, 0} } type RpcObjectListExportResponseErrorCode int32 @@ -3131,7 +3187,7 @@ func (x RpcObjectListExportResponseErrorCode) String() string { } func (RpcObjectListExportResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 1, 0, 0} } type RpcObjectImportRequestMode int32 @@ -3156,7 +3212,7 @@ func (x RpcObjectImportRequestMode) String() string { } func (RpcObjectImportRequestMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 0} } type RpcObjectImportRequestPbParamsType int32 @@ -3181,7 +3237,7 @@ func (x RpcObjectImportRequestPbParamsType) String() string { } func (RpcObjectImportRequestPbParamsType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 5, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 5, 0} } type RpcObjectImportRequestCsvParamsMode int32 @@ -3206,7 +3262,7 @@ func (x RpcObjectImportRequestCsvParamsMode) String() string { } func (RpcObjectImportRequestCsvParamsMode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 6, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 6, 0} } type RpcObjectImportResponseErrorCode int32 @@ -3252,7 +3308,7 @@ func (x RpcObjectImportResponseErrorCode) String() string { } func (RpcObjectImportResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 1, 0, 0} } type RpcObjectImportNotionValidateTokenResponseErrorCode int32 @@ -3295,7 +3351,7 @@ func (x RpcObjectImportNotionValidateTokenResponseErrorCode) String() string { } func (RpcObjectImportNotionValidateTokenResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 2, 0, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 2, 0, 1, 0, 0} } type RpcObjectImportListResponseErrorCode int32 @@ -3326,7 +3382,7 @@ func (x RpcObjectImportListResponseErrorCode) String() string { } func (RpcObjectImportListResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 1, 0, 0} } type RpcObjectImportListImportResponseType int32 @@ -3357,7 +3413,7 @@ func (x RpcObjectImportListImportResponseType) String() string { } func (RpcObjectImportListImportResponseType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 2, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 2, 0} } type RpcObjectImportUseCaseRequestUseCase int32 @@ -3397,7 +3453,7 @@ func (x RpcObjectImportUseCaseRequestUseCase) String() string { } func (RpcObjectImportUseCaseRequestUseCase) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 50, 0, 0} } type RpcObjectImportUseCaseResponseErrorCode int32 @@ -3425,7 +3481,7 @@ func (x RpcObjectImportUseCaseResponseErrorCode) String() string { } func (RpcObjectImportUseCaseResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 50, 1, 0, 0} } type RpcObjectImportExperienceResponseErrorCode int32 @@ -3456,7 +3512,7 @@ func (x RpcObjectImportExperienceResponseErrorCode) String() string { } func (RpcObjectImportExperienceResponseErrorCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 1, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 51, 1, 0, 0} } type RpcObjectCollectionAddResponseErrorCode int32 @@ -7531,6 +7587,59 @@ func (RpcDebugPingResponseErrorCode) EnumDescriptor() ([]byte, []int) { return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 11, 1, 0, 0} } +type RpcDebugAnystoreObjectChangesRequestOrderBy int32 + +const ( + RpcDebugAnystoreObjectChangesRequest_ORDER_ID RpcDebugAnystoreObjectChangesRequestOrderBy = 0 + RpcDebugAnystoreObjectChangesRequest_ITERATION_ORDER RpcDebugAnystoreObjectChangesRequestOrderBy = 1 +) + +var RpcDebugAnystoreObjectChangesRequestOrderBy_name = map[int32]string{ + 0: "ORDER_ID", + 1: "ITERATION_ORDER", +} + +var RpcDebugAnystoreObjectChangesRequestOrderBy_value = map[string]int32{ + "ORDER_ID": 0, + "ITERATION_ORDER": 1, +} + +func (x RpcDebugAnystoreObjectChangesRequestOrderBy) String() string { + return proto.EnumName(RpcDebugAnystoreObjectChangesRequestOrderBy_name, int32(x)) +} + +func (RpcDebugAnystoreObjectChangesRequestOrderBy) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12, 0, 0} +} + +type RpcDebugAnystoreObjectChangesResponseErrorCode int32 + +const ( + RpcDebugAnystoreObjectChangesResponseError_NULL RpcDebugAnystoreObjectChangesResponseErrorCode = 0 + RpcDebugAnystoreObjectChangesResponseError_UNKNOWN_ERROR RpcDebugAnystoreObjectChangesResponseErrorCode = 1 + RpcDebugAnystoreObjectChangesResponseError_BAD_INPUT RpcDebugAnystoreObjectChangesResponseErrorCode = 2 +) + +var RpcDebugAnystoreObjectChangesResponseErrorCode_name = map[int32]string{ + 0: "NULL", + 1: "UNKNOWN_ERROR", + 2: "BAD_INPUT", +} + +var RpcDebugAnystoreObjectChangesResponseErrorCode_value = map[string]int32{ + "NULL": 0, + "UNKNOWN_ERROR": 1, + "BAD_INPUT": 2, +} + +func (x RpcDebugAnystoreObjectChangesResponseErrorCode) String() string { + return proto.EnumName(RpcDebugAnystoreObjectChangesResponseErrorCode_name, int32(x)) +} + +func (RpcDebugAnystoreObjectChangesResponseErrorCode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12, 1, 1, 0} +} + type RpcMetricsSetParametersResponseErrorCode int32 const ( @@ -18510,6 +18619,7 @@ type RpcObjectCreateRequest struct { TemplateId string `protobuf:"bytes,3,opt,name=templateId,proto3" json:"templateId,omitempty"` SpaceId string `protobuf:"bytes,4,opt,name=spaceId,proto3" json:"spaceId,omitempty"` ObjectTypeUniqueKey string `protobuf:"bytes,5,opt,name=objectTypeUniqueKey,proto3" json:"objectTypeUniqueKey,omitempty"` + WithChat bool `protobuf:"varint,6,opt,name=withChat,proto3" json:"withChat,omitempty"` } func (m *RpcObjectCreateRequest) Reset() { *m = RpcObjectCreateRequest{} } @@ -18580,6 +18690,13 @@ func (m *RpcObjectCreateRequest) GetObjectTypeUniqueKey() string { return "" } +func (m *RpcObjectCreateRequest) GetWithChat() bool { + if m != nil { + return m.WithChat + } + return false +} + type RpcObjectCreateResponse struct { Error *RpcObjectCreateResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` ObjectId string `protobuf:"bytes,3,opt,name=objectId,proto3" json:"objectId,omitempty"` @@ -18737,8 +18854,9 @@ func (m *RpcObjectCreateBookmark) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectCreateBookmark proto.InternalMessageInfo type RpcObjectCreateBookmarkRequest struct { - Details *types.Struct `protobuf:"bytes,1,opt,name=details,proto3" json:"details,omitempty"` - SpaceId string `protobuf:"bytes,2,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + Details *types.Struct `protobuf:"bytes,1,opt,name=details,proto3" json:"details,omitempty"` + SpaceId string `protobuf:"bytes,2,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + WithChat bool `protobuf:"varint,3,opt,name=withChat,proto3" json:"withChat,omitempty"` } func (m *RpcObjectCreateBookmarkRequest) Reset() { *m = RpcObjectCreateBookmarkRequest{} } @@ -18788,6 +18906,13 @@ func (m *RpcObjectCreateBookmarkRequest) GetSpaceId() string { return "" } +func (m *RpcObjectCreateBookmarkRequest) GetWithChat() bool { + if m != nil { + return m.WithChat + } + return false +} + type RpcObjectCreateBookmarkResponse struct { Error *RpcObjectCreateBookmarkResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` ObjectId string `protobuf:"bytes,2,opt,name=objectId,proto3" json:"objectId,omitempty"` @@ -19354,6 +19479,7 @@ type RpcObjectCreateSetRequest struct { TemplateId string `protobuf:"bytes,3,opt,name=templateId,proto3" json:"templateId,omitempty"` InternalFlags []*model.InternalFlag `protobuf:"bytes,4,rep,name=internalFlags,proto3" json:"internalFlags,omitempty"` SpaceId string `protobuf:"bytes,5,opt,name=spaceId,proto3" json:"spaceId,omitempty"` + WithChat bool `protobuf:"varint,6,opt,name=withChat,proto3" json:"withChat,omitempty"` } func (m *RpcObjectCreateSetRequest) Reset() { *m = RpcObjectCreateSetRequest{} } @@ -19424,6 +19550,13 @@ func (m *RpcObjectCreateSetRequest) GetSpaceId() string { return "" } +func (m *RpcObjectCreateSetRequest) GetWithChat() bool { + if m != nil { + return m.WithChat + } + return false +} + type RpcObjectCreateSetResponse struct { Error *RpcObjectCreateSetResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` ObjectId string `protobuf:"bytes,3,opt,name=objectId,proto3" json:"objectId,omitempty"` @@ -19796,6 +19929,7 @@ type RpcObjectCreateFromUrlRequest struct { Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` Details *types.Struct `protobuf:"bytes,4,opt,name=details,proto3" json:"details,omitempty"` AddPageContent bool `protobuf:"varint,5,opt,name=addPageContent,proto3" json:"addPageContent,omitempty"` + WithChat bool `protobuf:"varint,6,opt,name=withChat,proto3" json:"withChat,omitempty"` } func (m *RpcObjectCreateFromUrlRequest) Reset() { *m = RpcObjectCreateFromUrlRequest{} } @@ -19866,10 +20000,18 @@ func (m *RpcObjectCreateFromUrlRequest) GetAddPageContent() bool { return false } +func (m *RpcObjectCreateFromUrlRequest) GetWithChat() bool { + if m != nil { + return m.WithChat + } + return false +} + type RpcObjectCreateFromUrlResponse struct { Error *RpcObjectCreateFromUrlResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` ObjectId string `protobuf:"bytes,2,opt,name=objectId,proto3" json:"objectId,omitempty"` Details *types.Struct `protobuf:"bytes,3,opt,name=details,proto3" json:"details,omitempty"` + ChatId string `protobuf:"bytes,4,opt,name=chatId,proto3" json:"chatId,omitempty"` } func (m *RpcObjectCreateFromUrlResponse) Reset() { *m = RpcObjectCreateFromUrlResponse{} } @@ -19926,6 +20068,13 @@ func (m *RpcObjectCreateFromUrlResponse) GetDetails() *types.Struct { return nil } +func (m *RpcObjectCreateFromUrlResponse) GetChatId() string { + if m != nil { + return m.ChatId + } + return "" +} + type RpcObjectCreateFromUrlResponseError struct { Code RpcObjectCreateFromUrlResponseErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=anytype.RpcObjectCreateFromUrlResponseErrorCode" json:"code,omitempty"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` @@ -21345,6 +21494,7 @@ func (m *RpcObjectSearch) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSearch proto.InternalMessageInfo type RpcObjectSearchRequest struct { + SpaceId string `protobuf:"bytes,8,opt,name=spaceId,proto3" json:"spaceId,omitempty"` Filters []*model.BlockContentDataviewFilter `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` Sorts []*model.BlockContentDataviewSort `protobuf:"bytes,2,rep,name=sorts,proto3" json:"sorts,omitempty"` FullText string `protobuf:"bytes,3,opt,name=fullText,proto3" json:"fullText,omitempty"` @@ -21389,6 +21539,13 @@ func (m *RpcObjectSearchRequest) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSearchRequest proto.InternalMessageInfo +func (m *RpcObjectSearchRequest) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + func (m *RpcObjectSearchRequest) GetFilters() []*model.BlockContentDataviewFilter { if m != nil { return m.Filters @@ -21579,6 +21736,7 @@ func (m *RpcObjectSearchWithMeta) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSearchWithMeta proto.InternalMessageInfo type RpcObjectSearchWithMetaRequest struct { + SpaceId string `protobuf:"bytes,11,opt,name=spaceId,proto3" json:"spaceId,omitempty"` Filters []*model.BlockContentDataviewFilter `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` Sorts []*model.BlockContentDataviewSort `protobuf:"bytes,2,rep,name=sorts,proto3" json:"sorts,omitempty"` FullText string `protobuf:"bytes,3,opt,name=fullText,proto3" json:"fullText,omitempty"` @@ -21626,6 +21784,13 @@ func (m *RpcObjectSearchWithMetaRequest) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSearchWithMetaRequest proto.InternalMessageInfo +func (m *RpcObjectSearchWithMetaRequest) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + func (m *RpcObjectSearchWithMetaRequest) GetFilters() []*model.BlockContentDataviewFilter { if m != nil { return m.Filters @@ -22178,6 +22343,7 @@ func (m *RpcObjectSearchSubscribe) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSearchSubscribe proto.InternalMessageInfo type RpcObjectSearchSubscribeRequest struct { + SpaceId string `protobuf:"bytes,15,opt,name=spaceId,proto3" json:"spaceId,omitempty"` // (optional) subscription identifier // client can provide some string or middleware will generate it automatically // if subId is already registered on middleware, the new query will replace previous subscription @@ -22195,9 +22361,8 @@ type RpcObjectSearchSubscribeRequest struct { // (optional) pagination: middleware will return results after given id AfterId string `protobuf:"bytes,8,opt,name=afterId,proto3" json:"afterId,omitempty"` // (optional) pagination: middleware will return results before given id - BeforeId string `protobuf:"bytes,9,opt,name=beforeId,proto3" json:"beforeId,omitempty"` - Source []string `protobuf:"bytes,10,rep,name=source,proto3" json:"source,omitempty"` - IgnoreWorkspace string `protobuf:"bytes,12,opt,name=ignoreWorkspace,proto3" json:"ignoreWorkspace,omitempty"` + BeforeId string `protobuf:"bytes,9,opt,name=beforeId,proto3" json:"beforeId,omitempty"` + Source []string `protobuf:"bytes,10,rep,name=source,proto3" json:"source,omitempty"` // disable dependent subscription NoDepSubscription bool `protobuf:"varint,13,opt,name=noDepSubscription,proto3" json:"noDepSubscription,omitempty"` CollectionId string `protobuf:"bytes,14,opt,name=collectionId,proto3" json:"collectionId,omitempty"` @@ -22236,6 +22401,13 @@ func (m *RpcObjectSearchSubscribeRequest) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSearchSubscribeRequest proto.InternalMessageInfo +func (m *RpcObjectSearchSubscribeRequest) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + func (m *RpcObjectSearchSubscribeRequest) GetSubId() string { if m != nil { return m.SubId @@ -22299,13 +22471,6 @@ func (m *RpcObjectSearchSubscribeRequest) GetSource() []string { return nil } -func (m *RpcObjectSearchSubscribeRequest) GetIgnoreWorkspace() string { - if m != nil { - return m.IgnoreWorkspace - } - return "" -} - func (m *RpcObjectSearchSubscribeRequest) GetNoDepSubscription() bool { if m != nil { return m.NoDepSubscription @@ -22448,6 +22613,469 @@ func (m *RpcObjectSearchSubscribeResponseError) GetDescription() string { return "" } +type RpcObjectCrossSpaceSearchSubscribe struct { +} + +func (m *RpcObjectCrossSpaceSearchSubscribe) Reset() { *m = RpcObjectCrossSpaceSearchSubscribe{} } +func (m *RpcObjectCrossSpaceSearchSubscribe) String() string { return proto.CompactTextString(m) } +func (*RpcObjectCrossSpaceSearchSubscribe) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchSubscribe) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21} +} +func (m *RpcObjectCrossSpaceSearchSubscribe) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchSubscribe) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribe.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchSubscribe) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribe.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchSubscribe) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchSubscribe) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribe.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribe proto.InternalMessageInfo + +type RpcObjectCrossSpaceSearchSubscribeRequest struct { + // (optional) subscription identifier + // client can provide some string or middleware will generate it automatically + // if subId is already registered on middleware, the new query will replace previous subscription + SubId string `protobuf:"bytes,1,opt,name=subId,proto3" json:"subId,omitempty"` + // filters + Filters []*model.BlockContentDataviewFilter `protobuf:"bytes,2,rep,name=filters,proto3" json:"filters,omitempty"` + // sorts + Sorts []*model.BlockContentDataviewSort `protobuf:"bytes,3,rep,name=sorts,proto3" json:"sorts,omitempty"` + // (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent + Keys []string `protobuf:"bytes,7,rep,name=keys,proto3" json:"keys,omitempty"` + Source []string `protobuf:"bytes,10,rep,name=source,proto3" json:"source,omitempty"` + // disable dependent subscription + NoDepSubscription bool `protobuf:"varint,13,opt,name=noDepSubscription,proto3" json:"noDepSubscription,omitempty"` + CollectionId string `protobuf:"bytes,14,opt,name=collectionId,proto3" json:"collectionId,omitempty"` +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) Reset() { + *m = RpcObjectCrossSpaceSearchSubscribeRequest{} +} +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) String() string { + return proto.CompactTextString(m) +} +func (*RpcObjectCrossSpaceSearchSubscribeRequest) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchSubscribeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 0} +} +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeRequest.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeRequest proto.InternalMessageInfo + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetSubId() string { + if m != nil { + return m.SubId + } + return "" +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetFilters() []*model.BlockContentDataviewFilter { + if m != nil { + return m.Filters + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetSorts() []*model.BlockContentDataviewSort { + if m != nil { + return m.Sorts + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetKeys() []string { + if m != nil { + return m.Keys + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetSource() []string { + if m != nil { + return m.Source + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetNoDepSubscription() bool { + if m != nil { + return m.NoDepSubscription + } + return false +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) GetCollectionId() string { + if m != nil { + return m.CollectionId + } + return "" +} + +type RpcObjectCrossSpaceSearchSubscribeResponse struct { + Error *RpcObjectCrossSpaceSearchSubscribeResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Records []*types.Struct `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` + Dependencies []*types.Struct `protobuf:"bytes,3,rep,name=dependencies,proto3" json:"dependencies,omitempty"` + SubId string `protobuf:"bytes,4,opt,name=subId,proto3" json:"subId,omitempty"` + Counters *EventObjectSubscriptionCounters `protobuf:"bytes,5,opt,name=counters,proto3" json:"counters,omitempty"` +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) Reset() { + *m = RpcObjectCrossSpaceSearchSubscribeResponse{} +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) String() string { + return proto.CompactTextString(m) +} +func (*RpcObjectCrossSpaceSearchSubscribeResponse) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchSubscribeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 1} +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponse.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponse proto.InternalMessageInfo + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) GetError() *RpcObjectCrossSpaceSearchSubscribeResponseError { + if m != nil { + return m.Error + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) GetRecords() []*types.Struct { + if m != nil { + return m.Records + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) GetDependencies() []*types.Struct { + if m != nil { + return m.Dependencies + } + return nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) GetSubId() string { + if m != nil { + return m.SubId + } + return "" +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) GetCounters() *EventObjectSubscriptionCounters { + if m != nil { + return m.Counters + } + return nil +} + +type RpcObjectCrossSpaceSearchSubscribeResponseError struct { + Code RpcObjectCrossSpaceSearchSubscribeResponseErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=anytype.RpcObjectCrossSpaceSearchSubscribeResponseErrorCode" json:"code,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) Reset() { + *m = RpcObjectCrossSpaceSearchSubscribeResponseError{} +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) String() string { + return proto.CompactTextString(m) +} +func (*RpcObjectCrossSpaceSearchSubscribeResponseError) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchSubscribeResponseError) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 1, 0} +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponseError.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponseError.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponseError.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchSubscribeResponseError proto.InternalMessageInfo + +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) GetCode() RpcObjectCrossSpaceSearchSubscribeResponseErrorCode { + if m != nil { + return m.Code + } + return RpcObjectCrossSpaceSearchSubscribeResponseError_NULL +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +type RpcObjectCrossSpaceSearchUnsubscribe struct { +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribe) Reset() { *m = RpcObjectCrossSpaceSearchUnsubscribe{} } +func (m *RpcObjectCrossSpaceSearchUnsubscribe) String() string { return proto.CompactTextString(m) } +func (*RpcObjectCrossSpaceSearchUnsubscribe) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchUnsubscribe) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribe) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribe) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribe.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchUnsubscribe) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribe.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribe) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchUnsubscribe) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribe.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribe proto.InternalMessageInfo + +type RpcObjectCrossSpaceSearchUnsubscribeRequest struct { + SubId string `protobuf:"bytes,1,opt,name=subId,proto3" json:"subId,omitempty"` +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) Reset() { + *m = RpcObjectCrossSpaceSearchUnsubscribeRequest{} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) String() string { + return proto.CompactTextString(m) +} +func (*RpcObjectCrossSpaceSearchUnsubscribeRequest) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchUnsubscribeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 0} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeRequest.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeRequest proto.InternalMessageInfo + +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) GetSubId() string { + if m != nil { + return m.SubId + } + return "" +} + +type RpcObjectCrossSpaceSearchUnsubscribeResponse struct { + Error *RpcObjectCrossSpaceSearchUnsubscribeResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) Reset() { + *m = RpcObjectCrossSpaceSearchUnsubscribeResponse{} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) String() string { + return proto.CompactTextString(m) +} +func (*RpcObjectCrossSpaceSearchUnsubscribeResponse) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchUnsubscribeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 1} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponse.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponse proto.InternalMessageInfo + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) GetError() *RpcObjectCrossSpaceSearchUnsubscribeResponseError { + if m != nil { + return m.Error + } + return nil +} + +type RpcObjectCrossSpaceSearchUnsubscribeResponseError struct { + Code RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=anytype.RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode" json:"code,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) Reset() { + *m = RpcObjectCrossSpaceSearchUnsubscribeResponseError{} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) String() string { + return proto.CompactTextString(m) +} +func (*RpcObjectCrossSpaceSearchUnsubscribeResponseError) ProtoMessage() {} +func (*RpcObjectCrossSpaceSearchUnsubscribeResponseError) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 1, 0} +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponseError.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponseError.Merge(m, src) +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) XXX_Size() int { + return m.Size() +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) XXX_DiscardUnknown() { + xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponseError.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcObjectCrossSpaceSearchUnsubscribeResponseError proto.InternalMessageInfo + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) GetCode() RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode { + if m != nil { + return m.Code + } + return RpcObjectCrossSpaceSearchUnsubscribeResponseError_NULL +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + type RpcObjectGroupsSubscribe struct { } @@ -22455,7 +23083,7 @@ func (m *RpcObjectGroupsSubscribe) Reset() { *m = RpcObjectGroupsSubscri func (m *RpcObjectGroupsSubscribe) String() string { return proto.CompactTextString(m) } func (*RpcObjectGroupsSubscribe) ProtoMessage() {} func (*RpcObjectGroupsSubscribe) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23} } func (m *RpcObjectGroupsSubscribe) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22497,7 +23125,7 @@ func (m *RpcObjectGroupsSubscribeRequest) Reset() { *m = RpcObjectGroups func (m *RpcObjectGroupsSubscribeRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectGroupsSubscribeRequest) ProtoMessage() {} func (*RpcObjectGroupsSubscribeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 0} } func (m *RpcObjectGroupsSubscribeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22578,7 +23206,7 @@ func (m *RpcObjectGroupsSubscribeResponse) Reset() { *m = RpcObjectGroup func (m *RpcObjectGroupsSubscribeResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectGroupsSubscribeResponse) ProtoMessage() {} func (*RpcObjectGroupsSubscribeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 1} } func (m *RpcObjectGroupsSubscribeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22637,7 +23265,7 @@ func (m *RpcObjectGroupsSubscribeResponseError) Reset() { *m = RpcObject func (m *RpcObjectGroupsSubscribeResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectGroupsSubscribeResponseError) ProtoMessage() {} func (*RpcObjectGroupsSubscribeResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 21, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 1, 0} } func (m *RpcObjectGroupsSubscribeResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22687,7 +23315,7 @@ func (m *RpcObjectSubscribeIds) Reset() { *m = RpcObjectSubscribeIds{} } func (m *RpcObjectSubscribeIds) String() string { return proto.CompactTextString(m) } func (*RpcObjectSubscribeIds) ProtoMessage() {} func (*RpcObjectSubscribeIds) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24} } func (m *RpcObjectSubscribeIds) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22717,6 +23345,7 @@ func (m *RpcObjectSubscribeIds) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSubscribeIds proto.InternalMessageInfo type RpcObjectSubscribeIdsRequest struct { + SpaceId string `protobuf:"bytes,13,opt,name=spaceId,proto3" json:"spaceId,omitempty"` // (optional) subscription identifier // client can provide some string or middleware will generate it automatically // if subId is already registered on middleware, the new query will replace previous subscription @@ -22725,8 +23354,7 @@ type RpcObjectSubscribeIdsRequest struct { Ids []string `protobuf:"bytes,2,rep,name=ids,proto3" json:"ids,omitempty"` // sorts // (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent - Keys []string `protobuf:"bytes,3,rep,name=keys,proto3" json:"keys,omitempty"` - IgnoreWorkspace string `protobuf:"bytes,11,opt,name=ignoreWorkspace,proto3" json:"ignoreWorkspace,omitempty"` + Keys []string `protobuf:"bytes,3,rep,name=keys,proto3" json:"keys,omitempty"` // disable dependent subscription NoDepSubscription bool `protobuf:"varint,12,opt,name=noDepSubscription,proto3" json:"noDepSubscription,omitempty"` } @@ -22735,7 +23363,7 @@ func (m *RpcObjectSubscribeIdsRequest) Reset() { *m = RpcObjectSubscribe func (m *RpcObjectSubscribeIdsRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSubscribeIdsRequest) ProtoMessage() {} func (*RpcObjectSubscribeIdsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 0} } func (m *RpcObjectSubscribeIdsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22764,6 +23392,13 @@ func (m *RpcObjectSubscribeIdsRequest) XXX_DiscardUnknown() { var xxx_messageInfo_RpcObjectSubscribeIdsRequest proto.InternalMessageInfo +func (m *RpcObjectSubscribeIdsRequest) GetSpaceId() string { + if m != nil { + return m.SpaceId + } + return "" +} + func (m *RpcObjectSubscribeIdsRequest) GetSubId() string { if m != nil { return m.SubId @@ -22785,13 +23420,6 @@ func (m *RpcObjectSubscribeIdsRequest) GetKeys() []string { return nil } -func (m *RpcObjectSubscribeIdsRequest) GetIgnoreWorkspace() string { - if m != nil { - return m.IgnoreWorkspace - } - return "" -} - func (m *RpcObjectSubscribeIdsRequest) GetNoDepSubscription() bool { if m != nil { return m.NoDepSubscription @@ -22810,7 +23438,7 @@ func (m *RpcObjectSubscribeIdsResponse) Reset() { *m = RpcObjectSubscrib func (m *RpcObjectSubscribeIdsResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSubscribeIdsResponse) ProtoMessage() {} func (*RpcObjectSubscribeIdsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 1} } func (m *RpcObjectSubscribeIdsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22876,7 +23504,7 @@ func (m *RpcObjectSubscribeIdsResponseError) Reset() { *m = RpcObjectSub func (m *RpcObjectSubscribeIdsResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSubscribeIdsResponseError) ProtoMessage() {} func (*RpcObjectSubscribeIdsResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 22, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 1, 0} } func (m *RpcObjectSubscribeIdsResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22926,7 +23554,7 @@ func (m *RpcObjectSearchUnsubscribe) Reset() { *m = RpcObjectSearchUnsub func (m *RpcObjectSearchUnsubscribe) String() string { return proto.CompactTextString(m) } func (*RpcObjectSearchUnsubscribe) ProtoMessage() {} func (*RpcObjectSearchUnsubscribe) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25} } func (m *RpcObjectSearchUnsubscribe) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -22963,7 +23591,7 @@ func (m *RpcObjectSearchUnsubscribeRequest) Reset() { *m = RpcObjectSear func (m *RpcObjectSearchUnsubscribeRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSearchUnsubscribeRequest) ProtoMessage() {} func (*RpcObjectSearchUnsubscribeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 0} } func (m *RpcObjectSearchUnsubscribeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23007,7 +23635,7 @@ func (m *RpcObjectSearchUnsubscribeResponse) Reset() { *m = RpcObjectSea func (m *RpcObjectSearchUnsubscribeResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSearchUnsubscribeResponse) ProtoMessage() {} func (*RpcObjectSearchUnsubscribeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 1} } func (m *RpcObjectSearchUnsubscribeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23054,7 +23682,7 @@ func (m *RpcObjectSearchUnsubscribeResponseError) Reset() { func (m *RpcObjectSearchUnsubscribeResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSearchUnsubscribeResponseError) ProtoMessage() {} func (*RpcObjectSearchUnsubscribeResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 23, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 1, 0} } func (m *RpcObjectSearchUnsubscribeResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23104,7 +23732,7 @@ func (m *RpcObjectSetLayout) Reset() { *m = RpcObjectSetLayout{} } func (m *RpcObjectSetLayout) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetLayout) ProtoMessage() {} func (*RpcObjectSetLayout) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26} } func (m *RpcObjectSetLayout) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23142,7 +23770,7 @@ func (m *RpcObjectSetLayoutRequest) Reset() { *m = RpcObjectSetLayoutReq func (m *RpcObjectSetLayoutRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetLayoutRequest) ProtoMessage() {} func (*RpcObjectSetLayoutRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 0} } func (m *RpcObjectSetLayoutRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23194,7 +23822,7 @@ func (m *RpcObjectSetLayoutResponse) Reset() { *m = RpcObjectSetLayoutRe func (m *RpcObjectSetLayoutResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetLayoutResponse) ProtoMessage() {} func (*RpcObjectSetLayoutResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 1} } func (m *RpcObjectSetLayoutResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23246,7 +23874,7 @@ func (m *RpcObjectSetLayoutResponseError) Reset() { *m = RpcObjectSetLay func (m *RpcObjectSetLayoutResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetLayoutResponseError) ProtoMessage() {} func (*RpcObjectSetLayoutResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 24, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 1, 0} } func (m *RpcObjectSetLayoutResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23296,7 +23924,7 @@ func (m *RpcObjectSetIsFavorite) Reset() { *m = RpcObjectSetIsFavorite{} func (m *RpcObjectSetIsFavorite) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsFavorite) ProtoMessage() {} func (*RpcObjectSetIsFavorite) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27} } func (m *RpcObjectSetIsFavorite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23334,7 +23962,7 @@ func (m *RpcObjectSetIsFavoriteRequest) Reset() { *m = RpcObjectSetIsFav func (m *RpcObjectSetIsFavoriteRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsFavoriteRequest) ProtoMessage() {} func (*RpcObjectSetIsFavoriteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 0} } func (m *RpcObjectSetIsFavoriteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23386,7 +24014,7 @@ func (m *RpcObjectSetIsFavoriteResponse) Reset() { *m = RpcObjectSetIsFa func (m *RpcObjectSetIsFavoriteResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsFavoriteResponse) ProtoMessage() {} func (*RpcObjectSetIsFavoriteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 1} } func (m *RpcObjectSetIsFavoriteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23438,7 +24066,7 @@ func (m *RpcObjectSetIsFavoriteResponseError) Reset() { *m = RpcObjectSe func (m *RpcObjectSetIsFavoriteResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsFavoriteResponseError) ProtoMessage() {} func (*RpcObjectSetIsFavoriteResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 25, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 1, 0} } func (m *RpcObjectSetIsFavoriteResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23488,7 +24116,7 @@ func (m *RpcObjectSetIsArchived) Reset() { *m = RpcObjectSetIsArchived{} func (m *RpcObjectSetIsArchived) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsArchived) ProtoMessage() {} func (*RpcObjectSetIsArchived) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28} } func (m *RpcObjectSetIsArchived) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23526,7 +24154,7 @@ func (m *RpcObjectSetIsArchivedRequest) Reset() { *m = RpcObjectSetIsArc func (m *RpcObjectSetIsArchivedRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsArchivedRequest) ProtoMessage() {} func (*RpcObjectSetIsArchivedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 0} } func (m *RpcObjectSetIsArchivedRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23577,7 +24205,7 @@ func (m *RpcObjectSetIsArchivedResponse) Reset() { *m = RpcObjectSetIsAr func (m *RpcObjectSetIsArchivedResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsArchivedResponse) ProtoMessage() {} func (*RpcObjectSetIsArchivedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 1} } func (m *RpcObjectSetIsArchivedResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23622,7 +24250,7 @@ func (m *RpcObjectSetIsArchivedResponseError) Reset() { *m = RpcObjectSe func (m *RpcObjectSetIsArchivedResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetIsArchivedResponseError) ProtoMessage() {} func (*RpcObjectSetIsArchivedResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 26, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 1, 0} } func (m *RpcObjectSetIsArchivedResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23672,7 +24300,7 @@ func (m *RpcObjectSetSource) Reset() { *m = RpcObjectSetSource{} } func (m *RpcObjectSetSource) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetSource) ProtoMessage() {} func (*RpcObjectSetSource) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29} } func (m *RpcObjectSetSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23710,7 +24338,7 @@ func (m *RpcObjectSetSourceRequest) Reset() { *m = RpcObjectSetSourceReq func (m *RpcObjectSetSourceRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetSourceRequest) ProtoMessage() {} func (*RpcObjectSetSourceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 0} } func (m *RpcObjectSetSourceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23762,7 +24390,7 @@ func (m *RpcObjectSetSourceResponse) Reset() { *m = RpcObjectSetSourceRe func (m *RpcObjectSetSourceResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetSourceResponse) ProtoMessage() {} func (*RpcObjectSetSourceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 1} } func (m *RpcObjectSetSourceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23814,7 +24442,7 @@ func (m *RpcObjectSetSourceResponseError) Reset() { *m = RpcObjectSetSou func (m *RpcObjectSetSourceResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetSourceResponseError) ProtoMessage() {} func (*RpcObjectSetSourceResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 27, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 1, 0} } func (m *RpcObjectSetSourceResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23864,7 +24492,7 @@ func (m *RpcObjectWorkspaceSetDashboard) Reset() { *m = RpcObjectWorkspa func (m *RpcObjectWorkspaceSetDashboard) String() string { return proto.CompactTextString(m) } func (*RpcObjectWorkspaceSetDashboard) ProtoMessage() {} func (*RpcObjectWorkspaceSetDashboard) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30} } func (m *RpcObjectWorkspaceSetDashboard) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23902,7 +24530,7 @@ func (m *RpcObjectWorkspaceSetDashboardRequest) Reset() { *m = RpcObject func (m *RpcObjectWorkspaceSetDashboardRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectWorkspaceSetDashboardRequest) ProtoMessage() {} func (*RpcObjectWorkspaceSetDashboardRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 0} } func (m *RpcObjectWorkspaceSetDashboardRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -23957,7 +24585,7 @@ func (m *RpcObjectWorkspaceSetDashboardResponse) Reset() { func (m *RpcObjectWorkspaceSetDashboardResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectWorkspaceSetDashboardResponse) ProtoMessage() {} func (*RpcObjectWorkspaceSetDashboardResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 1} } func (m *RpcObjectWorkspaceSetDashboardResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24020,7 +24648,7 @@ func (m *RpcObjectWorkspaceSetDashboardResponseError) String() string { } func (*RpcObjectWorkspaceSetDashboardResponseError) ProtoMessage() {} func (*RpcObjectWorkspaceSetDashboardResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 28, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 1, 0} } func (m *RpcObjectWorkspaceSetDashboardResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24070,7 +24698,7 @@ func (m *RpcObjectSetObjectType) Reset() { *m = RpcObjectSetObjectType{} func (m *RpcObjectSetObjectType) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetObjectType) ProtoMessage() {} func (*RpcObjectSetObjectType) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31} } func (m *RpcObjectSetObjectType) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24108,7 +24736,7 @@ func (m *RpcObjectSetObjectTypeRequest) Reset() { *m = RpcObjectSetObjec func (m *RpcObjectSetObjectTypeRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetObjectTypeRequest) ProtoMessage() {} func (*RpcObjectSetObjectTypeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 0} } func (m *RpcObjectSetObjectTypeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24160,7 +24788,7 @@ func (m *RpcObjectSetObjectTypeResponse) Reset() { *m = RpcObjectSetObje func (m *RpcObjectSetObjectTypeResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetObjectTypeResponse) ProtoMessage() {} func (*RpcObjectSetObjectTypeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 1} } func (m *RpcObjectSetObjectTypeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24212,7 +24840,7 @@ func (m *RpcObjectSetObjectTypeResponseError) Reset() { *m = RpcObjectSe func (m *RpcObjectSetObjectTypeResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetObjectTypeResponseError) ProtoMessage() {} func (*RpcObjectSetObjectTypeResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 29, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 1, 0} } func (m *RpcObjectSetObjectTypeResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24262,7 +24890,7 @@ func (m *RpcObjectSetInternalFlags) Reset() { *m = RpcObjectSetInternalF func (m *RpcObjectSetInternalFlags) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetInternalFlags) ProtoMessage() {} func (*RpcObjectSetInternalFlags) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32} } func (m *RpcObjectSetInternalFlags) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24300,7 +24928,7 @@ func (m *RpcObjectSetInternalFlagsRequest) Reset() { *m = RpcObjectSetIn func (m *RpcObjectSetInternalFlagsRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetInternalFlagsRequest) ProtoMessage() {} func (*RpcObjectSetInternalFlagsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 0} } func (m *RpcObjectSetInternalFlagsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24352,7 +24980,7 @@ func (m *RpcObjectSetInternalFlagsResponse) Reset() { *m = RpcObjectSetI func (m *RpcObjectSetInternalFlagsResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetInternalFlagsResponse) ProtoMessage() {} func (*RpcObjectSetInternalFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 1} } func (m *RpcObjectSetInternalFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24406,7 +25034,7 @@ func (m *RpcObjectSetInternalFlagsResponseError) Reset() { func (m *RpcObjectSetInternalFlagsResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetInternalFlagsResponseError) ProtoMessage() {} func (*RpcObjectSetInternalFlagsResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 30, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 1, 0} } func (m *RpcObjectSetInternalFlagsResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24456,7 +25084,7 @@ func (m *RpcObjectSetDetails) Reset() { *m = RpcObjectSetDetails{} } func (m *RpcObjectSetDetails) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetDetails) ProtoMessage() {} func (*RpcObjectSetDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33} } func (m *RpcObjectSetDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24494,7 +25122,7 @@ func (m *RpcObjectSetDetailsRequest) Reset() { *m = RpcObjectSetDetailsR func (m *RpcObjectSetDetailsRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetDetailsRequest) ProtoMessage() {} func (*RpcObjectSetDetailsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 0} } func (m *RpcObjectSetDetailsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24546,7 +25174,7 @@ func (m *RpcObjectSetDetailsResponse) Reset() { *m = RpcObjectSetDetails func (m *RpcObjectSetDetailsResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetDetailsResponse) ProtoMessage() {} func (*RpcObjectSetDetailsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 1} } func (m *RpcObjectSetDetailsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24598,7 +25226,7 @@ func (m *RpcObjectSetDetailsResponseError) Reset() { *m = RpcObjectSetDe func (m *RpcObjectSetDetailsResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectSetDetailsResponseError) ProtoMessage() {} func (*RpcObjectSetDetailsResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 31, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 1, 0} } func (m *RpcObjectSetDetailsResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24648,7 +25276,7 @@ func (m *RpcObjectToSet) Reset() { *m = RpcObjectToSet{} } func (m *RpcObjectToSet) String() string { return proto.CompactTextString(m) } func (*RpcObjectToSet) ProtoMessage() {} func (*RpcObjectToSet) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 34} } func (m *RpcObjectToSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24686,7 +25314,7 @@ func (m *RpcObjectToSetRequest) Reset() { *m = RpcObjectToSetRequest{} } func (m *RpcObjectToSetRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectToSetRequest) ProtoMessage() {} func (*RpcObjectToSetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 34, 0} } func (m *RpcObjectToSetRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24737,7 +25365,7 @@ func (m *RpcObjectToSetResponse) Reset() { *m = RpcObjectToSetResponse{} func (m *RpcObjectToSetResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectToSetResponse) ProtoMessage() {} func (*RpcObjectToSetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 34, 1} } func (m *RpcObjectToSetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24782,7 +25410,7 @@ func (m *RpcObjectToSetResponseError) Reset() { *m = RpcObjectToSetRespo func (m *RpcObjectToSetResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectToSetResponseError) ProtoMessage() {} func (*RpcObjectToSetResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 32, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 34, 1, 0} } func (m *RpcObjectToSetResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24832,7 +25460,7 @@ func (m *RpcObjectToCollection) Reset() { *m = RpcObjectToCollection{} } func (m *RpcObjectToCollection) String() string { return proto.CompactTextString(m) } func (*RpcObjectToCollection) ProtoMessage() {} func (*RpcObjectToCollection) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35} } func (m *RpcObjectToCollection) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24869,7 +25497,7 @@ func (m *RpcObjectToCollectionRequest) Reset() { *m = RpcObjectToCollect func (m *RpcObjectToCollectionRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectToCollectionRequest) ProtoMessage() {} func (*RpcObjectToCollectionRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 0} } func (m *RpcObjectToCollectionRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24913,7 +25541,7 @@ func (m *RpcObjectToCollectionResponse) Reset() { *m = RpcObjectToCollec func (m *RpcObjectToCollectionResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectToCollectionResponse) ProtoMessage() {} func (*RpcObjectToCollectionResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 1} } func (m *RpcObjectToCollectionResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -24958,7 +25586,7 @@ func (m *RpcObjectToCollectionResponseError) Reset() { *m = RpcObjectToC func (m *RpcObjectToCollectionResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectToCollectionResponseError) ProtoMessage() {} func (*RpcObjectToCollectionResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 33, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 1, 0} } func (m *RpcObjectToCollectionResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25011,7 +25639,7 @@ func (m *RpcObjectUndoRedoCounter) Reset() { *m = RpcObjectUndoRedoCount func (m *RpcObjectUndoRedoCounter) String() string { return proto.CompactTextString(m) } func (*RpcObjectUndoRedoCounter) ProtoMessage() {} func (*RpcObjectUndoRedoCounter) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 34} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 36} } func (m *RpcObjectUndoRedoCounter) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25061,7 +25689,7 @@ func (m *RpcObjectUndo) Reset() { *m = RpcObjectUndo{} } func (m *RpcObjectUndo) String() string { return proto.CompactTextString(m) } func (*RpcObjectUndo) ProtoMessage() {} func (*RpcObjectUndo) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37} } func (m *RpcObjectUndo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25098,7 +25726,7 @@ func (m *RpcObjectUndoRequest) Reset() { *m = RpcObjectUndoRequest{} } func (m *RpcObjectUndoRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectUndoRequest) ProtoMessage() {} func (*RpcObjectUndoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 0} } func (m *RpcObjectUndoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25146,7 +25774,7 @@ func (m *RpcObjectUndoResponse) Reset() { *m = RpcObjectUndoResponse{} } func (m *RpcObjectUndoResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectUndoResponse) ProtoMessage() {} func (*RpcObjectUndoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 1} } func (m *RpcObjectUndoResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25219,7 +25847,7 @@ func (m *RpcObjectUndoResponseError) Reset() { *m = RpcObjectUndoRespons func (m *RpcObjectUndoResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectUndoResponseError) ProtoMessage() {} func (*RpcObjectUndoResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 35, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 1, 0} } func (m *RpcObjectUndoResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25269,7 +25897,7 @@ func (m *RpcObjectRedo) Reset() { *m = RpcObjectRedo{} } func (m *RpcObjectRedo) String() string { return proto.CompactTextString(m) } func (*RpcObjectRedo) ProtoMessage() {} func (*RpcObjectRedo) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 36} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38} } func (m *RpcObjectRedo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25306,7 +25934,7 @@ func (m *RpcObjectRedoRequest) Reset() { *m = RpcObjectRedoRequest{} } func (m *RpcObjectRedoRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectRedoRequest) ProtoMessage() {} func (*RpcObjectRedoRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 36, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 0} } func (m *RpcObjectRedoRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25354,7 +25982,7 @@ func (m *RpcObjectRedoResponse) Reset() { *m = RpcObjectRedoResponse{} } func (m *RpcObjectRedoResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectRedoResponse) ProtoMessage() {} func (*RpcObjectRedoResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 36, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 1} } func (m *RpcObjectRedoResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25427,7 +26055,7 @@ func (m *RpcObjectRedoResponseError) Reset() { *m = RpcObjectRedoRespons func (m *RpcObjectRedoResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectRedoResponseError) ProtoMessage() {} func (*RpcObjectRedoResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 36, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 1, 0} } func (m *RpcObjectRedoResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25477,7 +26105,7 @@ func (m *RpcObjectListDuplicate) Reset() { *m = RpcObjectListDuplicate{} func (m *RpcObjectListDuplicate) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDuplicate) ProtoMessage() {} func (*RpcObjectListDuplicate) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39} } func (m *RpcObjectListDuplicate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25514,7 +26142,7 @@ func (m *RpcObjectListDuplicateRequest) Reset() { *m = RpcObjectListDupl func (m *RpcObjectListDuplicateRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDuplicateRequest) ProtoMessage() {} func (*RpcObjectListDuplicateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 0} } func (m *RpcObjectListDuplicateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25559,7 +26187,7 @@ func (m *RpcObjectListDuplicateResponse) Reset() { *m = RpcObjectListDup func (m *RpcObjectListDuplicateResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDuplicateResponse) ProtoMessage() {} func (*RpcObjectListDuplicateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 1} } func (m *RpcObjectListDuplicateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25611,7 +26239,7 @@ func (m *RpcObjectListDuplicateResponseError) Reset() { *m = RpcObjectLi func (m *RpcObjectListDuplicateResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDuplicateResponseError) ProtoMessage() {} func (*RpcObjectListDuplicateResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 37, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 1, 0} } func (m *RpcObjectListDuplicateResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25661,7 +26289,7 @@ func (m *RpcObjectListDelete) Reset() { *m = RpcObjectListDelete{} } func (m *RpcObjectListDelete) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDelete) ProtoMessage() {} func (*RpcObjectListDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40} } func (m *RpcObjectListDelete) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25699,7 +26327,7 @@ func (m *RpcObjectListDeleteRequest) Reset() { *m = RpcObjectListDeleteR func (m *RpcObjectListDeleteRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDeleteRequest) ProtoMessage() {} func (*RpcObjectListDeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 0} } func (m *RpcObjectListDeleteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25744,7 +26372,7 @@ func (m *RpcObjectListDeleteResponse) Reset() { *m = RpcObjectListDelete func (m *RpcObjectListDeleteResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDeleteResponse) ProtoMessage() {} func (*RpcObjectListDeleteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 1} } func (m *RpcObjectListDeleteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25796,7 +26424,7 @@ func (m *RpcObjectListDeleteResponseError) Reset() { *m = RpcObjectListD func (m *RpcObjectListDeleteResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListDeleteResponseError) ProtoMessage() {} func (*RpcObjectListDeleteResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 38, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 1, 0} } func (m *RpcObjectListDeleteResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25846,7 +26474,7 @@ func (m *RpcObjectListSetIsArchived) Reset() { *m = RpcObjectListSetIsAr func (m *RpcObjectListSetIsArchived) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsArchived) ProtoMessage() {} func (*RpcObjectListSetIsArchived) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41} } func (m *RpcObjectListSetIsArchived) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25884,7 +26512,7 @@ func (m *RpcObjectListSetIsArchivedRequest) Reset() { *m = RpcObjectList func (m *RpcObjectListSetIsArchivedRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsArchivedRequest) ProtoMessage() {} func (*RpcObjectListSetIsArchivedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 0} } func (m *RpcObjectListSetIsArchivedRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25935,7 +26563,7 @@ func (m *RpcObjectListSetIsArchivedResponse) Reset() { *m = RpcObjectLis func (m *RpcObjectListSetIsArchivedResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsArchivedResponse) ProtoMessage() {} func (*RpcObjectListSetIsArchivedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 1} } func (m *RpcObjectListSetIsArchivedResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -25982,7 +26610,7 @@ func (m *RpcObjectListSetIsArchivedResponseError) Reset() { func (m *RpcObjectListSetIsArchivedResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsArchivedResponseError) ProtoMessage() {} func (*RpcObjectListSetIsArchivedResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 39, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 1, 0} } func (m *RpcObjectListSetIsArchivedResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26032,7 +26660,7 @@ func (m *RpcObjectListSetIsFavorite) Reset() { *m = RpcObjectListSetIsFa func (m *RpcObjectListSetIsFavorite) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsFavorite) ProtoMessage() {} func (*RpcObjectListSetIsFavorite) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42} } func (m *RpcObjectListSetIsFavorite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26070,7 +26698,7 @@ func (m *RpcObjectListSetIsFavoriteRequest) Reset() { *m = RpcObjectList func (m *RpcObjectListSetIsFavoriteRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsFavoriteRequest) ProtoMessage() {} func (*RpcObjectListSetIsFavoriteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 0} } func (m *RpcObjectListSetIsFavoriteRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26121,7 +26749,7 @@ func (m *RpcObjectListSetIsFavoriteResponse) Reset() { *m = RpcObjectLis func (m *RpcObjectListSetIsFavoriteResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsFavoriteResponse) ProtoMessage() {} func (*RpcObjectListSetIsFavoriteResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 1} } func (m *RpcObjectListSetIsFavoriteResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26168,7 +26796,7 @@ func (m *RpcObjectListSetIsFavoriteResponseError) Reset() { func (m *RpcObjectListSetIsFavoriteResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetIsFavoriteResponseError) ProtoMessage() {} func (*RpcObjectListSetIsFavoriteResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 40, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 1, 0} } func (m *RpcObjectListSetIsFavoriteResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26218,7 +26846,7 @@ func (m *RpcObjectListSetObjectType) Reset() { *m = RpcObjectListSetObje func (m *RpcObjectListSetObjectType) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetObjectType) ProtoMessage() {} func (*RpcObjectListSetObjectType) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43} } func (m *RpcObjectListSetObjectType) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26256,7 +26884,7 @@ func (m *RpcObjectListSetObjectTypeRequest) Reset() { *m = RpcObjectList func (m *RpcObjectListSetObjectTypeRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetObjectTypeRequest) ProtoMessage() {} func (*RpcObjectListSetObjectTypeRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 0} } func (m *RpcObjectListSetObjectTypeRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26308,7 +26936,7 @@ func (m *RpcObjectListSetObjectTypeResponse) Reset() { *m = RpcObjectLis func (m *RpcObjectListSetObjectTypeResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetObjectTypeResponse) ProtoMessage() {} func (*RpcObjectListSetObjectTypeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 1} } func (m *RpcObjectListSetObjectTypeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26362,7 +26990,7 @@ func (m *RpcObjectListSetObjectTypeResponseError) Reset() { func (m *RpcObjectListSetObjectTypeResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetObjectTypeResponseError) ProtoMessage() {} func (*RpcObjectListSetObjectTypeResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 41, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 1, 0} } func (m *RpcObjectListSetObjectTypeResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26412,7 +27040,7 @@ func (m *RpcObjectListSetDetails) Reset() { *m = RpcObjectListSetDetails func (m *RpcObjectListSetDetails) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetDetails) ProtoMessage() {} func (*RpcObjectListSetDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44} } func (m *RpcObjectListSetDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26450,7 +27078,7 @@ func (m *RpcObjectListSetDetailsRequest) Reset() { *m = RpcObjectListSet func (m *RpcObjectListSetDetailsRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetDetailsRequest) ProtoMessage() {} func (*RpcObjectListSetDetailsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 0} } func (m *RpcObjectListSetDetailsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26502,7 +27130,7 @@ func (m *RpcObjectListSetDetailsResponse) Reset() { *m = RpcObjectListSe func (m *RpcObjectListSetDetailsResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetDetailsResponse) ProtoMessage() {} func (*RpcObjectListSetDetailsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 1} } func (m *RpcObjectListSetDetailsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26554,7 +27182,7 @@ func (m *RpcObjectListSetDetailsResponseError) Reset() { *m = RpcObjectL func (m *RpcObjectListSetDetailsResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListSetDetailsResponseError) ProtoMessage() {} func (*RpcObjectListSetDetailsResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 42, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 1, 0} } func (m *RpcObjectListSetDetailsResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26604,7 +27232,7 @@ func (m *RpcObjectListModifyDetailValues) Reset() { *m = RpcObjectListMo func (m *RpcObjectListModifyDetailValues) String() string { return proto.CompactTextString(m) } func (*RpcObjectListModifyDetailValues) ProtoMessage() {} func (*RpcObjectListModifyDetailValues) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45} } func (m *RpcObjectListModifyDetailValues) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26644,7 +27272,7 @@ func (m *RpcObjectListModifyDetailValuesRequest) Reset() { func (m *RpcObjectListModifyDetailValuesRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListModifyDetailValuesRequest) ProtoMessage() {} func (*RpcObjectListModifyDetailValuesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 0} } func (m *RpcObjectListModifyDetailValuesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26702,7 +27330,7 @@ func (m *RpcObjectListModifyDetailValuesRequestOperation) String() string { } func (*RpcObjectListModifyDetailValuesRequestOperation) ProtoMessage() {} func (*RpcObjectListModifyDetailValuesRequestOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 0, 0} } func (m *RpcObjectListModifyDetailValuesRequestOperation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26769,7 +27397,7 @@ func (m *RpcObjectListModifyDetailValuesResponse) Reset() { func (m *RpcObjectListModifyDetailValuesResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListModifyDetailValuesResponse) ProtoMessage() {} func (*RpcObjectListModifyDetailValuesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 1} } func (m *RpcObjectListModifyDetailValuesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26818,7 +27446,7 @@ func (m *RpcObjectListModifyDetailValuesResponseError) String() string { } func (*RpcObjectListModifyDetailValuesResponseError) ProtoMessage() {} func (*RpcObjectListModifyDetailValuesResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 43, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 1, 0} } func (m *RpcObjectListModifyDetailValuesResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26868,7 +27496,7 @@ func (m *RpcObjectApplyTemplate) Reset() { *m = RpcObjectApplyTemplate{} func (m *RpcObjectApplyTemplate) String() string { return proto.CompactTextString(m) } func (*RpcObjectApplyTemplate) ProtoMessage() {} func (*RpcObjectApplyTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46} } func (m *RpcObjectApplyTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26907,7 +27535,7 @@ func (m *RpcObjectApplyTemplateRequest) Reset() { *m = RpcObjectApplyTem func (m *RpcObjectApplyTemplateRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectApplyTemplateRequest) ProtoMessage() {} func (*RpcObjectApplyTemplateRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0} } func (m *RpcObjectApplyTemplateRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -26958,7 +27586,7 @@ func (m *RpcObjectApplyTemplateResponse) Reset() { *m = RpcObjectApplyTe func (m *RpcObjectApplyTemplateResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectApplyTemplateResponse) ProtoMessage() {} func (*RpcObjectApplyTemplateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 1} } func (m *RpcObjectApplyTemplateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27003,7 +27631,7 @@ func (m *RpcObjectApplyTemplateResponseError) Reset() { *m = RpcObjectAp func (m *RpcObjectApplyTemplateResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectApplyTemplateResponseError) ProtoMessage() {} func (*RpcObjectApplyTemplateResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 44, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 1, 0} } func (m *RpcObjectApplyTemplateResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27053,7 +27681,7 @@ func (m *RpcObjectListExport) Reset() { *m = RpcObjectListExport{} } func (m *RpcObjectListExport) String() string { return proto.CompactTextString(m) } func (*RpcObjectListExport) ProtoMessage() {} func (*RpcObjectListExport) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47} } func (m *RpcObjectListExport) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27106,7 +27734,7 @@ func (m *RpcObjectListExportRequest) Reset() { *m = RpcObjectListExportR func (m *RpcObjectListExportRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectListExportRequest) ProtoMessage() {} func (*RpcObjectListExportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 0} } func (m *RpcObjectListExportRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27209,7 +27837,7 @@ func (m *RpcObjectListExportResponse) Reset() { *m = RpcObjectListExport func (m *RpcObjectListExportResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectListExportResponse) ProtoMessage() {} func (*RpcObjectListExportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 1} } func (m *RpcObjectListExportResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27275,7 +27903,7 @@ func (m *RpcObjectListExportResponseError) Reset() { *m = RpcObjectListE func (m *RpcObjectListExportResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectListExportResponseError) ProtoMessage() {} func (*RpcObjectListExportResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 45, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 1, 0} } func (m *RpcObjectListExportResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27325,7 +27953,7 @@ func (m *RpcObjectImport) Reset() { *m = RpcObjectImport{} } func (m *RpcObjectImport) String() string { return proto.CompactTextString(m) } func (*RpcObjectImport) ProtoMessage() {} func (*RpcObjectImport) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48} } func (m *RpcObjectImport) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27379,7 +28007,7 @@ func (m *RpcObjectImportRequest) Reset() { *m = RpcObjectImportRequest{} func (m *RpcObjectImportRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequest) ProtoMessage() {} func (*RpcObjectImportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0} } func (m *RpcObjectImportRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27577,7 +28205,7 @@ func (m *RpcObjectImportRequestNotionParams) Reset() { *m = RpcObjectImp func (m *RpcObjectImportRequestNotionParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestNotionParams) ProtoMessage() {} func (*RpcObjectImportRequestNotionParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 0} } func (m *RpcObjectImportRequestNotionParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27621,7 +28249,7 @@ func (m *RpcObjectImportRequestMarkdownParams) Reset() { *m = RpcObjectI func (m *RpcObjectImportRequestMarkdownParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestMarkdownParams) ProtoMessage() {} func (*RpcObjectImportRequestMarkdownParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 1} } func (m *RpcObjectImportRequestMarkdownParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27665,7 +28293,7 @@ func (m *RpcObjectImportRequestBookmarksParams) Reset() { *m = RpcObject func (m *RpcObjectImportRequestBookmarksParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestBookmarksParams) ProtoMessage() {} func (*RpcObjectImportRequestBookmarksParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 2} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 2} } func (m *RpcObjectImportRequestBookmarksParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27709,7 +28337,7 @@ func (m *RpcObjectImportRequestHtmlParams) Reset() { *m = RpcObjectImpor func (m *RpcObjectImportRequestHtmlParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestHtmlParams) ProtoMessage() {} func (*RpcObjectImportRequestHtmlParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 3} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 3} } func (m *RpcObjectImportRequestHtmlParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27753,7 +28381,7 @@ func (m *RpcObjectImportRequestTxtParams) Reset() { *m = RpcObjectImport func (m *RpcObjectImportRequestTxtParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestTxtParams) ProtoMessage() {} func (*RpcObjectImportRequestTxtParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 4} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 4} } func (m *RpcObjectImportRequestTxtParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27800,7 +28428,7 @@ func (m *RpcObjectImportRequestPbParams) Reset() { *m = RpcObjectImportR func (m *RpcObjectImportRequestPbParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestPbParams) ProtoMessage() {} func (*RpcObjectImportRequestPbParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 5} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 5} } func (m *RpcObjectImportRequestPbParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27869,7 +28497,7 @@ func (m *RpcObjectImportRequestCsvParams) Reset() { *m = RpcObjectImport func (m *RpcObjectImportRequestCsvParams) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestCsvParams) ProtoMessage() {} func (*RpcObjectImportRequestCsvParams) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 6} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 6} } func (m *RpcObjectImportRequestCsvParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27942,7 +28570,7 @@ func (m *RpcObjectImportRequestSnapshot) Reset() { *m = RpcObjectImportR func (m *RpcObjectImportRequestSnapshot) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportRequestSnapshot) ProtoMessage() {} func (*RpcObjectImportRequestSnapshot) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 0, 7} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0, 7} } func (m *RpcObjectImportRequestSnapshot) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -27995,7 +28623,7 @@ func (m *RpcObjectImportResponse) Reset() { *m = RpcObjectImportResponse func (m *RpcObjectImportResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportResponse) ProtoMessage() {} func (*RpcObjectImportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 1} } func (m *RpcObjectImportResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28054,7 +28682,7 @@ func (m *RpcObjectImportResponseError) Reset() { *m = RpcObjectImportRes func (m *RpcObjectImportResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportResponseError) ProtoMessage() {} func (*RpcObjectImportResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 1, 0} } func (m *RpcObjectImportResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28104,7 +28732,7 @@ func (m *RpcObjectImportNotion) Reset() { *m = RpcObjectImportNotion{} } func (m *RpcObjectImportNotion) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportNotion) ProtoMessage() {} func (*RpcObjectImportNotion) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 2} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 2} } func (m *RpcObjectImportNotion) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28140,7 +28768,7 @@ func (m *RpcObjectImportNotionValidateToken) Reset() { *m = RpcObjectImp func (m *RpcObjectImportNotionValidateToken) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportNotionValidateToken) ProtoMessage() {} func (*RpcObjectImportNotionValidateToken) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 2, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 2, 0} } func (m *RpcObjectImportNotionValidateToken) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28181,7 +28809,7 @@ func (m *RpcObjectImportNotionValidateTokenRequest) String() string { } func (*RpcObjectImportNotionValidateTokenRequest) ProtoMessage() {} func (*RpcObjectImportNotionValidateTokenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 2, 0, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 2, 0, 0} } func (m *RpcObjectImportNotionValidateTokenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28229,7 +28857,7 @@ func (m *RpcObjectImportNotionValidateTokenResponse) String() string { } func (*RpcObjectImportNotionValidateTokenResponse) ProtoMessage() {} func (*RpcObjectImportNotionValidateTokenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 2, 0, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 2, 0, 1} } func (m *RpcObjectImportNotionValidateTokenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28278,7 +28906,7 @@ func (m *RpcObjectImportNotionValidateTokenResponseError) String() string { } func (*RpcObjectImportNotionValidateTokenResponseError) ProtoMessage() {} func (*RpcObjectImportNotionValidateTokenResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 46, 2, 0, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 2, 0, 1, 0} } func (m *RpcObjectImportNotionValidateTokenResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28328,7 +28956,7 @@ func (m *RpcObjectImportList) Reset() { *m = RpcObjectImportList{} } func (m *RpcObjectImportList) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportList) ProtoMessage() {} func (*RpcObjectImportList) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49} } func (m *RpcObjectImportList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28364,7 +28992,7 @@ func (m *RpcObjectImportListRequest) Reset() { *m = RpcObjectImportListR func (m *RpcObjectImportListRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportListRequest) ProtoMessage() {} func (*RpcObjectImportListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 0} } func (m *RpcObjectImportListRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28402,7 +29030,7 @@ func (m *RpcObjectImportListResponse) Reset() { *m = RpcObjectImportList func (m *RpcObjectImportListResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportListResponse) ProtoMessage() {} func (*RpcObjectImportListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 1} } func (m *RpcObjectImportListResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28454,7 +29082,7 @@ func (m *RpcObjectImportListResponseError) Reset() { *m = RpcObjectImpor func (m *RpcObjectImportListResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportListResponseError) ProtoMessage() {} func (*RpcObjectImportListResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 1, 0} } func (m *RpcObjectImportListResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28505,7 +29133,7 @@ func (m *RpcObjectImportListImportResponse) Reset() { *m = RpcObjectImpo func (m *RpcObjectImportListImportResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportListImportResponse) ProtoMessage() {} func (*RpcObjectImportListImportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 47, 2} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 2} } func (m *RpcObjectImportListImportResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28548,7 +29176,7 @@ func (m *RpcObjectImportUseCase) Reset() { *m = RpcObjectImportUseCase{} func (m *RpcObjectImportUseCase) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportUseCase) ProtoMessage() {} func (*RpcObjectImportUseCase) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 50} } func (m *RpcObjectImportUseCase) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28586,7 +29214,7 @@ func (m *RpcObjectImportUseCaseRequest) Reset() { *m = RpcObjectImportUs func (m *RpcObjectImportUseCaseRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportUseCaseRequest) ProtoMessage() {} func (*RpcObjectImportUseCaseRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 50, 0} } func (m *RpcObjectImportUseCaseRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28638,7 +29266,7 @@ func (m *RpcObjectImportUseCaseResponse) Reset() { *m = RpcObjectImportU func (m *RpcObjectImportUseCaseResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportUseCaseResponse) ProtoMessage() {} func (*RpcObjectImportUseCaseResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 50, 1} } func (m *RpcObjectImportUseCaseResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28690,7 +29318,7 @@ func (m *RpcObjectImportUseCaseResponseError) Reset() { *m = RpcObjectIm func (m *RpcObjectImportUseCaseResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportUseCaseResponseError) ProtoMessage() {} func (*RpcObjectImportUseCaseResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 48, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 50, 1, 0} } func (m *RpcObjectImportUseCaseResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28740,7 +29368,7 @@ func (m *RpcObjectImportExperience) Reset() { *m = RpcObjectImportExperi func (m *RpcObjectImportExperience) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportExperience) ProtoMessage() {} func (*RpcObjectImportExperience) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 51} } func (m *RpcObjectImportExperience) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28780,7 +29408,7 @@ func (m *RpcObjectImportExperienceRequest) Reset() { *m = RpcObjectImpor func (m *RpcObjectImportExperienceRequest) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportExperienceRequest) ProtoMessage() {} func (*RpcObjectImportExperienceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 51, 0} } func (m *RpcObjectImportExperienceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28846,7 +29474,7 @@ func (m *RpcObjectImportExperienceResponse) Reset() { *m = RpcObjectImpo func (m *RpcObjectImportExperienceResponse) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportExperienceResponse) ProtoMessage() {} func (*RpcObjectImportExperienceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 1} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 51, 1} } func (m *RpcObjectImportExperienceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -28900,7 +29528,7 @@ func (m *RpcObjectImportExperienceResponseError) Reset() { func (m *RpcObjectImportExperienceResponseError) String() string { return proto.CompactTextString(m) } func (*RpcObjectImportExperienceResponseError) ProtoMessage() {} func (*RpcObjectImportExperienceResponseError) Descriptor() ([]byte, []int) { - return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 49, 1, 0} + return fileDescriptor_8261c968b2e6f45c, []int{0, 5, 51, 1, 0} } func (m *RpcObjectImportExperienceResponseError) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -60001,6 +60629,282 @@ func (m *RpcDebugPingResponseError) GetDescription() string { return "" } +type RpcDebugAnystoreObjectChanges struct { +} + +func (m *RpcDebugAnystoreObjectChanges) Reset() { *m = RpcDebugAnystoreObjectChanges{} } +func (m *RpcDebugAnystoreObjectChanges) String() string { return proto.CompactTextString(m) } +func (*RpcDebugAnystoreObjectChanges) ProtoMessage() {} +func (*RpcDebugAnystoreObjectChanges) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12} +} +func (m *RpcDebugAnystoreObjectChanges) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcDebugAnystoreObjectChanges) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcDebugAnystoreObjectChanges.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcDebugAnystoreObjectChanges) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcDebugAnystoreObjectChanges.Merge(m, src) +} +func (m *RpcDebugAnystoreObjectChanges) XXX_Size() int { + return m.Size() +} +func (m *RpcDebugAnystoreObjectChanges) XXX_DiscardUnknown() { + xxx_messageInfo_RpcDebugAnystoreObjectChanges.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcDebugAnystoreObjectChanges proto.InternalMessageInfo + +type RpcDebugAnystoreObjectChangesRequest struct { + ObjectId string `protobuf:"bytes,1,opt,name=objectId,proto3" json:"objectId,omitempty"` + OrderBy RpcDebugAnystoreObjectChangesRequestOrderBy `protobuf:"varint,2,opt,name=orderBy,proto3,enum=anytype.RpcDebugAnystoreObjectChangesRequestOrderBy" json:"orderBy,omitempty"` +} + +func (m *RpcDebugAnystoreObjectChangesRequest) Reset() { *m = RpcDebugAnystoreObjectChangesRequest{} } +func (m *RpcDebugAnystoreObjectChangesRequest) String() string { return proto.CompactTextString(m) } +func (*RpcDebugAnystoreObjectChangesRequest) ProtoMessage() {} +func (*RpcDebugAnystoreObjectChangesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12, 0} +} +func (m *RpcDebugAnystoreObjectChangesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcDebugAnystoreObjectChangesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcDebugAnystoreObjectChangesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcDebugAnystoreObjectChangesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcDebugAnystoreObjectChangesRequest.Merge(m, src) +} +func (m *RpcDebugAnystoreObjectChangesRequest) XXX_Size() int { + return m.Size() +} +func (m *RpcDebugAnystoreObjectChangesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_RpcDebugAnystoreObjectChangesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcDebugAnystoreObjectChangesRequest proto.InternalMessageInfo + +func (m *RpcDebugAnystoreObjectChangesRequest) GetObjectId() string { + if m != nil { + return m.ObjectId + } + return "" +} + +func (m *RpcDebugAnystoreObjectChangesRequest) GetOrderBy() RpcDebugAnystoreObjectChangesRequestOrderBy { + if m != nil { + return m.OrderBy + } + return RpcDebugAnystoreObjectChangesRequest_ORDER_ID +} + +type RpcDebugAnystoreObjectChangesResponse struct { + Error *RpcDebugAnystoreObjectChangesResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` + Changes []*RpcDebugAnystoreObjectChangesResponseChange `protobuf:"bytes,2,rep,name=changes,proto3" json:"changes,omitempty"` + WrongOrder bool `protobuf:"varint,3,opt,name=wrongOrder,proto3" json:"wrongOrder,omitempty"` +} + +func (m *RpcDebugAnystoreObjectChangesResponse) Reset() { *m = RpcDebugAnystoreObjectChangesResponse{} } +func (m *RpcDebugAnystoreObjectChangesResponse) String() string { return proto.CompactTextString(m) } +func (*RpcDebugAnystoreObjectChangesResponse) ProtoMessage() {} +func (*RpcDebugAnystoreObjectChangesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12, 1} +} +func (m *RpcDebugAnystoreObjectChangesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcDebugAnystoreObjectChangesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcDebugAnystoreObjectChangesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcDebugAnystoreObjectChangesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcDebugAnystoreObjectChangesResponse.Merge(m, src) +} +func (m *RpcDebugAnystoreObjectChangesResponse) XXX_Size() int { + return m.Size() +} +func (m *RpcDebugAnystoreObjectChangesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RpcDebugAnystoreObjectChangesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcDebugAnystoreObjectChangesResponse proto.InternalMessageInfo + +func (m *RpcDebugAnystoreObjectChangesResponse) GetError() *RpcDebugAnystoreObjectChangesResponseError { + if m != nil { + return m.Error + } + return nil +} + +func (m *RpcDebugAnystoreObjectChangesResponse) GetChanges() []*RpcDebugAnystoreObjectChangesResponseChange { + if m != nil { + return m.Changes + } + return nil +} + +func (m *RpcDebugAnystoreObjectChangesResponse) GetWrongOrder() bool { + if m != nil { + return m.WrongOrder + } + return false +} + +type RpcDebugAnystoreObjectChangesResponseChange struct { + ChangeId string `protobuf:"bytes,1,opt,name=changeId,proto3" json:"changeId,omitempty"` + OrderId string `protobuf:"bytes,2,opt,name=orderId,proto3" json:"orderId,omitempty"` + Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` + Change *types.Struct `protobuf:"bytes,4,opt,name=change,proto3" json:"change,omitempty"` +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) Reset() { + *m = RpcDebugAnystoreObjectChangesResponseChange{} +} +func (m *RpcDebugAnystoreObjectChangesResponseChange) String() string { + return proto.CompactTextString(m) +} +func (*RpcDebugAnystoreObjectChangesResponseChange) ProtoMessage() {} +func (*RpcDebugAnystoreObjectChangesResponseChange) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12, 1, 0} +} +func (m *RpcDebugAnystoreObjectChangesResponseChange) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcDebugAnystoreObjectChangesResponseChange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseChange.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcDebugAnystoreObjectChangesResponseChange) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseChange.Merge(m, src) +} +func (m *RpcDebugAnystoreObjectChangesResponseChange) XXX_Size() int { + return m.Size() +} +func (m *RpcDebugAnystoreObjectChangesResponseChange) XXX_DiscardUnknown() { + xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseChange.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseChange proto.InternalMessageInfo + +func (m *RpcDebugAnystoreObjectChangesResponseChange) GetChangeId() string { + if m != nil { + return m.ChangeId + } + return "" +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) GetOrderId() string { + if m != nil { + return m.OrderId + } + return "" +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) GetChange() *types.Struct { + if m != nil { + return m.Change + } + return nil +} + +type RpcDebugAnystoreObjectChangesResponseError struct { + Code RpcDebugAnystoreObjectChangesResponseErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=anytype.RpcDebugAnystoreObjectChangesResponseErrorCode" json:"code,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` +} + +func (m *RpcDebugAnystoreObjectChangesResponseError) Reset() { + *m = RpcDebugAnystoreObjectChangesResponseError{} +} +func (m *RpcDebugAnystoreObjectChangesResponseError) String() string { + return proto.CompactTextString(m) +} +func (*RpcDebugAnystoreObjectChangesResponseError) ProtoMessage() {} +func (*RpcDebugAnystoreObjectChangesResponseError) Descriptor() ([]byte, []int) { + return fileDescriptor_8261c968b2e6f45c, []int{0, 30, 12, 1, 1} +} +func (m *RpcDebugAnystoreObjectChangesResponseError) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RpcDebugAnystoreObjectChangesResponseError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseError.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RpcDebugAnystoreObjectChangesResponseError) XXX_Merge(src proto.Message) { + xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseError.Merge(m, src) +} +func (m *RpcDebugAnystoreObjectChangesResponseError) XXX_Size() int { + return m.Size() +} +func (m *RpcDebugAnystoreObjectChangesResponseError) XXX_DiscardUnknown() { + xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseError.DiscardUnknown(m) +} + +var xxx_messageInfo_RpcDebugAnystoreObjectChangesResponseError proto.InternalMessageInfo + +func (m *RpcDebugAnystoreObjectChangesResponseError) GetCode() RpcDebugAnystoreObjectChangesResponseErrorCode { + if m != nil { + return m.Code + } + return RpcDebugAnystoreObjectChangesResponseError_NULL +} + +func (m *RpcDebugAnystoreObjectChangesResponseError) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + type RpcMetrics struct { } @@ -62614,8 +63518,11 @@ func (m *RpcMembershipGetVerificationEmail) XXX_DiscardUnknown() { var xxx_messageInfo_RpcMembershipGetVerificationEmail proto.InternalMessageInfo type RpcMembershipGetVerificationEmailRequest struct { - Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` - SubscribeToNewsletter bool `protobuf:"varint,2,opt,name=subscribeToNewsletter,proto3" json:"subscribeToNewsletter,omitempty"` + Email string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"` + SubscribeToNewsletter bool `protobuf:"varint,2,opt,name=subscribeToNewsletter,proto3" json:"subscribeToNewsletter,omitempty"` + InsiderTipsAndTutorials bool `protobuf:"varint,3,opt,name=insiderTipsAndTutorials,proto3" json:"insiderTipsAndTutorials,omitempty"` + // if we are coming from the onboarding list + IsOnboardingList bool `protobuf:"varint,4,opt,name=isOnboardingList,proto3" json:"isOnboardingList,omitempty"` } func (m *RpcMembershipGetVerificationEmailRequest) Reset() { @@ -62667,6 +63574,20 @@ func (m *RpcMembershipGetVerificationEmailRequest) GetSubscribeToNewsletter() bo return false } +func (m *RpcMembershipGetVerificationEmailRequest) GetInsiderTipsAndTutorials() bool { + if m != nil { + return m.InsiderTipsAndTutorials + } + return false +} + +func (m *RpcMembershipGetVerificationEmailRequest) GetIsOnboardingList() bool { + if m != nil { + return m.IsOnboardingList + } + return false +} + type RpcMembershipGetVerificationEmailResponse struct { Error *RpcMembershipGetVerificationEmailResponseError `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` } @@ -66841,6 +67762,8 @@ func init() { proto.RegisterEnum("anytype.RpcObjectGraphEdgeType", RpcObjectGraphEdgeType_name, RpcObjectGraphEdgeType_value) proto.RegisterEnum("anytype.RpcObjectGraphResponseErrorCode", RpcObjectGraphResponseErrorCode_name, RpcObjectGraphResponseErrorCode_value) proto.RegisterEnum("anytype.RpcObjectSearchSubscribeResponseErrorCode", RpcObjectSearchSubscribeResponseErrorCode_name, RpcObjectSearchSubscribeResponseErrorCode_value) + proto.RegisterEnum("anytype.RpcObjectCrossSpaceSearchSubscribeResponseErrorCode", RpcObjectCrossSpaceSearchSubscribeResponseErrorCode_name, RpcObjectCrossSpaceSearchSubscribeResponseErrorCode_value) + proto.RegisterEnum("anytype.RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode", RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode_name, RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode_value) proto.RegisterEnum("anytype.RpcObjectGroupsSubscribeResponseErrorCode", RpcObjectGroupsSubscribeResponseErrorCode_name, RpcObjectGroupsSubscribeResponseErrorCode_value) proto.RegisterEnum("anytype.RpcObjectSubscribeIdsResponseErrorCode", RpcObjectSubscribeIdsResponseErrorCode_name, RpcObjectSubscribeIdsResponseErrorCode_value) proto.RegisterEnum("anytype.RpcObjectSearchUnsubscribeResponseErrorCode", RpcObjectSearchUnsubscribeResponseErrorCode_name, RpcObjectSearchUnsubscribeResponseErrorCode_value) @@ -67019,6 +67942,8 @@ func init() { proto.RegisterEnum("anytype.RpcDebugRunProfilerResponseErrorCode", RpcDebugRunProfilerResponseErrorCode_name, RpcDebugRunProfilerResponseErrorCode_value) proto.RegisterEnum("anytype.RpcDebugAccountSelectTraceResponseErrorCode", RpcDebugAccountSelectTraceResponseErrorCode_name, RpcDebugAccountSelectTraceResponseErrorCode_value) proto.RegisterEnum("anytype.RpcDebugPingResponseErrorCode", RpcDebugPingResponseErrorCode_name, RpcDebugPingResponseErrorCode_value) + proto.RegisterEnum("anytype.RpcDebugAnystoreObjectChangesRequestOrderBy", RpcDebugAnystoreObjectChangesRequestOrderBy_name, RpcDebugAnystoreObjectChangesRequestOrderBy_value) + proto.RegisterEnum("anytype.RpcDebugAnystoreObjectChangesResponseErrorCode", RpcDebugAnystoreObjectChangesResponseErrorCode_name, RpcDebugAnystoreObjectChangesResponseErrorCode_value) proto.RegisterEnum("anytype.RpcMetricsSetParametersResponseErrorCode", RpcMetricsSetParametersResponseErrorCode_name, RpcMetricsSetParametersResponseErrorCode_value) proto.RegisterEnum("anytype.RpcLogSendRequestLevel", RpcLogSendRequestLevel_name, RpcLogSendRequestLevel_value) proto.RegisterEnum("anytype.RpcLogSendResponseErrorCode", RpcLogSendResponseErrorCode_name, RpcLogSendResponseErrorCode_value) @@ -67331,6 +68256,14 @@ func init() { proto.RegisterType((*RpcObjectSearchSubscribeRequest)(nil), "anytype.Rpc.Object.SearchSubscribe.Request") proto.RegisterType((*RpcObjectSearchSubscribeResponse)(nil), "anytype.Rpc.Object.SearchSubscribe.Response") proto.RegisterType((*RpcObjectSearchSubscribeResponseError)(nil), "anytype.Rpc.Object.SearchSubscribe.Response.Error") + proto.RegisterType((*RpcObjectCrossSpaceSearchSubscribe)(nil), "anytype.Rpc.Object.CrossSpaceSearchSubscribe") + proto.RegisterType((*RpcObjectCrossSpaceSearchSubscribeRequest)(nil), "anytype.Rpc.Object.CrossSpaceSearchSubscribe.Request") + proto.RegisterType((*RpcObjectCrossSpaceSearchSubscribeResponse)(nil), "anytype.Rpc.Object.CrossSpaceSearchSubscribe.Response") + proto.RegisterType((*RpcObjectCrossSpaceSearchSubscribeResponseError)(nil), "anytype.Rpc.Object.CrossSpaceSearchSubscribe.Response.Error") + proto.RegisterType((*RpcObjectCrossSpaceSearchUnsubscribe)(nil), "anytype.Rpc.Object.CrossSpaceSearchUnsubscribe") + proto.RegisterType((*RpcObjectCrossSpaceSearchUnsubscribeRequest)(nil), "anytype.Rpc.Object.CrossSpaceSearchUnsubscribe.Request") + proto.RegisterType((*RpcObjectCrossSpaceSearchUnsubscribeResponse)(nil), "anytype.Rpc.Object.CrossSpaceSearchUnsubscribe.Response") + proto.RegisterType((*RpcObjectCrossSpaceSearchUnsubscribeResponseError)(nil), "anytype.Rpc.Object.CrossSpaceSearchUnsubscribe.Response.Error") proto.RegisterType((*RpcObjectGroupsSubscribe)(nil), "anytype.Rpc.Object.GroupsSubscribe") proto.RegisterType((*RpcObjectGroupsSubscribeRequest)(nil), "anytype.Rpc.Object.GroupsSubscribe.Request") proto.RegisterType((*RpcObjectGroupsSubscribeResponse)(nil), "anytype.Rpc.Object.GroupsSubscribe.Response") @@ -68072,6 +69005,11 @@ func init() { proto.RegisterType((*RpcDebugPingRequest)(nil), "anytype.Rpc.Debug.Ping.Request") proto.RegisterType((*RpcDebugPingResponse)(nil), "anytype.Rpc.Debug.Ping.Response") proto.RegisterType((*RpcDebugPingResponseError)(nil), "anytype.Rpc.Debug.Ping.Response.Error") + proto.RegisterType((*RpcDebugAnystoreObjectChanges)(nil), "anytype.Rpc.Debug.AnystoreObjectChanges") + proto.RegisterType((*RpcDebugAnystoreObjectChangesRequest)(nil), "anytype.Rpc.Debug.AnystoreObjectChanges.Request") + proto.RegisterType((*RpcDebugAnystoreObjectChangesResponse)(nil), "anytype.Rpc.Debug.AnystoreObjectChanges.Response") + proto.RegisterType((*RpcDebugAnystoreObjectChangesResponseChange)(nil), "anytype.Rpc.Debug.AnystoreObjectChanges.Response.Change") + proto.RegisterType((*RpcDebugAnystoreObjectChangesResponseError)(nil), "anytype.Rpc.Debug.AnystoreObjectChanges.Response.Error") proto.RegisterType((*RpcMetrics)(nil), "anytype.Rpc.Metrics") proto.RegisterType((*RpcMetricsSetParameters)(nil), "anytype.Rpc.Metrics.SetParameters") proto.RegisterType((*RpcMetricsSetParametersRequest)(nil), "anytype.Rpc.Metrics.SetParameters.Request") @@ -68221,1164 +69159,1185 @@ func init() { func init() { proto.RegisterFile("pb/protos/commands.proto", fileDescriptor_8261c968b2e6f45c) } var fileDescriptor_8261c968b2e6f45c = []byte{ - // 18500 bytes of a gzipped FileDescriptorProto + // 18843 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7b, 0x98, 0x24, 0x47, 0x75, 0x27, 0x3a, 0x55, 0x59, 0x55, 0xdd, 0x1d, 0xfd, 0x98, 0x9a, 0xd4, 0xcc, 0x68, 0x14, 0x12, - 0xa3, 0x61, 0x24, 0x84, 0x2c, 0x44, 0x0b, 0x24, 0x0c, 0x48, 0x48, 0x48, 0xd5, 0xd5, 0xd9, 0xdd, - 0x85, 0xba, 0xab, 0x9a, 0xac, 0xec, 0x19, 0x64, 0xaf, 0x6f, 0x6d, 0x4e, 0x55, 0x74, 0x77, 0x6a, - 0xaa, 0x33, 0xcb, 0x59, 0xd9, 0x3d, 0x33, 0xdc, 0x6f, 0xef, 0xda, 0x60, 0x40, 0xd8, 0x66, 0x31, - 0xc6, 0xac, 0x0d, 0x98, 0xf7, 0xc3, 0x0b, 0x36, 0x60, 0xde, 0x0b, 0xb6, 0xb1, 0xcd, 0xdb, 0xd8, - 0xc6, 0x18, 0x8c, 0x79, 0xd8, 0x7c, 0x06, 0xf3, 0x58, 0xbc, 0x77, 0x59, 0xae, 0x7d, 0x17, 0x30, - 0x36, 0x5c, 0xdf, 0x2f, 0x1e, 0x99, 0x19, 0x51, 0x5d, 0x99, 0x15, 0x59, 0x5d, 0x59, 0x2d, 0xec, - 0xfd, 0x2f, 0x33, 0x32, 0x32, 0xe2, 0xc4, 0xf9, 0x9d, 0x13, 0x71, 0x22, 0xe2, 0xc4, 0x09, 0x70, - 0xaa, 0x73, 0xe1, 0xb6, 0x8e, 0xeb, 0x78, 0x4e, 0xf7, 0xb6, 0xa6, 0xb3, 0xb3, 0x63, 0xda, 0xad, - 0xee, 0x3c, 0x79, 0x57, 0x27, 0x4c, 0xfb, 0x8a, 0x77, 0xa5, 0x83, 0xe0, 0x8d, 0x9d, 0x8b, 0x5b, - 0xb7, 0xb5, 0xad, 0x0b, 0xb7, 0x75, 0x2e, 0xdc, 0xb6, 0xe3, 0xb4, 0x50, 0xdb, 0xff, 0x81, 0xbc, - 0xb0, 0xec, 0xf0, 0xe6, 0xa8, 0x5c, 0x6d, 0xa7, 0x69, 0xb6, 0xbb, 0x9e, 0xe3, 0x22, 0x96, 0xf3, - 0x64, 0x58, 0x25, 0xda, 0x43, 0xb6, 0xe7, 0x97, 0x70, 0xdd, 0x96, 0xe3, 0x6c, 0xb5, 0x11, 0xfd, - 0x76, 0x61, 0x77, 0xf3, 0xb6, 0xae, 0xe7, 0xee, 0x36, 0x3d, 0xf6, 0xf5, 0x4c, 0xef, 0xd7, 0x16, - 0xea, 0x36, 0x5d, 0xab, 0xe3, 0x39, 0x2e, 0xcd, 0x71, 0xf6, 0x59, 0x9f, 0x9d, 0x00, 0x8a, 0xde, - 0x69, 0xc2, 0xef, 0x4e, 0x00, 0xa5, 0xd4, 0xe9, 0xc0, 0x8f, 0x64, 0x01, 0x58, 0x46, 0xde, 0x39, - 0xe4, 0x76, 0x2d, 0xc7, 0x86, 0x47, 0xc1, 0x84, 0x8e, 0x7e, 0x7a, 0x17, 0x75, 0xbd, 0xbb, 0x72, - 0x0f, 0x7d, 0x43, 0xc9, 0xc0, 0x37, 0x64, 0xc1, 0xa4, 0x8e, 0xba, 0x1d, 0xc7, 0xee, 0x22, 0xf5, - 0x3e, 0x90, 0x47, 0xae, 0xeb, 0xb8, 0xa7, 0x32, 0x67, 0x32, 0x37, 0x4f, 0xdf, 0x7e, 0xcb, 0x3c, - 0x6b, 0xfe, 0xbc, 0xde, 0x69, 0xce, 0x97, 0x3a, 0x9d, 0xf9, 0xb0, 0xa4, 0x79, 0xff, 0xa7, 0x79, - 0x0d, 0xff, 0xa1, 0xd3, 0x1f, 0xd5, 0x53, 0x60, 0x62, 0x8f, 0x66, 0x38, 0x95, 0x3d, 0x93, 0xb9, - 0x79, 0x4a, 0xf7, 0x5f, 0xf1, 0x97, 0x16, 0xf2, 0x4c, 0xab, 0xdd, 0x3d, 0xa5, 0xd0, 0x2f, 0xec, - 0x15, 0xbe, 0x36, 0x03, 0xf2, 0xa4, 0x10, 0xb5, 0x0c, 0x72, 0x4d, 0xa7, 0x85, 0x48, 0xf5, 0x73, - 0xb7, 0xdf, 0x26, 0x5f, 0xfd, 0x7c, 0xd9, 0x69, 0x21, 0x9d, 0xfc, 0xac, 0x9e, 0x01, 0xd3, 0x3e, - 0x5b, 0x42, 0x32, 0xf8, 0xa4, 0xb3, 0xb7, 0x83, 0x1c, 0xce, 0xaf, 0x4e, 0x82, 0x5c, 0x75, 0x63, - 0x75, 0xb5, 0x78, 0x44, 0x3d, 0x06, 0x66, 0x37, 0xaa, 0xf7, 0x57, 0x6b, 0xe7, 0xab, 0x0d, 0x4d, - 0xd7, 0x6b, 0x7a, 0x31, 0xa3, 0xce, 0x82, 0xa9, 0x85, 0xd2, 0x62, 0xa3, 0x52, 0x5d, 0xdf, 0x30, - 0x8a, 0x59, 0xf8, 0x4a, 0x05, 0xcc, 0xd5, 0x91, 0xb7, 0x88, 0xf6, 0xac, 0x26, 0xaa, 0x7b, 0xa6, - 0x87, 0xe0, 0x0b, 0x33, 0x01, 0x33, 0xd5, 0x0d, 0x5c, 0x69, 0xf0, 0x89, 0x35, 0xe0, 0x8e, 0x7d, - 0x0d, 0x10, 0x4b, 0x98, 0x67, 0x7f, 0xcf, 0x73, 0x69, 0x3a, 0x5f, 0xce, 0xd9, 0xc7, 0x82, 0x69, - 0xee, 0x9b, 0x3a, 0x07, 0xc0, 0x42, 0xa9, 0x7c, 0xff, 0xb2, 0x5e, 0xdb, 0xa8, 0x2e, 0x16, 0x8f, - 0xe0, 0xf7, 0xa5, 0x9a, 0xae, 0xb1, 0xf7, 0x0c, 0xfc, 0x7e, 0x86, 0x03, 0x73, 0x51, 0x04, 0x73, - 0x7e, 0x30, 0x31, 0x7d, 0x00, 0x85, 0x6f, 0x0c, 0xc0, 0x59, 0x16, 0xc0, 0xb9, 0x23, 0x59, 0x71, - 0xe9, 0x03, 0xf4, 0x9c, 0x2c, 0x98, 0xac, 0x6f, 0xef, 0x7a, 0x2d, 0xe7, 0x92, 0x0d, 0xa7, 0x02, - 0x64, 0xe0, 0xb7, 0x78, 0x9e, 0x3c, 0x55, 0xe4, 0xc9, 0xcd, 0xfb, 0x1b, 0xc1, 0x4a, 0x88, 0xe0, - 0xc6, 0xab, 0x03, 0x6e, 0x94, 0x04, 0x6e, 0x3c, 0x56, 0xb6, 0xa0, 0xf4, 0xf9, 0xf0, 0x4b, 0x77, - 0x80, 0x7c, 0xbd, 0x63, 0x36, 0x11, 0xfc, 0x13, 0x05, 0xcc, 0xac, 0x22, 0x73, 0x0f, 0x95, 0x3a, - 0x1d, 0xd7, 0xd9, 0x43, 0xb0, 0x1c, 0xca, 0xeb, 0x29, 0x30, 0xd1, 0xc5, 0x99, 0x2a, 0x2d, 0xd2, - 0x82, 0x29, 0xdd, 0x7f, 0x55, 0x4f, 0x03, 0x60, 0xb5, 0x90, 0xed, 0x59, 0x9e, 0x85, 0xba, 0xa7, - 0xb2, 0x67, 0x94, 0x9b, 0xa7, 0x74, 0x2e, 0x05, 0x7e, 0x37, 0x2b, 0x2b, 0x63, 0x84, 0x8a, 0x79, - 0x9e, 0x82, 0x08, 0xae, 0xbe, 0x2e, 0x2b, 0x23, 0x63, 0x03, 0x8b, 0x4b, 0xc6, 0xdb, 0xb7, 0x66, - 0x92, 0x33, 0x17, 0xe7, 0xa8, 0xd6, 0x1a, 0xf5, 0x8d, 0xf2, 0x4a, 0xa3, 0xbe, 0x5e, 0x2a, 0x6b, - 0x45, 0xa4, 0x1e, 0x07, 0x45, 0xf2, 0xd8, 0xa8, 0xd4, 0x1b, 0x8b, 0xda, 0xaa, 0x66, 0x68, 0x8b, - 0xc5, 0x4d, 0x55, 0x05, 0x73, 0xba, 0xf6, 0xf4, 0x0d, 0xad, 0x6e, 0x34, 0x96, 0x4a, 0x95, 0x55, - 0x6d, 0xb1, 0xb8, 0x85, 0x7f, 0x5e, 0xad, 0xac, 0x55, 0x8c, 0x86, 0xae, 0x95, 0xca, 0x2b, 0xda, - 0x62, 0x71, 0x5b, 0xbd, 0x1a, 0x5c, 0x55, 0xad, 0x35, 0x4a, 0xeb, 0xeb, 0x7a, 0xed, 0x9c, 0xd6, - 0x60, 0x7f, 0xd4, 0x8b, 0x16, 0xad, 0xc8, 0x68, 0xd4, 0x57, 0x4a, 0xba, 0x56, 0x5a, 0x58, 0xd5, - 0x8a, 0x0f, 0xc2, 0x67, 0x2b, 0x60, 0x76, 0xcd, 0xbc, 0x88, 0xea, 0xdb, 0xa6, 0x8b, 0xcc, 0x0b, - 0x6d, 0x04, 0x6f, 0x90, 0xc0, 0x13, 0xfe, 0x09, 0x8f, 0x97, 0x26, 0xe2, 0x75, 0x5b, 0x1f, 0x06, - 0x0b, 0x55, 0x44, 0x00, 0xf6, 0x8f, 0x81, 0x1a, 0xac, 0x08, 0x80, 0x3d, 0x21, 0x61, 0x79, 0xc9, - 0x10, 0x7b, 0xd6, 0xc3, 0x00, 0x31, 0xf8, 0x25, 0x05, 0xcc, 0x55, 0xec, 0x3d, 0xcb, 0x43, 0xcb, - 0xc8, 0x46, 0x2e, 0x1e, 0x07, 0xa4, 0x60, 0x78, 0x83, 0xc2, 0xc1, 0xb0, 0x24, 0xc2, 0xf0, 0xb8, - 0x3e, 0x6c, 0x13, 0xeb, 0x88, 0x18, 0x6d, 0xaf, 0x03, 0x53, 0x16, 0xc9, 0x57, 0xb6, 0x5a, 0x8c, - 0x63, 0x61, 0x82, 0x7a, 0x23, 0x98, 0xa5, 0x2f, 0x4b, 0x56, 0x1b, 0xdd, 0x8f, 0xae, 0xb0, 0x71, - 0x57, 0x4c, 0x84, 0xbf, 0x18, 0x28, 0x5f, 0x45, 0xc0, 0xf2, 0xc7, 0x93, 0x12, 0x95, 0x0c, 0xcc, - 0x97, 0x3c, 0x1c, 0xd4, 0x6f, 0x9f, 0x96, 0x59, 0xf0, 0x87, 0x59, 0x30, 0x5d, 0xf7, 0x9c, 0x0e, - 0x16, 0x59, 0xcb, 0xde, 0x92, 0x03, 0xf7, 0xe3, 0xbc, 0x8e, 0x95, 0x45, 0x70, 0x1f, 0xdb, 0x87, - 0x8f, 0x5c, 0x05, 0x11, 0x1a, 0xf6, 0xdd, 0x40, 0xc3, 0x96, 0x04, 0x54, 0x6e, 0x4f, 0x54, 0xda, - 0x8f, 0xa0, 0x7e, 0xbd, 0x44, 0x01, 0x45, 0x5f, 0xcc, 0xbc, 0xf2, 0xae, 0xeb, 0x22, 0xdb, 0x93, - 0x03, 0xe1, 0xaf, 0x78, 0x10, 0x56, 0x44, 0x10, 0x6e, 0x8f, 0x11, 0x66, 0xbf, 0x96, 0x14, 0x75, - 0xec, 0x0f, 0x02, 0x34, 0xef, 0x17, 0xd0, 0x7c, 0x52, 0x72, 0xb2, 0x92, 0x41, 0xba, 0x32, 0x04, - 0xa2, 0xc7, 0x41, 0x11, 0x8f, 0x49, 0x65, 0xa3, 0x72, 0x4e, 0x6b, 0x54, 0xaa, 0xe7, 0x2a, 0x86, - 0x56, 0x44, 0xf0, 0xc5, 0x0a, 0x98, 0xa1, 0xa4, 0xe9, 0x68, 0xcf, 0xb9, 0x28, 0xd9, 0xeb, 0x7d, - 0x29, 0xa1, 0xb1, 0xc0, 0xd7, 0x10, 0xa1, 0x19, 0x3f, 0x9f, 0xc0, 0x58, 0x88, 0x29, 0xee, 0xe1, - 0xd4, 0x5b, 0xed, 0x53, 0x83, 0xad, 0x3e, 0xda, 0xd2, 0xb7, 0xb7, 0x7a, 0x49, 0x0e, 0x00, 0xda, - 0xc8, 0x73, 0x16, 0xba, 0x04, 0xd7, 0x42, 0x4c, 0x04, 0xb1, 0xcd, 0x0c, 0x14, 0xdb, 0x6c, 0x3f, - 0xb1, 0x7d, 0x2f, 0x3f, 0x66, 0x2d, 0x88, 0xe8, 0xdd, 0x1a, 0xc9, 0x6e, 0x4c, 0x49, 0xf4, 0xec, - 0xd0, 0x17, 0x94, 0xac, 0x68, 0x75, 0x5e, 0x07, 0xa6, 0xc8, 0x63, 0xd5, 0xdc, 0x41, 0x4c, 0x87, - 0xc2, 0x04, 0xf5, 0x2c, 0x98, 0xa1, 0x19, 0x9b, 0x8e, 0x8d, 0xdb, 0x93, 0x23, 0x19, 0x84, 0x34, - 0x0c, 0x62, 0xd3, 0x45, 0xa6, 0xe7, 0xb8, 0xa4, 0x8c, 0x3c, 0x05, 0x91, 0x4b, 0x82, 0xdf, 0x0c, - 0xb4, 0x50, 0x13, 0x24, 0xe7, 0xf1, 0x49, 0x9a, 0x92, 0x4c, 0x6e, 0xf6, 0x86, 0xd3, 0x3f, 0xaa, - 0x75, 0x0d, 0x8c, 0xf6, 0x12, 0x99, 0xda, 0x21, 0xf5, 0x24, 0x50, 0x59, 0x2a, 0xce, 0x5b, 0xae, - 0x55, 0x0d, 0xad, 0x6a, 0x14, 0x37, 0xfb, 0x4a, 0xd4, 0x16, 0x7c, 0x5d, 0x0e, 0xe4, 0x9e, 0xe6, - 0x58, 0x36, 0x7c, 0x4e, 0x46, 0x10, 0x09, 0x1b, 0x79, 0x97, 0x1c, 0xf7, 0x62, 0xa0, 0xa8, 0x61, - 0x42, 0x3c, 0x36, 0xa1, 0x28, 0x29, 0x03, 0x45, 0x29, 0xd7, 0x4f, 0x94, 0x7e, 0x99, 0x17, 0xa5, - 0xbb, 0x45, 0x51, 0xba, 0xa9, 0x0f, 0xff, 0x31, 0xf1, 0x11, 0x1d, 0xc0, 0xc7, 0x82, 0x0e, 0xe0, - 0x5e, 0x01, 0xc6, 0xc7, 0xc8, 0x15, 0x93, 0x0c, 0xc0, 0x2f, 0xa6, 0xaa, 0xf8, 0xfd, 0xa0, 0xde, - 0x8a, 0x80, 0x7a, 0xbb, 0x4f, 0x9f, 0x60, 0xed, 0xef, 0x3a, 0x1e, 0xdc, 0xdf, 0x4d, 0x5c, 0x54, - 0x4f, 0x80, 0x63, 0x8b, 0x95, 0xa5, 0x25, 0x4d, 0xd7, 0xaa, 0x46, 0xa3, 0xaa, 0x19, 0xe7, 0x6b, - 0xfa, 0xfd, 0xc5, 0x36, 0x7c, 0xad, 0x02, 0x00, 0xe6, 0x50, 0xd9, 0xb4, 0x9b, 0xa8, 0x2d, 0xd7, - 0xa3, 0xff, 0xcf, 0x6c, 0xb2, 0x3e, 0x21, 0x2c, 0x3f, 0x02, 0xce, 0x57, 0x64, 0xe5, 0xb5, 0x32, - 0xb2, 0xb0, 0x64, 0xa0, 0xbe, 0xf9, 0xe1, 0x60, 0x7b, 0x5e, 0x05, 0x8e, 0xfa, 0xe5, 0xb1, 0xec, - 0xfd, 0xa7, 0x7d, 0x6f, 0xcb, 0x81, 0x39, 0x06, 0x8b, 0x3f, 0x8f, 0x7f, 0x28, 0x23, 0x33, 0x91, - 0x87, 0x60, 0x92, 0x4d, 0xdb, 0xfd, 0xee, 0x3d, 0x78, 0x57, 0x97, 0xc1, 0x74, 0x07, 0xb9, 0x3b, - 0x56, 0xb7, 0x6b, 0x39, 0x36, 0x5d, 0x90, 0x9b, 0xbb, 0xfd, 0x51, 0x01, 0xc7, 0xc9, 0xda, 0xe5, - 0xfc, 0xba, 0xe9, 0x7a, 0x56, 0xd3, 0xea, 0x98, 0xb6, 0xb7, 0x1e, 0x66, 0xd6, 0xf9, 0x3f, 0xe1, - 0x8b, 0x12, 0x4e, 0x6b, 0xc4, 0x96, 0x44, 0x88, 0xc4, 0xef, 0x26, 0x98, 0x92, 0xc4, 0x16, 0x98, - 0x4c, 0x2c, 0x3e, 0x92, 0xaa, 0x58, 0xf4, 0xc1, 0x7b, 0x4b, 0xbd, 0x06, 0x9c, 0xa8, 0x54, 0xcb, - 0x35, 0x5d, 0xd7, 0xca, 0x46, 0x63, 0x5d, 0xd3, 0xd7, 0x2a, 0xf5, 0x7a, 0xa5, 0x56, 0xad, 0x1f, - 0x44, 0xdb, 0xe1, 0x27, 0x94, 0x40, 0x62, 0x16, 0x51, 0xb3, 0x6d, 0xd9, 0x08, 0xde, 0x7b, 0x40, - 0x81, 0x11, 0x57, 0x7d, 0xe4, 0x71, 0x66, 0xf5, 0x47, 0xe0, 0xfc, 0x9a, 0xe4, 0x38, 0xf7, 0x2f, - 0xf0, 0x5f, 0xb1, 0xfa, 0x7f, 0x49, 0x01, 0xc7, 0x38, 0x45, 0xd4, 0xd1, 0xce, 0xc8, 0x56, 0xf2, - 0x9e, 0xc5, 0xeb, 0x6e, 0x45, 0xc4, 0xb4, 0x9f, 0x35, 0xbd, 0x8f, 0x8c, 0x08, 0x58, 0xdf, 0x1c, - 0xc0, 0xba, 0x2a, 0xc0, 0xfa, 0xe4, 0x21, 0xca, 0x4c, 0x86, 0xec, 0x6f, 0xa7, 0x8a, 0xec, 0x35, - 0xe0, 0xc4, 0x7a, 0x49, 0x37, 0x2a, 0xe5, 0xca, 0x7a, 0x09, 0x8f, 0xa3, 0xdc, 0x90, 0x1d, 0x61, - 0xae, 0x8b, 0xa0, 0xf7, 0xc5, 0xf7, 0xf7, 0x73, 0xe0, 0xba, 0xfe, 0x1d, 0x6d, 0x79, 0xdb, 0xb4, - 0xb7, 0x10, 0xb4, 0x64, 0xa0, 0x5e, 0x04, 0x13, 0x4d, 0x92, 0x9d, 0xe2, 0xcc, 0x6f, 0xdd, 0xc4, - 0xf4, 0xe5, 0xb4, 0x06, 0xdd, 0xff, 0x15, 0xbe, 0x93, 0x17, 0x08, 0x43, 0x14, 0x88, 0xa7, 0xc6, - 0x83, 0xb7, 0x8f, 0xee, 0x08, 0xd9, 0xf8, 0x54, 0x20, 0x1b, 0xe7, 0x05, 0xd9, 0x28, 0x1f, 0xac, - 0xf8, 0x64, 0x62, 0xf2, 0xc7, 0x0f, 0x87, 0x0e, 0x20, 0x52, 0x9a, 0xac, 0xe8, 0x51, 0xa1, 0x6f, - 0x77, 0xff, 0x2a, 0x05, 0x14, 0x16, 0x51, 0x1b, 0xc9, 0xae, 0x44, 0x7e, 0x3b, 0x2b, 0xbb, 0x21, - 0x42, 0x61, 0xa0, 0x65, 0x47, 0xaf, 0x8e, 0x78, 0xd6, 0x0e, 0xea, 0x7a, 0xe6, 0x4e, 0x87, 0xb0, - 0x5a, 0xd1, 0xc3, 0x04, 0xf8, 0x73, 0x59, 0x99, 0xed, 0x92, 0x98, 0x6a, 0xfe, 0x75, 0xac, 0x29, - 0x7e, 0x75, 0x0e, 0x14, 0xce, 0x9b, 0xed, 0x36, 0xf2, 0xe0, 0xd7, 0xb2, 0xa0, 0x50, 0xc6, 0x73, - 0x52, 0x04, 0x1f, 0x13, 0x82, 0x05, 0xc1, 0xa4, 0xeb, 0x38, 0xde, 0xba, 0xe9, 0x6d, 0x33, 0xb4, - 0x82, 0x77, 0xb6, 0x4d, 0xfb, 0x5b, 0x3c, 0x68, 0xf7, 0x8a, 0xa0, 0xfd, 0x98, 0xc0, 0x4d, 0x5a, - 0xd1, 0x3c, 0xad, 0x24, 0x02, 0x35, 0x08, 0x26, 0x77, 0x6c, 0xb4, 0xe3, 0xd8, 0x56, 0xd3, 0x1f, - 0xe9, 0xfd, 0x77, 0xf8, 0xc1, 0x60, 0x96, 0xbc, 0x20, 0x60, 0x36, 0x2f, 0x5d, 0x4b, 0x32, 0xd0, - 0xea, 0x43, 0x60, 0x76, 0x3d, 0xb8, 0x96, 0x42, 0xd0, 0x30, 0x6a, 0x8d, 0xb2, 0xae, 0x95, 0x0c, - 0xad, 0xb1, 0x5a, 0x2b, 0x97, 0x56, 0x1b, 0xba, 0xb6, 0x5e, 0x2b, 0x22, 0xf8, 0xdf, 0xb2, 0x98, - 0xb9, 0x4d, 0x67, 0x0f, 0xb9, 0x70, 0x59, 0x8a, 0xcf, 0x71, 0x3c, 0x61, 0x18, 0xfc, 0xb2, 0xf4, - 0x56, 0x39, 0xe3, 0x0e, 0xa3, 0x20, 0xa2, 0x2b, 0xfc, 0x90, 0xd4, 0xb6, 0x77, 0x6c, 0x51, 0x0f, - 0x03, 0x4e, 0xff, 0xaf, 0x2c, 0x98, 0x28, 0x3b, 0xf6, 0x1e, 0x72, 0x3d, 0xde, 0xca, 0xe4, 0xb9, - 0x99, 0x11, 0xb9, 0x89, 0xbb, 0x26, 0x64, 0x7b, 0xae, 0xd3, 0xf1, 0xcd, 0x4c, 0xff, 0x15, 0xfe, - 0x46, 0x52, 0x0e, 0xb3, 0x9a, 0xa3, 0x97, 0x9b, 0xfa, 0x57, 0x24, 0x90, 0xa7, 0xf4, 0x28, 0xc0, - 0x6b, 0x93, 0xe0, 0xd2, 0x9f, 0x80, 0xf4, 0x77, 0x79, 0xbf, 0xac, 0x80, 0x59, 0xaa, 0x7c, 0x75, - 0x44, 0xc6, 0x45, 0x58, 0xe3, 0x17, 0x7a, 0x7a, 0x98, 0xbf, 0x72, 0x44, 0x60, 0x7f, 0xc1, 0xec, - 0x74, 0x82, 0x45, 0xbf, 0x95, 0x23, 0x3a, 0x7b, 0xa7, 0x62, 0xbe, 0x50, 0x00, 0x39, 0x73, 0xd7, - 0xdb, 0x86, 0x3f, 0x94, 0x36, 0xf9, 0x85, 0xce, 0x80, 0xd1, 0x13, 0x01, 0xc9, 0x71, 0x90, 0xf7, - 0x9c, 0x8b, 0xc8, 0xe7, 0x03, 0x7d, 0xc1, 0x70, 0x98, 0x9d, 0x8e, 0x41, 0x3e, 0x30, 0x38, 0xfc, - 0x77, 0x3c, 0xc2, 0x98, 0xcd, 0xa6, 0xb3, 0x6b, 0x7b, 0x15, 0x7f, 0xe1, 0x2f, 0x4c, 0x80, 0x9f, - 0xcf, 0xc8, 0x4c, 0x21, 0x24, 0x08, 0x4c, 0x06, 0xd9, 0x85, 0x21, 0x54, 0x69, 0x1e, 0xdc, 0x52, - 0x5a, 0x5f, 0x6f, 0x18, 0xb5, 0xfb, 0xb5, 0x6a, 0x38, 0xdc, 0x37, 0x2a, 0xd5, 0x86, 0xb1, 0xa2, - 0x35, 0xca, 0x1b, 0x3a, 0x59, 0x9d, 0x29, 0x95, 0xcb, 0xb5, 0x8d, 0xaa, 0x51, 0x44, 0xf0, 0x2d, - 0x59, 0x30, 0x53, 0x6e, 0x3b, 0xdd, 0x00, 0xe1, 0xeb, 0x43, 0x84, 0x03, 0x36, 0x66, 0x38, 0x36, - 0xc2, 0x7f, 0xce, 0xc8, 0x6e, 0xf5, 0xfa, 0x0c, 0xe1, 0x8a, 0x8f, 0xe8, 0xa5, 0x7e, 0x43, 0x6a, - 0xab, 0x77, 0x70, 0x79, 0xe9, 0xab, 0xc4, 0x67, 0xee, 0x02, 0x13, 0x25, 0x2a, 0x18, 0xf0, 0x6f, - 0x32, 0xa0, 0x50, 0x76, 0xec, 0x4d, 0x6b, 0x4b, 0xbd, 0x09, 0xcc, 0x21, 0xdb, 0xbc, 0xd0, 0x46, - 0x8b, 0xa6, 0x67, 0xee, 0x59, 0xe8, 0x12, 0x69, 0xc0, 0xa4, 0xde, 0x93, 0x8a, 0x89, 0x62, 0x29, - 0xe8, 0xc2, 0xee, 0x16, 0x21, 0x6a, 0x52, 0xe7, 0x93, 0xd4, 0x27, 0x83, 0xab, 0xe9, 0xeb, 0xba, - 0x8b, 0x5c, 0xd4, 0x46, 0x66, 0x17, 0x61, 0x63, 0xd4, 0x46, 0x6d, 0x22, 0xb4, 0x93, 0x7a, 0xd4, - 0x67, 0xf5, 0x2c, 0x98, 0xa1, 0x9f, 0x88, 0xa9, 0xd3, 0x25, 0x62, 0x3c, 0xa9, 0x0b, 0x69, 0xea, - 0x63, 0x41, 0x1e, 0x5d, 0xf6, 0x5c, 0xf3, 0x54, 0x8b, 0xe0, 0x75, 0xf5, 0x3c, 0xf5, 0xf5, 0x9a, - 0xf7, 0x7d, 0xbd, 0xe6, 0xeb, 0xc4, 0x13, 0x4c, 0xa7, 0xb9, 0xe0, 0xaf, 0x4f, 0x06, 0x86, 0xc4, - 0xbf, 0x64, 0x43, 0xc1, 0x50, 0x41, 0xce, 0x36, 0x77, 0x10, 0x93, 0x0b, 0xf2, 0xac, 0xde, 0x02, - 0x8e, 0x9a, 0x7b, 0xa6, 0x67, 0xba, 0xab, 0x4e, 0xd3, 0x6c, 0x93, 0xc1, 0xcf, 0xd7, 0xfc, 0xde, - 0x0f, 0x64, 0x1d, 0xde, 0x73, 0x5c, 0x44, 0x72, 0xf9, 0xeb, 0xf0, 0x7e, 0x02, 0x2e, 0xdd, 0x6a, - 0x3a, 0x36, 0xa1, 0x5f, 0xd1, 0xc9, 0x33, 0xe6, 0x4a, 0xcb, 0xea, 0xe2, 0x86, 0x90, 0x52, 0xaa, - 0x74, 0x41, 0xb9, 0x7e, 0xc5, 0x6e, 0x92, 0x35, 0xf8, 0x49, 0x3d, 0xea, 0xb3, 0xba, 0x00, 0xa6, - 0xd9, 0xf2, 0xf3, 0x1a, 0x96, 0xab, 0x02, 0x91, 0xab, 0x33, 0xa2, 0x27, 0x0d, 0xc5, 0x73, 0xbe, - 0x1a, 0xe6, 0xd3, 0xf9, 0x9f, 0xd4, 0xfb, 0xc0, 0xb5, 0xec, 0xb5, 0xbc, 0xdb, 0xf5, 0x9c, 0x1d, - 0x0a, 0xfa, 0x92, 0xd5, 0xa6, 0x2d, 0x98, 0x20, 0x2d, 0x88, 0xcb, 0xa2, 0xde, 0x0e, 0x8e, 0x77, - 0x5c, 0xb4, 0x89, 0xdc, 0x07, 0xcc, 0x9d, 0xdd, 0xcb, 0x86, 0x6b, 0xda, 0xdd, 0x8e, 0xe3, 0x7a, - 0xa7, 0x26, 0x09, 0xf1, 0x7d, 0xbf, 0xb1, 0x8e, 0x72, 0x12, 0x14, 0x28, 0xfb, 0xe0, 0x0b, 0xf3, - 0xd2, 0x4e, 0x74, 0xac, 0x41, 0xb1, 0xe6, 0xd9, 0xe3, 0xc0, 0x04, 0xeb, 0xe1, 0x08, 0x50, 0xd3, - 0xb7, 0x9f, 0xec, 0x99, 0xcd, 0xb1, 0x52, 0x74, 0x3f, 0x9b, 0x7a, 0x07, 0x28, 0x34, 0x49, 0xb3, - 0x08, 0x66, 0xd3, 0xb7, 0x5f, 0xdb, 0xbf, 0x52, 0x92, 0x45, 0x67, 0x59, 0xe1, 0x17, 0x14, 0x29, - 0xbf, 0xbb, 0x38, 0x8a, 0x93, 0x69, 0xf5, 0x37, 0xb3, 0x43, 0x74, 0x9b, 0xb7, 0x82, 0x9b, 0x59, - 0x9f, 0xc8, 0xec, 0x8f, 0xc5, 0xc6, 0xc2, 0x86, 0x6f, 0x82, 0x63, 0xab, 0xa4, 0x6e, 0x94, 0x74, - 0x3c, 0x7f, 0x5a, 0xc4, 0xa6, 0xfb, 0x2d, 0xe0, 0xa6, 0x01, 0xb9, 0x35, 0xa3, 0x51, 0x2d, 0xad, - 0x69, 0xc5, 0x4d, 0xd1, 0xb6, 0xa9, 0x1b, 0xb5, 0xf5, 0x86, 0xbe, 0x51, 0xad, 0x56, 0xaa, 0xcb, - 0xb4, 0x30, 0x6c, 0x12, 0x9e, 0x0c, 0x33, 0x9c, 0xd7, 0x2b, 0x86, 0xd6, 0x28, 0xd7, 0xaa, 0x4b, - 0x95, 0xe5, 0xa2, 0x35, 0xc8, 0x30, 0x7a, 0x50, 0x3d, 0x03, 0xae, 0x13, 0x28, 0xa9, 0xd4, 0xaa, - 0x78, 0x3e, 0x51, 0x2e, 0x55, 0xcb, 0x1a, 0x9e, 0x3c, 0x5c, 0x54, 0x21, 0x38, 0x41, 0x8b, 0x6b, - 0x2c, 0x55, 0x56, 0xf9, 0x2d, 0x80, 0x8f, 0x67, 0xd4, 0x53, 0xe0, 0x2a, 0xfe, 0x5b, 0xa5, 0x7a, - 0xae, 0xb4, 0x5a, 0x59, 0x2c, 0xfe, 0x51, 0x46, 0xbd, 0x11, 0x5c, 0x2f, 0xfc, 0x45, 0x57, 0xf3, - 0x1b, 0x95, 0xc5, 0xc6, 0x5a, 0xa5, 0xbe, 0x56, 0x32, 0xca, 0x2b, 0xc5, 0x4f, 0x90, 0xf9, 0x42, - 0x60, 0x00, 0x73, 0xce, 0x70, 0x2f, 0xe1, 0xc7, 0xf4, 0x92, 0x28, 0xa8, 0x8f, 0xe9, 0x0b, 0x7b, - 0xbc, 0x0d, 0xfb, 0x91, 0x60, 0x74, 0x58, 0x14, 0x44, 0xe8, 0x71, 0x09, 0xca, 0x4a, 0x26, 0x43, - 0xc6, 0x10, 0x22, 0x74, 0x06, 0x5c, 0x57, 0xd5, 0x28, 0x52, 0xba, 0x56, 0xae, 0x9d, 0xd3, 0xf4, - 0xc6, 0xf9, 0xd2, 0xea, 0xaa, 0x66, 0x34, 0x96, 0x2a, 0x7a, 0xdd, 0x28, 0x6e, 0xc2, 0xef, 0x64, - 0x83, 0x39, 0x34, 0xc7, 0xad, 0xbf, 0xc9, 0x26, 0x55, 0xeb, 0xd8, 0xb9, 0xf2, 0x8f, 0x83, 0x42, - 0xd7, 0x33, 0xbd, 0xdd, 0x2e, 0xd3, 0xea, 0x47, 0xf4, 0xd7, 0xea, 0xf9, 0x3a, 0xc9, 0xa4, 0xb3, - 0xcc, 0xf0, 0x0b, 0x99, 0x24, 0x6a, 0x3a, 0x82, 0x69, 0xb4, 0x35, 0x04, 0x8b, 0x4f, 0x03, 0xe8, - 0x4b, 0x7b, 0xa5, 0xde, 0x28, 0xad, 0xea, 0x5a, 0x69, 0xf1, 0x81, 0x60, 0xf2, 0x8c, 0xd4, 0x13, - 0xe0, 0xd8, 0x46, 0x15, 0x4f, 0x87, 0x89, 0xba, 0xd4, 0xaa, 0x55, 0xad, 0x8c, 0xf9, 0xfe, 0x73, - 0x64, 0xa9, 0x1a, 0x5b, 0xd0, 0x84, 0x6e, 0x6c, 0xe5, 0x70, 0xfc, 0xff, 0x86, 0xb4, 0x47, 0x47, - 0x28, 0x61, 0x7c, 0x59, 0xa3, 0xc5, 0xe1, 0xf3, 0x52, 0x4e, 0x1c, 0x52, 0x94, 0x24, 0xc3, 0xe3, - 0xdf, 0x0f, 0x81, 0xc7, 0x09, 0x70, 0x8c, 0xc7, 0x83, 0x38, 0x73, 0x44, 0xc3, 0xf0, 0x95, 0x49, - 0x50, 0xa8, 0xa3, 0x36, 0x6a, 0x7a, 0xf0, 0x6d, 0x9c, 0x31, 0x31, 0x07, 0xb2, 0x81, 0xf3, 0x40, - 0xd6, 0x6a, 0x09, 0xd3, 0xe7, 0x6c, 0xcf, 0xf4, 0x39, 0xc6, 0x0c, 0x50, 0x12, 0x99, 0x01, 0xb9, - 0x14, 0xcc, 0x80, 0xfc, 0xf0, 0x66, 0x40, 0x61, 0x90, 0x19, 0x00, 0x5f, 0x5f, 0x48, 0xda, 0x4b, - 0x50, 0x56, 0x1f, 0xee, 0xe0, 0xff, 0x3f, 0x73, 0x49, 0x7a, 0x95, 0xbe, 0x14, 0x27, 0x93, 0xe2, - 0x1f, 0x2a, 0x29, 0x2c, 0x3f, 0xa8, 0x37, 0x80, 0xeb, 0xc3, 0xf7, 0x86, 0xf6, 0x8c, 0x4a, 0xdd, - 0xa8, 0x93, 0x11, 0xbf, 0x5c, 0xd3, 0xf5, 0x8d, 0x75, 0xba, 0x72, 0x77, 0x12, 0xa8, 0x61, 0x29, - 0xfa, 0x46, 0x95, 0x8e, 0xef, 0x5b, 0x62, 0xe9, 0x4b, 0x95, 0xea, 0x62, 0x23, 0xd0, 0x99, 0xea, - 0x52, 0xad, 0xb8, 0x8d, 0xa7, 0x6c, 0x5c, 0xe9, 0x78, 0x80, 0x66, 0x35, 0x94, 0xaa, 0x8b, 0x8d, - 0xb5, 0xaa, 0xb6, 0x56, 0xab, 0x56, 0xca, 0x24, 0xbd, 0xae, 0x19, 0x45, 0x0b, 0x0f, 0x34, 0x3d, - 0x16, 0x45, 0x5d, 0x2b, 0xe9, 0xe5, 0x15, 0x4d, 0xa7, 0x55, 0x3e, 0xa8, 0xde, 0x04, 0xce, 0x96, - 0xaa, 0x35, 0x03, 0xa7, 0x94, 0xaa, 0x0f, 0x18, 0x0f, 0xac, 0x6b, 0x8d, 0x75, 0xbd, 0x56, 0xd6, - 0xea, 0x75, 0xac, 0xa7, 0xcc, 0xfe, 0x28, 0xb6, 0xd5, 0xa7, 0x82, 0xbb, 0x38, 0xd2, 0x34, 0x83, - 0x6c, 0x13, 0xad, 0xd5, 0x88, 0xa7, 0xc0, 0xa2, 0xd6, 0x58, 0x29, 0xd5, 0x1b, 0x95, 0x6a, 0xb9, - 0xb6, 0xb6, 0x5e, 0x32, 0x2a, 0x58, 0x9d, 0xd7, 0xf5, 0x9a, 0x51, 0x6b, 0x9c, 0xd3, 0xf4, 0x7a, - 0xa5, 0x56, 0x2d, 0xda, 0xb8, 0xc9, 0x9c, 0xfe, 0xfb, 0xfd, 0xb0, 0xa3, 0x5e, 0x07, 0x4e, 0xf9, - 0xe9, 0xab, 0x35, 0xcc, 0x68, 0xce, 0x22, 0xe9, 0xa4, 0x6a, 0x91, 0xfc, 0x53, 0x16, 0xe4, 0xea, - 0x9e, 0xd3, 0x81, 0x3f, 0x16, 0x76, 0x30, 0xa7, 0x01, 0x70, 0xc9, 0xae, 0x0f, 0x9e, 0x85, 0xb1, - 0x79, 0x19, 0x97, 0x02, 0x3f, 0x2a, 0xbd, 0x54, 0x1d, 0xf6, 0xd9, 0x4e, 0x27, 0xc2, 0x56, 0xf9, - 0xbe, 0x9c, 0xef, 0x7e, 0x74, 0x41, 0xc9, 0xe4, 0xfd, 0xe7, 0x87, 0x59, 0x8c, 0x86, 0xe0, 0x24, - 0x07, 0x1b, 0xe6, 0xbf, 0x2f, 0x12, 0x48, 0xbd, 0x1a, 0x5c, 0xd5, 0x23, 0x5c, 0x44, 0xa6, 0x36, - 0xd5, 0x47, 0x82, 0x47, 0x70, 0xe2, 0xad, 0xad, 0xd5, 0xce, 0x69, 0x81, 0x20, 0x2f, 0x96, 0x8c, - 0x52, 0x71, 0x0b, 0x7e, 0x46, 0x01, 0xb9, 0x35, 0x67, 0xaf, 0x77, 0x87, 0xc0, 0x46, 0x97, 0xb8, - 0xb5, 0x50, 0xff, 0x55, 0xf4, 0x55, 0x96, 0x62, 0xfb, 0x5a, 0xf4, 0x6e, 0xe0, 0xe7, 0xb3, 0x49, - 0xd8, 0xbe, 0x76, 0xd0, 0x2d, 0xc0, 0xbf, 0x1b, 0x86, 0xed, 0x11, 0xac, 0x45, 0xea, 0x59, 0x70, - 0x3a, 0xfc, 0x50, 0x59, 0xd4, 0xaa, 0x46, 0x65, 0xe9, 0x81, 0x90, 0xb9, 0x15, 0x5d, 0x8a, 0xfd, - 0x83, 0xba, 0xb1, 0xf8, 0x99, 0xc6, 0x29, 0x70, 0x3c, 0xfc, 0xb6, 0xac, 0x19, 0xfe, 0x97, 0x07, - 0xe1, 0x73, 0xf2, 0x60, 0x86, 0x76, 0xeb, 0x1b, 0x9d, 0x96, 0xe9, 0x21, 0x78, 0x47, 0x88, 0xee, - 0xcd, 0xe0, 0x68, 0x65, 0x7d, 0xa9, 0x5e, 0xf7, 0x1c, 0xd7, 0xdc, 0x42, 0xa5, 0x56, 0xcb, 0x65, - 0xdc, 0xea, 0x4d, 0x86, 0xef, 0x96, 0x5e, 0xe7, 0x13, 0x87, 0x12, 0x5a, 0x67, 0x04, 0xea, 0x5f, - 0x96, 0x5a, 0x97, 0x93, 0x28, 0x30, 0x19, 0xfa, 0x0f, 0x8e, 0x58, 0xe7, 0xa2, 0x71, 0xd9, 0x3c, - 0xfb, 0xbc, 0x2c, 0x98, 0x32, 0xac, 0x1d, 0xf4, 0x4c, 0xc7, 0x46, 0x5d, 0x75, 0x02, 0x28, 0xcb, - 0x6b, 0x46, 0xf1, 0x08, 0x7e, 0xc0, 0x46, 0x55, 0x86, 0x3c, 0x68, 0xb8, 0x02, 0xfc, 0x50, 0x32, - 0x8a, 0x0a, 0x7e, 0x58, 0xd3, 0x8c, 0x62, 0x0e, 0x3f, 0x54, 0x35, 0xa3, 0x98, 0xc7, 0x0f, 0xeb, - 0xab, 0x46, 0xb1, 0x80, 0x1f, 0x2a, 0x75, 0xa3, 0x38, 0x81, 0x1f, 0x16, 0xea, 0x46, 0x71, 0x12, - 0x3f, 0x9c, 0xab, 0x1b, 0xc5, 0x29, 0xfc, 0x50, 0x36, 0x8c, 0x22, 0xc0, 0x0f, 0x4f, 0xab, 0x1b, - 0xc5, 0x69, 0xfc, 0x50, 0x2a, 0x1b, 0xc5, 0x19, 0xf2, 0xa0, 0x19, 0xc5, 0x59, 0xfc, 0x50, 0xaf, - 0x1b, 0xc5, 0x39, 0x52, 0x72, 0xdd, 0x28, 0x1e, 0x25, 0x75, 0x55, 0x8c, 0x62, 0x11, 0x3f, 0xac, - 0xd4, 0x8d, 0xe2, 0x31, 0x92, 0xb9, 0x6e, 0x14, 0x55, 0x52, 0x69, 0xdd, 0x28, 0x5e, 0x45, 0xf2, - 0xd4, 0x8d, 0xe2, 0x71, 0x52, 0x45, 0xdd, 0x28, 0x9e, 0x20, 0x64, 0x68, 0x46, 0xf1, 0x24, 0xc9, - 0xa3, 0x1b, 0xc5, 0xab, 0xc9, 0xa7, 0xaa, 0x51, 0x3c, 0x45, 0x08, 0xd3, 0x8c, 0xe2, 0x35, 0xe4, - 0x41, 0x37, 0x8a, 0x90, 0x7c, 0x2a, 0x19, 0xc5, 0x6b, 0xe1, 0x23, 0xc0, 0xd4, 0x32, 0xf2, 0x28, - 0x88, 0xb0, 0x08, 0x94, 0x65, 0xe4, 0xf1, 0x66, 0xfc, 0x57, 0x15, 0x70, 0x35, 0x9b, 0xfa, 0x2d, - 0xb9, 0xce, 0xce, 0x2a, 0xda, 0x32, 0x9b, 0x57, 0xb4, 0xcb, 0xd8, 0x84, 0x82, 0x75, 0x61, 0xe9, - 0xaa, 0x13, 0x76, 0x46, 0xe4, 0x39, 0xd6, 0xe2, 0xf4, 0x17, 0xa3, 0x94, 0x70, 0x31, 0x8a, 0x59, - 0x64, 0xff, 0xc0, 0x4b, 0xb4, 0xb0, 0x7e, 0x9c, 0xe9, 0x59, 0x3f, 0xc6, 0x6a, 0xd2, 0x41, 0x6e, - 0xd7, 0xb1, 0xcd, 0x76, 0x9d, 0x6d, 0x97, 0xd2, 0x55, 0xaf, 0xde, 0x64, 0xf5, 0xe9, 0xbe, 0x66, - 0x50, 0xab, 0xec, 0x29, 0x71, 0x33, 0xdc, 0xde, 0x66, 0x46, 0x28, 0xc9, 0x27, 0x02, 0x25, 0x31, - 0x04, 0x25, 0xb9, 0xef, 0x00, 0x65, 0x27, 0xd3, 0x97, 0xca, 0x70, 0x53, 0x8b, 0xd0, 0x99, 0xd0, - 0x5f, 0xae, 0x56, 0xe0, 0x67, 0xb2, 0xe0, 0xa4, 0x66, 0xf7, 0xb3, 0xf0, 0x79, 0x59, 0x78, 0x0b, - 0x0f, 0xcd, 0xba, 0xc8, 0xd2, 0xbb, 0xfa, 0x36, 0xbb, 0x7f, 0x99, 0x11, 0x1c, 0xfd, 0x64, 0xc0, - 0xd1, 0xba, 0xc0, 0xd1, 0x7b, 0x87, 0x2f, 0x3a, 0x19, 0x43, 0xab, 0x23, 0xed, 0x80, 0x72, 0xf0, - 0x9b, 0x39, 0xf0, 0x08, 0xea, 0xf1, 0xc0, 0x28, 0xa4, 0x5a, 0x56, 0xb2, 0x5b, 0x3a, 0xea, 0x7a, - 0xa6, 0xeb, 0x09, 0xa7, 0x50, 0x7b, 0xa6, 0x52, 0x99, 0x14, 0xa6, 0x52, 0xd9, 0x81, 0x53, 0x29, - 0xf8, 0x2e, 0xde, 0x7c, 0x38, 0x2f, 0x62, 0x5c, 0xea, 0xdf, 0xff, 0xc7, 0xb5, 0x30, 0x0a, 0xea, - 0xc0, 0xae, 0xf8, 0x09, 0x01, 0xea, 0xa5, 0x03, 0xd7, 0x90, 0x0c, 0xf1, 0x8f, 0x8e, 0xd6, 0xce, - 0xcb, 0xf1, 0xdf, 0x44, 0xa3, 0xa4, 0xd8, 0x4a, 0xd5, 0x40, 0xff, 0xd4, 0x04, 0x98, 0x22, 0xba, - 0xb0, 0x6a, 0xd9, 0x17, 0xe1, 0x6b, 0x15, 0x30, 0x53, 0x45, 0x97, 0xca, 0xdb, 0x66, 0xbb, 0x8d, - 0xec, 0x2d, 0xc4, 0x9b, 0xed, 0xa7, 0xc0, 0x84, 0xd9, 0xe9, 0x54, 0xc3, 0x7d, 0x06, 0xff, 0x95, - 0xf5, 0xbf, 0xdf, 0xe8, 0xab, 0xe4, 0x99, 0x18, 0x25, 0x0f, 0xea, 0x9d, 0xe7, 0xeb, 0x8c, 0x98, - 0x21, 0x9f, 0x01, 0xd3, 0x4d, 0x3f, 0x4b, 0xe0, 0xad, 0xce, 0x27, 0xc1, 0xaf, 0x27, 0xea, 0x06, - 0xa4, 0x2a, 0x4f, 0x26, 0x14, 0x68, 0xc4, 0x76, 0xc8, 0x09, 0x70, 0xcc, 0xa8, 0xd5, 0x1a, 0x6b, - 0xa5, 0xea, 0x03, 0xe1, 0x29, 0xd1, 0x4d, 0xf8, 0x8a, 0x1c, 0x98, 0xab, 0x3b, 0xed, 0x3d, 0x14, - 0xc2, 0x54, 0x09, 0x61, 0xea, 0xe1, 0x53, 0x66, 0x1f, 0x9f, 0xd4, 0x93, 0xa0, 0x60, 0xda, 0xdd, - 0x4b, 0xc8, 0xb7, 0x0d, 0xd9, 0x1b, 0x83, 0xf1, 0xf7, 0x79, 0x3d, 0xd6, 0x45, 0x18, 0xef, 0x1e, - 0xc0, 0x49, 0x91, 0xaa, 0x08, 0x20, 0xcf, 0x82, 0x99, 0x2e, 0xdd, 0x2c, 0x34, 0xb8, 0x3d, 0x61, - 0x21, 0x8d, 0x90, 0x48, 0x77, 0xab, 0x15, 0x46, 0x22, 0x79, 0x83, 0xaf, 0x0d, 0xd4, 0x7f, 0x43, - 0x80, 0xb8, 0x74, 0x10, 0xc2, 0x92, 0x81, 0xfc, 0xaa, 0x51, 0xcf, 0xf0, 0x4e, 0x81, 0xe3, 0x4c, - 0x6b, 0x1b, 0xe5, 0x95, 0xd2, 0xea, 0xaa, 0x56, 0x5d, 0xd6, 0x1a, 0x95, 0x45, 0xba, 0x55, 0x11, - 0xa6, 0x94, 0x0c, 0x43, 0x5b, 0x5b, 0x37, 0xea, 0x0d, 0xed, 0x19, 0x65, 0x4d, 0x5b, 0x24, 0x8e, - 0x48, 0xe4, 0x24, 0x81, 0xef, 0x32, 0x56, 0xaa, 0xd6, 0xcf, 0x6b, 0x7a, 0x71, 0xfb, 0x6c, 0x09, - 0x4c, 0x73, 0xfd, 0x3c, 0xa6, 0x6e, 0x11, 0x6d, 0x9a, 0xbb, 0x6d, 0x66, 0xab, 0x15, 0x8f, 0x60, - 0xea, 0x08, 0x6f, 0x6a, 0x76, 0xfb, 0x4a, 0x31, 0xa3, 0x16, 0xc1, 0x0c, 0xdf, 0xa5, 0x17, 0xb3, - 0xf0, 0xfb, 0xd7, 0x82, 0xa9, 0xf3, 0x8e, 0x7b, 0x91, 0x78, 0x8f, 0xc1, 0xf7, 0xd1, 0x68, 0x12, - 0xfe, 0xb9, 0x3c, 0x6e, 0x60, 0x7f, 0x95, 0xbc, 0xb7, 0x80, 0x5f, 0xda, 0xfc, 0xc0, 0xb3, 0x77, - 0x67, 0xc0, 0xf4, 0x25, 0x3f, 0x77, 0xa8, 0xe9, 0x5c, 0x12, 0xfc, 0x2f, 0x72, 0xfb, 0xff, 0x83, - 0xab, 0x4c, 0x7f, 0x7f, 0xfa, 0x6d, 0x59, 0x50, 0x58, 0x46, 0x5e, 0xa9, 0xdd, 0xe6, 0xf9, 0xf6, - 0x52, 0xe9, 0xf3, 0x14, 0x42, 0x23, 0x4a, 0xed, 0x76, 0xb4, 0x52, 0x71, 0x0c, 0xf2, 0xfd, 0x7e, - 0x85, 0x34, 0xf8, 0x7a, 0xa9, 0x93, 0x50, 0x03, 0x2a, 0x4c, 0x9f, 0x63, 0x6f, 0x54, 0x82, 0x3d, - 0xee, 0xe7, 0x73, 0x56, 0xce, 0xe3, 0xc3, 0x48, 0x22, 0x99, 0xf8, 0xbd, 0x72, 0x3f, 0x9f, 0x7a, - 0x3f, 0x98, 0xd8, 0xed, 0xa2, 0xb2, 0xd9, 0x45, 0x84, 0xb6, 0xde, 0x96, 0xd6, 0x2e, 0x3c, 0x88, - 0x9a, 0xde, 0x7c, 0x65, 0x07, 0x1b, 0xd4, 0x1b, 0x34, 0x63, 0x10, 0x9c, 0x83, 0xbd, 0xeb, 0x7e, - 0x09, 0xf0, 0x85, 0x43, 0x40, 0x16, 0xbb, 0xdf, 0x1b, 0x79, 0xf4, 0x2a, 0x31, 0x50, 0x23, 0xd8, - 0xa4, 0x1d, 0x06, 0xa8, 0x4f, 0x65, 0x41, 0xae, 0xd6, 0x41, 0xb6, 0x9c, 0x03, 0xea, 0x6b, 0xe5, - 0xbd, 0xbc, 0x82, 0x86, 0xe1, 0xd2, 0x23, 0xb8, 0x77, 0x1b, 0xc8, 0x59, 0xf6, 0xa6, 0xc3, 0x0c, - 0xcc, 0x6b, 0x23, 0x36, 0x73, 0x2a, 0xf6, 0xa6, 0xa3, 0x93, 0x8c, 0xb2, 0x0e, 0x5e, 0x71, 0x75, - 0xa7, 0xcf, 0xd2, 0x6f, 0x4d, 0x82, 0x02, 0x15, 0x4b, 0xf8, 0x12, 0x05, 0x28, 0xa5, 0x56, 0x2b, - 0xe2, 0x10, 0x47, 0x76, 0xdf, 0x21, 0x0e, 0x87, 0xfc, 0x16, 0xf0, 0x3d, 0x78, 0x17, 0x43, 0x41, - 0x48, 0xf6, 0xd1, 0x4c, 0x35, 0x4a, 0xad, 0x56, 0xb4, 0x2f, 0x69, 0x50, 0x61, 0x56, 0xac, 0x90, - 0xd7, 0x54, 0x45, 0x4e, 0x53, 0x13, 0x77, 0xe8, 0x91, 0xf4, 0xa5, 0x0f, 0xd1, 0x3f, 0x64, 0xc1, - 0xc4, 0xaa, 0xd5, 0xf5, 0x30, 0x36, 0x25, 0x19, 0x6c, 0xae, 0x03, 0x53, 0x3e, 0x6b, 0x70, 0xd7, - 0x85, 0xfb, 0xe5, 0x30, 0x01, 0xbe, 0x8e, 0x47, 0xe7, 0x69, 0x22, 0x3a, 0x4f, 0x88, 0x6f, 0x3d, - 0xa3, 0x22, 0xda, 0x47, 0x3b, 0xac, 0x36, 0xdb, 0x5b, 0xed, 0x6f, 0x05, 0x0c, 0x5f, 0x13, 0x18, - 0x7e, 0xe7, 0x30, 0x55, 0xa6, 0xcf, 0xf4, 0xcf, 0x66, 0x01, 0xc0, 0x75, 0xb3, 0x83, 0x30, 0x8f, - 0x16, 0x8e, 0xb7, 0xc6, 0x70, 0xf7, 0x15, 0x3c, 0x77, 0xd7, 0x44, 0xee, 0x3e, 0x69, 0x70, 0x53, - 0xe3, 0x0e, 0xbc, 0xa8, 0x45, 0xa0, 0x58, 0x01, 0x6b, 0xf1, 0x23, 0x7c, 0x5b, 0xc0, 0xd4, 0x75, - 0x81, 0xa9, 0x77, 0x0f, 0x59, 0x53, 0xfa, 0x7c, 0xfd, 0xab, 0x2c, 0x98, 0xa8, 0x23, 0x0f, 0x77, - 0x93, 0xf0, 0x9c, 0xcc, 0x91, 0x13, 0x4e, 0xb7, 0xb3, 0x92, 0xba, 0xfd, 0xbd, 0x8c, 0x6c, 0x98, - 0x8c, 0x90, 0x33, 0x8c, 0xa6, 0x88, 0x45, 0x80, 0x37, 0x48, 0x85, 0xc9, 0x18, 0x54, 0x5a, 0xfa, - 0xdc, 0x7d, 0x4b, 0x36, 0xd8, 0x60, 0x7f, 0x8c, 0x30, 0x41, 0xe3, 0xcd, 0xdb, 0xcc, 0x7e, 0xf3, - 0xf6, 0x3b, 0x99, 0xe4, 0xa6, 0x46, 0xdc, 0xee, 0x72, 0x62, 0x83, 0x62, 0x04, 0x1b, 0xbf, 0xc3, - 0xf0, 0xeb, 0xd9, 0x0a, 0x28, 0xb0, 0x15, 0xe2, 0x7b, 0xe3, 0x57, 0x88, 0x07, 0x4f, 0x11, 0xde, - 0x3b, 0x84, 0xb9, 0x16, 0xb7, 0x6c, 0x1b, 0x90, 0x91, 0xe5, 0xc8, 0xb8, 0x15, 0xe4, 0x49, 0x1c, - 0x3f, 0x36, 0xce, 0x85, 0x7b, 0xf6, 0x7e, 0x11, 0x1a, 0xfe, 0xaa, 0xd3, 0x4c, 0x89, 0x51, 0x18, - 0xc1, 0x4a, 0xef, 0x30, 0x28, 0x7c, 0xfa, 0xa3, 0x99, 0xc0, 0x08, 0x79, 0x6f, 0x8e, 0x99, 0x78, - 0x1f, 0x13, 0x23, 0x0a, 0x34, 0x1d, 0xdb, 0x43, 0x97, 0xb9, 0xb5, 0xf5, 0x20, 0x21, 0xd6, 0x32, - 0x38, 0x05, 0x26, 0x3c, 0x97, 0x5f, 0x6f, 0xf7, 0x5f, 0xf9, 0x1e, 0x27, 0x2f, 0xf6, 0x38, 0x55, - 0x70, 0xd6, 0xb2, 0x9b, 0xed, 0xdd, 0x16, 0xd2, 0x51, 0xdb, 0xc4, 0xad, 0xea, 0x96, 0xba, 0x8b, - 0xa8, 0x83, 0xec, 0x16, 0xb2, 0x3d, 0x4a, 0xa7, 0xef, 0x5b, 0x2b, 0x91, 0x13, 0x7e, 0x8d, 0x17, - 0x8c, 0x7b, 0x44, 0xc1, 0x78, 0x74, 0xbf, 0xf9, 0x41, 0x8c, 0x11, 0x7a, 0x27, 0x00, 0xb4, 0x6d, - 0xe7, 0x2c, 0x74, 0x89, 0x75, 0x88, 0xd7, 0xf4, 0x98, 0xa2, 0xb5, 0x20, 0x83, 0xce, 0x65, 0x86, - 0x5f, 0x0a, 0x84, 0xe1, 0x3e, 0x41, 0x18, 0x6e, 0x95, 0x24, 0x21, 0x99, 0x1c, 0x74, 0x86, 0x58, - 0xb3, 0x98, 0x05, 0x53, 0xe1, 0x4a, 0xa3, 0xa2, 0x5e, 0x03, 0x4e, 0xf8, 0xbe, 0x0b, 0x55, 0x4d, - 0x5b, 0xac, 0x37, 0x36, 0xd6, 0x97, 0xf5, 0xd2, 0xa2, 0x56, 0x04, 0xaa, 0x0a, 0xe6, 0x6a, 0x0b, - 0x4f, 0xd3, 0xca, 0x46, 0xe0, 0x72, 0x90, 0x83, 0x7f, 0x99, 0x05, 0x79, 0xe2, 0x18, 0x0e, 0x7f, - 0x6a, 0x44, 0x92, 0xd3, 0x15, 0x76, 0x6a, 0x82, 0x79, 0x85, 0x7c, 0xa4, 0x3f, 0xc6, 0x4c, 0x42, - 0xd5, 0x81, 0x22, 0xfd, 0xc5, 0x14, 0x94, 0xbe, 0x7a, 0x62, 0x95, 0xac, 0x6f, 0x3b, 0x97, 0xfe, - 0x2d, 0xab, 0x24, 0x6e, 0xff, 0x21, 0xab, 0x64, 0x1f, 0x12, 0xc6, 0xae, 0x92, 0x7d, 0xf4, 0x2e, - 0x46, 0x4d, 0xe1, 0xd7, 0x73, 0xc1, 0xc2, 0xca, 0xff, 0x7d, 0xb0, 0x85, 0x95, 0x12, 0x98, 0xb5, - 0x6c, 0x0f, 0xb9, 0xb6, 0xd9, 0x5e, 0x6a, 0x9b, 0x5b, 0xfe, 0xf1, 0xe3, 0xde, 0x59, 0x78, 0x85, - 0xcb, 0xa3, 0x8b, 0x7f, 0xa8, 0xa7, 0x01, 0xf0, 0xd0, 0x4e, 0xa7, 0x6d, 0x7a, 0xa1, 0xe8, 0x71, - 0x29, 0xbc, 0xf4, 0xe5, 0x44, 0xe9, 0x7b, 0x1c, 0xb8, 0x8a, 0x82, 0x66, 0x5c, 0xe9, 0xa0, 0x0d, - 0xdb, 0xfa, 0xe9, 0x5d, 0x12, 0x80, 0x86, 0xca, 0x68, 0xbf, 0x4f, 0xf0, 0x7f, 0x48, 0x1f, 0xa3, - 0xf4, 0x35, 0x7b, 0xc0, 0x31, 0xca, 0x40, 0x9b, 0x94, 0x1e, 0x6d, 0x0a, 0x0c, 0x82, 0x9c, 0x84, - 0x41, 0xc0, 0x73, 0x3e, 0x2f, 0x69, 0x4c, 0xbf, 0x46, 0xea, 0x9c, 0x66, 0x5c, 0x33, 0xd2, 0xef, - 0xa1, 0xde, 0xa7, 0x80, 0x39, 0x5a, 0xf5, 0x82, 0xe3, 0x5c, 0xdc, 0x31, 0xdd, 0x8b, 0xfc, 0xdc, - 0x62, 0x08, 0x71, 0x8b, 0x5e, 0x29, 0xfb, 0x24, 0x8f, 0xec, 0xb2, 0x88, 0xec, 0xe3, 0xa3, 0x59, - 0xe2, 0xd3, 0x35, 0x9e, 0xc5, 0x8d, 0x37, 0x05, 0x98, 0x3d, 0x4d, 0xc0, 0xec, 0x89, 0x89, 0x09, - 0x4c, 0x1f, 0xbb, 0x3f, 0x0e, 0xb0, 0xf3, 0x3b, 0xec, 0xd4, 0xb0, 0xfb, 0xf2, 0x70, 0xd8, 0xf9, - 0x74, 0x0d, 0x81, 0x5d, 0x11, 0x28, 0x17, 0x83, 0x2d, 0x25, 0xfc, 0xc8, 0x37, 0x28, 0x97, 0x1e, - 0x9a, 0x11, 0x24, 0x8f, 0x05, 0xcd, 0xe3, 0x22, 0x09, 0xb5, 0x4e, 0xaa, 0x98, 0x7e, 0x51, 0x7a, - 0xbd, 0xa5, 0x2f, 0x83, 0x28, 0x75, 0xe3, 0xd1, 0x4a, 0xb9, 0xc5, 0x1a, 0x79, 0x32, 0xd3, 0x47, - 0xf3, 0xef, 0x73, 0x60, 0xca, 0x3f, 0xcc, 0xea, 0xc1, 0x3f, 0xe7, 0x86, 0xf0, 0x93, 0xa0, 0xd0, - 0x75, 0x76, 0xdd, 0x26, 0x62, 0x2b, 0x60, 0xec, 0x6d, 0x88, 0xd5, 0x9a, 0x81, 0xe3, 0xf2, 0xbe, - 0xa1, 0x3f, 0x97, 0x78, 0xe8, 0x8f, 0x34, 0x2c, 0xe1, 0x0b, 0xa5, 0x43, 0x0f, 0x0a, 0xb8, 0xd4, - 0x91, 0xf7, 0x70, 0x1c, 0xab, 0xff, 0x50, 0x6a, 0xbe, 0x3f, 0xa0, 0x25, 0xc9, 0xc4, 0xaa, 0x36, - 0x84, 0x51, 0x79, 0x2d, 0xb8, 0xda, 0xcf, 0xc1, 0xac, 0x49, 0x62, 0x3d, 0x6e, 0xe8, 0xab, 0x45, - 0x05, 0x3e, 0x3b, 0x07, 0x8a, 0x94, 0xb4, 0x5a, 0x60, 0x58, 0xc1, 0x97, 0x1e, 0xba, 0xf5, 0x18, - 0x3d, 0x1d, 0xfc, 0x74, 0x56, 0x36, 0xbc, 0x91, 0xc0, 0xf8, 0xb0, 0x75, 0x11, 0x92, 0x34, 0x84, - 0x2a, 0xc5, 0x08, 0x1f, 0xfc, 0xcd, 0x8c, 0x4c, 0xb4, 0x24, 0x39, 0x12, 0xd3, 0xef, 0x79, 0x5e, - 0x97, 0xf3, 0xe3, 0x0e, 0x2c, 0xb9, 0xce, 0xce, 0x86, 0xdb, 0x86, 0x1f, 0x94, 0x0a, 0x46, 0x17, - 0x61, 0xaa, 0x67, 0x23, 0x4d, 0x75, 0x3c, 0x44, 0xef, 0xba, 0x6d, 0x7f, 0x88, 0xde, 0x75, 0xdb, - 0x43, 0x0c, 0xd1, 0xea, 0x4d, 0x60, 0xce, 0x6c, 0xb5, 0xd6, 0xcd, 0x2d, 0x54, 0xc6, 0x73, 0x60, - 0xdb, 0x63, 0x67, 0x92, 0x7b, 0x52, 0x13, 0xec, 0x8c, 0x09, 0x40, 0x30, 0x1e, 0x3c, 0x9c, 0x76, - 0xc6, 0x24, 0xe8, 0x4b, 0x5f, 0x4a, 0x7e, 0x37, 0x0b, 0x26, 0xca, 0xdb, 0x26, 0xd9, 0x19, 0x7b, - 0x94, 0x10, 0x14, 0x24, 0x72, 0x6f, 0xf2, 0xf9, 0xd2, 0x9b, 0xc2, 0x7e, 0x0b, 0x69, 0xf9, 0x11, - 0xbc, 0x3f, 0x09, 0x0a, 0xcd, 0x6d, 0x33, 0xe4, 0x3c, 0x7b, 0x93, 0xdc, 0xfb, 0x8d, 0xad, 0x22, - 0x7d, 0xf6, 0x7d, 0x22, 0x0b, 0x66, 0x7d, 0xbb, 0x7f, 0x09, 0x79, 0xcd, 0x6d, 0x78, 0xa7, 0xec, - 0x02, 0x0f, 0xd3, 0x9a, 0x6c, 0xa0, 0x35, 0xf0, 0x87, 0x99, 0x84, 0xa2, 0x2d, 0xd4, 0x1c, 0xb1, - 0x3a, 0x96, 0x48, 0x16, 0xe3, 0x0a, 0x4c, 0x9f, 0x99, 0x5f, 0xca, 0x02, 0x60, 0x38, 0xc1, 0xfc, - 0xf3, 0x00, 0x9c, 0x7c, 0xb1, 0x74, 0x94, 0x77, 0xd6, 0xf0, 0xb0, 0xda, 0xe4, 0x3d, 0x84, 0xe4, - 0xd6, 0xd6, 0xa0, 0x9a, 0xc6, 0xa2, 0xeb, 0x53, 0x8b, 0xbb, 0x9d, 0xb6, 0xd5, 0x34, 0xbd, 0xde, - 0xfd, 0xd8, 0x68, 0xf6, 0x92, 0xeb, 0x5a, 0x12, 0x19, 0x78, 0x41, 0x1d, 0x11, 0xbc, 0xa4, 0x87, - 0x55, 0xb3, 0xfe, 0x61, 0x55, 0xc9, 0x3d, 0x96, 0x01, 0x85, 0x8f, 0x41, 0x3c, 0x15, 0x70, 0xb4, - 0xd6, 0x41, 0xf6, 0x82, 0x8b, 0xcc, 0x56, 0xd3, 0xdd, 0xdd, 0xb9, 0xd0, 0xe5, 0x9d, 0x09, 0xe2, - 0x65, 0x94, 0x5b, 0xb2, 0xcd, 0x0a, 0x4b, 0xb6, 0xf0, 0xb9, 0x8a, 0xec, 0xd1, 0x69, 0x6e, 0x63, - 0x81, 0xa3, 0x61, 0x88, 0x21, 0x2d, 0xd1, 0x16, 0x58, 0xcf, 0xea, 0x6c, 0x2e, 0xc9, 0xea, 0xec, - 0x9b, 0xa5, 0x0e, 0x62, 0x4b, 0xb5, 0x6b, 0x2c, 0x3b, 0x99, 0x73, 0x75, 0xe4, 0x45, 0xc0, 0x7b, - 0x23, 0x98, 0xbd, 0x10, 0x7e, 0x09, 0x20, 0x16, 0x13, 0xfb, 0xf8, 0x17, 0xbc, 0x25, 0xe9, 0x8a, - 0x89, 0x48, 0x42, 0x04, 0xba, 0x01, 0x82, 0x59, 0x99, 0x4d, 0xcc, 0x44, 0xcb, 0x1f, 0xb1, 0xf5, - 0xa7, 0x8f, 0xc2, 0x87, 0xb3, 0x60, 0x9a, 0x5c, 0x42, 0xb3, 0x70, 0x85, 0x78, 0xb7, 0x4b, 0x1a, - 0x25, 0x2f, 0xe0, 0xd9, 0xac, 0x82, 0x5c, 0xdb, 0xb2, 0x2f, 0xfa, 0xbb, 0xcf, 0xf8, 0x39, 0xbc, - 0xd2, 0x20, 0xdb, 0xe7, 0x4a, 0x83, 0x60, 0x7f, 0x20, 0xa8, 0xf7, 0x40, 0x77, 0x6c, 0x0d, 0x2c, - 0x2e, 0x7d, 0x36, 0xfe, 0x69, 0x0e, 0x14, 0xea, 0xc8, 0x74, 0x9b, 0xdb, 0xf0, 0x15, 0x5c, 0x9c, - 0x80, 0x25, 0x30, 0xb1, 0x69, 0xb5, 0x3d, 0xe4, 0x52, 0xbf, 0x1b, 0xbe, 0x03, 0xa7, 0x8a, 0xbc, - 0xd0, 0x76, 0x9a, 0x17, 0xe7, 0x99, 0xb1, 0x3d, 0xef, 0x87, 0x5c, 0x9a, 0x5f, 0x22, 0x3f, 0xe9, - 0xfe, 0xcf, 0xd8, 0xec, 0xeb, 0x3a, 0xae, 0x17, 0x15, 0xc3, 0x34, 0xa2, 0x94, 0xba, 0xe3, 0x7a, - 0x3a, 0xfd, 0x11, 0x83, 0xb9, 0xb9, 0xdb, 0x6e, 0x1b, 0xe8, 0xb2, 0xe7, 0x4f, 0xb4, 0xfc, 0x77, - 0x6c, 0x12, 0x3a, 0x9b, 0x9b, 0x5d, 0x44, 0xa7, 0xf9, 0x79, 0x9d, 0xbd, 0xa9, 0xc7, 0x41, 0xbe, - 0x6d, 0xed, 0x58, 0x74, 0x6a, 0x90, 0xd7, 0xe9, 0x8b, 0x7a, 0x0b, 0x28, 0x86, 0xb3, 0x12, 0x4a, - 0xe8, 0xa9, 0x02, 0x51, 0xc0, 0x7d, 0xe9, 0x58, 0x32, 0x2e, 0xa2, 0x2b, 0xdd, 0x53, 0x13, 0xe4, - 0x3b, 0x79, 0x16, 0x9d, 0x1c, 0x65, 0x76, 0x1a, 0x28, 0x5f, 0xa3, 0xe7, 0x9c, 0x2e, 0x6a, 0x3a, - 0x6e, 0xcb, 0xe7, 0x4d, 0xf4, 0x74, 0x81, 0xe5, 0x4b, 0xb6, 0x3f, 0xd0, 0xb7, 0xf2, 0xf4, 0xe5, - 0xe9, 0x65, 0x05, 0xdc, 0x39, 0xe2, 0xaa, 0xcf, 0x5b, 0xde, 0xf6, 0x1a, 0xf2, 0x4c, 0xf8, 0xa7, - 0xca, 0xff, 0x96, 0xab, 0x18, 0xb9, 0xa2, 0x47, 0xe6, 0xbd, 0x5d, 0xd7, 0xc6, 0xdc, 0x62, 0x41, - 0xaa, 0xb8, 0x14, 0xf5, 0x6e, 0x70, 0x4d, 0xf8, 0xe6, 0x2f, 0x53, 0x2e, 0xb2, 0xa9, 0xe6, 0x14, - 0xc9, 0x1e, 0x9d, 0x41, 0x5d, 0x07, 0x37, 0xd0, 0x8f, 0x2b, 0xc6, 0xda, 0xea, 0x8a, 0xb5, 0xb5, - 0xdd, 0xb6, 0xb6, 0xb6, 0xbd, 0x6e, 0xc5, 0xee, 0x7a, 0xc8, 0x6c, 0xd5, 0x36, 0x75, 0x1a, 0x63, - 0x18, 0x90, 0x72, 0x64, 0xb2, 0x8a, 0xde, 0x37, 0x72, 0x23, 0x15, 0x2f, 0x0f, 0x11, 0xfa, 0xf0, - 0x44, 0xac, 0x0f, 0xdd, 0xdd, 0x76, 0x80, 0xe9, 0x75, 0x3d, 0x98, 0x86, 0x02, 0xbd, 0xdb, 0x26, - 0x4a, 0x41, 0x32, 0x27, 0x1d, 0xb3, 0x62, 0x28, 0x49, 0x5f, 0x39, 0xfe, 0xbf, 0x02, 0xc8, 0x2f, - 0xbb, 0x66, 0x67, 0x1b, 0x3e, 0x3b, 0x85, 0xbe, 0x36, 0x90, 0xce, 0xec, 0x20, 0xe9, 0x54, 0x06, - 0x48, 0x67, 0x8e, 0x93, 0xce, 0x68, 0x4f, 0x81, 0xb3, 0x60, 0xa6, 0xe9, 0xb4, 0xdb, 0xa8, 0x89, - 0xf9, 0x51, 0x69, 0x91, 0xb8, 0x2a, 0x53, 0xba, 0x90, 0x46, 0x82, 0xcf, 0x21, 0xaf, 0x4e, 0xd7, - 0xaf, 0xa9, 0xd0, 0x87, 0x09, 0xf0, 0xa5, 0x59, 0x90, 0xd3, 0x5a, 0x5b, 0x48, 0x58, 0xe3, 0xce, - 0x70, 0x6b, 0xdc, 0x27, 0x41, 0xc1, 0x33, 0xdd, 0x2d, 0xe4, 0xf9, 0x73, 0x7e, 0xfa, 0x16, 0xc4, - 0xc4, 0x53, 0xb8, 0x98, 0x78, 0x4f, 0x02, 0x39, 0xcc, 0x33, 0x16, 0x6d, 0xe6, 0x86, 0x7e, 0xf0, - 0x13, 0xde, 0xcf, 0xe3, 0x1a, 0xe7, 0x71, 0xab, 0x75, 0xf2, 0x43, 0x2f, 0xd6, 0xf9, 0x7d, 0x58, - 0x93, 0xeb, 0x52, 0x9a, 0x8e, 0x5d, 0xd9, 0x31, 0xb7, 0x10, 0x6b, 0x66, 0x98, 0xe0, 0x7f, 0xd5, - 0x76, 0x9c, 0x07, 0x2d, 0x16, 0x9e, 0x2e, 0x4c, 0xc0, 0x4d, 0xd8, 0xb6, 0x5a, 0x2d, 0x64, 0x33, - 0xcd, 0x66, 0x6f, 0x67, 0x4f, 0x83, 0x1c, 0xa6, 0x01, 0xcb, 0x0f, 0x1e, 0xf8, 0x8b, 0x47, 0xd4, - 0x19, 0xac, 0x56, 0x54, 0x79, 0x8b, 0x19, 0x71, 0xad, 0x53, 0xc6, 0xf5, 0x85, 0x36, 0xae, 0xbf, - 0x72, 0x3d, 0x16, 0xe4, 0x6d, 0xa7, 0x85, 0x06, 0x0e, 0x35, 0x34, 0x97, 0xfa, 0x04, 0x90, 0x47, - 0x2d, 0xdc, 0x2b, 0x28, 0x24, 0xfb, 0xe9, 0x78, 0x5e, 0xea, 0x34, 0x73, 0x32, 0xff, 0x9a, 0x7e, - 0xd4, 0xa6, 0xaf, 0x80, 0xbf, 0x3e, 0x01, 0x8e, 0xd2, 0x3e, 0xa0, 0xbe, 0x7b, 0x01, 0x17, 0x75, - 0x01, 0xc1, 0x77, 0x2b, 0x42, 0x10, 0xce, 0xee, 0xee, 0x85, 0xc0, 0x6c, 0xa4, 0x2f, 0xbc, 0x82, - 0x66, 0x47, 0x32, 0x68, 0x29, 0xc3, 0x0e, 0x5a, 0xc2, 0x00, 0xa4, 0xf8, 0x2a, 0x1e, 0x0e, 0x57, - 0x05, 0x92, 0xec, 0x0f, 0x57, 0xfd, 0x06, 0x9b, 0x53, 0x60, 0xc2, 0xdc, 0xf4, 0x90, 0x5b, 0x69, - 0x11, 0x79, 0x9c, 0xd2, 0xfd, 0x57, 0x3c, 0x20, 0x5e, 0x40, 0x9b, 0x8e, 0x8b, 0x35, 0x7d, 0x8a, - 0x0e, 0x88, 0xfe, 0x3b, 0xa7, 0x9f, 0x40, 0xd8, 0x83, 0xba, 0x19, 0x1c, 0xb5, 0xb6, 0x6c, 0xc7, - 0x45, 0x81, 0x63, 0xe3, 0xa9, 0x19, 0x7a, 0xd6, 0xbe, 0x27, 0x59, 0xbd, 0x15, 0x1c, 0xb3, 0x9d, - 0x45, 0xd4, 0x61, 0x7c, 0xa7, 0xa8, 0xce, 0x12, 0x8d, 0xd8, 0xff, 0x61, 0x5f, 0xd7, 0x32, 0xb7, - 0xbf, 0x6b, 0x81, 0x9f, 0x4a, 0x3a, 0x1f, 0xee, 0x01, 0x7e, 0x64, 0x76, 0x99, 0xfa, 0x14, 0x30, - 0xd3, 0x62, 0x6e, 0x4f, 0x4d, 0x2b, 0xd0, 0x9a, 0xc8, 0xff, 0x84, 0xcc, 0xa1, 0xc8, 0xe5, 0x78, - 0x91, 0x5b, 0x06, 0x93, 0xe4, 0x90, 0x0b, 0x96, 0xb9, 0x7c, 0x4f, 0x2c, 0x3f, 0x32, 0x65, 0x0b, - 0x1a, 0xc5, 0xb1, 0x6d, 0xbe, 0xcc, 0x7e, 0xd1, 0x83, 0x9f, 0x93, 0xcd, 0xac, 0xe3, 0x39, 0x34, - 0x06, 0xef, 0xd4, 0x1c, 0x38, 0xba, 0xec, 0x3a, 0xbb, 0x9d, 0x6e, 0xa8, 0x9e, 0x7f, 0xd3, 0x7f, - 0x33, 0xa2, 0x20, 0x8e, 0x45, 0xfd, 0x15, 0xf7, 0x0c, 0x98, 0x76, 0x59, 0x8f, 0x1a, 0x6e, 0x4d, - 0xf0, 0x49, 0xbc, 0x6a, 0x2b, 0x07, 0x51, 0xed, 0x50, 0x41, 0x72, 0x82, 0x82, 0xf4, 0x0a, 0x72, - 0xbe, 0x8f, 0x20, 0xff, 0x75, 0x36, 0xa1, 0x20, 0xf7, 0xb0, 0x28, 0x42, 0x90, 0xcb, 0xa0, 0xb0, - 0x45, 0x32, 0x32, 0x39, 0x7e, 0x8c, 0x5c, 0xcb, 0x48, 0xe1, 0x3a, 0xfb, 0x35, 0xe4, 0xab, 0xc2, - 0xf1, 0x35, 0x99, 0x50, 0xc5, 0x53, 0x9b, 0xbe, 0x50, 0xbd, 0x23, 0x07, 0x66, 0x82, 0xda, 0xc9, - 0xb9, 0x91, 0xcc, 0xa0, 0x0e, 0x7f, 0xdf, 0xea, 0x4c, 0xd0, 0x95, 0x2a, 0x5c, 0x57, 0xda, 0xa7, - 0xf3, 0x9b, 0x4e, 0xd0, 0xf9, 0xcd, 0x44, 0x74, 0x7e, 0xf0, 0x67, 0x15, 0xd9, 0x98, 0xcf, 0x62, - 0x1f, 0x40, 0x5a, 0xf7, 0x70, 0xee, 0xd5, 0x24, 0x23, 0x4f, 0x0f, 0x6e, 0x55, 0xfa, 0x42, 0xf3, - 0x81, 0x2c, 0x38, 0x46, 0x7b, 0xc3, 0x0d, 0xbb, 0x1b, 0xf4, 0x45, 0x8f, 0x14, 0xbd, 0x32, 0x70, - 0x9b, 0xba, 0x81, 0x57, 0x06, 0x79, 0x13, 0x17, 0xc1, 0x63, 0x8f, 0x7c, 0x09, 0x7d, 0x2e, 0x57, - 0x4b, 0xc4, 0x8a, 0x92, 0xdc, 0xa1, 0x2e, 0xc9, 0x42, 0xd3, 0x67, 0xe0, 0xaf, 0x28, 0x60, 0xaa, - 0x8e, 0xbc, 0x55, 0xf3, 0x8a, 0xb3, 0xeb, 0x41, 0x53, 0x76, 0xf9, 0xfb, 0xc9, 0xa0, 0xd0, 0x26, - 0xbf, 0xb0, 0x0b, 0xcc, 0xce, 0xf4, 0x5d, 0x3f, 0x26, 0xfb, 0xe4, 0xb4, 0x68, 0x9d, 0xe5, 0x17, - 0xcf, 0xda, 0xc9, 0xec, 0x3e, 0x04, 0xd4, 0x8d, 0x64, 0xe9, 0x34, 0xd1, 0xde, 0x44, 0x54, 0xd5, - 0xe9, 0xc3, 0xf2, 0x5c, 0x05, 0xcc, 0xd6, 0x91, 0x57, 0xe9, 0x2e, 0x99, 0x7b, 0x8e, 0x6b, 0x79, - 0x88, 0xbf, 0x4b, 0x23, 0x1e, 0x9a, 0xd3, 0x00, 0x58, 0xc1, 0x6f, 0x2c, 0x98, 0x3a, 0x97, 0x02, - 0x7f, 0x33, 0xe9, 0x86, 0xbb, 0x40, 0xc7, 0x48, 0x40, 0x48, 0xb4, 0x87, 0x19, 0x57, 0x7d, 0xfa, - 0x40, 0x7c, 0x3e, 0xcb, 0x80, 0x28, 0xb9, 0xcd, 0x6d, 0x6b, 0x0f, 0xb5, 0x12, 0x02, 0xe1, 0xff, - 0x16, 0x02, 0x11, 0x14, 0x94, 0x78, 0x7b, 0x58, 0xa0, 0x63, 0x14, 0xdb, 0xc3, 0x71, 0x05, 0x8e, - 0xe5, 0x10, 0x2f, 0xee, 0x7a, 0xd8, 0x1a, 0xc3, 0xbd, 0xb2, 0x6c, 0x0d, 0x4d, 0xb8, 0x2c, 0x6f, - 0xc2, 0x0d, 0xd5, 0xb1, 0xd0, 0xba, 0x07, 0xc9, 0x74, 0x2e, 0x8d, 0x8e, 0xa5, 0x6f, 0xd5, 0xe9, - 0x33, 0xfd, 0x3d, 0x0a, 0x38, 0x11, 0x18, 0x3c, 0x75, 0xe4, 0x2d, 0x9a, 0xdd, 0xed, 0x0b, 0x8e, - 0xe9, 0xb6, 0xf8, 0x8b, 0xed, 0x86, 0x3e, 0xc9, 0x02, 0x3f, 0xc7, 0x83, 0x50, 0x15, 0x41, 0xe8, - 0xeb, 0x56, 0xd5, 0x97, 0x96, 0x51, 0x74, 0x32, 0xb1, 0x9e, 0x5f, 0xbf, 0x1d, 0x80, 0xf5, 0x74, - 0x01, 0xac, 0x7b, 0x86, 0x25, 0x31, 0x7d, 0xe0, 0x7e, 0x8d, 0x8e, 0x08, 0x9c, 0x07, 0xe0, 0x03, - 0xb2, 0x80, 0x45, 0x78, 0x80, 0x29, 0xd1, 0x87, 0x35, 0x86, 0x19, 0x23, 0x06, 0x7a, 0xef, 0xa5, - 0x3b, 0x46, 0x1c, 0xa2, 0x67, 0xde, 0x3b, 0x14, 0x50, 0x24, 0xc7, 0x9b, 0x39, 0xef, 0x48, 0xf8, - 0xa0, 0x2c, 0x3a, 0xfb, 0x3c, 0x31, 0x27, 0x92, 0x7a, 0x62, 0xc2, 0xb7, 0x27, 0xf5, 0xb7, 0xec, - 0xa5, 0x76, 0x24, 0x88, 0x25, 0x72, 0xa7, 0x1c, 0x40, 0x41, 0xfa, 0xa0, 0xfd, 0x27, 0x05, 0x00, - 0xac, 0xd0, 0xcc, 0xc5, 0xef, 0x19, 0xb2, 0x70, 0xdd, 0xc6, 0xfb, 0xa0, 0x62, 0xa0, 0x4e, 0xf4, - 0x00, 0x45, 0x4b, 0x0c, 0x9d, 0x07, 0xdf, 0x90, 0xd4, 0x77, 0x29, 0xa4, 0x6a, 0x24, 0xb0, 0x24, - 0xf2, 0x66, 0x8a, 0xac, 0x3b, 0x7d, 0x40, 0xfe, 0x6b, 0x16, 0xe4, 0x0d, 0xa7, 0x8e, 0xbc, 0x83, - 0x9b, 0x02, 0x89, 0x8f, 0xa3, 0x92, 0x7a, 0x47, 0x71, 0x1c, 0xb5, 0x5f, 0x41, 0xe9, 0xb3, 0xee, - 0xdd, 0x59, 0x30, 0x63, 0x38, 0xe5, 0x60, 0xb1, 0x4a, 0xde, 0x17, 0x4c, 0xfe, 0xde, 0xaa, 0xa0, - 0x81, 0x61, 0x35, 0x07, 0xba, 0xb7, 0x6a, 0x70, 0x79, 0xe9, 0xf3, 0xed, 0x4e, 0x70, 0x74, 0xc3, - 0x6e, 0x39, 0x3a, 0x6a, 0x39, 0x6c, 0x49, 0x56, 0x55, 0x41, 0x6e, 0xd7, 0x6e, 0x39, 0x84, 0xe4, - 0xbc, 0x4e, 0x9e, 0x71, 0x9a, 0x8b, 0x5a, 0x0e, 0xdb, 0xaf, 0x23, 0xcf, 0xf0, 0x6b, 0x0a, 0xc8, - 0xe1, 0x7f, 0xe5, 0x59, 0xfd, 0x0e, 0x25, 0xe1, 0x01, 0x5b, 0x5c, 0xfc, 0x48, 0x2c, 0xa1, 0x7b, - 0xb9, 0x45, 0x6a, 0xea, 0x21, 0x76, 0x43, 0x54, 0x7d, 0x1c, 0x2b, 0xc2, 0xc5, 0x69, 0xf5, 0x14, - 0x98, 0xb8, 0xd0, 0x76, 0x9a, 0x17, 0xc3, 0x73, 0xa0, 0xec, 0x55, 0xbd, 0x05, 0xe4, 0x5d, 0xd3, - 0xde, 0x42, 0x6c, 0xf1, 0xfb, 0x78, 0x4f, 0x5f, 0x48, 0x76, 0xa2, 0x75, 0x9a, 0x05, 0xbe, 0x3d, - 0xc9, 0xd1, 0xde, 0x3e, 0x8d, 0x4f, 0x26, 0x0f, 0x8b, 0x43, 0x9c, 0xc2, 0x28, 0x82, 0x99, 0x72, - 0x89, 0xde, 0x10, 0xb7, 0x56, 0x3b, 0xa7, 0x15, 0x15, 0x02, 0x33, 0xe6, 0x49, 0x8a, 0x30, 0xe3, - 0xe2, 0xff, 0xcd, 0xc2, 0xdc, 0xa7, 0xf1, 0x87, 0x01, 0xf3, 0x27, 0xb2, 0x60, 0x76, 0xd5, 0xea, - 0x7a, 0x51, 0xde, 0xb4, 0x31, 0xd1, 0x8d, 0x5e, 0x98, 0xd4, 0x54, 0x16, 0xea, 0x91, 0x0e, 0x6b, - 0x94, 0xc8, 0x1c, 0x8e, 0xab, 0x62, 0x3c, 0x6e, 0xdf, 0x84, 0x02, 0x7a, 0xab, 0x93, 0x34, 0x27, - 0x13, 0x1b, 0x4a, 0x61, 0x25, 0xe3, 0x37, 0x94, 0x22, 0xeb, 0x4e, 0x9f, 0xbf, 0x5f, 0xcb, 0x82, - 0x63, 0xb8, 0xfa, 0xb8, 0x65, 0xa9, 0x68, 0x36, 0x0f, 0x5c, 0x96, 0x4a, 0xbc, 0x32, 0xbe, 0x8f, - 0x96, 0x51, 0xac, 0x8c, 0x0f, 0x2a, 0x74, 0xcc, 0x6c, 0x8e, 0x58, 0x86, 0x1d, 0xc4, 0xe6, 0x98, - 0x65, 0xd8, 0xe1, 0xd9, 0x1c, 0xbf, 0x14, 0x3b, 0x24, 0x9b, 0x0f, 0x6d, 0x81, 0xf5, 0xf5, 0x4a, - 0xc0, 0xe6, 0xc8, 0xb5, 0x8d, 0x18, 0x36, 0x27, 0x3e, 0xdd, 0x06, 0xdf, 0x39, 0x24, 0xe3, 0x47, - 0xbc, 0xbe, 0x31, 0x0c, 0x4c, 0x87, 0xb8, 0xc6, 0xf1, 0x32, 0x05, 0xcc, 0x31, 0x2a, 0xfa, 0x4f, - 0x99, 0x63, 0x30, 0x4a, 0x3c, 0x65, 0x4e, 0xec, 0x63, 0x2f, 0x52, 0x36, 0x7e, 0x1f, 0xfb, 0xd8, - 0xfa, 0xd3, 0x07, 0xe7, 0x1b, 0x39, 0x70, 0x12, 0x93, 0xb0, 0xe6, 0xb4, 0xac, 0xcd, 0x2b, 0x94, - 0x8a, 0x73, 0x66, 0x7b, 0x17, 0x75, 0xe1, 0xfb, 0xb2, 0xb2, 0x28, 0xfd, 0x3b, 0x00, 0x9c, 0x0e, - 0x72, 0x69, 0x80, 0x20, 0x06, 0xd4, 0xdd, 0x51, 0x8d, 0xdd, 0x5f, 0x53, 0x10, 0xb4, 0xb7, 0xe6, - 0x17, 0xa2, 0x73, 0xe5, 0x61, 0xab, 0x70, 0x2a, 0xf8, 0xd2, 0xeb, 0xf0, 0x91, 0xd9, 0xef, 0xf0, - 0x71, 0x33, 0x50, 0xcc, 0x56, 0x2b, 0x80, 0xaa, 0x77, 0x33, 0x9b, 0xd4, 0xa9, 0xe3, 0x2c, 0x38, - 0x67, 0x17, 0x85, 0x47, 0x5f, 0x22, 0x72, 0x76, 0x91, 0xa7, 0xce, 0x83, 0x02, 0xbd, 0xe1, 0x2a, - 0x58, 0xd1, 0xef, 0x9f, 0x99, 0xe5, 0x12, 0x4d, 0xbb, 0x9a, 0x28, 0x86, 0x77, 0x26, 0xe2, 0x4c, - 0xbf, 0x7e, 0x3a, 0xb4, 0x93, 0x75, 0x41, 0xc0, 0x9e, 0x3a, 0x74, 0xc9, 0xe3, 0xd9, 0x0d, 0x2b, - 0x75, 0x3a, 0xed, 0x2b, 0x06, 0x0b, 0x46, 0x90, 0x68, 0x37, 0x8c, 0x8b, 0x69, 0x90, 0xed, 0x8d, - 0x69, 0x90, 0x7c, 0x37, 0x4c, 0xa0, 0x63, 0x14, 0xbb, 0x61, 0x71, 0x05, 0x8e, 0x61, 0x3d, 0x32, - 0x4f, 0xad, 0x66, 0x16, 0x7b, 0xf1, 0x4d, 0xd9, 0xbe, 0xee, 0x54, 0x40, 0x74, 0xa7, 0xea, 0x17, - 0x96, 0x31, 0x36, 0xe6, 0xac, 0xfa, 0x04, 0x50, 0xd8, 0x74, 0xdc, 0x1d, 0xd3, 0xdf, 0xb8, 0xef, - 0xf5, 0xde, 0x66, 0xf1, 0x0e, 0x97, 0x48, 0x1e, 0x9d, 0xe5, 0xc5, 0xf3, 0x91, 0x67, 0x5a, 0x1d, - 0x16, 0x4d, 0x0c, 0x3f, 0xaa, 0x37, 0x82, 0x59, 0x16, 0x54, 0xac, 0x8a, 0xba, 0x1e, 0x6a, 0xb1, - 0xd3, 0xdd, 0x62, 0xa2, 0x7a, 0x16, 0xcc, 0xb0, 0x84, 0x25, 0xab, 0x8d, 0xba, 0xec, 0x4a, 0x47, - 0x21, 0x4d, 0x3d, 0x09, 0x0a, 0x56, 0xf7, 0x69, 0x5d, 0xc7, 0x26, 0x3e, 0xb9, 0x93, 0x3a, 0x7b, - 0x23, 0x6e, 0x3b, 0x34, 0x5f, 0x60, 0xac, 0x52, 0x27, 0xfa, 0xde, 0x64, 0xf8, 0x99, 0x61, 0x26, - 0x0e, 0x89, 0xe3, 0x4c, 0x62, 0x14, 0x76, 0x9b, 0x4d, 0x84, 0x5a, 0xec, 0xb4, 0x81, 0xff, 0x9a, - 0x30, 0x02, 0x65, 0xe2, 0x69, 0xc6, 0x21, 0x85, 0xa0, 0xfc, 0xe0, 0x09, 0x50, 0xa0, 0x61, 0xd9, - 0xe1, 0x4b, 0xe6, 0xfa, 0x0a, 0xe3, 0x9c, 0x28, 0x8c, 0x1b, 0x60, 0xc6, 0x76, 0x70, 0x75, 0xeb, - 0xa6, 0x6b, 0xee, 0x74, 0xe3, 0x56, 0x11, 0x69, 0xb9, 0xc1, 0x90, 0x51, 0xe5, 0x7e, 0x5b, 0x39, - 0xa2, 0x0b, 0xc5, 0xa8, 0xff, 0x07, 0x38, 0x7a, 0x81, 0x9d, 0xb0, 0xed, 0xb2, 0x92, 0xb3, 0xd1, - 0x3e, 0x77, 0x3d, 0x25, 0x2f, 0x88, 0x7f, 0xae, 0x1c, 0xd1, 0x7b, 0x0b, 0x53, 0x7f, 0x12, 0xcc, - 0xe1, 0xd7, 0x96, 0x73, 0xc9, 0x27, 0x5c, 0x89, 0x36, 0x34, 0x7a, 0x8a, 0x5f, 0x13, 0x7e, 0x5c, - 0x39, 0xa2, 0xf7, 0x14, 0xa5, 0xd6, 0x00, 0xd8, 0xf6, 0x76, 0xda, 0xac, 0xe0, 0x5c, 0xb4, 0x48, - 0xf6, 0x14, 0xbc, 0x12, 0xfc, 0xb4, 0x72, 0x44, 0xe7, 0x8a, 0x50, 0x57, 0xc1, 0x94, 0x77, 0xd9, - 0x63, 0xe5, 0xe5, 0xa3, 0x37, 0xb7, 0x7b, 0xca, 0x33, 0xfc, 0x7f, 0x56, 0x8e, 0xe8, 0x61, 0x01, - 0x6a, 0x05, 0x4c, 0x76, 0x2e, 0xb0, 0xc2, 0x0a, 0x7d, 0xae, 0xa2, 0xee, 0x5f, 0xd8, 0xfa, 0x85, - 0xa0, 0xac, 0xe0, 0x77, 0x4c, 0x58, 0xb3, 0xbb, 0xc7, 0xca, 0x9a, 0x90, 0x26, 0xac, 0xec, 0xff, - 0x83, 0x09, 0x0b, 0x0a, 0x50, 0x2b, 0x60, 0xaa, 0x6b, 0x9b, 0x9d, 0xee, 0xb6, 0xe3, 0x75, 0x4f, - 0x4d, 0xf6, 0xf8, 0x45, 0x46, 0x97, 0x56, 0x67, 0xff, 0xe8, 0xe1, 0xdf, 0xea, 0x13, 0xc0, 0x89, - 0x5d, 0x72, 0xbd, 0x9d, 0x76, 0xd9, 0xea, 0x7a, 0x96, 0xbd, 0xe5, 0xc7, 0x46, 0xa4, 0xbd, 0x49, - 0xff, 0x8f, 0xea, 0x3c, 0x3b, 0xa5, 0x00, 0x88, 0x6e, 0xc2, 0xde, 0xcd, 0x38, 0x5a, 0x2d, 0x77, - 0x38, 0xe1, 0x29, 0x20, 0x87, 0x3f, 0x11, 0xcf, 0xc2, 0xb9, 0xfe, 0x0b, 0x7d, 0xbd, 0xb2, 0x43, - 0x14, 0x18, 0xff, 0x84, 0xc7, 0x46, 0xdb, 0x59, 0x77, 0x9d, 0x2d, 0x17, 0x75, 0xbb, 0xcc, 0xe1, - 0x90, 0x4b, 0xc1, 0x0a, 0x6e, 0x75, 0xd7, 0xac, 0x2d, 0x6a, 0x3d, 0x31, 0x77, 0x6c, 0x3e, 0x89, - 0xce, 0x36, 0xab, 0xe8, 0x12, 0xb9, 0x32, 0xed, 0xd4, 0x51, 0x7f, 0xb6, 0xe9, 0xa7, 0xc0, 0x9b, - 0xc0, 0x0c, 0xaf, 0x64, 0xf4, 0x6e, 0x17, 0x2b, 0xb4, 0xbd, 0xd8, 0x1b, 0xbc, 0x11, 0xcc, 0x89, - 0x32, 0xcd, 0x0d, 0x31, 0x8a, 0xdf, 0x15, 0xc2, 0x1b, 0xc0, 0xd1, 0x1e, 0xc5, 0xf2, 0xcf, 0xec, - 0x67, 0xc2, 0x33, 0xfb, 0x67, 0x00, 0x08, 0xa5, 0xb8, 0x6f, 0x31, 0xd7, 0x83, 0xa9, 0x40, 0x2e, - 0xfb, 0x66, 0xf8, 0x4a, 0x06, 0x4c, 0xfa, 0xc2, 0xd6, 0x2f, 0x03, 0x1e, 0x5f, 0x6c, 0x6e, 0x03, - 0x81, 0x4d, 0xb3, 0x85, 0x34, 0x3c, 0x8e, 0x84, 0x6e, 0xbc, 0x86, 0xe5, 0xb5, 0xfd, 0xe3, 0x28, - 0xbd, 0xc9, 0xea, 0x3a, 0x00, 0x16, 0xc1, 0xc8, 0x08, 0xcf, 0xa7, 0x3c, 0x2e, 0x81, 0x3e, 0x50, - 0x79, 0xe0, 0xca, 0x38, 0xfb, 0x48, 0x76, 0x78, 0x64, 0x0a, 0xe4, 0xeb, 0xeb, 0xa5, 0xb2, 0x56, - 0x3c, 0xa2, 0xce, 0x01, 0xa0, 0x3d, 0x63, 0x5d, 0xd3, 0x2b, 0x5a, 0xb5, 0xac, 0x15, 0x33, 0xf0, - 0xe5, 0x59, 0x30, 0x15, 0x28, 0x41, 0xdf, 0x46, 0x6a, 0x4c, 0xb4, 0x06, 0x5e, 0x9f, 0xb1, 0x5f, - 0xa9, 0x78, 0x21, 0x7b, 0x32, 0xb8, 0x7a, 0xb7, 0x8b, 0x96, 0x2c, 0xb7, 0xeb, 0xe9, 0xce, 0xa5, - 0x25, 0xc7, 0x0d, 0xa2, 0x81, 0xfa, 0xd7, 0x44, 0x47, 0x7c, 0xc6, 0x16, 0x45, 0x0b, 0x91, 0x23, - 0x0c, 0xc8, 0x65, 0x2b, 0xc3, 0x61, 0x02, 0x2e, 0xd7, 0xa3, 0xf7, 0x32, 0x77, 0x91, 0xee, 0x5c, - 0xea, 0x96, 0xec, 0x56, 0xd9, 0x69, 0xef, 0xee, 0xd8, 0x5d, 0x66, 0x13, 0x44, 0x7d, 0xc6, 0xdc, - 0x21, 0x97, 0xe3, 0xcc, 0x01, 0x50, 0xae, 0xad, 0xae, 0x6a, 0x65, 0xa3, 0x52, 0xab, 0x16, 0x8f, - 0x60, 0x6e, 0x19, 0xa5, 0x85, 0x55, 0xcc, 0x9d, 0x9f, 0x02, 0x93, 0xbe, 0x4e, 0xef, 0xbb, 0x13, - 0xbb, 0x04, 0x26, 0x7d, 0x2d, 0x67, 0x23, 0xc2, 0xa3, 0x7a, 0x8f, 0xa2, 0xed, 0x98, 0xae, 0x47, - 0xfc, 0xa7, 0xfd, 0x42, 0x16, 0xcc, 0x2e, 0xd2, 0x83, 0xdf, 0xce, 0x3e, 0x96, 0x51, 0xa0, 0x82, - 0xb9, 0xd2, 0xea, 0x6a, 0xa3, 0xa6, 0x37, 0xaa, 0x35, 0x63, 0xa5, 0x52, 0x5d, 0xa6, 0x23, 0x64, - 0x65, 0xb9, 0x5a, 0xd3, 0x35, 0x3a, 0x40, 0xd6, 0x8b, 0x19, 0x7a, 0x39, 0xd3, 0xc2, 0x24, 0x28, - 0x74, 0x08, 0x77, 0xe1, 0x17, 0x95, 0x84, 0x27, 0x4d, 0x03, 0x9c, 0x22, 0xae, 0x8f, 0x11, 0x7c, - 0xd0, 0xb3, 0x7d, 0xce, 0x69, 0x9d, 0x05, 0x33, 0xd4, 0x96, 0xeb, 0x92, 0xe5, 0x7b, 0x76, 0x03, - 0xa3, 0x90, 0x06, 0x3f, 0x9c, 0x4d, 0x70, 0xfc, 0xb4, 0x2f, 0x45, 0xc9, 0x8c, 0x8b, 0xbf, 0x18, - 0xe6, 0x32, 0x26, 0x15, 0xcc, 0x55, 0xaa, 0x86, 0xa6, 0x57, 0x4b, 0xab, 0x2c, 0x8b, 0xa2, 0x9e, - 0x02, 0xc7, 0xab, 0x35, 0x16, 0xff, 0xaa, 0x4e, 0xae, 0x7d, 0x5d, 0x5b, 0xaf, 0xe9, 0x46, 0x31, - 0xaf, 0x9e, 0x04, 0x2a, 0x7d, 0x16, 0x6e, 0x4d, 0x2e, 0xa8, 0x8f, 0x06, 0x37, 0xac, 0x56, 0xd6, - 0x2a, 0x46, 0xa3, 0xb6, 0xd4, 0xd0, 0x6b, 0xe7, 0xeb, 0x18, 0x41, 0x5d, 0x5b, 0x2d, 0x61, 0x41, - 0xe2, 0x2e, 0x69, 0x9a, 0x50, 0xaf, 0x02, 0x47, 0xc9, 0x05, 0x6c, 0xe4, 0xe6, 0x65, 0x5a, 0xdf, - 0xa4, 0x7a, 0x1d, 0x38, 0x55, 0xa9, 0xd6, 0x37, 0x96, 0x96, 0x2a, 0xe5, 0x8a, 0x56, 0x35, 0x1a, - 0xeb, 0x9a, 0xbe, 0x56, 0xa9, 0xd7, 0xf1, 0xbf, 0xc5, 0x29, 0xf8, 0x41, 0x05, 0x14, 0x68, 0x9f, - 0x09, 0xdf, 0xab, 0x80, 0xd9, 0x73, 0x66, 0xdb, 0xc2, 0x03, 0x05, 0xb9, 0x1b, 0x0b, 0x5e, 0x2f, - 0xb8, 0xa6, 0x7b, 0xe4, 0x0e, 0x2d, 0xe6, 0x9a, 0x4e, 0x5e, 0xe0, 0xcf, 0xf1, 0xa2, 0x61, 0x88, - 0xa2, 0xf1, 0xd4, 0x18, 0x20, 0x68, 0x8d, 0xf3, 0x42, 0x6d, 0x11, 0x93, 0x9b, 0xd7, 0x04, 0x38, - 0x9f, 0x17, 0x70, 0x2e, 0x1f, 0xac, 0xf8, 0x64, 0xe0, 0xff, 0xfa, 0xa8, 0xc0, 0x2f, 0x82, 0x99, - 0x8d, 0x6a, 0x69, 0xc3, 0x58, 0xa9, 0xe9, 0x95, 0x9f, 0x20, 0x51, 0x74, 0x67, 0xc1, 0xd4, 0x52, - 0x4d, 0x5f, 0xa8, 0x2c, 0x2e, 0x6a, 0xd5, 0x62, 0x5e, 0xbd, 0x1a, 0x5c, 0x55, 0xd7, 0xf4, 0x73, - 0x95, 0xb2, 0xd6, 0xd8, 0xa8, 0x96, 0xce, 0x95, 0x2a, 0xab, 0xa4, 0x8f, 0x28, 0xc4, 0xdc, 0xeb, - 0x35, 0x01, 0x7f, 0x26, 0x07, 0x00, 0x6d, 0x3a, 0xb6, 0xa4, 0xf9, 0xdb, 0x9f, 0xfe, 0x32, 0xe9, - 0xa4, 0x21, 0x2c, 0x26, 0x42, 0x7f, 0x2b, 0x60, 0xd2, 0x65, 0x1f, 0xd8, 0xf2, 0xc9, 0xa0, 0x72, - 0xe8, 0xa3, 0x5f, 0x9a, 0x1e, 0xfc, 0x0e, 0xdf, 0x97, 0x64, 0x8e, 0x10, 0x49, 0x58, 0x32, 0x24, - 0x97, 0x46, 0x03, 0x24, 0x7c, 0x41, 0x06, 0xcc, 0x89, 0x0d, 0xc3, 0x8d, 0x20, 0xc6, 0x94, 0x5c, - 0x23, 0xc4, 0x9f, 0x39, 0x23, 0xeb, 0xec, 0x1d, 0x6c, 0x38, 0x05, 0xbe, 0x66, 0xd2, 0xd3, 0x98, - 0xbe, 0xc5, 0x52, 0xcc, 0x60, 0xe2, 0xb1, 0xd1, 0x41, 0xaf, 0xfe, 0x35, 0x2e, 0x7b, 0x45, 0x05, - 0xbe, 0x3b, 0x07, 0x66, 0x85, 0xeb, 0xa5, 0xe0, 0x77, 0x32, 0x32, 0x57, 0xc6, 0x70, 0x17, 0x57, - 0x65, 0x0e, 0x7a, 0x71, 0xd5, 0xd9, 0x67, 0x65, 0xc0, 0x04, 0x4b, 0x24, 0x0c, 0xae, 0x55, 0xb1, - 0x2d, 0x70, 0x14, 0x4c, 0x2f, 0x6b, 0x46, 0xa3, 0x6e, 0x94, 0x74, 0x43, 0x5b, 0x2c, 0x66, 0xd4, - 0x13, 0xe0, 0xd8, 0xba, 0xa6, 0xd7, 0x6b, 0x98, 0x9f, 0xeb, 0x7a, 0x8d, 0x74, 0x84, 0x94, 0xcd, - 0x18, 0x86, 0x55, 0x6d, 0x71, 0x59, 0x6b, 0x2c, 0x94, 0xea, 0x5a, 0x51, 0xc1, 0xff, 0x56, 0x6b, - 0x86, 0x56, 0x6f, 0x2c, 0x56, 0x4a, 0xfa, 0x03, 0xc5, 0x1c, 0xfe, 0xb7, 0x6e, 0xe8, 0x25, 0x43, - 0x5b, 0xae, 0x94, 0xc9, 0x85, 0xc9, 0x58, 0x03, 0xf2, 0x78, 0x30, 0xd5, 0xd6, 0xd6, 0x8d, 0x07, - 0x8a, 0x85, 0xe4, 0x5e, 0x7d, 0xbd, 0x8d, 0x1b, 0xb3, 0x57, 0x5f, 0x5c, 0xf5, 0x63, 0xb8, 0x59, - 0x4b, 0x01, 0x45, 0x4a, 0x81, 0x76, 0xb9, 0x83, 0x5c, 0x0b, 0xd9, 0x4d, 0x04, 0x2f, 0xca, 0x44, - 0xdc, 0xdb, 0x17, 0xbf, 0x8a, 0x8c, 0x11, 0x9c, 0xe5, 0x49, 0x5f, 0x7a, 0x8c, 0xf6, 0xdc, 0x3e, - 0xa3, 0xfd, 0x93, 0x49, 0xdd, 0xfa, 0x7a, 0xc9, 0x1d, 0x09, 0x64, 0x1f, 0x4f, 0xe2, 0xd6, 0x37, - 0x80, 0x82, 0xb1, 0x04, 0xd2, 0x8c, 0x18, 0xd3, 0x8b, 0x0a, 0x7c, 0xdb, 0x14, 0x28, 0x52, 0x42, - 0x39, 0x5f, 0xa9, 0x5f, 0x61, 0x77, 0x7c, 0x35, 0x12, 0x84, 0x7e, 0xf2, 0x8f, 0xe6, 0x66, 0xc5, - 0xa3, 0xb9, 0xc2, 0xd2, 0x9b, 0xd2, 0xbb, 0xbf, 0x9d, 0x54, 0xfd, 0x38, 0xc7, 0xa8, 0xe8, 0x68, - 0x7b, 0xe9, 0xa9, 0x5f, 0x6c, 0xf5, 0xe3, 0xb9, 0x87, 0x86, 0xdd, 0x34, 0xa5, 0xc9, 0x22, 0x13, - 0x7f, 0xdd, 0x56, 0x52, 0x2f, 0x59, 0xc1, 0x31, 0x2d, 0xe6, 0x0e, 0xaa, 0xf4, 0xbc, 0x64, 0x07, - 0x51, 0x90, 0x3e, 0x0a, 0x3f, 0xcc, 0x82, 0x5c, 0xdd, 0x71, 0xbd, 0x51, 0x61, 0x90, 0x74, 0x67, - 0x8f, 0xe3, 0x40, 0x3d, 0x7a, 0xe6, 0x94, 0xde, 0xce, 0x5e, 0x7c, 0xfd, 0x63, 0x88, 0x9e, 0x75, - 0x14, 0xcc, 0x51, 0x4a, 0x82, 0x50, 0xf0, 0x3f, 0xc8, 0xd2, 0xfe, 0xea, 0x7e, 0x59, 0x44, 0xce, - 0x82, 0x19, 0x6e, 0x67, 0x2d, 0xb8, 0x96, 0x94, 0x4f, 0x83, 0xbf, 0xc1, 0xe3, 0xb2, 0x28, 0xe2, - 0xd2, 0x6f, 0xde, 0x18, 0x44, 0x53, 0x1f, 0x55, 0xcf, 0x94, 0x24, 0x10, 0x57, 0x4c, 0xe5, 0xe9, - 0x23, 0xf2, 0x1c, 0x05, 0x14, 0x98, 0x67, 0xd3, 0x48, 0x11, 0x48, 0xaa, 0x19, 0x01, 0x13, 0xe4, - 0x3c, 0xa0, 0x94, 0x51, 0x6b, 0x46, 0x7c, 0xfd, 0xe9, 0xe3, 0xf0, 0x2f, 0xcc, 0x65, 0xaf, 0xb4, - 0x67, 0x5a, 0x6d, 0xf3, 0x42, 0x3b, 0x41, 0x00, 0xcc, 0x0f, 0x27, 0x3c, 0xa4, 0x14, 0x34, 0x55, - 0xa8, 0x2f, 0x82, 0xe3, 0x3f, 0x0e, 0xa6, 0xdc, 0x60, 0x61, 0xcd, 0x3f, 0xc3, 0xdd, 0xe3, 0x2e, - 0xc9, 0xbe, 0xeb, 0x61, 0xce, 0x44, 0x27, 0x92, 0xa4, 0xe8, 0x19, 0xcb, 0x09, 0x8a, 0xe9, 0x52, - 0xab, 0xb5, 0x84, 0x4c, 0x6f, 0xd7, 0x45, 0xad, 0x44, 0x43, 0x84, 0xc8, 0xa2, 0x29, 0x9e, 0x13, - 0x42, 0xd8, 0xaa, 0x55, 0x11, 0x9d, 0x27, 0x0e, 0xe8, 0x0d, 0x7c, 0x5a, 0x46, 0xd2, 0x25, 0xbd, - 0x35, 0x80, 0xa4, 0x26, 0x40, 0xf2, 0x94, 0xe1, 0x88, 0x48, 0x1f, 0x90, 0x5f, 0x55, 0xc0, 0x1c, - 0xb5, 0x13, 0x46, 0x8d, 0xc9, 0xef, 0x25, 0xf4, 0x84, 0xe0, 0x2e, 0xdb, 0xe0, 0xc9, 0x19, 0x09, - 0x2c, 0x49, 0xfc, 0x26, 0xe4, 0xe8, 0x48, 0x1f, 0x99, 0xcf, 0x14, 0x00, 0xe0, 0xbc, 0xdb, 0x3e, - 0x5c, 0x08, 0x43, 0x48, 0xc1, 0xb7, 0xb3, 0xf9, 0x47, 0x5d, 0x88, 0x4d, 0xca, 0x79, 0xae, 0x05, - 0xdb, 0x2a, 0x62, 0xa2, 0xd4, 0xa8, 0xf2, 0x17, 0x09, 0x6d, 0x5e, 0xe6, 0x5b, 0x36, 0x70, 0x70, - 0x1f, 0xb2, 0x97, 0xfb, 0x48, 0x02, 0xe3, 0x77, 0x10, 0x29, 0xc9, 0x50, 0x5b, 0x1d, 0x62, 0x2e, - 0x79, 0x0a, 0x1c, 0xd7, 0xb5, 0xd2, 0x62, 0xad, 0xba, 0xfa, 0x00, 0x7f, 0x2b, 0x43, 0x51, 0xe1, - 0x27, 0x27, 0xa9, 0xc0, 0xf6, 0xba, 0x84, 0x7d, 0xa0, 0xc8, 0xab, 0xb8, 0xd9, 0x0a, 0x37, 0x9d, - 0x1f, 0xdc, 0xab, 0x49, 0x14, 0x7b, 0x98, 0x28, 0xbc, 0x79, 0x8a, 0x53, 0xa3, 0xe7, 0x2b, 0xa0, - 0x18, 0x5e, 0xe2, 0xcb, 0xae, 0xd8, 0xa9, 0x89, 0xce, 0x6f, 0x1d, 0xba, 0x8b, 0x12, 0x3a, 0xbf, - 0xf9, 0x09, 0xea, 0x4d, 0x60, 0xae, 0xb9, 0x8d, 0x9a, 0x17, 0x2b, 0xb6, 0xbf, 0x3b, 0x4c, 0xb7, - 0x12, 0x7b, 0x52, 0x45, 0x60, 0xee, 0x17, 0x81, 0x11, 0x27, 0xd1, 0xc2, 0x20, 0xcd, 0x13, 0x15, - 0x81, 0xcb, 0x1f, 0x05, 0xb8, 0x54, 0x05, 0x5c, 0xee, 0x1a, 0xaa, 0xd4, 0x64, 0xb0, 0x54, 0x87, - 0x80, 0x05, 0x82, 0x93, 0xb5, 0x75, 0xa3, 0x52, 0xab, 0x36, 0x36, 0xea, 0xda, 0x62, 0x63, 0xc1, - 0x07, 0xa7, 0x5e, 0x54, 0xe0, 0x37, 0xb3, 0x60, 0x82, 0x92, 0xd5, 0xed, 0xb9, 0x74, 0x37, 0xde, - 0xeb, 0x0f, 0xbe, 0x4d, 0xfa, 0x0c, 0x7f, 0xc0, 0x08, 0x56, 0x4f, 0x44, 0x3f, 0xf5, 0x64, 0x30, - 0x41, 0x41, 0xf6, 0x9d, 0x46, 0x4e, 0x47, 0xf4, 0x52, 0xac, 0x18, 0xdd, 0xcf, 0x2e, 0x79, 0x9e, - 0x7f, 0x00, 0x19, 0xe9, 0x8f, 0x2c, 0x6f, 0x54, 0xa8, 0x19, 0x7c, 0xde, 0xf2, 0xb6, 0x89, 0x53, - 0x20, 0x7c, 0xba, 0xcc, 0x12, 0xe5, 0xad, 0x20, 0xbf, 0x87, 0x73, 0x0f, 0x70, 0xb0, 0xa4, 0x99, - 0xe0, 0x1f, 0x4a, 0x47, 0xbe, 0x12, 0xe4, 0x33, 0xa0, 0x29, 0x7a, 0xc3, 0x73, 0x50, 0x4f, 0xa8, - 0x42, 0xe1, 0x50, 0x93, 0x72, 0xb3, 0x92, 0x38, 0x66, 0x9a, 0x14, 0x49, 0xe9, 0x03, 0xf5, 0xff, - 0x1e, 0x05, 0x13, 0x2b, 0x56, 0xd7, 0x73, 0xdc, 0x2b, 0xf0, 0x0d, 0x19, 0x30, 0x71, 0x0e, 0xb9, - 0x5d, 0xcb, 0xb1, 0xf7, 0xed, 0x6a, 0x9f, 0x01, 0xd3, 0x1d, 0x17, 0xed, 0x59, 0xce, 0x6e, 0x37, - 0x5c, 0x41, 0xe1, 0x93, 0x30, 0x4b, 0xcc, 0x5d, 0x6f, 0xdb, 0x71, 0xc3, 0xc0, 0x06, 0xfe, 0xbb, - 0x7a, 0x1a, 0x00, 0xfa, 0x5c, 0x35, 0x77, 0x10, 0xdb, 0xab, 0xe7, 0x52, 0x54, 0x15, 0xe4, 0x3c, - 0x6b, 0x07, 0xb1, 0xb8, 0x84, 0xe4, 0x19, 0x4b, 0x09, 0x89, 0x22, 0xc6, 0xa2, 0xb5, 0x29, 0xba, - 0xff, 0x0a, 0x3f, 0xa7, 0x80, 0xe9, 0x65, 0xe4, 0x31, 0x52, 0xbb, 0xf0, 0x85, 0x19, 0xa9, 0xe0, - 0xdd, 0x78, 0x20, 0x6c, 0x9b, 0x5d, 0xff, 0xbf, 0x60, 0x9d, 0x54, 0x4c, 0x0c, 0x83, 0x24, 0x2a, - 0x7c, 0x1c, 0x54, 0x12, 0x83, 0xcb, 0xab, 0x50, 0x17, 0x3f, 0x96, 0x99, 0xad, 0x8d, 0xef, 0xff, - 0x00, 0xdf, 0x9d, 0x95, 0x3d, 0xbf, 0xca, 0x78, 0x3f, 0xcf, 0xb5, 0x27, 0xb2, 0xcf, 0x98, 0xdc, - 0x63, 0x39, 0xf6, 0x85, 0xb8, 0xe5, 0x4b, 0x62, 0xc5, 0xe8, 0x41, 0x6e, 0xc9, 0x93, 0xaf, 0x83, - 0x29, 0x49, 0x5f, 0x1a, 0xbf, 0xa7, 0x80, 0xe9, 0xfa, 0xb6, 0x73, 0xc9, 0xe7, 0xe3, 0x4f, 0xc9, - 0x01, 0x7b, 0x1d, 0x98, 0xda, 0xeb, 0x01, 0x35, 0x4c, 0x88, 0xbe, 0xc6, 0x16, 0x3e, 0xa4, 0x24, - 0x85, 0x89, 0x23, 0x6e, 0xe4, 0x97, 0xcc, 0xaa, 0x4f, 0x04, 0x13, 0x8c, 0x6a, 0xb6, 0x2e, 0x12, - 0x0f, 0xb0, 0x9f, 0x99, 0x6f, 0x60, 0x4e, 0x6c, 0x60, 0x32, 0xe4, 0xa3, 0x1b, 0x37, 0x86, 0x40, - 0xf2, 0x59, 0x12, 0xf7, 0xc0, 0x07, 0xbe, 0x3c, 0x02, 0xe0, 0xe1, 0xf7, 0x33, 0xb2, 0xab, 0x87, - 0x01, 0x07, 0x02, 0x0a, 0x0e, 0x14, 0x98, 0x7f, 0x60, 0x71, 0xe9, 0xf3, 0xf3, 0xe5, 0x39, 0x30, - 0xb3, 0x68, 0x6d, 0x6e, 0x06, 0x9d, 0xe4, 0x8b, 0x24, 0x3b, 0xc9, 0xe8, 0x9d, 0x67, 0x6c, 0x8c, - 0xee, 0xba, 0x2e, 0xb2, 0xfd, 0x46, 0x31, 0x75, 0xea, 0x49, 0x55, 0x6f, 0x06, 0x47, 0xfd, 0x71, - 0x81, 0xef, 0x28, 0xa7, 0xf4, 0xde, 0x64, 0xf8, 0x5d, 0xe9, 0xad, 0x27, 0x9f, 0xa3, 0x7c, 0x93, - 0x22, 0x14, 0xf0, 0x6e, 0x30, 0xbb, 0x4d, 0x73, 0x93, 0xf9, 0xb9, 0xdf, 0x59, 0x9e, 0xec, 0x09, - 0x80, 0xba, 0x86, 0xba, 0x5d, 0x73, 0x0b, 0xe9, 0x62, 0xe6, 0x1e, 0xf5, 0x55, 0x92, 0xdc, 0x42, - 0x22, 0xb7, 0x8b, 0x25, 0xd1, 0x92, 0xf4, 0xa5, 0xe3, 0xab, 0x8f, 0x04, 0xb9, 0x25, 0xab, 0x8d, - 0xe0, 0xcf, 0x67, 0xc1, 0x94, 0x8e, 0x9a, 0x8e, 0xdd, 0xc4, 0x6f, 0x9c, 0x1f, 0xca, 0xdf, 0x67, - 0x64, 0x6f, 0xdf, 0xc2, 0xe5, 0xcc, 0x07, 0x65, 0x44, 0xe8, 0x8d, 0xdc, 0x2d, 0x5b, 0xb1, 0x45, - 0x8d, 0x21, 0xbe, 0x3a, 0x9e, 0x1f, 0x6c, 0x6e, 0xb6, 0x1d, 0x53, 0x58, 0xa1, 0xea, 0x35, 0x85, - 0x6e, 0x01, 0x45, 0xff, 0x38, 0x81, 0xe3, 0xad, 0x5b, 0xb6, 0x1d, 0x9c, 0x57, 0xdd, 0x97, 0x2e, - 0x6e, 0xae, 0xc6, 0x86, 0xfc, 0x20, 0x6d, 0x67, 0xb5, 0x47, 0x48, 0xf6, 0x4d, 0x60, 0xee, 0xc2, - 0x15, 0x0f, 0x75, 0x59, 0x2e, 0x56, 0x6d, 0x4e, 0xef, 0x49, 0x85, 0xef, 0x91, 0x0a, 0x0d, 0x12, - 0x53, 0x61, 0x32, 0x56, 0xaf, 0x0c, 0x31, 0x4d, 0x3b, 0x0e, 0x8a, 0xd5, 0xda, 0xa2, 0x46, 0xdc, - 0xa2, 0x7c, 0x3f, 0x93, 0x2d, 0xf8, 0x62, 0x05, 0xcc, 0x10, 0x1f, 0x03, 0x1f, 0x85, 0x1b, 0x24, - 0x26, 0x0d, 0xf0, 0x4b, 0xd2, 0x2e, 0x53, 0xa4, 0xc9, 0x7c, 0x05, 0xd1, 0x8c, 0xde, 0xb4, 0xda, - 0xbd, 0x8c, 0xce, 0xeb, 0x3d, 0xa9, 0x7d, 0x00, 0x51, 0xfa, 0x02, 0xf2, 0x3b, 0x52, 0x7e, 0x53, - 0x83, 0xa8, 0x3b, 0x2c, 0x54, 0x7e, 0x57, 0x01, 0xd3, 0x78, 0x92, 0xe2, 0x83, 0x52, 0x13, 0x40, - 0x71, 0xec, 0xf6, 0x95, 0x70, 0xed, 0xc2, 0x7f, 0x4d, 0xa4, 0x24, 0x7f, 0x25, 0x3d, 0xbd, 0x26, - 0x2c, 0xe2, 0x68, 0x19, 0x13, 0x7e, 0xef, 0x97, 0x9a, 0x74, 0x0f, 0x20, 0xee, 0xb0, 0xe0, 0xfb, - 0xad, 0x3c, 0x28, 0x6c, 0x74, 0x08, 0x72, 0x5f, 0xcb, 0xca, 0x04, 0xc3, 0xde, 0xe7, 0x33, 0x8f, - 0xcd, 0xac, 0xb6, 0xd3, 0x34, 0xdb, 0xeb, 0xe1, 0xe1, 0xa3, 0x30, 0x41, 0xbd, 0x8b, 0xb9, 0xd1, - 0xd1, 0x93, 0x5b, 0x37, 0xc5, 0xc6, 0x89, 0x26, 0x3c, 0xe2, 0xce, 0x27, 0xdc, 0x0a, 0x8e, 0xb5, - 0xac, 0xae, 0x79, 0xa1, 0x8d, 0x34, 0xbb, 0xe9, 0x5e, 0xa1, 0xec, 0x60, 0xd3, 0xaa, 0x7d, 0x1f, - 0xd4, 0x7b, 0x40, 0xbe, 0xeb, 0x5d, 0x69, 0xd3, 0x79, 0x22, 0x7f, 0x9c, 0x21, 0xb2, 0xaa, 0x3a, - 0xce, 0xae, 0xd3, 0xbf, 0xf8, 0x2b, 0x36, 0x27, 0x24, 0xaf, 0x0b, 0xbd, 0x03, 0x14, 0x1c, 0xd7, - 0xda, 0xb2, 0xe8, 0xf5, 0x0b, 0x73, 0xfb, 0xc2, 0x9f, 0x51, 0x53, 0xa0, 0x46, 0xb2, 0xe8, 0x2c, - 0x2b, 0x7c, 0x7f, 0x56, 0x36, 0xd6, 0x0a, 0xa1, 0x91, 0x82, 0x33, 0x9e, 0x2b, 0x43, 0x5f, 0x25, - 0x15, 0x05, 0x25, 0x9a, 0xac, 0xf4, 0x07, 0xe1, 0xcf, 0x66, 0xc1, 0xe4, 0xa2, 0x73, 0xc9, 0x26, - 0x02, 0x7b, 0xa7, 0x9c, 0xcd, 0xda, 0xe7, 0x5c, 0x9c, 0x78, 0x53, 0x57, 0xac, 0x13, 0x3c, 0x69, - 0xad, 0x5f, 0x65, 0x04, 0x0c, 0xb1, 0x1a, 0x20, 0x79, 0xb3, 0x52, 0x5c, 0x3d, 0xe9, 0xf3, 0xf5, - 0xcf, 0x14, 0x90, 0x5b, 0x74, 0x9d, 0x0e, 0x7c, 0x6b, 0x26, 0x81, 0x7f, 0x40, 0xcb, 0x75, 0x3a, - 0x06, 0xb9, 0x34, 0x25, 0xf4, 0xfc, 0xe7, 0xd3, 0xd4, 0x3b, 0xc1, 0x64, 0xc7, 0xe9, 0x5a, 0x9e, - 0x3f, 0x1d, 0x98, 0xbb, 0xfd, 0x11, 0x7d, 0xb5, 0x72, 0x9d, 0x65, 0xd2, 0x83, 0xec, 0xb8, 0xf7, - 0x25, 0x2c, 0xc4, 0x7c, 0xc1, 0x6c, 0xf4, 0x2f, 0x8e, 0xe9, 0x49, 0x85, 0x2f, 0xe1, 0x91, 0x7c, - 0x8a, 0x88, 0xe4, 0xa3, 0xfa, 0x70, 0xd8, 0x75, 0x3a, 0x23, 0xd9, 0xd1, 0x7b, 0x45, 0x80, 0xea, - 0x53, 0x05, 0x54, 0x6f, 0x91, 0xaa, 0x33, 0x7d, 0x44, 0xdf, 0x9f, 0x03, 0x80, 0x98, 0x0b, 0x1b, - 0x78, 0x22, 0x23, 0x67, 0x2b, 0x3d, 0x37, 0xc7, 0xf1, 0xb2, 0x24, 0xf2, 0xf2, 0x31, 0x11, 0xd6, - 0x08, 0x29, 0x3e, 0x82, 0xa3, 0x25, 0x90, 0xdf, 0xc5, 0x9f, 0x19, 0x47, 0x25, 0x8b, 0x20, 0xaf, - 0x3a, 0xfd, 0x13, 0xfe, 0x69, 0x06, 0xe4, 0x49, 0x82, 0x7a, 0x1a, 0x00, 0x32, 0x40, 0xd3, 0x33, - 0x24, 0x19, 0x32, 0x14, 0x73, 0x29, 0x44, 0x5a, 0xad, 0x16, 0xfb, 0x4c, 0x4d, 0xdf, 0x30, 0x01, - 0xff, 0x4d, 0x86, 0x6d, 0x52, 0x16, 0x1b, 0xc8, 0xb9, 0x14, 0xfc, 0x37, 0x79, 0x5b, 0x45, 0x9b, - 0x34, 0x76, 0x6e, 0x4e, 0x0f, 0x13, 0x82, 0xbf, 0x57, 0x83, 0xfb, 0x51, 0xfc, 0xbf, 0x49, 0x0a, - 0x9e, 0xd4, 0x12, 0xb1, 0x5c, 0x08, 0xab, 0x28, 0x90, 0x4c, 0xbd, 0xc9, 0xf0, 0x75, 0x81, 0xd8, - 0x2c, 0x0a, 0x62, 0xf3, 0xb8, 0x04, 0xec, 0x4d, 0x5f, 0x78, 0xbe, 0x92, 0x07, 0x53, 0x55, 0xa7, - 0xc5, 0x64, 0x87, 0x9b, 0xf8, 0x7d, 0x3c, 0x9f, 0x68, 0xe2, 0x17, 0x94, 0x11, 0x21, 0x20, 0xf7, - 0x89, 0x02, 0x22, 0x57, 0x02, 0x2f, 0x1f, 0xea, 0x02, 0x28, 0x10, 0xe9, 0xdd, 0x7f, 0xef, 0x4d, - 0x5c, 0x11, 0x84, 0xb5, 0x3a, 0xfb, 0xf3, 0x5f, 0x9d, 0x8c, 0xfd, 0x47, 0x90, 0x27, 0x0d, 0x8c, - 0xd9, 0x4a, 0x11, 0x1b, 0x9a, 0x8d, 0x6f, 0xa8, 0x12, 0xdf, 0xd0, 0x5c, 0x6f, 0x43, 0x93, 0xcc, - 0xe7, 0xa3, 0x24, 0x24, 0x7d, 0x19, 0xff, 0x1f, 0x13, 0x00, 0x54, 0xcd, 0x3d, 0x6b, 0x8b, 0x6e, - 0xc5, 0x7e, 0xce, 0x9f, 0xc7, 0xb0, 0x4d, 0xd3, 0xff, 0xc4, 0x0d, 0x84, 0x77, 0x82, 0x09, 0x36, - 0xee, 0xb1, 0x86, 0x5c, 0x2f, 0x34, 0x24, 0x2c, 0x85, 0x9a, 0x97, 0x97, 0x3d, 0xdd, 0xcf, 0x2f, - 0xdc, 0x04, 0x98, 0xed, 0xb9, 0x09, 0xb0, 0xff, 0x5e, 0x42, 0xc4, 0xfd, 0x80, 0xf0, 0x3d, 0xd2, - 0xfb, 0x59, 0x1c, 0x3d, 0x5c, 0x8b, 0x22, 0x54, 0xf0, 0x0e, 0x30, 0xe1, 0x04, 0xbb, 0xc7, 0x4a, - 0xe4, 0x7a, 0x56, 0xc5, 0xde, 0x74, 0x74, 0x3f, 0xa7, 0xe4, 0x26, 0x96, 0x14, 0x1d, 0x63, 0x39, - 0x13, 0x71, 0x72, 0xd9, 0x8f, 0x43, 0x84, 0xdb, 0x71, 0xde, 0xf2, 0xb6, 0x57, 0x2d, 0xfb, 0x62, - 0x17, 0xfe, 0x7b, 0x39, 0x0b, 0x92, 0xc3, 0x3f, 0x9b, 0x0c, 0x7f, 0x31, 0xcc, 0x43, 0x5d, 0x44, - 0xed, 0x9e, 0xa8, 0x52, 0xfa, 0x53, 0x1b, 0x01, 0xe0, 0x5d, 0xa0, 0x40, 0x09, 0x65, 0x9d, 0xe8, - 0xd9, 0x48, 0xfc, 0x82, 0x92, 0x74, 0xf6, 0x07, 0x7c, 0x77, 0x80, 0xe3, 0x39, 0x01, 0xc7, 0x85, - 0x03, 0x51, 0x96, 0x3a, 0xa4, 0x67, 0x1f, 0x0f, 0x26, 0x18, 0xa7, 0xd5, 0x39, 0x5e, 0x8b, 0x8b, - 0x47, 0x54, 0x00, 0x0a, 0x6b, 0xce, 0x1e, 0x32, 0x9c, 0x62, 0x06, 0x3f, 0x63, 0xfa, 0x0c, 0xa7, - 0x98, 0x85, 0xaf, 0x9c, 0x04, 0x93, 0x41, 0x00, 0x98, 0xcf, 0x66, 0x41, 0xb1, 0xec, 0x22, 0xd3, - 0x43, 0x4b, 0xae, 0xb3, 0x43, 0x5b, 0x24, 0xef, 0x8a, 0xf9, 0xab, 0xd2, 0xfe, 0x14, 0x41, 0x60, - 0x96, 0xde, 0xca, 0x24, 0x2f, 0x25, 0x7f, 0x8b, 0x94, 0x7f, 0x85, 0x6c, 0x2d, 0xe9, 0xab, 0xda, - 0x27, 0xb3, 0x20, 0x5f, 0x6e, 0x3b, 0x36, 0x4a, 0x74, 0x27, 0x79, 0xff, 0x1d, 0x05, 0xf8, 0xb3, - 0x59, 0x59, 0x5b, 0x23, 0x64, 0x00, 0xae, 0x5b, 0x92, 0xb7, 0x72, 0x83, 0x54, 0x6c, 0xd1, 0xe9, - 0x33, 0xf4, 0x9b, 0x59, 0x30, 0x45, 0x43, 0xa9, 0x94, 0xda, 0x6d, 0xf8, 0x88, 0x90, 0xa9, 0x7d, - 0x82, 0xe8, 0xc0, 0xdf, 0x91, 0xf6, 0x87, 0x0f, 0x5a, 0x15, 0x94, 0x9d, 0x20, 0xa6, 0x4c, 0x32, - 0xf7, 0x6c, 0xb9, 0x3d, 0xb1, 0x81, 0x04, 0xa5, 0xcf, 0xea, 0xbf, 0xcc, 0x62, 0x03, 0xc0, 0xbe, - 0xb8, 0xee, 0xa2, 0x3d, 0x0b, 0x5d, 0x82, 0xd7, 0x86, 0xcc, 0xde, 0x1f, 0x27, 0xe2, 0x4d, 0xd2, - 0x8b, 0x38, 0x5c, 0x91, 0x91, 0x5b, 0x52, 0xd3, 0xed, 0x30, 0x13, 0xeb, 0xc5, 0x7b, 0x83, 0x77, - 0x70, 0xc5, 0xe8, 0x7c, 0x76, 0xc9, 0x35, 0x9b, 0x68, 0x2a, 0xd2, 0x67, 0xec, 0x43, 0x13, 0x60, - 0x72, 0xc3, 0xee, 0x76, 0xda, 0x66, 0x77, 0x1b, 0xfe, 0x40, 0x09, 0xae, 0x04, 0xff, 0x71, 0xe1, - 0x38, 0xfa, 0x4f, 0xef, 0x22, 0xd7, 0x77, 0xaf, 0xa2, 0x2f, 0xfd, 0xef, 0x9c, 0x85, 0xef, 0x57, - 0x64, 0x27, 0xa9, 0x7e, 0xa5, 0xf1, 0x77, 0x65, 0x57, 0xc0, 0x64, 0xc7, 0x6a, 0x7a, 0xbb, 0x6e, - 0x70, 0x83, 0xe9, 0x63, 0xe5, 0x4a, 0x59, 0xa7, 0x7f, 0xe9, 0xc1, 0xef, 0xd0, 0x04, 0x13, 0x2c, - 0x71, 0xdf, 0xb6, 0xd0, 0xfe, 0xe3, 0x95, 0x27, 0x41, 0xc1, 0x74, 0x3d, 0xab, 0xeb, 0xdf, 0x10, - 0xcd, 0xde, 0x70, 0x77, 0x49, 0x9f, 0x36, 0xdc, 0xb6, 0x1f, 0xb8, 0x22, 0x48, 0x80, 0xbf, 0x2b, - 0x35, 0x7f, 0x8c, 0x6f, 0x79, 0x32, 0xc8, 0xef, 0x1f, 0x62, 0xad, 0xf9, 0x6a, 0x70, 0x95, 0x5e, - 0x32, 0xb4, 0x06, 0x8d, 0x73, 0x10, 0x84, 0x34, 0x68, 0xc1, 0x1f, 0xf0, 0xeb, 0x77, 0xe2, 0x18, - 0xc1, 0xb8, 0x18, 0x8e, 0x11, 0x41, 0x42, 0xcc, 0x18, 0xf1, 0x5b, 0xd2, 0xbb, 0x3b, 0x01, 0x4b, - 0x06, 0xac, 0xe5, 0xc5, 0x5d, 0x14, 0xf3, 0x01, 0xa9, 0x9d, 0x9a, 0x41, 0x35, 0x1d, 0x22, 0xfb, - 0x7f, 0x63, 0x02, 0x4c, 0x2c, 0x9b, 0xed, 0x36, 0x72, 0xaf, 0xe0, 0xa1, 0xa5, 0xe8, 0x53, 0xb8, - 0x66, 0xda, 0xd6, 0x26, 0x9e, 0xdf, 0xc7, 0x76, 0x7a, 0xef, 0x91, 0x0e, 0x42, 0xca, 0xea, 0x98, - 0xef, 0x2d, 0x3f, 0x82, 0xe7, 0xb7, 0x81, 0x9c, 0x65, 0x6f, 0x3a, 0xac, 0xeb, 0xeb, 0x5d, 0x45, - 0xf7, 0x7f, 0x26, 0x53, 0x10, 0x92, 0x51, 0x32, 0x0e, 0xa9, 0x24, 0x15, 0xe9, 0xf7, 0x80, 0xbf, - 0x9d, 0x03, 0xb3, 0x3e, 0x11, 0x15, 0xbb, 0x85, 0x2e, 0xf3, 0x4b, 0x2a, 0x2f, 0xce, 0xc9, 0x9e, - 0xa1, 0xea, 0x6d, 0x0f, 0x29, 0x2a, 0x82, 0xa5, 0x06, 0x00, 0x4d, 0xd3, 0x43, 0x5b, 0x8e, 0x6b, - 0x05, 0xfd, 0xda, 0x13, 0x92, 0x94, 0x56, 0xa6, 0x7f, 0x5f, 0xd1, 0xb9, 0x72, 0xd4, 0x7b, 0xc0, - 0x34, 0x0a, 0x8e, 0x49, 0xfb, 0x4b, 0x2e, 0xb1, 0x78, 0xf1, 0xf9, 0xe1, 0x5f, 0x4a, 0x1d, 0xd5, - 0x92, 0x69, 0x66, 0x32, 0xcc, 0x1a, 0xc3, 0xe9, 0xd0, 0x46, 0x75, 0xad, 0xa4, 0xd7, 0x57, 0x4a, - 0xab, 0xab, 0x95, 0xea, 0x72, 0x10, 0xf3, 0x43, 0x05, 0x73, 0x8b, 0xb5, 0xf3, 0x55, 0x2e, 0x28, - 0x4b, 0x0e, 0xae, 0x83, 0x49, 0x9f, 0x5f, 0xfd, 0x7c, 0x23, 0x79, 0x9e, 0x31, 0xdf, 0x48, 0x2e, - 0x09, 0x1b, 0x59, 0x56, 0x33, 0x70, 0x98, 0x21, 0xcf, 0xf0, 0x8f, 0x4d, 0x90, 0x27, 0x6b, 0xe3, - 0xf0, 0x1d, 0xe4, 0x0a, 0xe9, 0x4e, 0xdb, 0x6c, 0x22, 0xb8, 0x93, 0xc0, 0xaa, 0xf6, 0xa3, 0xe2, - 0x67, 0xf7, 0x45, 0xc5, 0x27, 0x8f, 0xcc, 0x7a, 0x3b, 0xde, 0x6f, 0x3d, 0x5e, 0xa7, 0x59, 0xc4, - 0x53, 0x4d, 0xb1, 0xbb, 0x24, 0x74, 0x19, 0x9f, 0x91, 0x19, 0x21, 0x92, 0xd1, 0x34, 0x25, 0xb3, - 0x28, 0xe5, 0xf6, 0x53, 0xe2, 0x28, 0x4a, 0x5f, 0xe3, 0xbf, 0x98, 0x03, 0xf9, 0x7a, 0xa7, 0x6d, - 0x79, 0xf0, 0x65, 0xd9, 0x91, 0x60, 0x46, 0x6f, 0x32, 0x50, 0x06, 0xde, 0x64, 0x10, 0xee, 0x82, - 0xe6, 0x24, 0x76, 0x41, 0x0d, 0x74, 0xd9, 0x13, 0x77, 0x41, 0xef, 0x64, 0x71, 0xbb, 0xe8, 0x1e, - 0xea, 0xa3, 0xfa, 0xb0, 0x94, 0x34, 0xab, 0x4f, 0x40, 0xb8, 0xb3, 0x8f, 0x67, 0x71, 0xa9, 0x00, - 0x28, 0x2c, 0xd4, 0x0c, 0xa3, 0xb6, 0x56, 0x3c, 0x42, 0x02, 0x9a, 0xd4, 0xd6, 0x8b, 0x19, 0x75, - 0x0a, 0xe4, 0x2b, 0xd5, 0xaa, 0xa6, 0x17, 0xb3, 0x24, 0x52, 0x56, 0xc5, 0x58, 0xd5, 0x8a, 0x8a, - 0x18, 0xd6, 0x3a, 0xd6, 0x8c, 0x16, 0xeb, 0x4e, 0x53, 0xbc, 0xe4, 0x0c, 0xea, 0x68, 0x7a, 0xd2, - 0x17, 0xae, 0xff, 0xac, 0x80, 0xfc, 0x1a, 0x72, 0xb7, 0x10, 0xfc, 0xe9, 0x04, 0x9b, 0x75, 0x9b, - 0x96, 0xdb, 0xa5, 0x71, 0xc5, 0xc2, 0xcd, 0x3a, 0x3e, 0x4d, 0xbd, 0x11, 0xcc, 0x76, 0x51, 0xd3, - 0xb1, 0x5b, 0x7e, 0x26, 0xda, 0x1f, 0x89, 0x89, 0xf0, 0xa5, 0x09, 0x21, 0x23, 0x84, 0x8e, 0x64, - 0xc7, 0x2d, 0x09, 0x30, 0xfd, 0x6a, 0x4d, 0x1f, 0x98, 0xef, 0x2a, 0xf8, 0xa7, 0xce, 0x15, 0xf8, - 0x52, 0xe9, 0x5d, 0xd4, 0x5b, 0x41, 0x81, 0x88, 0xa9, 0x3f, 0x46, 0xf7, 0xef, 0x8f, 0x59, 0x1e, - 0x75, 0x01, 0x1c, 0xeb, 0xa2, 0x36, 0x6a, 0x7a, 0xa8, 0x85, 0x55, 0x57, 0x1f, 0xd8, 0x29, 0xec, - 0xcf, 0x0e, 0xff, 0x9c, 0x07, 0xf0, 0x6e, 0x11, 0xc0, 0x9b, 0xfa, 0xb0, 0x12, 0x37, 0x28, 0xda, - 0x56, 0xc6, 0xcd, 0xa8, 0xb7, 0x9d, 0x60, 0x71, 0xdb, 0x7f, 0xc7, 0xdf, 0xb6, 0xbd, 0x9d, 0x36, - 0xf9, 0xc6, 0x1c, 0xfe, 0xfd, 0x77, 0x75, 0x1e, 0x4c, 0x98, 0xf6, 0x15, 0xf2, 0x29, 0x17, 0xd3, - 0x6a, 0x3f, 0x13, 0x7c, 0x65, 0x80, 0xfc, 0xbd, 0x02, 0xf2, 0x8f, 0x91, 0x23, 0x37, 0x7d, 0xe0, - 0x7f, 0x6e, 0x02, 0xe4, 0xd7, 0xcd, 0xae, 0x87, 0xe0, 0xff, 0xa3, 0xc8, 0x22, 0x7f, 0x13, 0x98, - 0xdb, 0x74, 0x9a, 0xbb, 0x5d, 0xd4, 0x12, 0x95, 0xb2, 0x27, 0x75, 0x14, 0x98, 0xab, 0xb7, 0x80, - 0xa2, 0x9f, 0xc8, 0x8a, 0xf5, 0xb7, 0xd3, 0xf7, 0xa5, 0x93, 0x20, 0xc9, 0xdd, 0x75, 0xd3, 0xf5, - 0x6a, 0x9b, 0x24, 0x2d, 0x08, 0x92, 0xcc, 0x27, 0x0a, 0xd0, 0x17, 0x62, 0xa0, 0x9f, 0x88, 0x86, - 0x7e, 0x52, 0x02, 0x7a, 0xb5, 0x04, 0x26, 0x37, 0xad, 0x36, 0x22, 0x3f, 0x4c, 0x91, 0x1f, 0xfa, - 0x8d, 0x49, 0x84, 0xf7, 0xc1, 0x98, 0xb4, 0x64, 0xb5, 0x91, 0x1e, 0xfc, 0xe6, 0x4f, 0x64, 0x40, - 0x38, 0x91, 0x59, 0xa5, 0xfe, 0xad, 0xd8, 0xf0, 0xb2, 0xcd, 0x1d, 0xe4, 0x2f, 0xa2, 0xd9, 0xec, - 0xb0, 0x49, 0xcb, 0xf4, 0x4c, 0x02, 0xc6, 0x8c, 0x4e, 0x9e, 0x45, 0xff, 0x0e, 0xa5, 0xd7, 0xbf, - 0xe3, 0x79, 0x4a, 0xb2, 0x1e, 0xd1, 0x27, 0x36, 0x42, 0xa3, 0x2e, 0xf8, 0x00, 0x51, 0x4b, 0x31, - 0x78, 0xc7, 0xc0, 0x34, 0x4d, 0x17, 0x79, 0xeb, 0xbc, 0x47, 0x45, 0x5e, 0x17, 0x13, 0x89, 0x6b, - 0x5d, 0xb7, 0x6e, 0xee, 0x20, 0x52, 0x59, 0x19, 0x7f, 0x63, 0x2e, 0x53, 0xfb, 0xd2, 0xc3, 0xfe, - 0x37, 0x3f, 0xea, 0xfe, 0xb7, 0x5f, 0x1b, 0xd3, 0x57, 0xc3, 0xd7, 0xe4, 0x80, 0x52, 0xde, 0xf5, - 0x1e, 0xd6, 0xdd, 0xef, 0x0f, 0xa5, 0xfd, 0x55, 0x58, 0x7f, 0x16, 0x79, 0x87, 0xf8, 0x98, 0x7a, - 0xdf, 0x84, 0x52, 0x22, 0xe7, 0x17, 0x13, 0xd5, 0xb6, 0xf4, 0x65, 0xe4, 0xad, 0x4a, 0xe0, 0xf0, - 0xf8, 0x9c, 0xcc, 0xc1, 0x4d, 0x73, 0x48, 0xfb, 0x27, 0xae, 0x67, 0x08, 0xde, 0xfd, 0x8e, 0x27, - 0x27, 0x84, 0x54, 0x23, 0xdb, 0xe4, 0x84, 0x95, 0x33, 0x3a, 0x7d, 0x81, 0x2f, 0x97, 0x76, 0x03, - 0xa7, 0x6c, 0x8b, 0x75, 0x09, 0x4c, 0x66, 0x53, 0xc9, 0xdd, 0x13, 0x19, 0x53, 0x6d, 0xfa, 0x80, - 0x7d, 0x3b, 0x7a, 0xc9, 0x70, 0x18, 0xc4, 0xe0, 0xab, 0xa4, 0xb7, 0x95, 0x68, 0xb3, 0x07, 0xac, - 0x17, 0x26, 0xe3, 0xb7, 0xdc, 0xa6, 0x53, 0x6c, 0xc5, 0xe9, 0x73, 0xfc, 0x5b, 0x0a, 0x28, 0xd0, - 0xad, 0x44, 0xf8, 0xe6, 0x4c, 0x82, 0x0b, 0xb6, 0x3d, 0xd1, 0x15, 0x30, 0x78, 0x4f, 0xb2, 0xe6, - 0x20, 0xb8, 0x0c, 0xe6, 0x12, 0xb9, 0x0c, 0x8a, 0xe7, 0x2a, 0x25, 0xf4, 0x88, 0xb6, 0x31, 0xe5, - 0xe9, 0x64, 0x12, 0x0d, 0xeb, 0x4b, 0x50, 0xfa, 0x78, 0x3f, 0x3f, 0x0f, 0x66, 0x68, 0xd5, 0xe7, - 0xad, 0xd6, 0x16, 0xf2, 0xe0, 0xbb, 0xb2, 0x3f, 0x3a, 0xa8, 0xab, 0x55, 0x30, 0x73, 0x89, 0x90, - 0xbd, 0x6a, 0x5e, 0x71, 0x76, 0x3d, 0xb6, 0x72, 0x71, 0x4b, 0xec, 0xba, 0x07, 0x6d, 0xe7, 0x3c, - 0xfd, 0x43, 0x17, 0xfe, 0xc7, 0x3c, 0xa6, 0x0b, 0xfe, 0xd4, 0x11, 0xab, 0x40, 0x8c, 0x2c, 0x3e, - 0x49, 0x3d, 0x09, 0x0a, 0x7b, 0x16, 0xba, 0x54, 0x69, 0x31, 0xeb, 0x96, 0xbd, 0x89, 0x27, 0xce, - 0x63, 0xf7, 0x5f, 0x79, 0xb8, 0x19, 0x2d, 0xe9, 0x4a, 0xa1, 0xdc, 0x2e, 0xec, 0x40, 0xb2, 0xc6, - 0x70, 0xc6, 0x57, 0xbc, 0x87, 0x31, 0xc9, 0xfd, 0xfe, 0x51, 0x86, 0xb3, 0x18, 0xff, 0x22, 0xf6, - 0x04, 0x09, 0x65, 0xc0, 0x88, 0xaf, 0x68, 0x94, 0x0b, 0xca, 0x30, 0xa0, 0xea, 0xf4, 0x39, 0xff, - 0x3a, 0x05, 0x4c, 0xd5, 0x91, 0xb7, 0x64, 0xa1, 0x76, 0xab, 0x0b, 0xdd, 0x83, 0x9b, 0x46, 0xb7, - 0x81, 0xc2, 0x26, 0x29, 0x6c, 0xd0, 0xf9, 0x03, 0x96, 0x0d, 0xbe, 0x26, 0x2b, 0xbb, 0xb3, 0xcb, - 0x56, 0xdf, 0x7c, 0x6a, 0x47, 0x02, 0x93, 0x9c, 0x67, 0x6e, 0x7c, 0xcd, 0xe9, 0xa3, 0xf4, 0x36, - 0x05, 0xcc, 0xb0, 0x8b, 0xdb, 0x4a, 0x6d, 0x6b, 0xcb, 0x86, 0xbb, 0x23, 0xd0, 0x10, 0xf5, 0x71, - 0x20, 0x6f, 0xe2, 0xd2, 0x98, 0x93, 0x3e, 0xec, 0xdb, 0x79, 0x92, 0xfa, 0x74, 0x9a, 0x31, 0x41, - 0xec, 0xc5, 0x50, 0xb0, 0x7d, 0x9a, 0xc7, 0x18, 0x7b, 0x71, 0x60, 0xe5, 0xe9, 0x23, 0xf6, 0x65, - 0x05, 0x1c, 0x67, 0x04, 0x9c, 0x43, 0xae, 0x67, 0x35, 0xcd, 0x36, 0x45, 0xee, 0x05, 0x99, 0x51, - 0x40, 0xb7, 0x02, 0x66, 0xf7, 0xf8, 0x62, 0x19, 0x84, 0x67, 0xfb, 0x42, 0x28, 0x10, 0xa0, 0x8b, - 0x3f, 0x26, 0x88, 0x61, 0x27, 0x70, 0x55, 0x28, 0x73, 0x8c, 0x31, 0xec, 0xa4, 0x89, 0x48, 0x1f, - 0xe2, 0x97, 0xe4, 0x68, 0x3c, 0x9b, 0xb0, 0xfb, 0xfc, 0x9c, 0x34, 0xb6, 0x1b, 0x60, 0x9a, 0x60, - 0x49, 0x7f, 0x64, 0xcb, 0x10, 0x31, 0x42, 0x1c, 0xf4, 0x3b, 0xec, 0xae, 0xa8, 0xe0, 0x5f, 0x9d, - 0x2f, 0x07, 0x9e, 0x07, 0x20, 0xfc, 0xc4, 0x77, 0xd2, 0x99, 0xa8, 0x4e, 0x3a, 0x2b, 0xd7, 0x49, - 0xbf, 0x49, 0x3a, 0x78, 0x49, 0x7f, 0xb2, 0x0f, 0x2e, 0x1e, 0x72, 0x61, 0x2b, 0x06, 0xd7, 0x9e, - 0xbe, 0x5c, 0xbc, 0x32, 0xd7, 0x7b, 0x43, 0xf7, 0x87, 0x47, 0x32, 0x9f, 0xe2, 0xfb, 0x03, 0xa5, - 0xa7, 0x3f, 0x38, 0x80, 0x25, 0x7d, 0x33, 0x38, 0x4a, 0xab, 0x28, 0x07, 0x64, 0xe5, 0x69, 0x68, - 0x86, 0x9e, 0x64, 0xf8, 0x91, 0x21, 0x84, 0x60, 0xd0, 0xf5, 0xe1, 0x71, 0x9d, 0x5c, 0x32, 0x63, - 0x37, 0xa9, 0x80, 0x1c, 0xde, 0xad, 0xe3, 0xdf, 0xcc, 0x51, 0x6b, 0x77, 0x83, 0x5c, 0xe7, 0x05, - 0xbf, 0x90, 0x1b, 0xc5, 0x88, 0x70, 0x1f, 0xc8, 0x11, 0x57, 0x75, 0x25, 0x72, 0x49, 0x23, 0xac, - 0x32, 0xbc, 0x6b, 0x0d, 0x5d, 0xf6, 0x56, 0x8e, 0xe8, 0xe4, 0x4f, 0xf5, 0x16, 0x70, 0xf4, 0x82, - 0xd9, 0xbc, 0xb8, 0xe5, 0x3a, 0xbb, 0xe4, 0xe2, 0x23, 0x87, 0xdd, 0xa0, 0x44, 0x6e, 0xa2, 0x13, - 0x3f, 0xa8, 0xb7, 0xfb, 0xa6, 0x43, 0x7e, 0x90, 0xe9, 0xb0, 0x72, 0x84, 0x19, 0x0f, 0xea, 0xe3, - 0x83, 0x4e, 0xa7, 0x10, 0xdb, 0xe9, 0xac, 0x1c, 0xf1, 0xbb, 0x1d, 0x75, 0x11, 0x4c, 0xb6, 0xac, - 0x3d, 0xb2, 0x55, 0x4d, 0x66, 0x5d, 0x83, 0x8e, 0x12, 0x2f, 0x5a, 0x7b, 0x74, 0x63, 0x7b, 0xe5, - 0x88, 0x1e, 0xfc, 0xa9, 0x2e, 0x83, 0x29, 0xb2, 0x2d, 0x40, 0x8a, 0x99, 0x4c, 0x74, 0x4c, 0x78, - 0xe5, 0x88, 0x1e, 0xfe, 0x8b, 0xad, 0x8f, 0x1c, 0x39, 0xc3, 0x71, 0xaf, 0xbf, 0xdd, 0x9e, 0x49, - 0xb4, 0xdd, 0x8e, 0x79, 0x41, 0x37, 0xdc, 0x4f, 0x82, 0x7c, 0x93, 0x70, 0x38, 0xcb, 0x38, 0x4c, - 0x5f, 0xd5, 0xbb, 0x41, 0x6e, 0xc7, 0x74, 0xfd, 0xc9, 0xf3, 0x4d, 0x83, 0xcb, 0x5d, 0x33, 0xdd, - 0x8b, 0x18, 0x41, 0xfc, 0xd7, 0xc2, 0x04, 0xc8, 0x13, 0xc6, 0x05, 0x0f, 0xf0, 0xad, 0x39, 0x6a, - 0x86, 0x94, 0x1d, 0x1b, 0x0f, 0xfb, 0x86, 0xe3, 0x1f, 0x74, 0xf9, 0xc3, 0xcc, 0x68, 0x2c, 0xc8, - 0xbe, 0x57, 0x5a, 0x2b, 0x91, 0x57, 0x5a, 0xf7, 0xdc, 0xad, 0x9a, 0xeb, 0xbd, 0x5b, 0x35, 0x5c, - 0x3e, 0xc8, 0x0f, 0x76, 0x54, 0xf9, 0xf3, 0x21, 0x4c, 0x97, 0x5e, 0x46, 0x44, 0xcf, 0xc0, 0xdb, - 0x96, 0xcd, 0xb5, 0xd9, 0x7f, 0x4d, 0xd8, 0x29, 0x25, 0x35, 0x6a, 0x06, 0x90, 0x97, 0x7e, 0xdf, - 0xf4, 0x9b, 0x39, 0x70, 0x8a, 0xde, 0xe0, 0xbb, 0x87, 0x0c, 0x47, 0xbc, 0x6a, 0x10, 0xfe, 0xc9, - 0x48, 0x84, 0xa6, 0xcf, 0x80, 0xa3, 0xf4, 0x1d, 0x70, 0xf6, 0x1d, 0x36, 0xce, 0x0d, 0x38, 0x6c, - 0x9c, 0x4f, 0xb6, 0x72, 0xf8, 0xfb, 0xbc, 0xfc, 0xac, 0x8b, 0xf2, 0x73, 0x57, 0x04, 0x40, 0xfd, - 0xf8, 0x32, 0x12, 0xfb, 0xe6, 0x1d, 0x81, 0xa4, 0xd4, 0x05, 0x49, 0xb9, 0x77, 0x78, 0x42, 0xd2, - 0x97, 0x96, 0xdf, 0xcb, 0x81, 0xab, 0x42, 0x62, 0xaa, 0xe8, 0x12, 0x13, 0x94, 0xcf, 0x8e, 0x44, - 0x50, 0x92, 0xc7, 0x32, 0x48, 0x5b, 0x62, 0xfe, 0x54, 0xfa, 0x0c, 0x50, 0x2f, 0x50, 0x01, 0x6f, - 0x22, 0x84, 0xe5, 0x24, 0x28, 0xd0, 0x1e, 0x86, 0x41, 0xc3, 0xde, 0x12, 0x76, 0x37, 0x72, 0x27, - 0x87, 0x64, 0x69, 0x1b, 0x83, 0xfc, 0xb0, 0x75, 0x0d, 0x63, 0xd7, 0xb5, 0x2b, 0xb6, 0xe7, 0xc0, - 0x67, 0x8d, 0x44, 0x70, 0x02, 0x6f, 0x38, 0x65, 0x18, 0x6f, 0xb8, 0xa1, 0x56, 0x39, 0xfc, 0x16, - 0x1c, 0xca, 0x2a, 0x47, 0x44, 0xe5, 0xe9, 0xe3, 0xf7, 0x76, 0x85, 0xde, 0xe6, 0x5f, 0x47, 0xde, - 0x82, 0x68, 0x21, 0xc2, 0x07, 0x46, 0x01, 0xe4, 0x71, 0xdf, 0x4c, 0x62, 0x97, 0x51, 0x91, 0x17, - 0xf1, 0xc4, 0x53, 0xec, 0xa5, 0x08, 0xc2, 0x74, 0xb0, 0x87, 0xc2, 0x91, 0x20, 0x25, 0x77, 0x17, - 0x42, 0x02, 0x32, 0xd2, 0xc7, 0xec, 0x45, 0x0a, 0x28, 0xb0, 0x9b, 0xdb, 0x37, 0x52, 0x71, 0x98, - 0x10, 0x43, 0x23, 0x4b, 0xec, 0xc8, 0x25, 0xbe, 0xdf, 0x3c, 0xbd, 0xbd, 0xb8, 0x43, 0xba, 0xc0, - 0xfc, 0xbb, 0x59, 0x30, 0x5d, 0x47, 0x5e, 0xd9, 0x74, 0x5d, 0xcb, 0xdc, 0x1a, 0x95, 0xc7, 0xb7, - 0xac, 0xf7, 0x30, 0xfc, 0x5e, 0x46, 0xf6, 0x3c, 0x4d, 0xb0, 0x10, 0xee, 0x93, 0x1a, 0x11, 0xdb, - 0x4f, 0xee, 0xe6, 0xf8, 0x41, 0xa5, 0x8d, 0xc1, 0x63, 0x3b, 0x0b, 0x26, 0xfc, 0x33, 0x75, 0xb7, - 0x09, 0xe7, 0x2c, 0xb7, 0xbd, 0x1d, 0xff, 0x18, 0x0c, 0x79, 0xde, 0x7f, 0x96, 0x0b, 0xbe, 0x22, - 0xa1, 0xa3, 0x7c, 0xfc, 0x81, 0xc0, 0x64, 0x3a, 0x96, 0xc4, 0x1d, 0xfe, 0xb0, 0x8e, 0x00, 0xfe, - 0xce, 0x04, 0x5b, 0x8e, 0x5c, 0x35, 0x3d, 0x74, 0x19, 0x7e, 0x4e, 0x01, 0x13, 0x75, 0xe4, 0xe1, - 0xf1, 0x16, 0x93, 0x7f, 0x60, 0x09, 0x57, 0xb9, 0x15, 0x8f, 0x29, 0xb6, 0x86, 0xf1, 0x34, 0x30, - 0xd5, 0x71, 0x9d, 0x26, 0xea, 0x76, 0xd9, 0xea, 0x05, 0xef, 0xa8, 0xd6, 0x6f, 0xf4, 0x27, 0xa4, - 0xcd, 0xaf, 0xfb, 0xff, 0xe8, 0xe1, 0xef, 0x49, 0xcd, 0x00, 0x5a, 0x12, 0x6b, 0xe0, 0xb8, 0xcd, - 0x80, 0xb8, 0xca, 0xd3, 0x07, 0xfa, 0xd3, 0x0a, 0x98, 0xa9, 0x23, 0x2f, 0xe0, 0x62, 0x82, 0x4d, - 0x8e, 0x68, 0x78, 0x05, 0x28, 0x95, 0x83, 0x41, 0x29, 0x7f, 0x9f, 0x9e, 0xc8, 0xcd, 0xa0, 0xb0, - 0x31, 0xde, 0xa7, 0x27, 0x47, 0xc1, 0x18, 0x8e, 0xaf, 0x3d, 0x0a, 0x4c, 0x11, 0x5a, 0x88, 0xc2, - 0xfe, 0x62, 0x2e, 0x54, 0xde, 0xcf, 0xa7, 0xa4, 0xbc, 0xf7, 0x80, 0x3c, 0xb9, 0xa7, 0x9f, 0x28, - 0xee, 0xb4, 0x8c, 0xd9, 0xbe, 0x86, 0xb3, 0xeb, 0xf4, 0xaf, 0xfe, 0x7e, 0x9a, 0xf9, 0x64, 0x7e, - 0x9a, 0x6f, 0xc8, 0x26, 0x1a, 0x09, 0xe9, 0xdc, 0x61, 0x84, 0x2a, 0x9f, 0x60, 0xdc, 0x8c, 0xa9, - 0x3b, 0x7d, 0xe1, 0x78, 0x81, 0x02, 0x26, 0xf1, 0xb8, 0x4d, 0xec, 0xf1, 0xf3, 0x07, 0x17, 0x87, - 0xfe, 0x86, 0x7e, 0xc2, 0x1e, 0xd8, 0xe7, 0xc8, 0xe8, 0xcc, 0xfb, 0x04, 0x3d, 0x70, 0x5c, 0xe5, - 0xe9, 0xe3, 0xf1, 0x4e, 0x8a, 0x07, 0xd1, 0x07, 0xf8, 0x46, 0x05, 0x28, 0xcb, 0xc8, 0x1b, 0xb7, - 0x15, 0xf9, 0x36, 0xe9, 0x50, 0x45, 0x02, 0xc3, 0x08, 0xcd, 0xf3, 0xcb, 0x68, 0x34, 0x0a, 0x24, - 0x17, 0xa3, 0x48, 0x8a, 0x80, 0xf4, 0x51, 0x7b, 0x2f, 0x45, 0x8d, 0x6e, 0x2e, 0xfc, 0xcc, 0x08, - 0x7a, 0xd5, 0xf1, 0x2e, 0x7c, 0xf8, 0x0c, 0x24, 0x65, 0x1c, 0x96, 0xbe, 0xf5, 0xab, 0x7c, 0x2c, - 0xf7, 0xd7, 0x01, 0xac, 0xec, 0xdb, 0xa8, 0x79, 0x11, 0xb5, 0xe0, 0x4f, 0x1e, 0x1c, 0xba, 0x53, - 0x60, 0xa2, 0x49, 0x4b, 0x23, 0xe0, 0x4d, 0xea, 0xfe, 0x6b, 0x82, 0xcb, 0x98, 0xc5, 0x8e, 0x88, - 0xfe, 0x3e, 0xc6, 0xcb, 0x98, 0x25, 0xaa, 0x1f, 0x83, 0xd9, 0x42, 0x67, 0x19, 0x95, 0xa6, 0x63, - 0xc3, 0xff, 0x70, 0x70, 0x58, 0xae, 0x03, 0x53, 0x56, 0xd3, 0xb1, 0x2b, 0x3b, 0x7e, 0x70, 0xbf, - 0x29, 0x3d, 0x4c, 0xf0, 0xbf, 0x6a, 0x3b, 0xce, 0x83, 0x16, 0xdb, 0x35, 0x0f, 0x13, 0x86, 0x35, - 0x26, 0x30, 0xe9, 0x87, 0x65, 0x4c, 0xf4, 0xa9, 0x3b, 0x7d, 0xc8, 0x3e, 0x12, 0x7a, 0xb7, 0xd1, - 0xae, 0xf0, 0x61, 0xb1, 0x0a, 0x3c, 0xcc, 0x70, 0xc6, 0xb7, 0xe2, 0x50, 0x86, 0xb3, 0x18, 0x02, - 0xc6, 0x70, 0xbf, 0x48, 0x88, 0x63, 0xea, 0x6b, 0xc0, 0x07, 0x40, 0x67, 0x74, 0xe6, 0xe1, 0x90, - 0xe8, 0x1c, 0x8e, 0x89, 0xf8, 0x01, 0x16, 0xea, 0x92, 0x59, 0x3c, 0xf0, 0x3f, 0x8e, 0x02, 0x9c, - 0xbb, 0x86, 0xf1, 0x57, 0xa0, 0xde, 0x0a, 0x09, 0xae, 0x91, 0xde, 0xc7, 0x41, 0x5c, 0xca, 0x18, - 0x2f, 0x58, 0x97, 0xa9, 0x3f, 0x7d, 0x00, 0x7f, 0x41, 0x01, 0x73, 0xc4, 0x47, 0xa0, 0x8d, 0x4c, - 0x97, 0x76, 0x94, 0x23, 0x71, 0x94, 0x7f, 0xa7, 0x74, 0x80, 0x1f, 0x91, 0x0f, 0x21, 0x1d, 0x23, - 0x81, 0x42, 0x2e, 0xba, 0x8f, 0x24, 0x09, 0x63, 0xd9, 0x46, 0x29, 0x06, 0x24, 0x30, 0x11, 0x1f, - 0x0d, 0x1e, 0x09, 0x3d, 0x72, 0x45, 0x66, 0xf8, 0xca, 0x36, 0x66, 0x8f, 0x5c, 0x19, 0x22, 0xc6, - 0x70, 0xc3, 0xe4, 0xe3, 0xd8, 0x82, 0xb3, 0x41, 0x6e, 0x59, 0x7f, 0x55, 0x2e, 0x38, 0xd1, 0xf6, - 0xe9, 0x91, 0x78, 0x60, 0x1e, 0x20, 0xb0, 0xbd, 0x0a, 0x72, 0xae, 0x73, 0x89, 0x2e, 0x6d, 0xcd, - 0xea, 0xe4, 0x99, 0x98, 0xfc, 0x4e, 0x7b, 0x77, 0xc7, 0xa6, 0x27, 0x43, 0x67, 0x75, 0xff, 0x55, - 0xbd, 0x11, 0xcc, 0x5e, 0xb2, 0xbc, 0xed, 0x15, 0x64, 0xb6, 0x90, 0xab, 0x3b, 0x97, 0x88, 0xc7, - 0xdc, 0xa4, 0x2e, 0x26, 0x8a, 0xfe, 0x2b, 0x12, 0xf6, 0x25, 0xb9, 0x7a, 0x7d, 0x2c, 0xc7, 0xdf, - 0x92, 0x58, 0x9e, 0xd1, 0x54, 0xa5, 0x2f, 0x30, 0xef, 0x53, 0xc0, 0x94, 0xee, 0x5c, 0x62, 0x42, - 0xf2, 0x7f, 0x1d, 0xae, 0x8c, 0x24, 0x9e, 0xe8, 0xd1, 0xab, 0xf4, 0x7d, 0xf2, 0xc7, 0x3e, 0xd1, - 0x8b, 0xad, 0x7e, 0x2c, 0x27, 0x97, 0x66, 0x74, 0xe7, 0x52, 0x1d, 0x79, 0x54, 0x23, 0x60, 0x63, - 0x44, 0x4e, 0xd6, 0x56, 0x97, 0x16, 0xc8, 0xe6, 0xe1, 0xc1, 0x7b, 0xd2, 0x5d, 0x84, 0x80, 0x41, - 0x01, 0x89, 0xe3, 0xde, 0x45, 0x18, 0x48, 0xc1, 0x18, 0x62, 0xa4, 0x28, 0x60, 0x5a, 0x77, 0x2e, - 0xe1, 0xa1, 0x61, 0xc9, 0x6a, 0xb7, 0x47, 0x33, 0x42, 0x26, 0x35, 0xfe, 0x7d, 0x36, 0xf8, 0x54, - 0x8c, 0xdd, 0xf8, 0x1f, 0x40, 0x40, 0xfa, 0x30, 0x3c, 0x8f, 0x2a, 0x8b, 0x3f, 0x42, 0xdb, 0xa3, - 0xc1, 0x61, 0x58, 0x85, 0x08, 0xc8, 0x38, 0x34, 0x85, 0x88, 0xa2, 0x60, 0x2c, 0x3b, 0x27, 0x73, - 0x65, 0x32, 0xcc, 0x8f, 0x56, 0x27, 0xde, 0x9d, 0xcc, 0x35, 0x91, 0x0d, 0xbb, 0x02, 0x21, 0x23, - 0x41, 0x23, 0x81, 0x0b, 0xa2, 0x04, 0x0d, 0xe9, 0xe3, 0xf1, 0x41, 0x05, 0xcc, 0x50, 0x12, 0x1e, - 0x26, 0x56, 0xc0, 0x50, 0x4a, 0xc5, 0xb7, 0xe0, 0x70, 0x94, 0x2a, 0x86, 0x82, 0xb1, 0xdc, 0xd2, - 0x89, 0xed, 0xb8, 0x21, 0x8e, 0x8f, 0x47, 0x21, 0x38, 0xb4, 0x31, 0x36, 0xc2, 0x23, 0xe4, 0xc3, - 0x18, 0x63, 0x87, 0x74, 0x8c, 0xfc, 0x79, 0x81, 0x16, 0x8d, 0x12, 0x83, 0x03, 0xa8, 0xc2, 0x08, - 0x61, 0x18, 0x52, 0x15, 0x0e, 0x09, 0x89, 0xaf, 0x28, 0x00, 0x50, 0x02, 0xd6, 0x9c, 0x3d, 0x72, - 0x29, 0xcf, 0x08, 0xba, 0xb3, 0x5e, 0xb7, 0x7a, 0x65, 0x80, 0x5b, 0x7d, 0xc2, 0x10, 0x2e, 0x49, - 0x57, 0x02, 0x39, 0x2e, 0xe3, 0x46, 0x8e, 0x7d, 0x25, 0x30, 0xbe, 0xfe, 0xf4, 0x31, 0xfe, 0x12, - 0xb5, 0xe6, 0xc2, 0x03, 0xa6, 0xbf, 0x36, 0x12, 0x94, 0xb9, 0xd9, 0xbf, 0x22, 0xce, 0xfe, 0x0f, - 0x80, 0xed, 0xb0, 0x36, 0xe2, 0xa0, 0x83, 0xa3, 0xe9, 0xdb, 0x88, 0x87, 0x77, 0x40, 0xf4, 0x67, - 0x72, 0xe0, 0x28, 0xeb, 0x44, 0x7e, 0x14, 0x20, 0x4e, 0x78, 0x0e, 0x4f, 0xe8, 0x24, 0x07, 0xa0, - 0x3c, 0xaa, 0x05, 0xa9, 0x24, 0x4b, 0x99, 0x12, 0xe4, 0x8d, 0x65, 0x75, 0xa3, 0xa0, 0x5d, 0xee, - 0x98, 0x76, 0x4b, 0x3e, 0xdc, 0xef, 0x00, 0xe0, 0xfd, 0xb5, 0x46, 0x45, 0x5c, 0x6b, 0xec, 0xb3, - 0x32, 0x99, 0x78, 0xe7, 0x9a, 0xb0, 0x8c, 0x92, 0x3b, 0xf6, 0x9d, 0xeb, 0xe8, 0xba, 0xd3, 0x47, - 0xe9, 0xdd, 0x0a, 0xc8, 0xd5, 0x1d, 0xd7, 0x83, 0x0f, 0x25, 0xd1, 0x4e, 0xca, 0xf9, 0x10, 0x24, - 0xff, 0x5d, 0x2d, 0x0b, 0xb7, 0x26, 0xdf, 0x16, 0x7f, 0xd4, 0xd9, 0xf4, 0x4c, 0xe2, 0xd5, 0x8d, - 0xeb, 0xe7, 0xae, 0x4f, 0x4e, 0x1a, 0x4f, 0x87, 0xf2, 0xaf, 0x1e, 0x7d, 0x00, 0x23, 0xb5, 0x78, - 0x3a, 0x91, 0x35, 0xa7, 0x8f, 0xdb, 0x7f, 0x9f, 0x63, 0xbe, 0xad, 0x4b, 0x56, 0x1b, 0xc1, 0x87, - 0xa8, 0xcb, 0x48, 0xd5, 0xdc, 0x41, 0xf2, 0x47, 0x62, 0x62, 0x5d, 0x5b, 0x49, 0x7c, 0x59, 0x25, - 0x8c, 0x2f, 0x9b, 0x54, 0xa1, 0xe8, 0x01, 0x74, 0x4a, 0xd2, 0xb8, 0x15, 0x2a, 0xa6, 0xee, 0xb1, - 0xc4, 0xe9, 0x3c, 0x56, 0x47, 0x1e, 0x35, 0x2a, 0x6b, 0xfe, 0x0d, 0x2c, 0x3f, 0x35, 0x92, 0x88, - 0x9d, 0xc1, 0x05, 0x2f, 0x4a, 0xcf, 0x05, 0x2f, 0xef, 0xe3, 0xc1, 0x59, 0x13, 0xc1, 0x79, 0x52, - 0x34, 0x83, 0x44, 0x22, 0x47, 0x02, 0xd3, 0xdb, 0x02, 0x98, 0xd6, 0x05, 0x98, 0xee, 0x1e, 0x92, - 0x8a, 0xf4, 0x01, 0xfb, 0x3c, 0x36, 0x55, 0xc8, 0xa4, 0xbf, 0x64, 0xb7, 0x58, 0x84, 0xd5, 0x7f, - 0x38, 0xec, 0xcd, 0xb6, 0xfd, 0x21, 0x58, 0x85, 0x58, 0xce, 0xf9, 0xde, 0xdb, 0xea, 0x17, 0x68, - 0x38, 0x57, 0xdc, 0x89, 0x92, 0x9d, 0x36, 0xf9, 0x1b, 0xeb, 0x83, 0xff, 0xe0, 0x9f, 0x25, 0x5b, - 0x7f, 0x23, 0x45, 0xf4, 0x30, 0x2e, 0x65, 0x1b, 0x28, 0xc1, 0xca, 0x9c, 0x04, 0x75, 0xff, 0x36, - 0xdc, 0xc2, 0xc2, 0x48, 0x20, 0x43, 0xba, 0x85, 0x91, 0x02, 0x0e, 0xd3, 0x2d, 0x6c, 0x10, 0x01, - 0x63, 0xb8, 0x65, 0x3e, 0xcf, 0x76, 0xe5, 0x89, 0xcf, 0x24, 0xfc, 0xeb, 0x6c, 0xea, 0xa3, 0xed, - 0xf7, 0x33, 0x89, 0xfc, 0x98, 0x09, 0x5d, 0xf1, 0xc3, 0x6d, 0x12, 0xcf, 0xe4, 0xb8, 0xe2, 0xc6, - 0xb0, 0xfe, 0x93, 0x25, 0x3e, 0xe5, 0xe7, 0xad, 0x96, 0xb7, 0x3d, 0xa2, 0x93, 0x19, 0x97, 0x70, - 0x59, 0xfe, 0x75, 0xc5, 0xe4, 0x05, 0xfe, 0x73, 0x26, 0x51, 0x28, 0xa8, 0x80, 0x25, 0x84, 0xac, - 0x08, 0x16, 0x27, 0x08, 0xe0, 0x14, 0x5b, 0xde, 0x18, 0x25, 0xfa, 0x9c, 0xd5, 0x42, 0xce, 0xc3, - 0x50, 0xa2, 0x09, 0x5d, 0xa3, 0x93, 0xe8, 0xb8, 0xe2, 0xfe, 0x8d, 0x4a, 0x74, 0xc0, 0x92, 0x11, - 0x49, 0x74, 0x6c, 0x79, 0xe9, 0xf3, 0xf8, 0x15, 0x33, 0x6c, 0x42, 0xb4, 0x6a, 0xd9, 0x17, 0xe1, - 0x77, 0x0a, 0xfe, 0x45, 0xc9, 0xe7, 0x2d, 0x6f, 0x9b, 0xc5, 0x74, 0xf9, 0x3d, 0xe9, 0x3b, 0x4e, - 0x86, 0x88, 0xdb, 0x22, 0x86, 0x85, 0xca, 0xef, 0x0b, 0x0b, 0x55, 0x02, 0xb3, 0x96, 0xed, 0x21, - 0xd7, 0x36, 0xdb, 0x4b, 0x6d, 0x73, 0xab, 0x7b, 0x6a, 0xa2, 0xef, 0x25, 0x74, 0x15, 0x2e, 0x8f, - 0x2e, 0xfe, 0xc1, 0x5f, 0x27, 0x39, 0x29, 0x5e, 0x8b, 0x1f, 0x11, 0xc5, 0x6a, 0x2a, 0x3a, 0x8a, - 0x55, 0x10, 0xa5, 0x0a, 0x0c, 0x0e, 0x72, 0x2d, 0x6b, 0xe3, 0x26, 0x0c, 0xdb, 0x77, 0x9b, 0x64, - 0x34, 0xb5, 0x20, 0x84, 0xe3, 0xab, 0x95, 0x44, 0xab, 0x74, 0x58, 0x10, 0xe6, 0x7b, 0x85, 0x20, - 0xb1, 0x85, 0xca, 0x37, 0x5e, 0xe9, 0x69, 0x7c, 0x60, 0xf2, 0xe4, 0x24, 0x4c, 0x1e, 0x5e, 0xa8, - 0xf2, 0x72, 0x42, 0x95, 0x64, 0xd1, 0x4f, 0xa6, 0xb5, 0x63, 0x38, 0x55, 0x94, 0x07, 0xc7, 0xfc, - 0xa8, 0xb5, 0x9d, 0x0e, 0x32, 0x5d, 0xd3, 0x6e, 0x22, 0xf8, 0x91, 0xec, 0x28, 0xcc, 0xde, 0x25, - 0x30, 0x69, 0x35, 0x1d, 0xbb, 0x6e, 0x3d, 0xd3, 0xbf, 0x24, 0x2e, 0x3e, 0x58, 0x3a, 0xe1, 0x48, - 0x85, 0xfd, 0xa1, 0x07, 0xff, 0xaa, 0x15, 0x30, 0xd5, 0x34, 0xdd, 0x16, 0x0d, 0xa6, 0x97, 0xef, - 0xb9, 0x90, 0x29, 0xb2, 0xa0, 0xb2, 0xff, 0x8b, 0x1e, 0xfe, 0xad, 0xd6, 0x44, 0x26, 0x16, 0x7a, - 0xa2, 0x72, 0x44, 0x16, 0xb6, 0x18, 0xfe, 0x24, 0xf0, 0x1c, 0x73, 0xc7, 0x45, 0x6d, 0x72, 0x27, - 0x3c, 0xed, 0x21, 0xa6, 0xf4, 0x30, 0x21, 0xe9, 0x34, 0x9f, 0x54, 0xb5, 0x0f, 0x8d, 0x71, 0x4f, - 0xf3, 0xa5, 0xa8, 0x48, 0x5f, 0x32, 0xdf, 0x51, 0x00, 0xb3, 0xb4, 0x57, 0x63, 0xec, 0x84, 0xbf, - 0x40, 0xae, 0x74, 0xf6, 0xee, 0x47, 0x57, 0x60, 0xfd, 0xe0, 0x63, 0x72, 0x11, 0x28, 0x17, 0x83, - 0xc0, 0x81, 0xf8, 0x31, 0xe9, 0xfe, 0xbb, 0x4f, 0xd7, 0x3c, 0xa5, 0x69, 0xdc, 0xfb, 0xef, 0xf1, - 0xd5, 0xa7, 0x8f, 0xcf, 0x2f, 0x2b, 0x40, 0x29, 0xb5, 0x5a, 0xb0, 0x79, 0x70, 0x28, 0xce, 0x80, - 0x69, 0x5f, 0x67, 0xc2, 0x58, 0x8e, 0x7c, 0x52, 0xd2, 0xc5, 0xcc, 0x80, 0x37, 0xa5, 0xd6, 0xd8, - 0x77, 0x07, 0x62, 0xea, 0x4e, 0x1f, 0x94, 0x5f, 0x9b, 0x60, 0x4a, 0xb3, 0xe0, 0x38, 0x17, 0xc9, - 0x91, 0x97, 0x87, 0x14, 0x90, 0x5f, 0x42, 0x5e, 0x73, 0x7b, 0x44, 0x3a, 0xb3, 0xeb, 0xb6, 0x7d, - 0x9d, 0xd9, 0x77, 0x3f, 0xfd, 0x60, 0x1b, 0xd6, 0x27, 0x6b, 0x9e, 0x90, 0x34, 0xee, 0x28, 0xcd, - 0xb1, 0xb5, 0xa7, 0x0f, 0xce, 0x3f, 0x2b, 0x60, 0x2e, 0x58, 0xe1, 0xa2, 0x98, 0xfc, 0xd2, 0xc3, - 0x6e, 0xdd, 0x12, 0x7e, 0x36, 0x59, 0xa8, 0xb3, 0x80, 0xa7, 0x62, 0xcb, 0x52, 0x5e, 0x58, 0x4c, - 0x10, 0x04, 0x4d, 0x8e, 0xc0, 0x31, 0xcc, 0xe0, 0x15, 0x30, 0x49, 0x08, 0x5a, 0xb4, 0xf6, 0x88, - 0x0b, 0xa0, 0xb0, 0xd0, 0xf8, 0xb3, 0x23, 0x59, 0x68, 0xbc, 0x5b, 0x5c, 0x68, 0x94, 0x8c, 0x5c, - 0xec, 0xaf, 0x33, 0x26, 0xf4, 0x89, 0xc1, 0xff, 0x8f, 0x7c, 0x99, 0x31, 0x81, 0x4f, 0xcc, 0x80, - 0xfa, 0xd3, 0x47, 0xf4, 0xd5, 0xff, 0x8e, 0x75, 0xb6, 0xfe, 0xc6, 0x28, 0xfc, 0xef, 0xc7, 0x40, - 0xee, 0x1c, 0x7e, 0xf8, 0x5f, 0xe1, 0xcd, 0x56, 0x2f, 0x1d, 0x41, 0x90, 0x85, 0xa7, 0x82, 0x1c, - 0x2e, 0x9f, 0x4d, 0x5b, 0x6e, 0x91, 0xdb, 0xa5, 0xc5, 0x84, 0xe8, 0xe4, 0x3f, 0xf5, 0x24, 0x28, - 0x74, 0x9d, 0x5d, 0xb7, 0x89, 0xcd, 0x67, 0x2c, 0x31, 0xec, 0x2d, 0x69, 0x70, 0x51, 0xa1, 0xe8, - 0xf9, 0xd1, 0xb9, 0x7e, 0x72, 0x17, 0x1d, 0x29, 0xc2, 0x45, 0x47, 0x09, 0xf6, 0x0f, 0x24, 0x68, - 0x4b, 0x5f, 0x22, 0xfe, 0x9a, 0xdc, 0xf9, 0xd7, 0x1a, 0x15, 0xec, 0x11, 0x6c, 0x39, 0xa8, 0x38, - 0x24, 0x75, 0xdc, 0x16, 0x59, 0x1b, 0xc4, 0x73, 0x1f, 0xab, 0xe3, 0xb6, 0x04, 0x0d, 0x63, 0x39, - 0x6d, 0x5e, 0x60, 0xce, 0xa6, 0x0f, 0x8c, 0x12, 0xdd, 0x9c, 0x20, 0xf4, 0x07, 0x42, 0x67, 0x84, - 0x4e, 0xa8, 0x43, 0xa3, 0x73, 0x48, 0x6e, 0xa8, 0x1f, 0x55, 0x48, 0x44, 0x4b, 0xdf, 0xc8, 0x91, - 0xbf, 0xb0, 0x28, 0x31, 0x44, 0x78, 0x0c, 0x16, 0xe2, 0x39, 0xcf, 0x0e, 0x1f, 0xe2, 0x5b, 0x64, - 0x1d, 0x47, 0xff, 0xb8, 0x43, 0x7c, 0xcb, 0x12, 0x92, 0x3e, 0x90, 0xaf, 0xa7, 0x17, 0x84, 0x95, - 0x9a, 0x9e, 0xb5, 0x37, 0x62, 0x4d, 0x13, 0x87, 0x97, 0x84, 0x51, 0x7d, 0xf7, 0x71, 0x88, 0x52, - 0x38, 0xee, 0xa8, 0xbe, 0x72, 0x64, 0xa4, 0x0f, 0xd3, 0xd7, 0x0b, 0x98, 0x7b, 0x6c, 0x6d, 0xe6, - 0x8d, 0x6c, 0x35, 0x00, 0x1d, 0x1c, 0xad, 0xb3, 0x60, 0x86, 0x9b, 0xfa, 0xfb, 0x17, 0xcf, 0x08, - 0x69, 0x49, 0x0f, 0xac, 0x07, 0x2c, 0x1b, 0xf9, 0xc2, 0x40, 0x82, 0x05, 0x5f, 0x19, 0x22, 0xc6, - 0x72, 0xaf, 0x9b, 0x3f, 0x86, 0x8d, 0x09, 0xab, 0xdf, 0xe3, 0xb1, 0xaa, 0x89, 0x58, 0xdd, 0x29, - 0xc3, 0x26, 0xb9, 0x31, 0x4d, 0x6a, 0xde, 0xf8, 0xf6, 0x00, 0x2e, 0x5d, 0x80, 0xeb, 0xa9, 0x43, - 0xd3, 0x91, 0x3e, 0x62, 0x2f, 0xa3, 0xdd, 0x61, 0x9d, 0x9a, 0xec, 0xa3, 0xe9, 0x0e, 0xd9, 0x6c, - 0x40, 0x11, 0x66, 0x03, 0x09, 0xfd, 0xe6, 0x43, 0x77, 0x50, 0x9f, 0xb8, 0x41, 0x10, 0xe5, 0x46, - 0xec, 0x37, 0x3f, 0x90, 0x82, 0xf4, 0xc1, 0xf9, 0x7b, 0x05, 0x80, 0x65, 0xd7, 0xd9, 0xed, 0xd4, - 0xdc, 0x16, 0x72, 0xe1, 0xdf, 0x86, 0x13, 0x80, 0x17, 0x8f, 0x60, 0x02, 0xb0, 0x0e, 0xc0, 0x56, - 0x50, 0x38, 0x93, 0xf0, 0xc7, 0xc9, 0x99, 0xfb, 0x21, 0x51, 0x3a, 0x57, 0x86, 0x78, 0x75, 0xec, - 0xd3, 0x45, 0x8c, 0xe3, 0xfa, 0xac, 0xb0, 0xb8, 0x51, 0x4e, 0x00, 0xde, 0x19, 0x60, 0x6d, 0x08, - 0x58, 0xdf, 0x77, 0x00, 0x4a, 0xd2, 0xc7, 0xfc, 0x1f, 0x26, 0xc0, 0x34, 0xdd, 0xae, 0xa3, 0x3c, - 0xfd, 0xbb, 0x10, 0xf4, 0x5f, 0x1b, 0x01, 0xe8, 0x1b, 0x60, 0xc6, 0x09, 0x4b, 0xa7, 0x7d, 0x2a, - 0xbf, 0x00, 0x13, 0x0b, 0x3b, 0x47, 0x97, 0x2e, 0x14, 0x03, 0x3f, 0xc4, 0x23, 0xaf, 0x8b, 0xc8, - 0xdf, 0x1d, 0xc3, 0x6f, 0xae, 0xc4, 0x51, 0x42, 0xff, 0xae, 0x00, 0xfa, 0x0d, 0x01, 0xfa, 0xd2, - 0x41, 0x48, 0x19, 0x43, 0xd8, 0x7c, 0x05, 0xe4, 0xc8, 0x29, 0xb7, 0xdf, 0x4c, 0x71, 0x7e, 0x7f, - 0x0a, 0x4c, 0x10, 0x95, 0x0d, 0xe6, 0x1d, 0xfe, 0x2b, 0xfe, 0x62, 0x6e, 0x7a, 0xc8, 0x0d, 0x3c, - 0x16, 0xfc, 0x57, 0x4c, 0x83, 0xef, 0x5d, 0xdc, 0x3d, 0x55, 0xa0, 0x1b, 0x91, 0x41, 0xc2, 0xd0, - 0x93, 0x12, 0x9e, 0xe3, 0x23, 0x3b, 0xf7, 0x36, 0xcc, 0xa4, 0x64, 0x00, 0x21, 0xe9, 0x03, 0xff, - 0x85, 0x1c, 0x38, 0x45, 0x57, 0x95, 0x96, 0x5c, 0x67, 0xa7, 0xe7, 0x96, 0x2a, 0xeb, 0xe0, 0xb2, - 0x70, 0x13, 0x98, 0xf3, 0x04, 0xbf, 0x6a, 0x26, 0x13, 0x3d, 0xa9, 0xf0, 0xcf, 0x79, 0x9f, 0x8a, - 0x67, 0x88, 0x48, 0x2e, 0xc4, 0x30, 0x30, 0x8a, 0xf6, 0xc4, 0x0b, 0xf5, 0x92, 0x84, 0x72, 0x8b, - 0x54, 0xca, 0x50, 0x6b, 0x96, 0x81, 0x4c, 0xe5, 0x65, 0x64, 0xea, 0xfd, 0x81, 0x4c, 0xfd, 0xa4, - 0x20, 0x53, 0xcb, 0x07, 0x67, 0x49, 0xfa, 0xb2, 0xf5, 0xaa, 0x60, 0x63, 0x28, 0xd8, 0xb6, 0xdb, - 0x49, 0x61, 0xb3, 0x8e, 0xf7, 0x47, 0xca, 0x09, 0xfe, 0x48, 0xe2, 0xbd, 0x12, 0x09, 0x66, 0xc2, - 0x22, 0xd5, 0x11, 0xb2, 0x34, 0x07, 0xb2, 0x96, 0x4f, 0x5d, 0xd6, 0x6a, 0x0d, 0x35, 0xd7, 0x8d, - 0xad, 0x68, 0x0c, 0x6b, 0x4b, 0x73, 0xa0, 0xb0, 0x64, 0xb5, 0x3d, 0xe4, 0xc2, 0x2f, 0xb1, 0x99, - 0xee, 0xab, 0x52, 0x1c, 0x00, 0x16, 0x41, 0x61, 0x93, 0xd4, 0xc6, 0x4c, 0xe6, 0x5b, 0xe5, 0xb4, - 0x87, 0x52, 0xa8, 0xb3, 0x7f, 0x93, 0x46, 0xd9, 0xeb, 0x29, 0x66, 0x64, 0x53, 0xe4, 0x04, 0x51, - 0xf6, 0x06, 0x93, 0x30, 0x96, 0x0b, 0xa6, 0x0a, 0x3a, 0xda, 0xc1, 0x63, 0xfc, 0xc5, 0xf4, 0x10, - 0x2e, 0x02, 0xc5, 0x6a, 0x75, 0x49, 0xe7, 0x38, 0xa5, 0xe3, 0xc7, 0xa4, 0xbe, 0x42, 0xbd, 0xac, - 0xa2, 0x24, 0x8f, 0xdb, 0x57, 0x48, 0x8a, 0x8a, 0xf4, 0x31, 0xfb, 0x3e, 0x71, 0x14, 0xed, 0xb4, - 0xcd, 0x26, 0xc2, 0xd4, 0xa7, 0x86, 0x1a, 0xed, 0xc9, 0x72, 0x7e, 0x4f, 0xc6, 0xe9, 0x69, 0xfe, - 0x00, 0x7a, 0x3a, 0xec, 0x32, 0x64, 0xc0, 0x73, 0xd2, 0xf0, 0x43, 0x5b, 0x86, 0x8c, 0x25, 0x63, - 0x0c, 0xd7, 0x87, 0xfa, 0x07, 0x62, 0xc7, 0xaa, 0xad, 0xc3, 0x6e, 0xd2, 0x30, 0x66, 0x8d, 0xec, - 0xf0, 0xeb, 0x30, 0x9b, 0x34, 0xd1, 0x34, 0x8c, 0x01, 0xad, 0x39, 0x86, 0xd6, 0x67, 0xd8, 0x30, - 0x9a, 0xf2, 0x3e, 0x69, 0xd7, 0x71, 0xbd, 0x64, 0xfb, 0xa4, 0x98, 0x3a, 0x9d, 0xfc, 0x97, 0xf4, - 0xe0, 0x95, 0x78, 0x3e, 0x7a, 0x54, 0xc3, 0x67, 0x82, 0x83, 0x57, 0x83, 0x08, 0x48, 0x1f, 0xde, - 0xb7, 0x1c, 0xd2, 0xe0, 0x39, 0xac, 0x3a, 0x32, 0x1d, 0x18, 0xd9, 0xd0, 0x39, 0x8c, 0x3a, 0x46, - 0xd3, 0x90, 0x3e, 0x5e, 0xdf, 0xe6, 0x06, 0xce, 0x37, 0x8d, 0x71, 0xe0, 0xf4, 0x35, 0x33, 0x3f, - 0xa4, 0x66, 0x0e, 0xbb, 0xff, 0xc3, 0x78, 0x3d, 0xba, 0x01, 0x73, 0x98, 0xfd, 0x9f, 0x18, 0x22, - 0xd2, 0x47, 0xfc, 0xcd, 0x0a, 0xc8, 0xd7, 0xc7, 0x3f, 0x5e, 0x0e, 0x3b, 0x17, 0x21, 0xbc, 0xaa, - 0x8f, 0x6c, 0xb8, 0x1c, 0x66, 0x2e, 0x12, 0x49, 0xc2, 0x18, 0x02, 0xe8, 0x1f, 0x05, 0x33, 0x64, - 0x49, 0xc4, 0xdf, 0x66, 0xfd, 0x36, 0x1b, 0x35, 0xdf, 0x90, 0xa2, 0xae, 0x3e, 0x0d, 0x4c, 0xfa, - 0xfb, 0x77, 0x6c, 0xe4, 0x9c, 0x97, 0xd3, 0x4f, 0x9f, 0x4a, 0x3d, 0xf8, 0xff, 0x40, 0xce, 0x10, - 0x23, 0xdf, 0xab, 0x1d, 0xd6, 0x19, 0xe2, 0x50, 0xf7, 0x6b, 0xff, 0x2c, 0x1c, 0x51, 0xff, 0x43, - 0x7a, 0x98, 0xf7, 0xee, 0xe3, 0xe6, 0xfa, 0xec, 0xe3, 0x7e, 0x84, 0xc7, 0xb2, 0x2e, 0x62, 0x79, - 0x8f, 0x2c, 0x0b, 0x47, 0x38, 0xd6, 0xbe, 0x3b, 0x80, 0xf3, 0x9c, 0x00, 0xe7, 0xc2, 0x81, 0x68, - 0x19, 0xc3, 0xc1, 0xc7, 0x5c, 0x38, 0xe6, 0x7e, 0x2c, 0x45, 0x3d, 0xee, 0x39, 0x55, 0x91, 0xdb, - 0x77, 0xaa, 0x42, 0xd0, 0xf4, 0xfc, 0x01, 0x35, 0xfd, 0x63, 0xbc, 0x74, 0x18, 0xa2, 0x74, 0x3c, - 0x55, 0x1e, 0x91, 0xd1, 0x8d, 0xcc, 0xef, 0x09, 0xc4, 0xe3, 0xbc, 0x20, 0x1e, 0xe5, 0x83, 0x11, - 0x93, 0xbe, 0x7c, 0xfc, 0x91, 0x3f, 0xa1, 0x3d, 0x64, 0x7d, 0x1f, 0x76, 0xab, 0x58, 0x60, 0xe2, - 0xc8, 0x46, 0xee, 0x61, 0xb6, 0x8a, 0x07, 0x51, 0x32, 0x86, 0x98, 0x6a, 0xb3, 0x60, 0x9a, 0xd0, - 0x74, 0xde, 0x6a, 0x6d, 0x21, 0x0f, 0xbe, 0x9a, 0xfa, 0x28, 0xfa, 0x11, 0x2c, 0x47, 0x14, 0x66, - 0x28, 0xea, 0xbc, 0x6b, 0x52, 0x8f, 0x0e, 0x4a, 0xe4, 0x3c, 0x47, 0xe0, 0xb8, 0x23, 0x21, 0x0e, - 0xa4, 0x20, 0x7d, 0xc8, 0x3e, 0x44, 0xdd, 0x6d, 0x56, 0xcd, 0x2b, 0xce, 0xae, 0x07, 0x9f, 0x33, - 0x82, 0x0e, 0x7a, 0x01, 0x14, 0xda, 0xa4, 0x34, 0x76, 0x2c, 0x23, 0x7e, 0xba, 0xc3, 0x58, 0x40, - 0xeb, 0xd7, 0xd9, 0x9f, 0x49, 0xcf, 0x66, 0x84, 0x7c, 0xa4, 0xe5, 0x8c, 0xfb, 0x6c, 0xc6, 0x80, - 0xfa, 0xc7, 0x72, 0x57, 0xce, 0x24, 0xae, 0xdd, 0xda, 0xb1, 0xbc, 0x11, 0x45, 0x70, 0x68, 0xe3, - 0xb2, 0xfc, 0x08, 0x0e, 0xe4, 0x25, 0xe9, 0x89, 0x51, 0x8e, 0x2b, 0xf8, 0xf7, 0x71, 0x9f, 0x18, - 0x8d, 0xaf, 0x3e, 0x7d, 0x4c, 0xfe, 0x33, 0xd5, 0xac, 0x73, 0xd4, 0xf9, 0x36, 0x45, 0xbf, 0xde, - 0xa1, 0x95, 0x85, 0x92, 0x76, 0x78, 0xca, 0xd2, 0xb7, 0xfe, 0xf4, 0x81, 0xf9, 0xe4, 0x69, 0x90, - 0x5f, 0x44, 0x17, 0x76, 0xb7, 0xe0, 0xdd, 0x60, 0xd2, 0x70, 0x11, 0xaa, 0xd8, 0x9b, 0x0e, 0xe6, - 0xae, 0x87, 0x9f, 0x7d, 0x48, 0xd8, 0x1b, 0xc6, 0x63, 0x1b, 0x99, 0xad, 0xf0, 0xfc, 0x99, 0xff, - 0x0a, 0x5f, 0x9a, 0x05, 0xb9, 0xba, 0x67, 0x7a, 0x70, 0x2a, 0xc0, 0x16, 0x3e, 0x87, 0xc7, 0xe2, - 0x6e, 0x11, 0x8b, 0x9b, 0x04, 0x5e, 0x10, 0x0a, 0xe6, 0xf1, 0xff, 0x11, 0x00, 0x40, 0x30, 0xf9, - 0x60, 0xd7, 0xb1, 0x71, 0x0e, 0xff, 0x08, 0xa4, 0xff, 0x0e, 0x5f, 0x19, 0xb0, 0xfb, 0x5e, 0x81, - 0xdd, 0x8f, 0x91, 0xab, 0x62, 0x0c, 0x2b, 0x6d, 0x59, 0x30, 0x85, 0x59, 0xbb, 0x82, 0xcc, 0x56, - 0x17, 0x3e, 0x32, 0x14, 0xfe, 0x08, 0x36, 0xc3, 0x0f, 0x48, 0x07, 0xd5, 0xa4, 0xad, 0x0a, 0x0a, - 0x8f, 0xf6, 0xe8, 0xf0, 0x37, 0xff, 0xb3, 0x62, 0x30, 0x92, 0xdb, 0x40, 0xce, 0xb2, 0x37, 0x1d, - 0xe6, 0x5f, 0x78, 0x6d, 0x44, 0xd9, 0x58, 0x26, 0x74, 0x92, 0x51, 0x32, 0xe2, 0x66, 0x3c, 0x59, - 0x63, 0xb9, 0xbc, 0x2e, 0x87, 0x6b, 0x87, 0xff, 0xe7, 0x40, 0x66, 0xab, 0x2a, 0xc8, 0x75, 0x4c, - 0x6f, 0x9b, 0x55, 0x4d, 0x9e, 0xb1, 0x8d, 0xbc, 0x6b, 0x9b, 0xb6, 0x63, 0x5f, 0xd9, 0xb1, 0x9e, - 0x19, 0xdc, 0x91, 0x2b, 0xa4, 0x61, 0xca, 0xb7, 0x90, 0x8d, 0x5c, 0xd3, 0x43, 0xf5, 0xbd, 0x2d, - 0x32, 0xc7, 0x9a, 0xd4, 0xf9, 0xa4, 0xc4, 0xf2, 0x8f, 0x29, 0x8e, 0x96, 0xff, 0x4d, 0xab, 0x8d, - 0x48, 0xa4, 0x26, 0x26, 0xff, 0xfe, 0x7b, 0x22, 0xf9, 0xef, 0x53, 0x45, 0xfa, 0x68, 0xfc, 0x20, - 0x0b, 0x66, 0xea, 0x58, 0xe0, 0xea, 0xbb, 0x3b, 0x3b, 0xa6, 0x7b, 0x05, 0xde, 0x10, 0xa2, 0xc2, - 0x89, 0x66, 0x46, 0xf4, 0x4b, 0xf9, 0xa8, 0xf4, 0xf5, 0xd0, 0x4c, 0xb5, 0xb9, 0x1a, 0x12, 0xeb, - 0xc1, 0xe3, 0x41, 0x1e, 0x8b, 0xb7, 0xef, 0x71, 0x19, 0xab, 0x08, 0x34, 0xa7, 0x64, 0x44, 0xab, - 0x81, 0xb4, 0x8d, 0x21, 0x9a, 0x46, 0x16, 0x1c, 0xad, 0x7b, 0x66, 0xf3, 0xe2, 0xb2, 0xe3, 0x3a, - 0xbb, 0x9e, 0x65, 0xa3, 0x2e, 0x7c, 0x44, 0x88, 0x80, 0x2f, 0xff, 0x99, 0x50, 0xfe, 0xe1, 0xbf, - 0x64, 0x64, 0x47, 0xd1, 0xa0, 0x5b, 0xe5, 0x8b, 0x8f, 0x08, 0x50, 0x25, 0x37, 0x2e, 0xca, 0x94, - 0x98, 0x3e, 0xd3, 0xde, 0xa4, 0x80, 0xa2, 0x76, 0xb9, 0xe3, 0xb8, 0xde, 0xaa, 0xd3, 0x34, 0xdb, - 0x5d, 0xcf, 0x71, 0x11, 0xac, 0xc5, 0x72, 0x0d, 0xf7, 0x30, 0x2d, 0xa7, 0x19, 0x0e, 0x8e, 0xec, - 0x8d, 0x17, 0x3b, 0x45, 0x94, 0xf1, 0x0f, 0x49, 0xef, 0x32, 0x52, 0xae, 0xf4, 0x52, 0x14, 0x21, - 0xe7, 0xfd, 0xba, 0xb4, 0x64, 0x87, 0x25, 0xe4, 0x76, 0x1e, 0xa5, 0x88, 0x1a, 0xc3, 0x52, 0x79, - 0x16, 0xcc, 0xd6, 0x77, 0x2f, 0x04, 0x85, 0x74, 0x79, 0x23, 0xe4, 0x35, 0xd2, 0x51, 0x2a, 0x98, - 0xe0, 0xf1, 0x05, 0x45, 0xf0, 0xf7, 0x46, 0x30, 0xdb, 0xe5, 0xb3, 0x31, 0xbc, 0xc5, 0x44, 0xc9, - 0xe8, 0x14, 0x83, 0x6b, 0x4d, 0x9f, 0x81, 0xef, 0xc9, 0x82, 0xd9, 0x5a, 0x07, 0xd9, 0xa8, 0x45, - 0xbd, 0x20, 0x05, 0x06, 0xbe, 0x34, 0x21, 0x03, 0x85, 0x82, 0x22, 0x18, 0x18, 0x7a, 0x2c, 0x2f, - 0xfa, 0xcc, 0x0b, 0x13, 0x12, 0x31, 0x2e, 0xae, 0xb6, 0xf4, 0x19, 0xf7, 0xc5, 0x2c, 0x98, 0xd6, - 0x77, 0xed, 0x75, 0xd7, 0xc1, 0xa3, 0xb1, 0x0b, 0xef, 0x09, 0x3b, 0x88, 0x5b, 0xc1, 0xb1, 0xd6, - 0xae, 0x4b, 0xd6, 0x9f, 0x2a, 0x76, 0x1d, 0x35, 0x1d, 0xbb, 0xd5, 0x25, 0xed, 0xc8, 0xeb, 0xfb, - 0x3f, 0xdc, 0x95, 0x7b, 0xe8, 0x1b, 0x4a, 0x06, 0xfe, 0x82, 0x74, 0xa8, 0x1b, 0xda, 0x78, 0xae, - 0x6a, 0xf9, 0x9e, 0x40, 0x32, 0xa0, 0xcd, 0xa0, 0x1a, 0xd2, 0x67, 0xee, 0x67, 0xb2, 0x40, 0x2d, - 0x35, 0x9b, 0xce, 0xae, 0xed, 0xd5, 0x51, 0x1b, 0x35, 0x3d, 0xc3, 0x35, 0x9b, 0x88, 0xb7, 0x9f, - 0x8b, 0x40, 0x69, 0x59, 0x2e, 0xeb, 0x83, 0xf1, 0x23, 0xe3, 0xe3, 0x4b, 0xa5, 0x77, 0x1c, 0x69, - 0x2b, 0xf7, 0xd7, 0x92, 0x80, 0x9d, 0x72, 0xfb, 0x8a, 0x92, 0x15, 0x8d, 0xe1, 0x36, 0x97, 0x2c, - 0xc8, 0xad, 0x5b, 0xf6, 0x16, 0x1f, 0x13, 0xe8, 0x38, 0xb6, 0x7e, 0x5a, 0xe8, 0x32, 0x93, 0x4f, - 0xfa, 0xa2, 0xde, 0x0e, 0x8e, 0xdb, 0xbb, 0x3b, 0x17, 0x90, 0x5b, 0xdb, 0x24, 0x63, 0x43, 0xd7, - 0x70, 0xea, 0xc8, 0xa6, 0xa6, 0x53, 0x5e, 0xef, 0xfb, 0x4d, 0x34, 0x1c, 0x24, 0x4c, 0x5e, 0x4c, - 0x49, 0x04, 0xaf, 0x03, 0xa2, 0xb2, 0x1c, 0x51, 0x89, 0x8c, 0xdd, 0x3e, 0x85, 0xa7, 0xcf, 0xdf, - 0xaf, 0x65, 0xc1, 0xc4, 0x1a, 0xf2, 0x5c, 0xab, 0xd9, 0x85, 0x9f, 0xc7, 0x03, 0x13, 0xf2, 0xd6, - 0x4d, 0xd7, 0xdc, 0x41, 0x1e, 0x72, 0xbb, 0x50, 0x0b, 0x99, 0x0e, 0xc1, 0x64, 0xa7, 0x6d, 0x7a, - 0x9b, 0x8e, 0xbb, 0xc3, 0x24, 0x38, 0x78, 0xc7, 0x16, 0xc3, 0x1e, 0x72, 0xbb, 0x21, 0x59, 0xfe, - 0x2b, 0x13, 0x70, 0x79, 0xfb, 0x8c, 0x91, 0x32, 0x2f, 0x90, 0x71, 0x20, 0xfb, 0x4c, 0xa6, 0xc4, - 0xb1, 0xdc, 0x58, 0xa2, 0xac, 0x3a, 0x5b, 0xf0, 0xe5, 0x0a, 0xc8, 0x11, 0xc9, 0x7b, 0x73, 0x46, - 0x98, 0x54, 0xec, 0xa0, 0x6e, 0xd7, 0xdc, 0x42, 0xfe, 0xa4, 0x82, 0xbd, 0xaa, 0x77, 0x82, 0x7c, - 0x1b, 0xed, 0xa1, 0x36, 0x21, 0x63, 0xee, 0xf6, 0x1b, 0x84, 0x96, 0xad, 0x3a, 0x5b, 0xf3, 0xb8, - 0xac, 0x79, 0x56, 0xce, 0xfc, 0x2a, 0xce, 0xaa, 0xd3, 0x3f, 0xce, 0x3e, 0x0d, 0xe4, 0xc9, 0xbb, - 0x3a, 0x05, 0xf2, 0x8b, 0xda, 0xc2, 0xc6, 0x72, 0xf1, 0x08, 0x7e, 0xf4, 0xe9, 0x9b, 0x02, 0xf9, - 0xa5, 0x92, 0x51, 0x5a, 0x2d, 0x66, 0x71, 0x3b, 0x2a, 0xd5, 0xa5, 0x5a, 0x51, 0xc1, 0x89, 0xeb, - 0xa5, 0x6a, 0xa5, 0x5c, 0xcc, 0xa9, 0xd3, 0x60, 0xe2, 0x7c, 0x49, 0xaf, 0x56, 0xaa, 0xcb, 0xc5, - 0x3c, 0xfc, 0x3a, 0x8f, 0xdf, 0x5d, 0x22, 0x7e, 0x37, 0x46, 0xd1, 0xd4, 0x0f, 0xb2, 0x5f, 0x0f, - 0x20, 0xbb, 0x47, 0x80, 0xec, 0xc7, 0x64, 0x0a, 0x19, 0x03, 0x4a, 0x59, 0x30, 0xb1, 0xee, 0x3a, - 0x4d, 0xd4, 0xed, 0xc2, 0x5f, 0xcd, 0x82, 0x42, 0xd9, 0xb4, 0x9b, 0xa8, 0x0d, 0xaf, 0x09, 0xa1, - 0xa2, 0xde, 0x41, 0x99, 0xe0, 0x80, 0xc0, 0xdf, 0xf3, 0x9c, 0xb9, 0x4f, 0xe4, 0xcc, 0x2d, 0x42, - 0xa3, 0x58, 0xb9, 0xf3, 0xb4, 0xcc, 0x08, 0xfe, 0xbc, 0x36, 0xe0, 0x4f, 0x59, 0xe0, 0xcf, 0x6d, - 0xf2, 0x45, 0xa5, 0xcf, 0xa5, 0xef, 0x65, 0xc0, 0xf1, 0x65, 0x64, 0x23, 0xd7, 0x6a, 0x52, 0xe2, - 0xfd, 0xf6, 0xdf, 0x23, 0xb6, 0xff, 0xd1, 0x02, 0xd1, 0xfd, 0xfe, 0x10, 0x1b, 0xff, 0xaa, 0xa0, - 0xf1, 0xf7, 0x09, 0x8d, 0xbf, 0x55, 0xb2, 0x9c, 0x31, 0x5c, 0x4f, 0x3a, 0x05, 0x66, 0xaa, 0x8e, - 0x67, 0x6d, 0x5a, 0x4d, 0xba, 0x95, 0xfc, 0x32, 0x05, 0xe4, 0x56, 0xad, 0xae, 0x07, 0x4b, 0xa1, - 0x88, 0x9c, 0x01, 0xd3, 0x96, 0xdd, 0x6c, 0xef, 0xb6, 0x90, 0x8e, 0x4c, 0x2a, 0x2b, 0x93, 0x3a, - 0x9f, 0x14, 0xae, 0xd0, 0x63, 0xb2, 0x14, 0x7f, 0x85, 0xfe, 0x93, 0xd2, 0xd6, 0x14, 0x4f, 0x02, - 0x89, 0x2b, 0x15, 0x31, 0x24, 0x95, 0xc0, 0xac, 0xcd, 0x65, 0xa5, 0xa6, 0xeb, 0xfe, 0xb8, 0xc0, - 0x7c, 0x71, 0xba, 0xf8, 0x07, 0x7c, 0x9f, 0x94, 0xf1, 0x35, 0x88, 0xa0, 0x64, 0xc8, 0x2c, 0x25, - 0x47, 0x46, 0x55, 0xc1, 0x5c, 0xa5, 0x6a, 0x68, 0x7a, 0xb5, 0xb4, 0xca, 0xb2, 0x28, 0xf0, 0x07, - 0x59, 0x90, 0xd7, 0x51, 0xa7, 0x7d, 0x85, 0x0f, 0xfc, 0xc8, 0xfc, 0xbd, 0x32, 0x81, 0xbf, 0x97, - 0xba, 0x04, 0x80, 0xd9, 0xc4, 0x15, 0x93, 0x1b, 0x2e, 0xb2, 0x7d, 0xc3, 0x91, 0x09, 0x0d, 0x2c, - 0x05, 0xb9, 0x75, 0xee, 0x4f, 0xf8, 0x02, 0xe9, 0x05, 0x20, 0xa1, 0x34, 0x42, 0x61, 0x44, 0x77, - 0xf0, 0x7e, 0xa9, 0x35, 0x9b, 0x81, 0xc5, 0x1d, 0x0e, 0xfb, 0xbf, 0x9c, 0x05, 0x39, 0x03, 0xcf, - 0xc8, 0xb8, 0xc9, 0xd9, 0x9f, 0x0c, 0x27, 0xe3, 0xb8, 0x98, 0x08, 0x19, 0xbf, 0x17, 0xcc, 0xf0, - 0x12, 0xcb, 0x76, 0x3c, 0x62, 0x45, 0x5c, 0xf8, 0x61, 0x18, 0x09, 0xef, 0x43, 0xce, 0xe1, 0xb0, - 0xf8, 0x2b, 0xb7, 0x00, 0xb0, 0x86, 0xb0, 0x5d, 0xdb, 0xdd, 0xb6, 0x3a, 0xf0, 0xbf, 0x29, 0x60, - 0x6a, 0x19, 0x79, 0x75, 0xcf, 0xf4, 0x76, 0xbb, 0x3d, 0xab, 0x96, 0xb6, 0x53, 0x36, 0x9b, 0xdb, - 0x88, 0x75, 0x47, 0xfe, 0x2b, 0x7c, 0x97, 0x22, 0xbb, 0x2d, 0x18, 0xd6, 0x33, 0x1f, 0xd4, 0x11, - 0x81, 0xc9, 0x63, 0x41, 0xae, 0x65, 0x7a, 0x26, 0xc3, 0xe2, 0x9a, 0x1e, 0x2c, 0xc2, 0x82, 0x74, - 0x92, 0x0d, 0xfe, 0x76, 0x56, 0x66, 0x5f, 0x50, 0xa2, 0xfe, 0x64, 0x20, 0xbc, 0x2f, 0x33, 0x04, - 0x0a, 0xc7, 0xc0, 0x6c, 0xb5, 0x66, 0x34, 0x56, 0x6b, 0xcb, 0xcb, 0x1a, 0x4e, 0x2d, 0x2a, 0xea, - 0x49, 0xa0, 0xae, 0x97, 0x1e, 0x58, 0xd3, 0xaa, 0x46, 0xa3, 0x5a, 0x5b, 0xd4, 0xd8, 0x9f, 0x39, - 0xf5, 0x28, 0x98, 0x2e, 0x97, 0xca, 0x2b, 0x7e, 0x42, 0x5e, 0x3d, 0x05, 0x8e, 0xaf, 0x69, 0x6b, - 0x0b, 0x9a, 0x5e, 0x5f, 0xa9, 0xac, 0x37, 0x70, 0x31, 0x4b, 0xb5, 0x8d, 0xea, 0x62, 0xb1, 0xa0, - 0x42, 0x70, 0x92, 0xfb, 0x72, 0x5e, 0xaf, 0x55, 0x97, 0x1b, 0x75, 0xa3, 0x64, 0x68, 0xc5, 0x09, - 0xf5, 0x2a, 0x70, 0xb4, 0x5c, 0xaa, 0x92, 0xec, 0xe5, 0x5a, 0xb5, 0xaa, 0x95, 0x8d, 0xe2, 0x24, - 0xfc, 0x97, 0x1c, 0x98, 0xae, 0x74, 0xab, 0xe6, 0x0e, 0x3a, 0x67, 0xb6, 0xad, 0x16, 0xfc, 0x05, - 0xce, 0x9a, 0xbc, 0x11, 0xcc, 0xba, 0xf4, 0x11, 0xb5, 0x0c, 0x0b, 0x51, 0x34, 0x67, 0x75, 0x31, - 0x51, 0x3d, 0x09, 0x0a, 0x36, 0x29, 0x80, 0xb1, 0x86, 0xbd, 0xa9, 0x0b, 0x00, 0xd0, 0x27, 0x23, - 0xbc, 0x6b, 0xed, 0x6c, 0xaf, 0x36, 0x99, 0x3b, 0xa8, 0x8b, 0xdc, 0x3d, 0xab, 0x89, 0xfc, 0x9c, - 0x3a, 0xf7, 0x17, 0xfc, 0x8a, 0x22, 0xbb, 0x4c, 0xc8, 0x81, 0xca, 0x35, 0x27, 0xa2, 0x37, 0xfc, - 0x79, 0x45, 0x66, 0x91, 0x4f, 0xaa, 0xc8, 0x64, 0x92, 0xf2, 0xa2, 0xec, 0x10, 0x92, 0x32, 0x0b, - 0xa6, 0x8c, 0x5a, 0xad, 0x51, 0x5f, 0xa9, 0xe9, 0x46, 0x51, 0x51, 0x67, 0xc0, 0x24, 0x7e, 0x5d, - 0xad, 0x55, 0x97, 0x8b, 0x39, 0xf5, 0x04, 0x38, 0xb6, 0x52, 0xaa, 0x37, 0x2a, 0xd5, 0x73, 0xa5, - 0xd5, 0xca, 0x62, 0xa3, 0xbc, 0x52, 0xd2, 0xeb, 0xc5, 0xbc, 0x7a, 0x0d, 0x38, 0x61, 0x54, 0x34, - 0xbd, 0xb1, 0xa4, 0x95, 0x8c, 0x0d, 0x5d, 0xab, 0x37, 0xaa, 0xb5, 0x46, 0xb5, 0xb4, 0xa6, 0x15, - 0x0b, 0x58, 0xfd, 0xc9, 0xa7, 0x50, 0x6c, 0x26, 0xf6, 0x0b, 0xe3, 0x64, 0x84, 0x30, 0x4e, 0xf5, - 0x0a, 0x23, 0xe0, 0xc5, 0x4a, 0xd7, 0xea, 0x9a, 0x7e, 0x4e, 0x2b, 0x4e, 0xf7, 0x93, 0xb5, 0x19, - 0xf5, 0x38, 0x28, 0x62, 0x1a, 0x1a, 0x95, 0xba, 0x9f, 0x73, 0xb1, 0x38, 0x0b, 0x3f, 0x56, 0x00, - 0x27, 0x75, 0xb4, 0x65, 0x75, 0x3d, 0xe4, 0xae, 0x9b, 0x57, 0x76, 0x90, 0xed, 0xf9, 0x9d, 0xfc, - 0x3f, 0x26, 0x16, 0xc6, 0x35, 0x30, 0xdb, 0xa1, 0x65, 0xac, 0x21, 0x6f, 0xdb, 0x69, 0xb1, 0x51, - 0xf8, 0xd1, 0x91, 0x3d, 0xc7, 0xfc, 0x3a, 0x9f, 0x5d, 0x17, 0xff, 0xe6, 0x64, 0x5b, 0x89, 0x91, - 0xed, 0xdc, 0x30, 0xb2, 0xad, 0x5e, 0x07, 0xa6, 0x76, 0xbb, 0xc8, 0xd5, 0x76, 0x4c, 0xab, 0xed, - 0xdf, 0x95, 0x15, 0x24, 0xc0, 0xb7, 0xe7, 0x64, 0x1d, 0x4f, 0xb9, 0xb6, 0xf4, 0x67, 0x63, 0x44, - 0xdf, 0x7a, 0x1a, 0x00, 0xd6, 0xd8, 0x0d, 0xb7, 0xcd, 0x84, 0x95, 0x4b, 0xc1, 0xf4, 0x5d, 0xb0, - 0xda, 0x6d, 0xcb, 0xde, 0x0a, 0x96, 0xef, 0xc3, 0x04, 0xf8, 0x22, 0x45, 0xc6, 0x11, 0x35, 0x29, - 0x6d, 0xc9, 0xb4, 0xe9, 0x05, 0xd9, 0x31, 0xf7, 0xbb, 0xfb, 0x55, 0xa7, 0xa0, 0x16, 0xc1, 0x0c, - 0x49, 0x63, 0x1a, 0x58, 0x9c, 0xc0, 0x7d, 0xb0, 0x5f, 0xdc, 0x9a, 0x66, 0xac, 0xd4, 0x16, 0x83, - 0x6f, 0x93, 0xb8, 0x48, 0x4c, 0x4c, 0xa9, 0xfa, 0x00, 0xd1, 0xc6, 0x29, 0xf5, 0x11, 0xe0, 0x1a, - 0xae, 0xc3, 0x2e, 0xad, 0xea, 0x5a, 0x69, 0xf1, 0x81, 0x86, 0xf6, 0x8c, 0x4a, 0xdd, 0xa8, 0x8b, - 0xca, 0xe5, 0xeb, 0xd1, 0x34, 0xa6, 0x57, 0x5b, 0x2b, 0x55, 0x56, 0x59, 0xff, 0xbe, 0x54, 0xd3, - 0xd7, 0x4a, 0x46, 0x71, 0x06, 0xbe, 0x5c, 0x01, 0xc5, 0x65, 0xe4, 0xad, 0x3b, 0xae, 0x67, 0xb6, - 0x57, 0x2d, 0xfb, 0xe2, 0x86, 0xdb, 0xe6, 0x6d, 0xa6, 0x7f, 0x96, 0x3e, 0x6d, 0x2b, 0x0e, 0x91, - 0x42, 0x81, 0xd1, 0x0b, 0xdb, 0x1d, 0x92, 0x2d, 0x14, 0xa6, 0x30, 0x01, 0xfe, 0x6c, 0x56, 0xe6, - 0x74, 0xad, 0x7c, 0xad, 0xc9, 0xe4, 0xe4, 0xd9, 0xe3, 0x1e, 0x9f, 0xfb, 0xa0, 0x56, 0x80, 0x0f, - 0xe5, 0xc0, 0xe4, 0x92, 0x65, 0x9b, 0x6d, 0xeb, 0x99, 0x42, 0x18, 0xb2, 0xb0, 0x8f, 0xc9, 0xc4, - 0xf4, 0x31, 0xd9, 0xa1, 0xc6, 0xcf, 0x5f, 0x51, 0x64, 0xb7, 0x30, 0x38, 0xde, 0xfb, 0x44, 0x46, - 0x0c, 0x9e, 0x7f, 0x90, 0x95, 0xd9, 0xa4, 0x18, 0x5c, 0x5e, 0x32, 0x0c, 0x3f, 0xf1, 0xa3, 0x61, - 0x63, 0xf5, 0xe8, 0xf7, 0x64, 0x3f, 0x51, 0x98, 0x82, 0x7f, 0xa1, 0x00, 0xb8, 0x8c, 0xbc, 0x73, - 0xc8, 0x0d, 0xa6, 0x02, 0xa4, 0xd7, 0x67, 0xf6, 0x36, 0xa7, 0xb2, 0x6f, 0xe6, 0x01, 0x3c, 0x2f, - 0x02, 0x58, 0x8a, 0x51, 0x9e, 0x88, 0xa2, 0x23, 0x94, 0xb7, 0x02, 0x0a, 0x5d, 0xf2, 0x9d, 0x89, - 0xd9, 0xe3, 0xa3, 0x87, 0x4b, 0x52, 0x18, 0x5f, 0x3a, 0x2d, 0x58, 0x67, 0x05, 0xc0, 0xef, 0x07, - 0x93, 0xa0, 0x9f, 0x10, 0xa4, 0x63, 0xe9, 0xc0, 0xc4, 0x26, 0x93, 0x17, 0x37, 0x5d, 0x71, 0xe9, - 0x67, 0xdf, 0xc0, 0x2f, 0xe4, 0xc0, 0xf1, 0x7e, 0xcd, 0xe1, 0x6f, 0x2b, 0x3b, 0x0e, 0xf2, 0x88, - 0x8c, 0xf8, 0x54, 0xd9, 0xe9, 0x8b, 0xfa, 0x04, 0x70, 0x82, 0x6d, 0xa1, 0x5e, 0x40, 0x86, 0x53, - 0x45, 0x97, 0xba, 0x6d, 0xe4, 0x79, 0xc8, 0x25, 0x2d, 0x9b, 0xd4, 0xfb, 0x7f, 0x84, 0x7f, 0xa7, - 0xc8, 0x3a, 0xab, 0x0f, 0xe0, 0x77, 0x84, 0xa6, 0x3f, 0x5f, 0x91, 0x71, 0x3f, 0x4f, 0x56, 0x76, - 0x32, 0x14, 0x9f, 0x37, 0xee, 0x11, 0xbe, 0xff, 0xd0, 0x4a, 0x74, 0x9e, 0xa6, 0xfb, 0x23, 0xf4, - 0x39, 0x4d, 0xaf, 0x2c, 0x55, 0x34, 0x3c, 0xde, 0x9f, 0x00, 0xc7, 0xc2, 0x6f, 0x8b, 0x0f, 0x34, - 0xea, 0x5a, 0xd5, 0x28, 0x4e, 0xe2, 0x0e, 0x84, 0x26, 0x2f, 0x95, 0x2a, 0xab, 0xda, 0x62, 0xc3, - 0xa8, 0xe1, 0x2f, 0x8b, 0xc3, 0x8d, 0xf9, 0xf0, 0x39, 0x39, 0x70, 0x94, 0xf0, 0xf6, 0x0a, 0xe1, - 0x2a, 0x66, 0x4a, 0x8f, 0x2f, 0x4b, 0x00, 0xd0, 0x14, 0x65, 0x2f, 0xfc, 0xb4, 0xf4, 0x4d, 0x54, - 0x1c, 0x84, 0x3d, 0x75, 0x44, 0x48, 0xc6, 0xf7, 0xb2, 0x32, 0x27, 0x40, 0xa5, 0x8b, 0x4d, 0x26, - 0x14, 0xff, 0x34, 0xee, 0xa1, 0x20, 0x1a, 0x7c, 0x62, 0xfe, 0x95, 0xc9, 0xcf, 0xcf, 0x58, 0xaf, - 0xe8, 0x44, 0x1c, 0xe6, 0x00, 0x20, 0x29, 0x44, 0x82, 0xa8, 0x1c, 0xf4, 0x1d, 0x48, 0xa2, 0xe4, - 0xa0, 0x54, 0x36, 0x2a, 0xe7, 0xb4, 0x28, 0x39, 0xf8, 0x94, 0x02, 0x26, 0x97, 0x91, 0x87, 0x27, - 0x3b, 0x5d, 0xf8, 0x14, 0x89, 0x85, 0x19, 0x6c, 0x5f, 0x90, 0x2b, 0x78, 0x83, 0xf9, 0x39, 0x7d, - 0x83, 0xcf, 0x1d, 0xc6, 0x36, 0xf0, 0xab, 0x8e, 0x18, 0x48, 0x9e, 0x04, 0xf2, 0x1e, 0xfe, 0xcc, - 0xd6, 0x87, 0x1f, 0x19, 0x39, 0x8e, 0xe0, 0x42, 0x16, 0x4d, 0xcf, 0xd4, 0x69, 0x7e, 0x6e, 0xd8, - 0x90, 0x34, 0x2a, 0x22, 0x08, 0xf9, 0x51, 0x34, 0x0c, 0xbf, 0xae, 0x80, 0x13, 0x54, 0x3f, 0x4a, - 0x9d, 0x4e, 0xdd, 0x73, 0x5c, 0xa4, 0xa3, 0x26, 0xb2, 0x3a, 0x5e, 0xcf, 0xc2, 0x9b, 0x4b, 0x53, - 0xfd, 0x9d, 0x3d, 0xf6, 0x0a, 0xdf, 0xa8, 0xc8, 0xc6, 0x38, 0xdc, 0xa7, 0x8f, 0x3d, 0xf5, 0x45, - 0x28, 0xfb, 0x47, 0xb2, 0x32, 0x51, 0x0b, 0x13, 0x16, 0x9e, 0x0c, 0xa8, 0x0f, 0x1e, 0x02, 0x50, - 0xfe, 0x92, 0x8a, 0xae, 0x95, 0xb5, 0xca, 0x3a, 0x1e, 0x04, 0xae, 0x07, 0xd7, 0xae, 0x6f, 0xe8, - 0xe5, 0x95, 0x52, 0x5d, 0x6b, 0xe8, 0xda, 0x72, 0xa5, 0x6e, 0xe8, 0x25, 0xa3, 0x52, 0xf3, 0x09, - 0x98, 0x50, 0xaf, 0x03, 0xa7, 0xea, 0x1b, 0x0b, 0xf5, 0xb2, 0x5e, 0x59, 0x27, 0xe9, 0xba, 0x56, - 0xd5, 0xce, 0xb3, 0xaf, 0x93, 0xf0, 0x03, 0x45, 0x30, 0x8d, 0x2d, 0xf3, 0x3a, 0x35, 0xd8, 0xe1, - 0xb7, 0x72, 0x60, 0x5a, 0x47, 0x5d, 0xa7, 0xbd, 0x47, 0x8c, 0xf7, 0x71, 0xcd, 0x09, 0xbe, 0xab, - 0xc8, 0x9e, 0x8f, 0xe2, 0x88, 0x9d, 0xe7, 0x08, 0x8d, 0x9e, 0x01, 0x9a, 0x7b, 0xa6, 0xd5, 0x36, - 0x2f, 0xb0, 0xae, 0x66, 0x52, 0x0f, 0x13, 0xd4, 0x79, 0xa0, 0x3a, 0x97, 0x6c, 0xe4, 0xd6, 0x9b, - 0x97, 0x34, 0x6f, 0xbb, 0xd4, 0x6a, 0xb9, 0xa8, 0xdb, 0x65, 0xcb, 0x0a, 0x7d, 0xbe, 0xa8, 0x37, - 0x83, 0xa3, 0x24, 0x95, 0xcb, 0x4c, 0x0f, 0x73, 0xf6, 0x26, 0x07, 0x39, 0x4b, 0xf6, 0x15, 0x3f, - 0x67, 0x9e, 0xcb, 0x19, 0x26, 0xf3, 0xee, 0x88, 0x05, 0xd1, 0x0b, 0xf6, 0x0c, 0x98, 0xb6, 0xcd, - 0x1d, 0xa4, 0x5d, 0xee, 0x58, 0x2e, 0xea, 0x9e, 0x9a, 0x20, 0xbb, 0x69, 0x7c, 0x12, 0xfc, 0x03, - 0xa9, 0xf3, 0x5c, 0x72, 0x1c, 0x4b, 0x26, 0xfb, 0xcb, 0x43, 0x88, 0x7e, 0x9f, 0x7e, 0x46, 0x81, - 0x1f, 0x50, 0xc0, 0x0c, 0x23, 0xaa, 0x64, 0x5f, 0xa9, 0xb4, 0xe0, 0xf5, 0x82, 0x59, 0x6a, 0xe2, - 0x34, 0xdf, 0x2c, 0x25, 0x2f, 0xf0, 0x17, 0x15, 0x59, 0x77, 0xa2, 0x3e, 0x0d, 0x27, 0x75, 0x44, - 0xbb, 0xb8, 0x6c, 0x3a, 0xbb, 0xcc, 0xa5, 0x66, 0x52, 0xa7, 0x2f, 0x69, 0xae, 0xb6, 0xc1, 0x3f, - 0x94, 0x72, 0x56, 0x92, 0x6c, 0xc6, 0x21, 0x01, 0xf8, 0x71, 0x05, 0xcc, 0x31, 0xaa, 0xea, 0xcc, - 0x8f, 0x56, 0xca, 0xa1, 0xfc, 0x97, 0xa4, 0x0d, 0xc1, 0x3e, 0xed, 0x67, 0x35, 0x3d, 0x6c, 0x80, - 0xfc, 0x90, 0x54, 0xf0, 0x11, 0xe9, 0x86, 0x1c, 0x12, 0x94, 0xef, 0xc8, 0x81, 0xe9, 0x8d, 0x2e, - 0x72, 0x99, 0x5f, 0x1c, 0x7c, 0x6d, 0x0e, 0x28, 0xcb, 0x48, 0xd8, 0xe1, 0x7c, 0x61, 0x4e, 0x76, - 0xb5, 0x8e, 0x6f, 0x2c, 0x57, 0x28, 0xb6, 0x91, 0x22, 0x60, 0xbb, 0x09, 0xcc, 0x51, 0x96, 0x96, - 0x3c, 0x0f, 0x1b, 0x89, 0xfe, 0xb1, 0x80, 0x9e, 0xd4, 0x51, 0xec, 0xe1, 0x90, 0xba, 0x70, 0x96, - 0x32, 0xa6, 0x69, 0x15, 0x6d, 0xd2, 0xd0, 0x54, 0x39, 0xbd, 0x27, 0x95, 0x5c, 0x0f, 0xdc, 0x41, - 0xd4, 0x3f, 0x94, 0xcb, 0x9c, 0x27, 0x99, 0xfb, 0x7d, 0x82, 0xdf, 0x92, 0x8a, 0xd9, 0x27, 0xcf, - 0x9d, 0x64, 0xb2, 0xd0, 0x19, 0x8d, 0x49, 0x72, 0x1c, 0x14, 0x71, 0x0e, 0xb2, 0x31, 0xa2, 0x6b, - 0xf5, 0xda, 0xea, 0x39, 0xad, 0xff, 0xfa, 0x42, 0x1e, 0x3e, 0x4f, 0x01, 0x53, 0x0b, 0xae, 0x63, - 0xb6, 0x9a, 0x66, 0xd7, 0x83, 0xdf, 0xcf, 0x82, 0x99, 0x75, 0xf3, 0x4a, 0xdb, 0x31, 0x5b, 0xc4, - 0x13, 0xb1, 0xa7, 0x2f, 0xe8, 0xd0, 0x4f, 0x7e, 0x5f, 0xc0, 0x5e, 0x45, 0xc7, 0xfb, 0xc0, 0x35, - 0x3e, 0x23, 0x73, 0x61, 0x55, 0xb0, 0xff, 0x96, 0xed, 0x17, 0x0c, 0xcc, 0xa7, 0x6b, 0x9e, 0xa7, - 0x29, 0xc2, 0xa2, 0xfc, 0x80, 0x5c, 0x78, 0x2f, 0x99, 0x22, 0x0f, 0x67, 0xbb, 0xfc, 0xa1, 0x49, - 0x50, 0x58, 0x44, 0xc4, 0x8a, 0xfb, 0xaf, 0xdc, 0xad, 0xf4, 0x77, 0x0a, 0x4e, 0x8e, 0x2d, 0x92, - 0x21, 0xe8, 0x8e, 0x83, 0xf7, 0xe0, 0xe6, 0xf9, 0x2c, 0x77, 0xf3, 0xbc, 0xbc, 0xfb, 0x17, 0xad, - 0x77, 0xc0, 0xad, 0xf3, 0x72, 0xee, 0x5f, 0xb1, 0x45, 0xa5, 0xef, 0x04, 0xf5, 0xae, 0x2c, 0xf3, - 0x79, 0xe2, 0x7a, 0xbd, 0x57, 0xf3, 0xf2, 0x19, 0xeb, 0x06, 0xc6, 0x88, 0x8f, 0xf1, 0x5a, 0xba, - 0x03, 0x4c, 0x50, 0x9e, 0xfb, 0xf3, 0xd1, 0x5e, 0x07, 0x02, 0x5a, 0x04, 0x39, 0xdb, 0xe4, 0xe7, - 0x94, 0xf4, 0x1d, 0x8b, 0xae, 0x7c, 0x2c, 0x67, 0xfc, 0x66, 0xaa, 0xc8, 0xbb, 0xe4, 0xb8, 0x17, - 0xeb, 0x9e, 0xe9, 0x21, 0xf8, 0x4f, 0x59, 0xa0, 0xd4, 0x91, 0xc7, 0x9f, 0x2e, 0xae, 0x82, 0x63, - 0xb4, 0x41, 0x2c, 0x23, 0xe9, 0xbf, 0x69, 0x43, 0xce, 0xf4, 0x65, 0x02, 0x97, 0x4f, 0xdf, 0xff, - 0x2b, 0xfc, 0xd5, 0xbe, 0x41, 0x15, 0xb2, 0x7d, 0x26, 0x0d, 0x8c, 0x33, 0x3c, 0x81, 0x58, 0xc0, - 0x22, 0xe4, 0xf4, 0xf7, 0xa5, 0xcc, 0x6a, 0xb9, 0x32, 0x0f, 0xa7, 0x2b, 0x78, 0xe5, 0x35, 0x20, - 0x57, 0xde, 0x36, 0x3d, 0xf8, 0x4e, 0x05, 0x80, 0x52, 0xab, 0xb5, 0x46, 0x1d, 0x6e, 0x79, 0x4f, - 0xb1, 0xb3, 0x60, 0xa6, 0xb9, 0x6d, 0x86, 0xb1, 0xc3, 0x69, 0x7f, 0x20, 0xa4, 0xa9, 0x4f, 0x08, - 0x3d, 0x77, 0x29, 0x57, 0x61, 0x0f, 0x4c, 0xb8, 0x0e, 0x56, 0x76, 0xe0, 0xd5, 0x2b, 0x86, 0x9a, - 0x8a, 0x3d, 0x2f, 0x8b, 0x7f, 0x9f, 0x0f, 0xc9, 0x8b, 0x9e, 0xc3, 0xb1, 0xa2, 0x83, 0x93, 0x82, - 0x61, 0x42, 0xc2, 0x93, 0x54, 0x72, 0x07, 0x66, 0xe3, 0xe9, 0x1a, 0x4b, 0x68, 0x38, 0x55, 0x6b, - 0x59, 0x3e, 0x6b, 0x59, 0x40, 0x0a, 0xf8, 0x82, 0x4c, 0x32, 0xf8, 0xe2, 0x19, 0x77, 0x1f, 0x98, - 0x45, 0x2d, 0xcb, 0x43, 0x7e, 0x2b, 0x19, 0x03, 0xe3, 0x20, 0x16, 0x7f, 0x80, 0xcf, 0x96, 0x0e, - 0x6a, 0x42, 0x18, 0xba, 0xbf, 0x45, 0x11, 0xfa, 0x27, 0x17, 0xa6, 0x44, 0xae, 0xcc, 0xf4, 0xc1, - 0x7a, 0xae, 0x02, 0x4e, 0x18, 0xce, 0xd6, 0x56, 0x1b, 0xf9, 0x6c, 0x42, 0xd4, 0x6d, 0x12, 0x9a, - 0xa3, 0x84, 0x8b, 0xec, 0xd1, 0x38, 0x0f, 0x5a, 0x6c, 0xf6, 0x42, 0x5f, 0xe0, 0xf3, 0xa5, 0xc3, - 0x2f, 0x12, 0x76, 0xf5, 0xa5, 0x33, 0x02, 0x05, 0xb9, 0x80, 0x8a, 0xd2, 0xc5, 0xa6, 0x0f, 0xc4, - 0xe7, 0xb3, 0x60, 0x96, 0xde, 0x0c, 0xe5, 0x0b, 0xe8, 0xfd, 0x23, 0x04, 0x00, 0x7e, 0x3f, 0x23, - 0xeb, 0x00, 0x4b, 0x78, 0x22, 0x50, 0x12, 0xc1, 0x62, 0xb9, 0x43, 0xcb, 0x03, 0x8b, 0x4b, 0x9f, - 0xb5, 0xff, 0x45, 0x01, 0xd3, 0xcb, 0xc8, 0xd7, 0xb4, 0x2e, 0x7f, 0xcd, 0x86, 0x0c, 0x63, 0x6f, - 0x04, 0xb3, 0x17, 0xd0, 0xa6, 0xe3, 0x22, 0x72, 0x6d, 0x48, 0xc0, 0x5c, 0x31, 0x31, 0x22, 0xb2, - 0x8b, 0x10, 0x42, 0x64, 0x41, 0x64, 0xfb, 0xad, 0xfb, 0xf9, 0xc4, 0x51, 0x19, 0x31, 0x9c, 0x3c, - 0x11, 0x4c, 0x32, 0x50, 0x7d, 0x0b, 0x2c, 0xae, 0xcb, 0x0b, 0xf2, 0xc2, 0xd7, 0x07, 0x60, 0x69, - 0x02, 0x58, 0x8f, 0x4f, 0x42, 0xc4, 0x58, 0xae, 0x46, 0x2d, 0x72, 0xf5, 0x2f, 0x5c, 0xa9, 0xb4, - 0xba, 0x70, 0x2d, 0x19, 0x5e, 0xa7, 0x01, 0x08, 0xe4, 0xde, 0x3f, 0x11, 0xca, 0xa5, 0x88, 0x41, - 0x5f, 0x63, 0x0f, 0x3c, 0xf5, 0xb2, 0x83, 0x90, 0x33, 0x62, 0x60, 0xe4, 0x0e, 0x4a, 0xc9, 0x50, - 0x32, 0x86, 0x00, 0x2f, 0x0a, 0x38, 0x51, 0xf7, 0xf7, 0xcd, 0x57, 0xcd, 0x6e, 0xa8, 0x52, 0xe5, - 0x64, 0x10, 0x09, 0x87, 0x2c, 0x02, 0x65, 0xf9, 0x76, 0xb2, 0xe1, 0xa0, 0x2f, 0x25, 0xa3, 0x45, - 0x47, 0xbd, 0x15, 0x1c, 0xb3, 0x77, 0x77, 0x02, 0xae, 0x13, 0x8d, 0x67, 0x1a, 0xbe, 0xff, 0x43, - 0x92, 0x41, 0x47, 0x86, 0xf8, 0xb1, 0x4c, 0x17, 0xa7, 0x37, 0xec, 0xc0, 0x15, 0x02, 0x3e, 0x36, - 0x11, 0x8c, 0xf0, 0x3b, 0x99, 0x44, 0xbd, 0x1b, 0x57, 0x53, 0xc4, 0x90, 0x92, 0xa0, 0x97, 0x8a, - 0x2e, 0x2c, 0x75, 0xb6, 0x9d, 0x9d, 0x00, 0x79, 0x6d, 0xa7, 0xe3, 0x5d, 0x39, 0xfb, 0x28, 0x30, - 0x5b, 0xf7, 0x5c, 0x64, 0xee, 0x70, 0x8b, 0xfe, 0x9e, 0x73, 0x11, 0xd9, 0xfe, 0xa2, 0x3f, 0x79, - 0xb9, 0xeb, 0x4e, 0x30, 0x61, 0x3b, 0x0d, 0x73, 0xd7, 0xdb, 0x56, 0xaf, 0x9f, 0xdf, 0x72, 0x9c, - 0xad, 0x36, 0x9a, 0xef, 0xb8, 0x8e, 0xe7, 0x5c, 0xd8, 0xdd, 0x9c, 0x67, 0xe0, 0xd7, 0xd8, 0xf1, - 0xff, 0xaf, 0xdc, 0x4d, 0x96, 0x7d, 0x0b, 0xb6, 0x53, 0xda, 0xf5, 0xb6, 0x17, 0xae, 0xfb, 0xf8, - 0xdf, 0x9e, 0xce, 0x7c, 0xea, 0x6f, 0x4f, 0x67, 0xbe, 0xfc, 0xb7, 0xa7, 0x33, 0xbf, 0xf4, 0xd5, - 0xd3, 0x47, 0x3e, 0xf5, 0xd5, 0xd3, 0x47, 0x3e, 0xff, 0xd5, 0xd3, 0x47, 0x7e, 0x22, 0xdb, 0xb9, - 0x70, 0xa1, 0x40, 0x4a, 0xb9, 0xe3, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x86, 0xc5, 0x56, - 0xe2, 0xeb, 0x01, 0x00, + 0x23, 0x31, 0x12, 0x42, 0x16, 0xa2, 0x05, 0x12, 0x06, 0x24, 0x24, 0xa4, 0xea, 0xea, 0xec, 0xee, + 0x42, 0xdd, 0x55, 0x4d, 0x56, 0xf5, 0x0c, 0xb2, 0xd7, 0xb7, 0x36, 0xa7, 0x2a, 0xba, 0x3b, 0x35, + 0xd5, 0x99, 0xe5, 0xcc, 0xec, 0x1e, 0x35, 0xf7, 0xdb, 0xbb, 0xc6, 0x18, 0x10, 0xb6, 0x59, 0x8c, + 0x31, 0x6b, 0x63, 0xcc, 0xfb, 0xb5, 0x60, 0x1e, 0xe6, 0xbd, 0x60, 0x1b, 0xdb, 0x3c, 0x0c, 0xc6, + 0x36, 0xc6, 0x60, 0x0c, 0xc6, 0xe6, 0x1a, 0xcc, 0xc3, 0x78, 0xbf, 0x65, 0xb9, 0xf6, 0x5d, 0x60, + 0xb1, 0xe1, 0xfa, 0x7e, 0xf1, 0xc8, 0xcc, 0x88, 0xea, 0xca, 0xac, 0xc8, 0xea, 0xca, 0x6a, 0x61, + 0xf6, 0xbf, 0xcc, 0xc8, 0xc8, 0x13, 0x27, 0xce, 0xef, 0x44, 0xc4, 0x89, 0x88, 0x13, 0x27, 0xc0, + 0x99, 0xee, 0xc5, 0x5b, 0xbb, 0x8e, 0xed, 0xd9, 0xee, 0xad, 0x2d, 0x7b, 0x67, 0xc7, 0xb0, 0xda, + 0xee, 0x3c, 0x79, 0x57, 0x27, 0x0c, 0x6b, 0xdf, 0xdb, 0xef, 0x22, 0x78, 0x43, 0xf7, 0xd2, 0xd6, + 0xad, 0x1d, 0xf3, 0xe2, 0xad, 0xdd, 0x8b, 0xb7, 0xee, 0xd8, 0x6d, 0xd4, 0xf1, 0x7f, 0x20, 0x2f, + 0x2c, 0x3b, 0xbc, 0x29, 0x2a, 0x57, 0xc7, 0x6e, 0x19, 0x1d, 0xd7, 0xb3, 0x1d, 0xc4, 0x72, 0x9e, + 0x0e, 0x8b, 0x44, 0x7b, 0xc8, 0xf2, 0x7c, 0x0a, 0xd7, 0x6c, 0xd9, 0xf6, 0x56, 0x07, 0xd1, 0x6f, + 0x17, 0x77, 0x37, 0x6f, 0x75, 0x3d, 0x67, 0xb7, 0xe5, 0xb1, 0xaf, 0xd7, 0xf5, 0x7e, 0x6d, 0x23, + 0xb7, 0xe5, 0x98, 0x5d, 0xcf, 0x76, 0x68, 0x8e, 0x73, 0x7f, 0xfb, 0xb5, 0x09, 0xa0, 0xe8, 0xdd, + 0x16, 0xfc, 0xce, 0x04, 0x50, 0x4a, 0xdd, 0x2e, 0xfc, 0x68, 0x16, 0x80, 0x65, 0xe4, 0x9d, 0x47, + 0x8e, 0x6b, 0xda, 0x16, 0x3c, 0x0e, 0x26, 0x74, 0xf4, 0xd3, 0xbb, 0xc8, 0xf5, 0xee, 0xcc, 0x3d, + 0xf4, 0x75, 0x25, 0x03, 0x5f, 0x9f, 0x05, 0x93, 0x3a, 0x72, 0xbb, 0xb6, 0xe5, 0x22, 0xf5, 0x5e, + 0x90, 0x47, 0x8e, 0x63, 0x3b, 0x67, 0x32, 0xd7, 0x65, 0x6e, 0x9a, 0xbe, 0xed, 0xe6, 0x79, 0x56, + 0xfd, 0x79, 0xbd, 0xdb, 0x9a, 0x2f, 0x75, 0xbb, 0xf3, 0x21, 0xa5, 0x79, 0xff, 0xa7, 0x79, 0x0d, + 0xff, 0xa1, 0xd3, 0x1f, 0xd5, 0x33, 0x60, 0x62, 0x8f, 0x66, 0x38, 0x93, 0xbd, 0x2e, 0x73, 0xd3, + 0x94, 0xee, 0xbf, 0xe2, 0x2f, 0x6d, 0xe4, 0x19, 0x66, 0xc7, 0x3d, 0xa3, 0xd0, 0x2f, 0xec, 0x15, + 0xbe, 0x26, 0x03, 0xf2, 0x84, 0x88, 0x5a, 0x06, 0xb9, 0x96, 0xdd, 0x46, 0xa4, 0xf8, 0xb9, 0xdb, + 0x6e, 0x95, 0x2f, 0x7e, 0xbe, 0x6c, 0xb7, 0x91, 0x4e, 0x7e, 0x56, 0xaf, 0x03, 0xd3, 0xbe, 0x58, + 0x42, 0x36, 0xf8, 0xa4, 0x73, 0xb7, 0x81, 0x1c, 0xce, 0xaf, 0x4e, 0x82, 0x5c, 0x75, 0x63, 0x75, + 0xb5, 0x78, 0x4c, 0x3d, 0x01, 0x66, 0x37, 0xaa, 0xf7, 0x55, 0x6b, 0x17, 0xaa, 0x4d, 0x4d, 0xd7, + 0x6b, 0x7a, 0x31, 0xa3, 0xce, 0x82, 0xa9, 0x85, 0xd2, 0x62, 0xb3, 0x52, 0x5d, 0xdf, 0x68, 0x14, + 0xb3, 0xf0, 0x15, 0x0a, 0x98, 0xab, 0x23, 0x6f, 0x11, 0xed, 0x99, 0x2d, 0x54, 0xf7, 0x0c, 0x0f, + 0xc1, 0x17, 0x66, 0x02, 0x61, 0xaa, 0x1b, 0xb8, 0xd0, 0xe0, 0x13, 0xab, 0xc0, 0xed, 0x07, 0x2a, + 0x20, 0x52, 0x98, 0x67, 0x7f, 0xcf, 0x73, 0x69, 0x3a, 0x4f, 0xe7, 0xdc, 0x63, 0xc1, 0x34, 0xf7, + 0x4d, 0x9d, 0x03, 0x60, 0xa1, 0x54, 0xbe, 0x6f, 0x59, 0xaf, 0x6d, 0x54, 0x17, 0x8b, 0xc7, 0xf0, + 0xfb, 0x52, 0x4d, 0xd7, 0xd8, 0x7b, 0x06, 0x7e, 0x2f, 0xc3, 0x81, 0xb9, 0x28, 0x82, 0x39, 0x3f, + 0x98, 0x99, 0x3e, 0x80, 0xc2, 0x37, 0x04, 0xe0, 0x2c, 0x0b, 0xe0, 0xdc, 0x9e, 0x8c, 0x5c, 0xfa, + 0x00, 0x3d, 0x27, 0x0b, 0x26, 0xeb, 0xdb, 0xbb, 0x5e, 0xdb, 0xbe, 0x6c, 0xc1, 0xa9, 0x00, 0x19, + 0xf8, 0x4d, 0x5e, 0x26, 0x4f, 0x15, 0x65, 0x72, 0xd3, 0xc1, 0x4a, 0x30, 0x0a, 0x11, 0xd2, 0x78, + 0x55, 0x20, 0x8d, 0x92, 0x20, 0x8d, 0xc7, 0xca, 0x12, 0x4a, 0x5f, 0x0e, 0xbf, 0x74, 0x3b, 0xc8, + 0xd7, 0xbb, 0x46, 0x0b, 0xc1, 0x3f, 0x51, 0xc0, 0xcc, 0x2a, 0x32, 0xf6, 0x50, 0xa9, 0xdb, 0x75, + 0xec, 0x3d, 0x04, 0xcb, 0xa1, 0xbe, 0x9e, 0x01, 0x13, 0x2e, 0xce, 0x54, 0x69, 0x93, 0x1a, 0x4c, + 0xe9, 0xfe, 0xab, 0x7a, 0x16, 0x00, 0xb3, 0x8d, 0x2c, 0xcf, 0xf4, 0x4c, 0xe4, 0x9e, 0xc9, 0x5e, + 0xa7, 0xdc, 0x34, 0xa5, 0x73, 0x29, 0xf0, 0x3b, 0x59, 0x59, 0x1d, 0x23, 0x5c, 0xcc, 0xf3, 0x1c, + 0x44, 0x48, 0xf5, 0xb5, 0x59, 0x19, 0x1d, 0x1b, 0x48, 0x2e, 0x99, 0x6c, 0xdf, 0x96, 0x49, 0x2e, + 0x5c, 0x9c, 0xa3, 0x5a, 0x6b, 0xd6, 0x37, 0xca, 0x2b, 0xcd, 0xfa, 0x7a, 0xa9, 0xac, 0x15, 0x91, + 0x7a, 0x12, 0x14, 0xc9, 0x63, 0xb3, 0x52, 0x6f, 0x2e, 0x6a, 0xab, 0x5a, 0x43, 0x5b, 0x2c, 0x6e, + 0xaa, 0x2a, 0x98, 0xd3, 0xb5, 0xa7, 0x6f, 0x68, 0xf5, 0x46, 0x73, 0xa9, 0x54, 0x59, 0xd5, 0x16, + 0x8b, 0x5b, 0xf8, 0xe7, 0xd5, 0xca, 0x5a, 0xa5, 0xd1, 0xd4, 0xb5, 0x52, 0x79, 0x45, 0x5b, 0x2c, + 0x6e, 0xab, 0x57, 0x82, 0x2b, 0xaa, 0xb5, 0x66, 0x69, 0x7d, 0x5d, 0xaf, 0x9d, 0xd7, 0x9a, 0xec, + 0x8f, 0x7a, 0xd1, 0xa4, 0x05, 0x35, 0x9a, 0xf5, 0x95, 0x92, 0xae, 0x95, 0x16, 0x56, 0xb5, 0xe2, + 0x03, 0xf0, 0xd9, 0x0a, 0x98, 0x5d, 0x33, 0x2e, 0xa1, 0xfa, 0xb6, 0xe1, 0x20, 0xe3, 0x62, 0x07, + 0xc1, 0xeb, 0x25, 0xf0, 0x84, 0x7f, 0xc2, 0xe3, 0xa5, 0x89, 0x78, 0xdd, 0xda, 0x47, 0xc0, 0x42, + 0x11, 0x11, 0x80, 0xfd, 0xaf, 0xa0, 0x19, 0xac, 0x08, 0x80, 0x3d, 0x21, 0x21, 0xbd, 0x64, 0x88, + 0xfd, 0xec, 0xc3, 0x00, 0x31, 0xf8, 0x45, 0x05, 0xcc, 0x55, 0xac, 0x3d, 0xd3, 0x43, 0xcb, 0xc8, + 0x42, 0x0e, 0x1e, 0x07, 0xa4, 0x60, 0x78, 0xbd, 0xc2, 0xc1, 0xb0, 0x24, 0xc2, 0xf0, 0xb8, 0x3e, + 0x62, 0x13, 0xcb, 0x88, 0x18, 0x6d, 0xaf, 0x01, 0x53, 0x26, 0xc9, 0x57, 0x36, 0xdb, 0x4c, 0x62, + 0x61, 0x82, 0x7a, 0x03, 0x98, 0xa5, 0x2f, 0x4b, 0x66, 0x07, 0xdd, 0x87, 0xf6, 0xd9, 0xb8, 0x2b, + 0x26, 0xc2, 0x5f, 0x0c, 0x1a, 0x5f, 0x45, 0xc0, 0xf2, 0xc7, 0x93, 0x32, 0x95, 0x0c, 0xcc, 0x97, + 0x3c, 0x1c, 0x9a, 0xdf, 0x81, 0x56, 0x66, 0xc2, 0x1f, 0x64, 0xc1, 0x74, 0xdd, 0xb3, 0xbb, 0x58, + 0x65, 0x4d, 0x6b, 0x4b, 0x0e, 0xdc, 0x8f, 0xf3, 0x6d, 0xac, 0x2c, 0x82, 0xfb, 0xd8, 0x3e, 0x72, + 0xe4, 0x0a, 0x88, 0x68, 0x61, 0xdf, 0x09, 0x5a, 0xd8, 0x92, 0x80, 0xca, 0x6d, 0x89, 0xa8, 0xfd, + 0x10, 0xb6, 0xaf, 0x97, 0x28, 0xa0, 0xe8, 0xab, 0x99, 0x57, 0xde, 0x75, 0x1c, 0x64, 0x79, 0x72, + 0x20, 0xfc, 0x35, 0x0f, 0xc2, 0x8a, 0x08, 0xc2, 0x6d, 0x31, 0xca, 0xec, 0x97, 0x92, 0x62, 0x1b, + 0xfb, 0xfd, 0x00, 0xcd, 0xfb, 0x04, 0x34, 0x9f, 0x94, 0x9c, 0xad, 0x64, 0x90, 0xae, 0x0c, 0x81, + 0xe8, 0x49, 0x50, 0xc4, 0x63, 0x52, 0xb9, 0x51, 0x39, 0xaf, 0x35, 0x2b, 0xd5, 0xf3, 0x95, 0x86, + 0x56, 0x44, 0xf0, 0xc5, 0x0a, 0x98, 0xa1, 0xac, 0xe9, 0x68, 0xcf, 0xbe, 0x24, 0xd9, 0xeb, 0x7d, + 0x31, 0xa1, 0xb1, 0xc0, 0x97, 0x10, 0xd1, 0x32, 0x7e, 0x3e, 0x81, 0xb1, 0x10, 0x43, 0xee, 0xe1, + 0xd4, 0x5b, 0x1d, 0x68, 0x06, 0x5b, 0x7d, 0x5a, 0x4b, 0xdf, 0xde, 0xea, 0x25, 0x39, 0x00, 0x68, + 0x25, 0xcf, 0x9b, 0xe8, 0x32, 0x5c, 0x0b, 0x31, 0x11, 0xd4, 0x36, 0x33, 0x50, 0x6d, 0xb3, 0xfd, + 0xd4, 0xf6, 0x7d, 0xfc, 0x98, 0xb5, 0x20, 0xa2, 0x77, 0x4b, 0xa4, 0xb8, 0x31, 0x27, 0xd1, 0xb3, + 0x43, 0x5f, 0x51, 0xb2, 0xa2, 0xd5, 0x79, 0x0d, 0x98, 0x22, 0x8f, 0x55, 0x63, 0x07, 0xb1, 0x36, + 0x14, 0x26, 0xa8, 0xe7, 0xc0, 0x0c, 0xcd, 0xd8, 0xb2, 0x2d, 0x5c, 0x9f, 0x1c, 0xc9, 0x20, 0xa4, + 0x61, 0x10, 0x5b, 0x0e, 0x32, 0x3c, 0xdb, 0x21, 0x34, 0xf2, 0x14, 0x44, 0x2e, 0x09, 0x7e, 0x23, + 0x68, 0x85, 0x9a, 0xa0, 0x39, 0x8f, 0x4f, 0x52, 0x95, 0x64, 0x7a, 0xb3, 0x37, 0x5c, 0xfb, 0xa3, + 0xad, 0xae, 0x89, 0xd1, 0x5e, 0x22, 0x53, 0x3b, 0xa4, 0x9e, 0x06, 0x2a, 0x4b, 0xc5, 0x79, 0xcb, + 0xb5, 0x6a, 0x43, 0xab, 0x36, 0x8a, 0x9b, 0x7d, 0x35, 0x6a, 0x0b, 0xbe, 0x36, 0x07, 0x72, 0x4f, + 0xb3, 0x4d, 0x0b, 0x3e, 0x27, 0x23, 0xa8, 0x84, 0x85, 0xbc, 0xcb, 0xb6, 0x73, 0x29, 0x68, 0xa8, + 0x61, 0x42, 0x3c, 0x36, 0xa1, 0x2a, 0x29, 0x03, 0x55, 0x29, 0xd7, 0x4f, 0x95, 0x7e, 0x99, 0x57, + 0xa5, 0xbb, 0x44, 0x55, 0xba, 0xb1, 0x8f, 0xfc, 0x31, 0xf3, 0x11, 0x1d, 0xc0, 0xc7, 0x82, 0x0e, + 0xe0, 0x1e, 0x01, 0xc6, 0xc7, 0xc8, 0x91, 0x49, 0x06, 0xe0, 0x17, 0x52, 0x6d, 0xf8, 0xfd, 0xa0, + 0xde, 0x8a, 0x80, 0x7a, 0xbb, 0x4f, 0x9f, 0x60, 0x1e, 0xec, 0x3a, 0x1e, 0x38, 0xd8, 0x4d, 0x5c, + 0x52, 0x4f, 0x81, 0x13, 0x8b, 0x95, 0xa5, 0x25, 0x4d, 0xd7, 0xaa, 0x8d, 0x66, 0x55, 0x6b, 0x5c, + 0xa8, 0xe9, 0xf7, 0x15, 0x3b, 0xf0, 0x35, 0x0a, 0x00, 0x58, 0x42, 0x65, 0xc3, 0x6a, 0xa1, 0x8e, + 0x5c, 0x8f, 0xfe, 0x3f, 0xb2, 0xc9, 0xfa, 0x84, 0x90, 0x7e, 0x04, 0x9c, 0x2f, 0xcf, 0xca, 0xb7, + 0xca, 0x48, 0x62, 0xc9, 0x40, 0x7d, 0xf3, 0xc3, 0xc1, 0xf6, 0xbc, 0x02, 0x1c, 0xf7, 0xe9, 0xb1, + 0xec, 0xfd, 0xa7, 0x7d, 0x6f, 0xcf, 0x81, 0x39, 0x06, 0x8b, 0x3f, 0x8f, 0x7f, 0x28, 0x23, 0x33, + 0x91, 0x87, 0x60, 0x92, 0x4d, 0xdb, 0xfd, 0xee, 0x3d, 0x78, 0x57, 0x97, 0xc1, 0x74, 0x17, 0x39, + 0x3b, 0xa6, 0xeb, 0x9a, 0xb6, 0x45, 0x17, 0xe4, 0xe6, 0x6e, 0x7b, 0x54, 0x20, 0x71, 0xb2, 0x76, + 0x39, 0xbf, 0x6e, 0x38, 0x9e, 0xd9, 0x32, 0xbb, 0x86, 0xe5, 0xad, 0x87, 0x99, 0x75, 0xfe, 0x4f, + 0xf8, 0xa2, 0x84, 0xd3, 0x1a, 0xb1, 0x26, 0x11, 0x2a, 0xf1, 0x3b, 0x09, 0xa6, 0x24, 0xb1, 0x04, + 0x93, 0xa9, 0xc5, 0x47, 0x53, 0x55, 0x8b, 0x3e, 0x78, 0x6f, 0xa9, 0x57, 0x81, 0x53, 0x95, 0x6a, + 0xb9, 0xa6, 0xeb, 0x5a, 0xb9, 0xd1, 0x5c, 0xd7, 0xf4, 0xb5, 0x4a, 0xbd, 0x5e, 0xa9, 0x55, 0xeb, + 0x87, 0x69, 0xed, 0xf0, 0x13, 0x4a, 0xa0, 0x31, 0x8b, 0xa8, 0xd5, 0x31, 0x2d, 0x04, 0xef, 0x39, + 0xa4, 0xc2, 0x88, 0xab, 0x3e, 0xf2, 0x38, 0xb3, 0xf2, 0x23, 0x70, 0x7e, 0x75, 0x72, 0x9c, 0xfb, + 0x13, 0xfc, 0x37, 0xdc, 0xfc, 0xbf, 0xa8, 0x80, 0x13, 0x5c, 0x43, 0xd4, 0xd1, 0xce, 0xc8, 0x56, + 0xf2, 0x7e, 0x96, 0x6f, 0xbb, 0x15, 0x11, 0xd3, 0x7e, 0xd6, 0xf4, 0x01, 0x36, 0x22, 0x60, 0x7d, + 0x73, 0x00, 0xeb, 0xaa, 0x00, 0xeb, 0x93, 0x87, 0xa0, 0x99, 0x0c, 0xd9, 0xdf, 0x4a, 0x15, 0xd9, + 0xab, 0xc0, 0xa9, 0xf5, 0x92, 0xde, 0xa8, 0x94, 0x2b, 0xeb, 0x25, 0x3c, 0x8e, 0x72, 0x43, 0x76, + 0x84, 0xb9, 0x2e, 0x82, 0xde, 0x17, 0xdf, 0xdf, 0xcb, 0x81, 0x6b, 0xfa, 0x77, 0xb4, 0xe5, 0x6d, + 0xc3, 0xda, 0x42, 0xd0, 0x94, 0x81, 0x7a, 0x11, 0x4c, 0xb4, 0x48, 0x76, 0x8a, 0x33, 0xbf, 0x75, + 0x13, 0xd3, 0x97, 0xd3, 0x12, 0x74, 0xff, 0x57, 0xf8, 0x2e, 0x5e, 0x21, 0x1a, 0xa2, 0x42, 0x3c, + 0x35, 0x1e, 0xbc, 0x03, 0x7c, 0x47, 0xe8, 0xc6, 0xa7, 0x02, 0xdd, 0xb8, 0x20, 0xe8, 0x46, 0xf9, + 0x70, 0xe4, 0x93, 0xa9, 0xc9, 0x1f, 0x3f, 0x1c, 0x3a, 0x80, 0x48, 0x6d, 0x32, 0xa3, 0x47, 0x85, + 0xbe, 0xdd, 0xfd, 0x2b, 0x15, 0x50, 0x58, 0x44, 0x1d, 0x24, 0xbb, 0x12, 0xf9, 0xad, 0xac, 0xec, + 0x86, 0x08, 0x85, 0x81, 0xd2, 0x8e, 0x5e, 0x1d, 0xf1, 0xcc, 0x1d, 0xe4, 0x7a, 0xc6, 0x4e, 0x97, + 0x88, 0x5a, 0xd1, 0xc3, 0x04, 0xf8, 0x73, 0x59, 0x99, 0xed, 0x92, 0x98, 0x62, 0xfe, 0x6d, 0xac, + 0x29, 0x7e, 0x65, 0x0e, 0x14, 0x2e, 0x18, 0x9d, 0x0e, 0xf2, 0xe0, 0x57, 0xb3, 0xa0, 0x50, 0xc6, + 0x73, 0x52, 0x04, 0x1f, 0x13, 0x82, 0x05, 0xc1, 0xa4, 0x63, 0xdb, 0xde, 0xba, 0xe1, 0x6d, 0x33, + 0xb4, 0x82, 0x77, 0xb6, 0x4d, 0xfb, 0x16, 0x1e, 0xb4, 0x7b, 0x44, 0xd0, 0x7e, 0x4c, 0x90, 0x26, + 0x2d, 0x68, 0x9e, 0x16, 0x12, 0x81, 0x1a, 0x04, 0x93, 0x3b, 0x16, 0xda, 0xb1, 0x2d, 0xb3, 0xe5, + 0x8f, 0xf4, 0xfe, 0x3b, 0xfc, 0x50, 0x30, 0x4b, 0x5e, 0x10, 0x30, 0x9b, 0x97, 0x2e, 0x25, 0x19, + 0x68, 0xf5, 0x21, 0x30, 0xbb, 0x16, 0x5c, 0x4d, 0x21, 0x68, 0x36, 0x6a, 0xcd, 0xb2, 0xae, 0x95, + 0x1a, 0x5a, 0x73, 0xb5, 0x56, 0x2e, 0xad, 0x36, 0x75, 0x6d, 0xbd, 0x56, 0x44, 0xf0, 0xef, 0xb3, + 0x58, 0xb8, 0x2d, 0x7b, 0x0f, 0x39, 0x70, 0x59, 0x4a, 0xce, 0x71, 0x32, 0x61, 0x18, 0xfc, 0xb2, + 0xf4, 0x56, 0x39, 0x93, 0x0e, 0xe3, 0x20, 0xa2, 0x2b, 0xfc, 0xb0, 0xd4, 0xb6, 0x77, 0x2c, 0xa9, + 0x87, 0x81, 0xa4, 0xff, 0x67, 0x16, 0x4c, 0x94, 0x6d, 0x6b, 0x0f, 0x39, 0x1e, 0x6f, 0x65, 0xf2, + 0xd2, 0xcc, 0x88, 0xd2, 0xc4, 0x5d, 0x13, 0xb2, 0x3c, 0xc7, 0xee, 0xfa, 0x66, 0xa6, 0xff, 0x0a, + 0xdf, 0x98, 0x54, 0xc2, 0xac, 0xe4, 0xe8, 0xe5, 0xa6, 0xfe, 0x05, 0x09, 0xec, 0x29, 0x3d, 0x0d, + 0xe0, 0x35, 0x49, 0x70, 0xe9, 0xcf, 0x40, 0xfa, 0xbb, 0xbc, 0x5f, 0x52, 0xc0, 0x2c, 0x6d, 0x7c, + 0x75, 0x44, 0xc6, 0x45, 0x58, 0xe3, 0x17, 0x7a, 0x7a, 0x84, 0xbf, 0x72, 0x4c, 0x10, 0x7f, 0xc1, + 0xe8, 0x76, 0x83, 0x45, 0xbf, 0x95, 0x63, 0x3a, 0x7b, 0xa7, 0x6a, 0xbe, 0x50, 0x00, 0x39, 0x63, + 0xd7, 0xdb, 0x86, 0x3f, 0x90, 0x36, 0xf9, 0x85, 0xce, 0x80, 0xf1, 0x13, 0x01, 0xc9, 0x49, 0x90, + 0xf7, 0xec, 0x4b, 0xc8, 0x97, 0x03, 0x7d, 0xc1, 0x70, 0x18, 0xdd, 0x6e, 0x83, 0x7c, 0x60, 0x70, + 0xf8, 0xef, 0x78, 0x84, 0x31, 0x5a, 0x2d, 0x7b, 0xd7, 0xf2, 0x2a, 0xfe, 0xc2, 0x5f, 0x98, 0x00, + 0x3f, 0x9f, 0x91, 0x99, 0x42, 0x48, 0x30, 0x98, 0x0c, 0xb2, 0x8b, 0x43, 0x34, 0xa5, 0x79, 0x70, + 0x73, 0x69, 0x7d, 0xbd, 0xd9, 0xa8, 0xdd, 0xa7, 0x55, 0xc3, 0xe1, 0xbe, 0x59, 0xa9, 0x36, 0x1b, + 0x2b, 0x5a, 0xb3, 0xbc, 0xa1, 0x93, 0xd5, 0x99, 0x52, 0xb9, 0x5c, 0xdb, 0xa8, 0x36, 0x8a, 0x08, + 0xbe, 0x35, 0x0b, 0x66, 0xca, 0x1d, 0xdb, 0x0d, 0x10, 0xbe, 0x36, 0x44, 0x38, 0x10, 0x63, 0x86, + 0x13, 0x23, 0xfc, 0x97, 0x8c, 0xec, 0x56, 0xaf, 0x2f, 0x10, 0x8e, 0x7c, 0x44, 0x2f, 0xf5, 0x46, + 0xa9, 0xad, 0xde, 0xc1, 0xf4, 0xd2, 0x6f, 0x12, 0x9f, 0xb9, 0x13, 0x4c, 0x94, 0xa8, 0x62, 0xc0, + 0xbf, 0xcd, 0x80, 0x42, 0xd9, 0xb6, 0x36, 0xcd, 0x2d, 0xf5, 0x46, 0x30, 0x87, 0x2c, 0xe3, 0x62, + 0x07, 0x2d, 0x1a, 0x9e, 0xb1, 0x67, 0xa2, 0xcb, 0xa4, 0x02, 0x93, 0x7a, 0x4f, 0x2a, 0x66, 0x8a, + 0xa5, 0xa0, 0x8b, 0xbb, 0x5b, 0x84, 0xa9, 0x49, 0x9d, 0x4f, 0x52, 0x9f, 0x0c, 0xae, 0xa4, 0xaf, + 0xeb, 0x0e, 0x72, 0x50, 0x07, 0x19, 0x2e, 0xc2, 0xc6, 0xa8, 0x85, 0x3a, 0x44, 0x69, 0x27, 0xf5, + 0xa8, 0xcf, 0xea, 0x39, 0x30, 0x43, 0x3f, 0x11, 0x53, 0xc7, 0x25, 0x6a, 0x3c, 0xa9, 0x0b, 0x69, + 0xea, 0x63, 0x41, 0x1e, 0x3d, 0xe8, 0x39, 0xc6, 0x99, 0x36, 0xc1, 0xeb, 0xca, 0x79, 0xea, 0xeb, + 0x35, 0xef, 0xfb, 0x7a, 0xcd, 0xd7, 0x89, 0x27, 0x98, 0x4e, 0x73, 0xc1, 0xdf, 0x98, 0x0c, 0x0c, + 0x89, 0x7f, 0xcd, 0x86, 0x8a, 0xa1, 0x82, 0x9c, 0x65, 0xec, 0x20, 0xa6, 0x17, 0xe4, 0x59, 0xbd, + 0x19, 0x1c, 0x37, 0xf6, 0x0c, 0xcf, 0x70, 0x56, 0xed, 0x96, 0xd1, 0x21, 0x83, 0x9f, 0xdf, 0xf2, + 0x7b, 0x3f, 0x90, 0x75, 0x78, 0xcf, 0x76, 0x10, 0xc9, 0xe5, 0xaf, 0xc3, 0xfb, 0x09, 0x98, 0xba, + 0xd9, 0xb2, 0x2d, 0xc2, 0xbf, 0xa2, 0x93, 0x67, 0x2c, 0x95, 0xb6, 0xe9, 0xe2, 0x8a, 0x10, 0x2a, + 0x55, 0xba, 0xa0, 0x5c, 0xdf, 0xb7, 0x5a, 0x64, 0x0d, 0x7e, 0x52, 0x8f, 0xfa, 0xac, 0x2e, 0x80, + 0x69, 0xb6, 0xfc, 0xbc, 0x86, 0xf5, 0xaa, 0x40, 0xf4, 0xea, 0x3a, 0xd1, 0x93, 0x86, 0xe2, 0x39, + 0x5f, 0x0d, 0xf3, 0xe9, 0xfc, 0x4f, 0xea, 0xbd, 0xe0, 0x6a, 0xf6, 0x5a, 0xde, 0x75, 0x3d, 0x7b, + 0x87, 0x82, 0xbe, 0x64, 0x76, 0x68, 0x0d, 0x26, 0x48, 0x0d, 0xe2, 0xb2, 0xa8, 0xb7, 0x81, 0x93, + 0x5d, 0x07, 0x6d, 0x22, 0xe7, 0x7e, 0x63, 0x67, 0xf7, 0xc1, 0x86, 0x63, 0x58, 0x6e, 0xd7, 0x76, + 0xbc, 0x33, 0x93, 0x84, 0xf9, 0xbe, 0xdf, 0x58, 0x47, 0x39, 0x09, 0x0a, 0x54, 0x7c, 0xf0, 0x85, + 0x79, 0x69, 0x27, 0x3a, 0x56, 0xa1, 0x58, 0xf3, 0xec, 0x71, 0x60, 0x82, 0xf5, 0x70, 0x04, 0xa8, + 0xe9, 0xdb, 0x4e, 0xf7, 0xcc, 0xe6, 0x18, 0x15, 0xdd, 0xcf, 0xa6, 0xde, 0x0e, 0x0a, 0x2d, 0x52, + 0x2d, 0x82, 0xd9, 0xf4, 0x6d, 0x57, 0xf7, 0x2f, 0x94, 0x64, 0xd1, 0x59, 0x56, 0xf8, 0x57, 0x8a, + 0x94, 0xdf, 0x5d, 0x1c, 0xc7, 0xc9, 0x5a, 0xf5, 0x37, 0xb2, 0x43, 0x74, 0x9b, 0xb7, 0x80, 0x9b, + 0x58, 0x9f, 0xc8, 0xec, 0x8f, 0xc5, 0xe6, 0xc2, 0x86, 0x6f, 0x82, 0x63, 0xab, 0xa4, 0xde, 0x28, + 0xe9, 0x78, 0xfe, 0xb4, 0x88, 0x4d, 0xf7, 0x9b, 0xc1, 0x8d, 0x03, 0x72, 0x6b, 0x8d, 0x66, 0xb5, + 0xb4, 0xa6, 0x15, 0x37, 0x45, 0xdb, 0xa6, 0xde, 0xa8, 0xad, 0x37, 0xf5, 0x8d, 0x6a, 0xb5, 0x52, + 0x5d, 0xa6, 0xc4, 0xb0, 0x49, 0x78, 0x3a, 0xcc, 0x70, 0x41, 0xaf, 0x34, 0xb4, 0x66, 0xb9, 0x56, + 0x5d, 0xaa, 0x2c, 0x17, 0xcd, 0x41, 0x86, 0xd1, 0x03, 0xea, 0x75, 0xe0, 0x1a, 0x81, 0x93, 0x4a, + 0xad, 0x8a, 0xe7, 0x13, 0xe5, 0x52, 0xb5, 0xac, 0xe1, 0xc9, 0xc3, 0x25, 0x15, 0x82, 0x53, 0x94, + 0x5c, 0x73, 0xa9, 0xb2, 0xca, 0x6f, 0x01, 0x7c, 0x3c, 0xa3, 0x9e, 0x01, 0x57, 0xf0, 0xdf, 0x2a, + 0xd5, 0xf3, 0xa5, 0xd5, 0xca, 0x62, 0xf1, 0x8f, 0x32, 0xea, 0x0d, 0xe0, 0x5a, 0xe1, 0x2f, 0xba, + 0x9a, 0xdf, 0xac, 0x2c, 0x36, 0xd7, 0x2a, 0xf5, 0xb5, 0x52, 0xa3, 0xbc, 0x52, 0xfc, 0x04, 0x99, + 0x2f, 0x04, 0x06, 0x30, 0xe7, 0x0c, 0xf7, 0x12, 0x7e, 0x4c, 0x2f, 0x89, 0x8a, 0xfa, 0x98, 0xbe, + 0xb0, 0xc7, 0xdb, 0xb0, 0x1f, 0x0d, 0x46, 0x87, 0x45, 0x41, 0x85, 0x1e, 0x97, 0x80, 0x56, 0x32, + 0x1d, 0x6a, 0x0c, 0xa1, 0x42, 0xd7, 0x81, 0x6b, 0xaa, 0x1a, 0x45, 0x4a, 0xd7, 0xca, 0xb5, 0xf3, + 0x9a, 0xde, 0xbc, 0x50, 0x5a, 0x5d, 0xd5, 0x1a, 0xcd, 0xa5, 0x8a, 0x5e, 0x6f, 0x14, 0x37, 0xe1, + 0xb7, 0xb3, 0xc1, 0x1c, 0x9a, 0x93, 0xd6, 0xdf, 0x66, 0x93, 0x36, 0xeb, 0xd8, 0xb9, 0xf2, 0x8f, + 0x83, 0x82, 0xeb, 0x19, 0xde, 0xae, 0xcb, 0x5a, 0xf5, 0x23, 0xfa, 0xb7, 0xea, 0xf9, 0x3a, 0xc9, + 0xa4, 0xb3, 0xcc, 0xf0, 0xaf, 0x32, 0x49, 0x9a, 0xe9, 0x08, 0xa6, 0xd1, 0xe6, 0x10, 0x22, 0x3e, + 0x0b, 0xa0, 0xaf, 0xed, 0x95, 0x7a, 0xb3, 0xb4, 0xaa, 0x6b, 0xa5, 0xc5, 0xfb, 0x83, 0xc9, 0x33, + 0x52, 0x4f, 0x81, 0x13, 0x1b, 0x55, 0x3c, 0x1d, 0x26, 0xcd, 0xa5, 0x56, 0xad, 0x6a, 0x65, 0x2c, + 0xf7, 0x9f, 0x23, 0x4b, 0xd5, 0xd8, 0x82, 0x26, 0x7c, 0x63, 0x2b, 0x87, 0x93, 0xff, 0xd7, 0xa5, + 0x3d, 0x3a, 0x42, 0x0d, 0xe3, 0x69, 0x8d, 0x16, 0x87, 0xcf, 0x4b, 0x39, 0x71, 0x48, 0x71, 0x92, + 0x0c, 0x8f, 0x7f, 0x3f, 0x04, 0x1e, 0xa7, 0xc0, 0x09, 0x1e, 0x0f, 0xe2, 0xcc, 0x11, 0x0d, 0xc3, + 0x97, 0x27, 0x41, 0xa1, 0x8e, 0x3a, 0xa8, 0xe5, 0xc1, 0xb7, 0x73, 0xc6, 0xc4, 0x1c, 0xc8, 0x06, + 0xce, 0x03, 0x59, 0xb3, 0x2d, 0x4c, 0x9f, 0xb3, 0x3d, 0xd3, 0xe7, 0x18, 0x33, 0x40, 0x49, 0x64, + 0x06, 0xe4, 0x52, 0x30, 0x03, 0xf2, 0xc3, 0x9b, 0x01, 0x85, 0x41, 0x66, 0x00, 0x7c, 0x5d, 0x21, + 0x69, 0x2f, 0x41, 0x45, 0x7d, 0xb4, 0x83, 0xff, 0xff, 0xc8, 0x25, 0xe9, 0x55, 0xfa, 0x72, 0x9c, + 0x4c, 0x8b, 0x7f, 0xa0, 0xa4, 0xb0, 0xfc, 0xa0, 0x5e, 0x0f, 0xae, 0x0d, 0xdf, 0x9b, 0xda, 0x33, + 0x2a, 0xf5, 0x46, 0x9d, 0x8c, 0xf8, 0xe5, 0x9a, 0xae, 0x6f, 0xac, 0xd3, 0x95, 0xbb, 0xd3, 0x40, + 0x0d, 0xa9, 0xe8, 0x1b, 0x55, 0x3a, 0xbe, 0x6f, 0x89, 0xd4, 0x97, 0x2a, 0xd5, 0xc5, 0x66, 0xd0, + 0x66, 0xaa, 0x4b, 0xb5, 0xe2, 0x36, 0x9e, 0xb2, 0x71, 0xd4, 0xf1, 0x00, 0xcd, 0x4a, 0x28, 0x55, + 0x17, 0x9b, 0x6b, 0x55, 0x6d, 0xad, 0x56, 0xad, 0x94, 0x49, 0x7a, 0x5d, 0x6b, 0x14, 0x4d, 0x3c, + 0xd0, 0xf4, 0x58, 0x14, 0x75, 0xad, 0xa4, 0x97, 0x57, 0x34, 0x9d, 0x16, 0xf9, 0x80, 0x7a, 0x23, + 0x38, 0x57, 0xaa, 0xd6, 0x1a, 0x38, 0xa5, 0x54, 0xbd, 0xbf, 0x71, 0xff, 0xba, 0xd6, 0x5c, 0xd7, + 0x6b, 0x65, 0xad, 0x5e, 0xc7, 0xed, 0x94, 0xd9, 0x1f, 0xc5, 0x8e, 0xfa, 0x54, 0x70, 0x27, 0xc7, + 0x9a, 0xd6, 0x20, 0xdb, 0x44, 0x6b, 0x35, 0xe2, 0x29, 0xb0, 0xa8, 0x35, 0x57, 0x4a, 0xf5, 0x66, + 0xa5, 0x5a, 0xae, 0xad, 0xad, 0x97, 0x1a, 0x15, 0xdc, 0x9c, 0xd7, 0xf5, 0x5a, 0xa3, 0xd6, 0x3c, + 0xaf, 0xe9, 0xf5, 0x4a, 0xad, 0x5a, 0xb4, 0x70, 0x95, 0xb9, 0xf6, 0xef, 0xf7, 0xc3, 0xb6, 0x7a, + 0x0d, 0x38, 0xe3, 0xa7, 0xaf, 0xd6, 0xb0, 0xa0, 0x39, 0x8b, 0xa4, 0x9b, 0xaa, 0x45, 0xf2, 0xcf, + 0x59, 0x90, 0xab, 0x7b, 0x76, 0x17, 0xfe, 0x58, 0xd8, 0xc1, 0x9c, 0x05, 0xc0, 0x21, 0xbb, 0x3e, + 0x78, 0x16, 0xc6, 0xe6, 0x65, 0x5c, 0x0a, 0xfc, 0x43, 0xe9, 0xa5, 0xea, 0xb0, 0xcf, 0xb6, 0xbb, + 0x11, 0xb6, 0xca, 0xf7, 0xe4, 0x7c, 0xf7, 0xa3, 0x09, 0x25, 0xd3, 0xf7, 0x9f, 0x1f, 0x66, 0x31, + 0x1a, 0x82, 0xd3, 0x1c, 0x6c, 0x58, 0xfe, 0xbe, 0x4a, 0x20, 0xf5, 0x4a, 0x70, 0x45, 0x8f, 0x72, + 0x11, 0x9d, 0xda, 0x54, 0x1f, 0x09, 0x1e, 0xc1, 0xa9, 0xb7, 0xb6, 0x56, 0x3b, 0xaf, 0x05, 0x8a, + 0xbc, 0x58, 0x6a, 0x94, 0x8a, 0x5b, 0xf0, 0x33, 0x0a, 0xc8, 0xad, 0xd9, 0x7b, 0xbd, 0x3b, 0x04, + 0x16, 0xba, 0xcc, 0xad, 0x85, 0xfa, 0xaf, 0xa2, 0xaf, 0xb2, 0x94, 0xd8, 0xd7, 0xa2, 0x77, 0x03, + 0x3f, 0x9f, 0x4d, 0x22, 0xf6, 0xb5, 0xc3, 0x6e, 0x01, 0xfe, 0xc3, 0x30, 0x62, 0x8f, 0x10, 0x2d, + 0x52, 0xcf, 0x81, 0xb3, 0xe1, 0x87, 0xca, 0xa2, 0x56, 0x6d, 0x54, 0x96, 0xee, 0x0f, 0x85, 0x5b, + 0xd1, 0xa5, 0xc4, 0x3f, 0xa8, 0x1b, 0x8b, 0x9f, 0x69, 0x9c, 0x01, 0x27, 0xc3, 0x6f, 0xcb, 0x5a, + 0xc3, 0xff, 0xf2, 0x00, 0x7c, 0x4e, 0x1e, 0xcc, 0xd0, 0x6e, 0x7d, 0xa3, 0xdb, 0x36, 0x3c, 0x04, + 0x6f, 0x0f, 0xd1, 0xbd, 0x09, 0x1c, 0xaf, 0xac, 0x2f, 0xd5, 0xeb, 0x9e, 0xed, 0x18, 0x5b, 0xa8, + 0xd4, 0x6e, 0x3b, 0x4c, 0x5a, 0xbd, 0xc9, 0xf0, 0x3d, 0xd2, 0xeb, 0x7c, 0xe2, 0x50, 0x42, 0xcb, + 0x8c, 0x40, 0xfd, 0x4b, 0x52, 0xeb, 0x72, 0x12, 0x04, 0x93, 0xa1, 0xff, 0xc0, 0x88, 0xdb, 0x5c, + 0x34, 0x2e, 0x9b, 0xe7, 0x9e, 0x97, 0x05, 0x53, 0x0d, 0x73, 0x07, 0x3d, 0xd3, 0xb6, 0x90, 0xab, + 0x4e, 0x00, 0x65, 0x79, 0xad, 0x51, 0x3c, 0x86, 0x1f, 0xb0, 0x51, 0x95, 0x21, 0x0f, 0x1a, 0x2e, + 0x00, 0x3f, 0x94, 0x1a, 0x45, 0x05, 0x3f, 0xac, 0x69, 0x8d, 0x62, 0x0e, 0x3f, 0x54, 0xb5, 0x46, + 0x31, 0x8f, 0x1f, 0xd6, 0x57, 0x1b, 0xc5, 0x02, 0x7e, 0xa8, 0xd4, 0x1b, 0xc5, 0x09, 0xfc, 0xb0, + 0x50, 0x6f, 0x14, 0x27, 0xf1, 0xc3, 0xf9, 0x7a, 0xa3, 0x38, 0x85, 0x1f, 0xca, 0x8d, 0x46, 0x11, + 0xe0, 0x87, 0xa7, 0xd5, 0x1b, 0xc5, 0x69, 0xfc, 0x50, 0x2a, 0x37, 0x8a, 0x33, 0xe4, 0x41, 0x6b, + 0x14, 0x67, 0xf1, 0x43, 0xbd, 0xde, 0x28, 0xce, 0x11, 0xca, 0xf5, 0x46, 0xf1, 0x38, 0x29, 0xab, + 0xd2, 0x28, 0x16, 0xf1, 0xc3, 0x4a, 0xbd, 0x51, 0x3c, 0x41, 0x32, 0xd7, 0x1b, 0x45, 0x95, 0x14, + 0x5a, 0x6f, 0x14, 0xaf, 0x20, 0x79, 0xea, 0x8d, 0xe2, 0x49, 0x52, 0x44, 0xbd, 0x51, 0x3c, 0x45, + 0xd8, 0xd0, 0x1a, 0xc5, 0xd3, 0x24, 0x8f, 0xde, 0x28, 0x5e, 0x49, 0x3e, 0x55, 0x1b, 0xc5, 0x33, + 0x84, 0x31, 0xad, 0x51, 0xbc, 0x8a, 0x3c, 0xe8, 0x8d, 0x22, 0x24, 0x9f, 0x4a, 0x8d, 0xe2, 0xd5, + 0xf0, 0x11, 0x60, 0x6a, 0x19, 0x79, 0x14, 0x44, 0x58, 0x04, 0xca, 0x32, 0xf2, 0x78, 0x33, 0xfe, + 0x2b, 0x0a, 0xb8, 0x92, 0x4d, 0xfd, 0x96, 0x1c, 0x7b, 0x67, 0x15, 0x6d, 0x19, 0xad, 0x7d, 0xed, + 0x41, 0x6c, 0x42, 0xc1, 0xba, 0xb0, 0x74, 0xd5, 0x0d, 0x3b, 0x23, 0xf2, 0x1c, 0x6b, 0x71, 0xfa, + 0x8b, 0x51, 0x4a, 0xb8, 0x18, 0xc5, 0x2c, 0xb2, 0x7f, 0xe2, 0x35, 0x5a, 0x58, 0x3f, 0xce, 0xf4, + 0xac, 0x1f, 0xe3, 0x66, 0xd2, 0x45, 0x8e, 0x6b, 0x5b, 0x46, 0xa7, 0xce, 0xb6, 0x4b, 0xe9, 0xaa, + 0x57, 0x6f, 0xb2, 0xfa, 0x74, 0xbf, 0x65, 0x50, 0xab, 0xec, 0x29, 0x71, 0x33, 0xdc, 0xde, 0x6a, + 0x46, 0x34, 0x92, 0x4f, 0x04, 0x8d, 0xa4, 0x21, 0x34, 0x92, 0x7b, 0x0f, 0x41, 0x3b, 0x59, 0x7b, + 0xa9, 0x0c, 0x37, 0xb5, 0x08, 0x9d, 0x09, 0xfd, 0xe5, 0x6a, 0x05, 0x7e, 0x26, 0x0b, 0x4e, 0x6b, + 0x56, 0x3f, 0x0b, 0x9f, 0xd7, 0x85, 0xb7, 0xf2, 0xd0, 0xac, 0x8b, 0x22, 0xbd, 0xb3, 0x6f, 0xb5, + 0xfb, 0xd3, 0x8c, 0x90, 0xe8, 0x27, 0x03, 0x89, 0xd6, 0x05, 0x89, 0xde, 0x33, 0x3c, 0xe9, 0x64, + 0x02, 0xad, 0x8e, 0xb4, 0x03, 0xca, 0xc1, 0x6f, 0xe4, 0xc0, 0x23, 0xa8, 0xc7, 0x03, 0xe3, 0x90, + 0xb6, 0xb2, 0x92, 0xd5, 0xd6, 0x91, 0xeb, 0x19, 0x8e, 0x27, 0x9c, 0x42, 0xed, 0x99, 0x4a, 0x65, + 0x52, 0x98, 0x4a, 0x65, 0x07, 0x4e, 0xa5, 0xe0, 0xbb, 0x79, 0xf3, 0xe1, 0x82, 0x88, 0x71, 0xa9, + 0x7f, 0xff, 0x1f, 0x57, 0xc3, 0x28, 0xa8, 0x03, 0xbb, 0xe2, 0x27, 0x04, 0xa8, 0x97, 0x0e, 0x5d, + 0x42, 0x32, 0xc4, 0xff, 0x70, 0xb4, 0x76, 0x5e, 0x8e, 0xff, 0x26, 0x1a, 0x25, 0xc5, 0x76, 0xaa, + 0x06, 0xfa, 0xa7, 0x26, 0xc0, 0x14, 0x69, 0x0b, 0xab, 0xa6, 0x75, 0x09, 0xbe, 0x46, 0x01, 0x33, + 0x55, 0x74, 0xb9, 0xbc, 0x6d, 0x74, 0x3a, 0xc8, 0xda, 0x42, 0xbc, 0xd9, 0x7e, 0x06, 0x4c, 0x18, + 0xdd, 0x6e, 0x35, 0xdc, 0x67, 0xf0, 0x5f, 0x59, 0xff, 0xfb, 0xf5, 0xbe, 0x8d, 0x3c, 0x13, 0xd3, + 0xc8, 0x83, 0x72, 0xe7, 0xf9, 0x32, 0x23, 0x66, 0xc8, 0xd7, 0x81, 0xe9, 0x96, 0x9f, 0x25, 0xf0, + 0x56, 0xe7, 0x93, 0xe0, 0xd7, 0x12, 0x75, 0x03, 0x52, 0x85, 0x27, 0x53, 0x0a, 0x34, 0x62, 0x3b, + 0xe4, 0x14, 0x38, 0xd1, 0xa8, 0xd5, 0x9a, 0x6b, 0xa5, 0xea, 0xfd, 0xe1, 0x29, 0xd1, 0x4d, 0xf8, + 0xf2, 0x1c, 0x98, 0xab, 0xdb, 0x9d, 0x3d, 0x14, 0xc2, 0x54, 0x09, 0x61, 0xea, 0x91, 0x53, 0xe6, + 0x80, 0x9c, 0xd4, 0xd3, 0xa0, 0x60, 0x58, 0xee, 0x65, 0xe4, 0xdb, 0x86, 0xec, 0x8d, 0xc1, 0xf8, + 0x7b, 0x7c, 0x3b, 0xd6, 0x45, 0x18, 0xef, 0x1a, 0x20, 0x49, 0x91, 0xab, 0x08, 0x20, 0xcf, 0x81, + 0x19, 0x97, 0x6e, 0x16, 0x36, 0xb8, 0x3d, 0x61, 0x21, 0x8d, 0xb0, 0x48, 0x77, 0xab, 0x15, 0xc6, + 0x22, 0x79, 0x83, 0xaf, 0x09, 0x9a, 0xff, 0x86, 0x00, 0x71, 0xe9, 0x30, 0x8c, 0x25, 0x03, 0xf9, + 0x95, 0xa3, 0x9e, 0xe1, 0x9d, 0x01, 0x27, 0x59, 0xab, 0x6d, 0x96, 0x57, 0x4a, 0xab, 0xab, 0x5a, + 0x75, 0x59, 0x6b, 0x56, 0x16, 0xe9, 0x56, 0x45, 0x98, 0x52, 0x6a, 0x34, 0xb4, 0xb5, 0xf5, 0x46, + 0xbd, 0xa9, 0x3d, 0xa3, 0xac, 0x69, 0x8b, 0xc4, 0x11, 0x89, 0x9c, 0x24, 0xf0, 0x5d, 0xc6, 0x4a, + 0xd5, 0xfa, 0x05, 0x4d, 0x2f, 0x6e, 0x9f, 0x2b, 0x81, 0x69, 0xae, 0x9f, 0xc7, 0xdc, 0x2d, 0xa2, + 0x4d, 0x63, 0xb7, 0xc3, 0x6c, 0xb5, 0xe2, 0x31, 0xcc, 0x1d, 0x91, 0x4d, 0xcd, 0xea, 0xec, 0x17, + 0x33, 0x6a, 0x11, 0xcc, 0xf0, 0x5d, 0x7a, 0x31, 0x0b, 0xbf, 0x77, 0x35, 0x98, 0xba, 0x60, 0x3b, + 0x97, 0x88, 0xf7, 0x18, 0x7c, 0x3f, 0x8d, 0x26, 0xe1, 0x9f, 0xcb, 0xe3, 0x06, 0xf6, 0x57, 0xca, + 0x7b, 0x0b, 0xf8, 0xd4, 0xe6, 0x07, 0x9e, 0xbd, 0xbb, 0x0e, 0x4c, 0x5f, 0xf6, 0x73, 0x87, 0x2d, + 0x9d, 0x4b, 0x82, 0xff, 0x45, 0x6e, 0xff, 0x7f, 0x70, 0x91, 0xe9, 0xef, 0x4f, 0xbf, 0x3d, 0x0b, + 0x0a, 0xcb, 0xc8, 0x2b, 0x75, 0x3a, 0xbc, 0xdc, 0x5e, 0x2a, 0x7d, 0x9e, 0x42, 0xa8, 0x44, 0xa9, + 0xd3, 0x89, 0x6e, 0x54, 0x9c, 0x80, 0x7c, 0xbf, 0x5f, 0x21, 0x0d, 0xbe, 0x4e, 0xea, 0x24, 0xd4, + 0x80, 0x02, 0xd3, 0x97, 0xd8, 0x1b, 0x94, 0x60, 0x8f, 0xfb, 0xf9, 0x9c, 0x95, 0xf3, 0xf8, 0x30, + 0x92, 0x48, 0x26, 0x7e, 0xaf, 0xdc, 0xcf, 0xa7, 0xde, 0x07, 0x26, 0x76, 0x5d, 0x54, 0x36, 0x5c, + 0x44, 0x78, 0xeb, 0xad, 0x69, 0xed, 0xe2, 0x03, 0xa8, 0xe5, 0xcd, 0x57, 0x76, 0xb0, 0x41, 0xbd, + 0x41, 0x33, 0x06, 0xc1, 0x39, 0xd8, 0xbb, 0xee, 0x53, 0x80, 0x2f, 0x1c, 0x02, 0xb2, 0xd8, 0xfd, + 0xde, 0xc8, 0xa3, 0x57, 0x89, 0x81, 0x1a, 0xc1, 0x26, 0xed, 0x30, 0x40, 0x7d, 0x2a, 0x0b, 0x72, + 0xb5, 0x2e, 0xb2, 0xe4, 0x1c, 0x50, 0x5f, 0x23, 0xef, 0xe5, 0x15, 0x54, 0x0c, 0x53, 0x8f, 0x90, + 0xde, 0xad, 0x20, 0x67, 0x5a, 0x9b, 0x36, 0x33, 0x30, 0xaf, 0x8e, 0xd8, 0xcc, 0xa9, 0x58, 0x9b, + 0xb6, 0x4e, 0x32, 0xca, 0x3a, 0x78, 0xc5, 0x95, 0x9d, 0xbe, 0x48, 0xbf, 0x39, 0x09, 0x0a, 0x54, + 0x2d, 0xe1, 0x4b, 0x14, 0xa0, 0x94, 0xda, 0xed, 0x88, 0x43, 0x1c, 0xd9, 0x03, 0x87, 0x38, 0x6c, + 0xf2, 0x5b, 0x20, 0xf7, 0xe0, 0x5d, 0x0c, 0x05, 0x21, 0xd9, 0x47, 0xb3, 0xa6, 0x51, 0x6a, 0xb7, + 0xa3, 0x7d, 0x49, 0x83, 0x02, 0xb3, 0x62, 0x81, 0x7c, 0x4b, 0x55, 0xe4, 0x5a, 0x6a, 0xe2, 0x0e, + 0x3d, 0x92, 0xbf, 0xf4, 0x21, 0xfa, 0xa7, 0x2c, 0x98, 0x58, 0x35, 0x5d, 0x0f, 0x63, 0x53, 0x92, + 0xc1, 0xe6, 0x1a, 0x30, 0xe5, 0x8b, 0x06, 0x77, 0x5d, 0xb8, 0x5f, 0x0e, 0x13, 0xe0, 0x6b, 0x79, + 0x74, 0x9e, 0x26, 0xa2, 0xf3, 0x84, 0xf8, 0xda, 0x33, 0x2e, 0xa2, 0x7d, 0xb4, 0xc3, 0x62, 0xb3, + 0xbd, 0xc5, 0xbe, 0x25, 0x10, 0xf8, 0x9a, 0x20, 0xf0, 0x3b, 0x86, 0x29, 0x32, 0x7d, 0xa1, 0x7f, + 0x36, 0x0b, 0x00, 0x2e, 0x9b, 0x1d, 0x84, 0x79, 0xb4, 0x70, 0xbc, 0x35, 0x46, 0xba, 0x2f, 0xe7, + 0xa5, 0xbb, 0x26, 0x4a, 0xf7, 0x49, 0x83, 0xab, 0x1a, 0x77, 0xe0, 0x45, 0x2d, 0x02, 0xc5, 0x0c, + 0x44, 0x8b, 0x1f, 0xe1, 0xdb, 0x03, 0xa1, 0xae, 0x0b, 0x42, 0xbd, 0x6b, 0xc8, 0x92, 0xd2, 0x97, + 0xeb, 0x5f, 0x67, 0xc1, 0x44, 0x1d, 0x79, 0xb8, 0x9b, 0x84, 0xe7, 0x65, 0x8e, 0x9c, 0x70, 0x6d, + 0x3b, 0x2b, 0xd9, 0xb6, 0xbf, 0x9b, 0x91, 0x0d, 0x93, 0x11, 0x4a, 0x86, 0xf1, 0x14, 0xb1, 0x08, + 0xf0, 0x7a, 0xa9, 0x30, 0x19, 0x83, 0xa8, 0xa5, 0x2f, 0xdd, 0xb7, 0x66, 0x83, 0x0d, 0xf6, 0xc7, + 0x08, 0x13, 0x34, 0xde, 0xbc, 0xcd, 0x1c, 0x34, 0x6f, 0xbf, 0x9d, 0x49, 0x6e, 0x6a, 0xc4, 0xed, + 0x2e, 0x27, 0x36, 0x28, 0x46, 0xb0, 0xf1, 0x3b, 0x8c, 0xbc, 0x9e, 0xad, 0x80, 0x02, 0x5b, 0x21, + 0xbe, 0x27, 0x7e, 0x85, 0x78, 0xf0, 0x14, 0xe1, 0x7d, 0x43, 0x98, 0x6b, 0x71, 0xcb, 0xb6, 0x01, + 0x1b, 0x59, 0x8e, 0x8d, 0x5b, 0x40, 0x9e, 0xc4, 0xf1, 0x63, 0xe3, 0x5c, 0xb8, 0x67, 0xef, 0x93, + 0xd0, 0xf0, 0x57, 0x9d, 0x66, 0x4a, 0x8c, 0xc2, 0x08, 0x56, 0x7a, 0x87, 0x41, 0xe1, 0x9f, 0x3f, + 0x95, 0x09, 0x8c, 0x90, 0xf7, 0xe5, 0x98, 0x89, 0xf7, 0x31, 0x31, 0xa2, 0x40, 0xcb, 0xb6, 0x3c, + 0xf4, 0x20, 0xb7, 0xb6, 0x1e, 0x24, 0xc4, 0x5a, 0x06, 0x67, 0xc0, 0x84, 0xe7, 0xf0, 0xeb, 0xed, + 0xfe, 0x2b, 0xdf, 0xe3, 0xe4, 0xc5, 0x1e, 0xa7, 0x0a, 0xce, 0x99, 0x56, 0xab, 0xb3, 0xdb, 0x46, + 0x3a, 0xea, 0x18, 0xb8, 0x56, 0x6e, 0xc9, 0x5d, 0x44, 0x5d, 0x64, 0xb5, 0x91, 0xe5, 0x51, 0x3e, + 0x7d, 0xdf, 0x5a, 0x89, 0x9c, 0xf0, 0xab, 0xbc, 0x62, 0xdc, 0x2d, 0x2a, 0xc6, 0xa3, 0xfb, 0xcd, + 0x0f, 0x62, 0x8c, 0xd0, 0x3b, 0x00, 0xa0, 0x75, 0x3b, 0x6f, 0xa2, 0xcb, 0xac, 0x43, 0xbc, 0xaa, + 0xc7, 0x14, 0xad, 0x05, 0x19, 0x74, 0x2e, 0x33, 0xfc, 0x62, 0xa0, 0x0c, 0xf7, 0x0a, 0xca, 0x70, + 0x8b, 0x24, 0x0b, 0xc9, 0xf4, 0xa0, 0x3b, 0xc4, 0x9a, 0xc5, 0x2c, 0x98, 0x0a, 0x57, 0x1a, 0x15, + 0xf5, 0x2a, 0x70, 0xca, 0xf7, 0x5d, 0xa8, 0x6a, 0xda, 0x62, 0xbd, 0xb9, 0xb1, 0xbe, 0xac, 0x97, + 0x16, 0xb5, 0x22, 0x50, 0x55, 0x30, 0x57, 0x5b, 0x78, 0x9a, 0x56, 0x6e, 0x04, 0x2e, 0x07, 0x39, + 0xf8, 0x97, 0x59, 0x90, 0x27, 0x8e, 0xe1, 0xf0, 0xa7, 0x46, 0xa4, 0x39, 0xae, 0xb0, 0x53, 0x13, + 0xcc, 0x2b, 0xe4, 0x23, 0xfd, 0x31, 0x61, 0x12, 0xae, 0x0e, 0x15, 0xe9, 0x2f, 0x86, 0x50, 0xfa, + 0xcd, 0x13, 0x37, 0xc9, 0xfa, 0xb6, 0x7d, 0xf9, 0x47, 0xb9, 0x49, 0xe2, 0xfa, 0x1f, 0x71, 0x93, + 0xec, 0xc3, 0xc2, 0xd8, 0x9b, 0x64, 0x9f, 0x76, 0x17, 0xd3, 0x4c, 0xe1, 0xb3, 0xf2, 0xc1, 0xc2, + 0xca, 0xf3, 0xb2, 0x87, 0x5a, 0x58, 0x29, 0x81, 0x59, 0xd3, 0xf2, 0x90, 0x63, 0x19, 0x9d, 0xa5, + 0x8e, 0xb1, 0xe5, 0x1f, 0x3f, 0xee, 0x9d, 0x85, 0x57, 0xb8, 0x3c, 0xba, 0xf8, 0x87, 0x7a, 0x16, + 0x00, 0x0f, 0xed, 0x74, 0x3b, 0x86, 0x17, 0xaa, 0x1e, 0x97, 0xc2, 0x6b, 0x5f, 0x4e, 0xd4, 0xbe, + 0xc7, 0x81, 0x2b, 0x28, 0x68, 0x8d, 0xfd, 0x2e, 0xda, 0xb0, 0xcc, 0x9f, 0xde, 0x25, 0x01, 0x68, + 0xa8, 0x8e, 0xf6, 0xfb, 0x84, 0xf5, 0xff, 0xb2, 0xe9, 0x6d, 0x97, 0xb7, 0x0d, 0xdf, 0xb3, 0x2f, + 0x78, 0x87, 0xff, 0x5d, 0xfa, 0x88, 0xa5, 0xdf, 0xea, 0x07, 0x1c, 0xb1, 0x0c, 0x5a, 0x9a, 0xd2, + 0xd3, 0xd2, 0x02, 0x63, 0x21, 0x27, 0x61, 0x2c, 0xf0, 0xa8, 0xe4, 0x25, 0x0d, 0xed, 0x57, 0x4b, + 0x9d, 0xe1, 0x8c, 0xab, 0xc6, 0x18, 0x26, 0x72, 0x0a, 0x98, 0xa3, 0x45, 0x2f, 0xd8, 0xf6, 0xa5, + 0x1d, 0xc3, 0xb9, 0x04, 0x9d, 0x43, 0xa9, 0x62, 0xec, 0x9a, 0x48, 0x80, 0xba, 0xd2, 0x83, 0xfa, + 0x27, 0x79, 0xd4, 0x97, 0x45, 0xd4, 0x1f, 0x1f, 0x2d, 0x2e, 0x9f, 0xe7, 0xf1, 0x2c, 0x8a, 0xbc, + 0x29, 0xc0, 0xf3, 0x69, 0x02, 0x9e, 0x4f, 0x4c, 0xcc, 0x60, 0xfa, 0xb8, 0xfe, 0x71, 0x80, 0xab, + 0xdf, 0xd1, 0xf3, 0xf3, 0xc9, 0x51, 0xe2, 0x0a, 0xbf, 0x34, 0x1c, 0x76, 0x3e, 0x5f, 0x43, 0x60, + 0x57, 0x04, 0xca, 0xa5, 0x60, 0x2b, 0x0a, 0x3f, 0xf2, 0x15, 0xca, 0xa5, 0x87, 0x66, 0x04, 0xcb, + 0x63, 0x41, 0xf3, 0xa4, 0xc8, 0x42, 0xad, 0x9b, 0x2a, 0xa6, 0x5f, 0x90, 0x5e, 0xa7, 0xe9, 0x2b, + 0x20, 0xca, 0xdd, 0x78, 0x5a, 0xa5, 0xdc, 0x22, 0x8f, 0x3c, 0x9b, 0xe9, 0xa3, 0xf9, 0x82, 0x3c, + 0x98, 0xf2, 0x0f, 0xc1, 0x92, 0xc8, 0xd8, 0x01, 0x86, 0xa7, 0x41, 0xc1, 0xb5, 0x77, 0x9d, 0x16, + 0x62, 0x2b, 0x67, 0xec, 0x6d, 0x88, 0x55, 0x9e, 0x81, 0xe3, 0xf9, 0x01, 0x93, 0x21, 0x97, 0xd8, + 0x64, 0x88, 0x36, 0x48, 0xe3, 0x06, 0xf8, 0x17, 0x4a, 0x87, 0x33, 0x14, 0x30, 0xab, 0x23, 0xef, + 0xe1, 0x38, 0xc6, 0xff, 0x81, 0xd4, 0x1a, 0xc2, 0x80, 0x9a, 0x24, 0x53, 0xb9, 0xda, 0x10, 0x86, + 0xea, 0xd5, 0xe0, 0x4a, 0x3f, 0x07, 0xb3, 0x50, 0x89, 0x45, 0xba, 0xa1, 0xaf, 0x16, 0x15, 0xf8, + 0xec, 0x1c, 0x28, 0x52, 0xd6, 0x6a, 0x81, 0xb1, 0x06, 0x5f, 0x9a, 0x39, 0x6a, 0x8b, 0x34, 0x7a, + 0x8a, 0xf9, 0xe9, 0xac, 0x6c, 0xc8, 0x24, 0x41, 0xf0, 0x61, 0xed, 0x22, 0x34, 0x69, 0x88, 0x66, + 0x16, 0xa3, 0x7c, 0xf0, 0x37, 0x33, 0x32, 0x11, 0x98, 0xe4, 0x58, 0x4c, 0xbf, 0x57, 0xfa, 0x5c, + 0xce, 0x8f, 0x65, 0xb0, 0xe4, 0xd8, 0x3b, 0x1b, 0x4e, 0x07, 0xfe, 0xdf, 0x52, 0x01, 0xee, 0x22, + 0xcc, 0xff, 0x6c, 0xb4, 0xf9, 0x5f, 0x04, 0xca, 0xae, 0xd3, 0xf1, 0x87, 0xef, 0x5d, 0xa7, 0x33, + 0xc4, 0xf0, 0xad, 0xde, 0x08, 0xe6, 0x8c, 0x76, 0x7b, 0xdd, 0xd8, 0x42, 0x65, 0x3c, 0xaf, 0xb6, + 0x3c, 0x76, 0xce, 0xb9, 0x27, 0x35, 0xb6, 0x2b, 0xfa, 0xaa, 0xf4, 0x4e, 0x9c, 0x00, 0x12, 0x93, + 0xcf, 0x58, 0x86, 0x37, 0x3c, 0x24, 0xb4, 0xb6, 0x8d, 0x30, 0xea, 0x02, 0x7b, 0x93, 0xdc, 0xa1, + 0x93, 0xe0, 0x3b, 0x7d, 0xcd, 0xfa, 0x9d, 0x2c, 0x98, 0xc0, 0xf2, 0x2e, 0xb5, 0xdb, 0xf0, 0x51, + 0x42, 0x70, 0x92, 0xc8, 0x3d, 0xd2, 0xe7, 0x4b, 0x6f, 0x4e, 0xfb, 0x35, 0xa4, 0xf4, 0x23, 0x30, + 0x09, 0x85, 0x98, 0x15, 0x84, 0x28, 0xb7, 0x07, 0x1d, 0x5b, 0x44, 0xfa, 0xe2, 0xfb, 0x44, 0x16, + 0xcc, 0xfa, 0xf3, 0x88, 0x25, 0xe4, 0xb5, 0xb6, 0xe1, 0x1d, 0xb2, 0x0b, 0x4d, 0xac, 0xa5, 0x65, + 0x83, 0x96, 0x06, 0x7f, 0x90, 0x49, 0xa8, 0xf2, 0x42, 0xc9, 0x11, 0xab, 0x74, 0x89, 0x74, 0x31, + 0x8e, 0x60, 0xfa, 0xc2, 0xfc, 0x62, 0x16, 0x80, 0x86, 0x1d, 0xcc, 0x75, 0x0f, 0x21, 0xc9, 0x17, + 0x4b, 0x47, 0x9b, 0x67, 0x15, 0x0f, 0x8b, 0x4d, 0xde, 0x73, 0x48, 0x6e, 0xb1, 0x0d, 0x2a, 0x69, + 0x2c, 0x6d, 0x7d, 0x6a, 0x71, 0xb7, 0xdb, 0x31, 0x5b, 0x86, 0xd7, 0xbb, 0x2f, 0x1c, 0x2d, 0x5e, + 0x72, 0x6d, 0x4c, 0x22, 0xa3, 0x30, 0x28, 0x23, 0x42, 0x96, 0xf4, 0xd0, 0x6c, 0xd6, 0x3f, 0x34, + 0x2b, 0xb9, 0xd7, 0x33, 0x80, 0xf8, 0x18, 0xd4, 0x53, 0x01, 0xc7, 0x6b, 0x5d, 0x64, 0x2d, 0x38, + 0xc8, 0x68, 0xb7, 0x9c, 0xdd, 0x9d, 0x8b, 0x2e, 0xef, 0xd4, 0x10, 0xaf, 0xa3, 0xdc, 0xd2, 0x71, + 0x56, 0x58, 0x3a, 0x86, 0xcf, 0x55, 0x64, 0x8f, 0x70, 0x73, 0x1b, 0x1c, 0x1c, 0x0f, 0x43, 0x0c, + 0x75, 0x89, 0xb6, 0xe2, 0x7a, 0x56, 0x89, 0x73, 0x49, 0x56, 0x89, 0xdf, 0x2c, 0x75, 0x20, 0x5c, + 0xaa, 0x5e, 0x63, 0xd9, 0x51, 0x9d, 0xab, 0x23, 0x2f, 0x02, 0xde, 0x1b, 0xc0, 0xec, 0xc5, 0xf0, + 0x4b, 0x00, 0xb1, 0x98, 0xd8, 0xc7, 0xcf, 0xe1, 0xad, 0x49, 0x57, 0x60, 0x44, 0x16, 0x22, 0xd0, + 0x0d, 0x10, 0xcc, 0xca, 0x6c, 0xa6, 0x26, 0x5a, 0x4e, 0x89, 0x2d, 0x3f, 0x7d, 0x14, 0x3e, 0x92, + 0x05, 0xd3, 0xe4, 0x32, 0x9c, 0x85, 0x7d, 0xe2, 0x65, 0x2f, 0x69, 0x94, 0xbc, 0x80, 0x17, 0xb3, + 0x0a, 0x72, 0x1d, 0xd3, 0xba, 0xe4, 0xef, 0x82, 0xe3, 0xe7, 0xf0, 0x6a, 0x85, 0x6c, 0x9f, 0xab, + 0x15, 0x82, 0x7d, 0x8a, 0xa0, 0xdc, 0x43, 0xdd, 0xf5, 0x35, 0x90, 0x5c, 0xfa, 0x62, 0xfc, 0xfb, + 0x1c, 0x28, 0xd4, 0x91, 0xe1, 0xb4, 0xb6, 0xe1, 0xfb, 0xb2, 0x7d, 0xa7, 0x0a, 0x93, 0xe2, 0x54, + 0x61, 0x09, 0x4c, 0x6c, 0x9a, 0x1d, 0x0f, 0x39, 0xd4, 0x33, 0x88, 0xef, 0xda, 0x69, 0x13, 0x5f, + 0xe8, 0xd8, 0xad, 0x4b, 0xf3, 0xcc, 0x74, 0x9f, 0xf7, 0x83, 0x42, 0xcd, 0x2f, 0x91, 0x9f, 0x74, + 0xff, 0x67, 0x6c, 0x10, 0xba, 0xb6, 0xe3, 0x45, 0x45, 0x59, 0x8d, 0xa0, 0x52, 0xb7, 0x1d, 0x4f, + 0xa7, 0x3f, 0x62, 0x98, 0x37, 0x77, 0x3b, 0x9d, 0x06, 0x7a, 0xd0, 0xf3, 0xa7, 0x6d, 0xfe, 0x3b, + 0x36, 0x16, 0xed, 0xcd, 0x4d, 0x17, 0xd1, 0x45, 0x83, 0xbc, 0xce, 0xde, 0xd4, 0x93, 0x20, 0xdf, + 0x31, 0x77, 0x4c, 0x3a, 0xd1, 0xc8, 0xeb, 0xf4, 0x45, 0xbd, 0x19, 0x14, 0xc3, 0x39, 0x0e, 0x65, + 0xf4, 0x4c, 0x81, 0x34, 0xcd, 0x03, 0xe9, 0x58, 0x67, 0x2e, 0xa1, 0x7d, 0xf7, 0xcc, 0x04, 0xf9, + 0x4e, 0x9e, 0x45, 0x37, 0x4c, 0x99, 0xfd, 0x0e, 0x2a, 0xf1, 0xe8, 0x19, 0xac, 0x83, 0x5a, 0xb6, + 0xd3, 0xf6, 0x65, 0x13, 0x3d, 0xc1, 0x60, 0xf9, 0x92, 0xed, 0x52, 0xf4, 0x2d, 0x3c, 0x7d, 0x4d, + 0x7b, 0x77, 0x01, 0x77, 0x9b, 0xb8, 0xe8, 0x0b, 0xa6, 0xb7, 0xbd, 0x86, 0x3c, 0x03, 0xfe, 0xbd, + 0xd2, 0x57, 0xe3, 0xa6, 0xff, 0xb7, 0xc6, 0x0d, 0xd0, 0x38, 0x7a, 0xdc, 0xdf, 0xdb, 0x75, 0x2c, + 0x2c, 0x47, 0x16, 0x60, 0x8b, 0x4b, 0x51, 0xef, 0x02, 0x57, 0x85, 0x6f, 0xfe, 0x52, 0xe9, 0x22, + 0x9b, 0xb6, 0x4e, 0x91, 0xec, 0xd1, 0x19, 0xd4, 0x75, 0x70, 0x3d, 0xfd, 0xb8, 0xd2, 0x58, 0x5b, + 0x5d, 0x31, 0xb7, 0xb6, 0x3b, 0xe6, 0xd6, 0xb6, 0xe7, 0x56, 0x2c, 0xd7, 0x43, 0x46, 0xbb, 0xb6, + 0xa9, 0xd3, 0xf8, 0xc8, 0x80, 0xd0, 0x91, 0xc9, 0x2a, 0x7a, 0x0e, 0xc9, 0x8d, 0x6e, 0xbc, 0xa6, + 0x44, 0xb4, 0x94, 0x27, 0xe2, 0x96, 0xe2, 0xee, 0x76, 0x02, 0x4c, 0xaf, 0xe9, 0xc1, 0x34, 0x54, + 0xf5, 0xdd, 0x0e, 0x69, 0x2e, 0x24, 0x73, 0xd2, 0x71, 0x2e, 0x86, 0x93, 0xf4, 0x9b, 0xcd, 0xff, + 0x57, 0x00, 0xf9, 0x65, 0xc7, 0xe8, 0x6e, 0xc3, 0x67, 0x73, 0xfd, 0xf3, 0xa8, 0xda, 0x44, 0xa0, + 0x9d, 0xd9, 0x41, 0xda, 0xa9, 0x0c, 0xd0, 0xce, 0x1c, 0xa7, 0x9d, 0xd1, 0x8b, 0xca, 0xe7, 0xc0, + 0x4c, 0xcb, 0xee, 0x74, 0x50, 0x0b, 0xcb, 0xa3, 0xd2, 0x26, 0xab, 0x39, 0x53, 0xba, 0x90, 0x46, + 0x02, 0xe7, 0x21, 0xaf, 0x4e, 0xd7, 0xd0, 0xa9, 0xd2, 0x87, 0x09, 0xf0, 0xa5, 0x59, 0x90, 0xd3, + 0xda, 0x5b, 0x48, 0x58, 0x67, 0xcf, 0x70, 0xeb, 0xec, 0xa7, 0x41, 0xc1, 0x33, 0x9c, 0x2d, 0xe4, + 0xf9, 0xeb, 0x04, 0xf4, 0x2d, 0x88, 0xe7, 0xa7, 0x70, 0xf1, 0xfc, 0x9e, 0x04, 0x72, 0x58, 0x66, + 0x2c, 0x52, 0xce, 0xf5, 0xfd, 0xe0, 0x27, 0xb2, 0x9f, 0xc7, 0x25, 0xce, 0xe3, 0x5a, 0xeb, 0xe4, + 0x87, 0x5e, 0xac, 0xf3, 0x07, 0xb0, 0x26, 0x57, 0xbd, 0xb4, 0x6c, 0xab, 0xb2, 0x63, 0x6c, 0x21, + 0x56, 0xcd, 0x30, 0xc1, 0xff, 0xaa, 0xed, 0xd8, 0x0f, 0x98, 0x2c, 0xb4, 0x5e, 0x98, 0x80, 0xab, + 0xb0, 0x6d, 0xb6, 0xdb, 0xc8, 0x62, 0x2d, 0x9b, 0xbd, 0x9d, 0x3b, 0x0b, 0x72, 0x98, 0x07, 0xac, + 0x3f, 0xd8, 0x58, 0x28, 0x1e, 0x53, 0x67, 0x70, 0xb3, 0xa2, 0x8d, 0xb7, 0x98, 0x11, 0xd7, 0x54, + 0x65, 0xdc, 0x76, 0x68, 0xe5, 0xfa, 0x37, 0xae, 0xc7, 0x82, 0xbc, 0x65, 0xb7, 0xd1, 0xc0, 0x41, + 0x88, 0xe6, 0x52, 0x9f, 0x00, 0xf2, 0xa8, 0x8d, 0x7b, 0x05, 0x85, 0x64, 0x3f, 0x1b, 0x2f, 0x4b, + 0x9d, 0x66, 0x4e, 0xe6, 0x1b, 0xd4, 0x8f, 0xdb, 0xf4, 0x1b, 0xe0, 0x2f, 0x4e, 0x80, 0xe3, 0xb4, + 0x0f, 0xa8, 0xef, 0x5e, 0xc4, 0xa4, 0x2e, 0x22, 0xf8, 0xfa, 0xfe, 0x03, 0xd7, 0x71, 0x51, 0xd9, + 0x4f, 0x82, 0xbc, 0xbb, 0x7b, 0x31, 0x30, 0x42, 0xe9, 0x0b, 0xdf, 0x74, 0xb3, 0x23, 0x19, 0xce, + 0x94, 0x61, 0x87, 0x33, 0x61, 0x68, 0x52, 0xfc, 0xc6, 0x1f, 0x0e, 0x64, 0x05, 0x92, 0xec, 0x0f, + 0x64, 0xfd, 0x86, 0xa1, 0x33, 0x60, 0xc2, 0xd8, 0xf4, 0x90, 0x13, 0x9a, 0x89, 0xec, 0x15, 0x0f, + 0x95, 0x17, 0xd1, 0xa6, 0xed, 0x60, 0xb1, 0x4c, 0xd1, 0xa1, 0xd2, 0x7f, 0xe7, 0x5a, 0x2e, 0x10, + 0x76, 0xc8, 0x6e, 0x01, 0x27, 0x2c, 0x7b, 0x11, 0x75, 0x99, 0x9c, 0x29, 0x8a, 0xb3, 0xa4, 0x05, + 0x1c, 0xfc, 0x70, 0xa0, 0x2b, 0x99, 0x3b, 0xd8, 0x95, 0xc0, 0x4f, 0x25, 0x9d, 0x33, 0xf7, 0x00, + 0x3d, 0x32, 0x0b, 0x4d, 0x7d, 0x0a, 0x98, 0x69, 0x33, 0x17, 0xad, 0x96, 0x19, 0xb4, 0x92, 0xc8, + 0xff, 0x84, 0xcc, 0xa1, 0x22, 0xe5, 0x78, 0x45, 0x5a, 0x06, 0x93, 0xe4, 0x40, 0x0e, 0xd6, 0xa4, + 0x7c, 0x4f, 0xdc, 0x41, 0x32, 0xad, 0x0b, 0x2a, 0xc5, 0x89, 0x6d, 0xbe, 0xcc, 0x7e, 0xd1, 0x83, + 0x9f, 0x93, 0xcd, 0xbe, 0xe3, 0x25, 0x94, 0x7e, 0x73, 0x7c, 0x4b, 0x01, 0x5c, 0x55, 0x76, 0x6c, + 0xd7, 0x25, 0xd1, 0x24, 0x7a, 0x1b, 0xe6, 0x1b, 0xb3, 0x42, 0x64, 0xdf, 0x87, 0x75, 0xf3, 0xeb, + 0xd7, 0xa0, 0xc6, 0xd7, 0x34, 0xbe, 0x2a, 0x7d, 0x24, 0x39, 0xd8, 0x7f, 0x88, 0x10, 0xfa, 0x8f, + 0x46, 0x23, 0x79, 0x77, 0x46, 0xe6, 0x94, 0x74, 0x42, 0x59, 0xa5, 0xdf, 0x5c, 0xbe, 0x90, 0x05, + 0x57, 0xf7, 0x72, 0xb3, 0x61, 0xb9, 0x41, 0x83, 0xb9, 0x76, 0x40, 0x7b, 0x11, 0x4f, 0xd5, 0xc6, + 0xde, 0x64, 0x12, 0x51, 0x77, 0xae, 0xb4, 0x88, 0xc5, 0x92, 0xf7, 0x66, 0x64, 0x6e, 0x32, 0x49, + 0x4c, 0x3e, 0x7d, 0xe1, 0x7e, 0x3a, 0x07, 0x8e, 0x2f, 0x3b, 0xf6, 0x6e, 0xd7, 0x0d, 0x7b, 0xa0, + 0xbf, 0xed, 0xbf, 0xe1, 0x5a, 0x90, 0x31, 0x0d, 0xae, 0x03, 0xd3, 0x0e, 0xb3, 0xe6, 0xc2, 0xed, + 0x57, 0x3e, 0x89, 0xef, 0xbd, 0x94, 0xc3, 0xf4, 0x5e, 0x61, 0x3f, 0x93, 0x13, 0xfa, 0x99, 0xde, + 0x9e, 0x23, 0xdf, 0xa7, 0xe7, 0xf8, 0x9b, 0x6c, 0xc2, 0x41, 0xb5, 0x47, 0x44, 0x11, 0xfd, 0x45, + 0x19, 0x14, 0xb6, 0x48, 0x46, 0xd6, 0x5d, 0x3c, 0x46, 0xae, 0x66, 0x84, 0xb8, 0xce, 0x7e, 0x0d, + 0xe5, 0xaa, 0xf0, 0x3a, 0x9c, 0x68, 0x80, 0x8b, 0xe7, 0x36, 0x7d, 0xa5, 0x7a, 0x4d, 0x0e, 0xcc, + 0x04, 0xa5, 0x57, 0xda, 0x2e, 0x7c, 0x41, 0x7f, 0x8d, 0x9a, 0x95, 0xd1, 0xa8, 0x03, 0xeb, 0xcc, + 0xc1, 0xa8, 0xa3, 0x70, 0xa3, 0x4e, 0xdf, 0xd1, 0x65, 0x26, 0x62, 0x74, 0x81, 0xcf, 0x52, 0x64, + 0x63, 0xe3, 0x8b, 0x5d, 0x2b, 0xa9, 0xcd, 0xc3, 0x79, 0xb0, 0x90, 0x8c, 0xd0, 0x3f, 0xb8, 0x56, + 0xe9, 0x2b, 0xc9, 0x07, 0xb3, 0xe0, 0xc4, 0xc1, 0xce, 0xfc, 0x91, 0xa2, 0x17, 0x1a, 0xae, 0x93, + 0x1b, 0x78, 0xa1, 0x91, 0x37, 0x71, 0x93, 0x2e, 0xf6, 0x68, 0xac, 0x60, 0xef, 0x0d, 0xee, 0xc4, + 0xe5, 0x0e, 0xbf, 0x4a, 0x12, 0x4d, 0x5f, 0x80, 0xbf, 0xa2, 0x80, 0xa9, 0x3a, 0xf2, 0x56, 0x8d, + 0x7d, 0x7b, 0xd7, 0x83, 0x86, 0xec, 0xf6, 0xdc, 0x93, 0x41, 0xa1, 0x43, 0x7e, 0x61, 0x17, 0x3d, + 0x5e, 0xd7, 0x77, 0x7f, 0x8b, 0xf8, 0xfe, 0x50, 0xd2, 0x3a, 0xcb, 0x2f, 0x9e, 0x49, 0x96, 0xd9, + 0x1d, 0x0d, 0xb8, 0x1b, 0xc9, 0xd6, 0x4e, 0xa2, 0xbd, 0xd3, 0xa8, 0xa2, 0xd3, 0x87, 0xe5, 0xb9, + 0x0a, 0x98, 0xad, 0x23, 0xaf, 0xe2, 0x2e, 0x19, 0x7b, 0xb6, 0x63, 0x7a, 0x88, 0xbf, 0x73, 0x28, + 0x1e, 0x9a, 0xb3, 0x00, 0x98, 0xc1, 0x6f, 0xec, 0xd2, 0x09, 0x2e, 0x05, 0xfe, 0x66, 0x52, 0x47, + 0x21, 0x81, 0x8f, 0x91, 0x80, 0x90, 0xc8, 0xc7, 0x22, 0xae, 0xf8, 0xf4, 0x81, 0xf8, 0x7c, 0x96, + 0x01, 0x51, 0x72, 0x5a, 0xdb, 0xe6, 0x1e, 0x6a, 0x27, 0x04, 0xc2, 0xff, 0x2d, 0x04, 0x22, 0x20, + 0x94, 0xd8, 0x7d, 0x45, 0xe0, 0x63, 0x14, 0xee, 0x2b, 0x71, 0x04, 0xc7, 0x12, 0xec, 0x00, 0x77, + 0x3d, 0x6c, 0x3d, 0xf3, 0x1e, 0x59, 0xb1, 0x86, 0x26, 0x5b, 0x96, 0x37, 0xd9, 0x86, 0xea, 0x58, + 0x68, 0xd9, 0x83, 0x74, 0x3a, 0x97, 0x46, 0xc7, 0xd2, 0xb7, 0xe8, 0xf4, 0x85, 0xfe, 0x5e, 0x05, + 0x9c, 0x0a, 0x4e, 0x01, 0xd7, 0x91, 0xb7, 0x68, 0xb8, 0xdb, 0x17, 0x6d, 0xc3, 0x69, 0xf3, 0x17, + 0x80, 0x0e, 0x7d, 0xe2, 0x0f, 0x7e, 0x8e, 0x07, 0xa1, 0x2a, 0x82, 0xd0, 0xd7, 0x55, 0xb4, 0x2f, + 0x2f, 0xa3, 0xe8, 0x64, 0x62, 0xbd, 0x59, 0x7f, 0x2b, 0x00, 0xeb, 0xe9, 0x02, 0x58, 0x77, 0x0f, + 0xcb, 0x62, 0xfa, 0xc0, 0xfd, 0x1a, 0x1d, 0x11, 0x38, 0xaf, 0xe6, 0xfb, 0x65, 0x01, 0x8b, 0xf0, + 0x6a, 0x55, 0x22, 0xbd, 0x5a, 0x87, 0x1a, 0x23, 0x06, 0x7a, 0x24, 0xa7, 0x3b, 0x46, 0x1c, 0xa1, + 0xb7, 0xf1, 0x3b, 0x15, 0x50, 0x24, 0x61, 0x20, 0x38, 0x8f, 0x6f, 0xf8, 0x80, 0x2c, 0x3a, 0x07, + 0xbc, 0xcb, 0x27, 0x92, 0x7a, 0x97, 0xc3, 0x77, 0x24, 0xf5, 0x21, 0xef, 0xe5, 0x76, 0x24, 0x88, + 0x25, 0x72, 0x11, 0x1f, 0xc0, 0x41, 0xfa, 0xa0, 0xfd, 0x27, 0x05, 0x00, 0xdc, 0xa0, 0xd9, 0xd9, + 0x87, 0x67, 0xc8, 0xc2, 0x75, 0x2b, 0xef, 0x57, 0x8f, 0x81, 0x3a, 0xd5, 0x03, 0x14, 0xa5, 0x18, + 0x9e, 0xaa, 0x78, 0x7d, 0x52, 0xdf, 0xca, 0x90, 0xab, 0x91, 0xc0, 0x92, 0xc8, 0xdb, 0x32, 0xb2, + 0xec, 0xf4, 0x01, 0xf9, 0xaf, 0x59, 0x90, 0x6f, 0xd8, 0x75, 0xe4, 0x1d, 0xde, 0x14, 0x48, 0x7c, + 0x6c, 0x9f, 0x94, 0x3b, 0x8a, 0x63, 0xfb, 0xfd, 0x08, 0xa5, 0x2f, 0xba, 0xf7, 0x64, 0xc1, 0x4c, + 0xc3, 0x2e, 0x07, 0x8b, 0x53, 0xf2, 0xbe, 0xaa, 0xf2, 0xf7, 0xfb, 0x05, 0x15, 0x0c, 0x8b, 0x39, + 0xd4, 0xfd, 0x7e, 0x83, 0xe9, 0xa5, 0x2f, 0xb7, 0x3b, 0xc0, 0xf1, 0x0d, 0xab, 0x6d, 0xeb, 0xa8, + 0x6d, 0xb3, 0x95, 0x6e, 0x55, 0x05, 0xb9, 0x5d, 0xab, 0x6d, 0x13, 0x96, 0xf3, 0x3a, 0x79, 0xc6, + 0x69, 0x0e, 0x6a, 0xdb, 0xcc, 0x37, 0x80, 0x3c, 0xc3, 0xaf, 0x2a, 0x20, 0x87, 0xff, 0x95, 0x17, + 0xf5, 0x3b, 0x95, 0x84, 0x81, 0x08, 0x30, 0xf9, 0x91, 0x58, 0x42, 0xf7, 0x70, 0x6b, 0xff, 0xd4, + 0x83, 0xf5, 0xfa, 0xa8, 0xf2, 0x38, 0x51, 0x84, 0x6b, 0xfe, 0xea, 0x19, 0x30, 0x71, 0xb1, 0x63, + 0xb7, 0x2e, 0x85, 0xe7, 0xe5, 0xd9, 0xab, 0x7a, 0x33, 0xc8, 0x3b, 0x86, 0xb5, 0x85, 0xd8, 0x9e, + 0xc2, 0xc9, 0x9e, 0xbe, 0x90, 0x78, 0xbd, 0xe8, 0x34, 0x0b, 0x7c, 0x47, 0x92, 0x10, 0x08, 0x7d, + 0x2a, 0x9f, 0x4c, 0x1f, 0x16, 0x87, 0x38, 0x59, 0x56, 0x04, 0x33, 0xe5, 0x12, 0xbd, 0x49, 0x73, + 0xad, 0x76, 0x5e, 0x2b, 0x2a, 0x04, 0x66, 0x2c, 0x93, 0x14, 0x61, 0xc6, 0xe4, 0x7f, 0x64, 0x61, + 0xee, 0x53, 0xf9, 0xa3, 0x80, 0xf9, 0x13, 0x59, 0x30, 0xbb, 0x6a, 0xba, 0x5e, 0x94, 0xb7, 0x7f, + 0x4c, 0x14, 0xb8, 0x17, 0x26, 0x35, 0x95, 0x85, 0x72, 0xa4, 0xc3, 0xbf, 0x25, 0x32, 0x87, 0xe3, + 0x8a, 0x18, 0xcf, 0xb1, 0x14, 0xc2, 0x01, 0xbd, 0xfd, 0x4e, 0x5a, 0x92, 0x89, 0x0d, 0xa5, 0xb0, + 0x90, 0xf1, 0x1b, 0x4a, 0x91, 0x65, 0xa7, 0x2f, 0xdf, 0xaf, 0x66, 0xc1, 0x09, 0x5c, 0x7c, 0xdc, + 0xb2, 0x54, 0xb4, 0x98, 0x07, 0x2e, 0x4b, 0x25, 0x5e, 0x19, 0x3f, 0xc0, 0xcb, 0x28, 0x56, 0xc6, + 0x07, 0x11, 0x1d, 0xb3, 0x98, 0x23, 0x96, 0x61, 0x07, 0x89, 0x39, 0x66, 0x19, 0x76, 0x78, 0x31, + 0xc7, 0x2f, 0xc5, 0x0e, 0x29, 0xe6, 0x23, 0x5b, 0x60, 0x7d, 0x9d, 0x12, 0x88, 0x39, 0x72, 0x6d, + 0x23, 0x46, 0xcc, 0x89, 0x4f, 0xec, 0xc2, 0x77, 0x0d, 0x29, 0xf8, 0x11, 0xaf, 0x6f, 0x0c, 0x03, + 0xd3, 0x11, 0xae, 0x71, 0xfc, 0xba, 0x02, 0xe6, 0x18, 0x17, 0xfd, 0xa7, 0xcc, 0x31, 0x18, 0x25, + 0x9e, 0x32, 0x27, 0x3e, 0x03, 0x24, 0x72, 0x36, 0xfe, 0x33, 0x40, 0xb1, 0xe5, 0xa7, 0x0f, 0xce, + 0xd7, 0x73, 0xe0, 0x34, 0x66, 0x61, 0xcd, 0x6e, 0x9b, 0x9b, 0xfb, 0x94, 0x8b, 0xf3, 0x46, 0x67, + 0x17, 0xb9, 0xf0, 0xfd, 0x59, 0x59, 0x94, 0xfe, 0x1d, 0x00, 0x76, 0x17, 0x39, 0x34, 0x90, 0x1a, + 0x03, 0xea, 0xae, 0xa8, 0xca, 0x1e, 0x2c, 0x29, 0x08, 0x6e, 0x5e, 0xf3, 0x89, 0xe8, 0x1c, 0x3d, + 0x6c, 0x15, 0x4e, 0x05, 0x5f, 0x7a, 0x1d, 0x3c, 0x32, 0x07, 0x1d, 0x3c, 0x6e, 0x02, 0x8a, 0xd1, + 0x6e, 0x07, 0x50, 0xf5, 0x6e, 0x66, 0x93, 0x32, 0x75, 0x9c, 0x05, 0xe7, 0x74, 0x51, 0x78, 0x34, + 0x2f, 0x22, 0xa7, 0x8b, 0x3c, 0x75, 0x1e, 0x14, 0xe8, 0x4d, 0x80, 0xc1, 0x8a, 0x7e, 0xff, 0xcc, + 0x2c, 0x97, 0x68, 0xda, 0xd5, 0x44, 0x35, 0xbc, 0x23, 0x91, 0x64, 0xfa, 0xf5, 0xd3, 0xa1, 0x9d, + 0xac, 0x0b, 0x0a, 0xf6, 0xd4, 0xa1, 0x29, 0x8f, 0x67, 0x37, 0xac, 0xd4, 0xed, 0x76, 0xf6, 0x1b, + 0x2c, 0xf8, 0x4a, 0xa2, 0xdd, 0x30, 0x2e, 0x86, 0x4b, 0xb6, 0x37, 0x86, 0x4b, 0xf2, 0xdd, 0x30, + 0x81, 0x8f, 0x51, 0xec, 0x86, 0xc5, 0x11, 0x1c, 0xc3, 0x7a, 0x64, 0x9e, 0x5a, 0xcd, 0x2c, 0x46, + 0xed, 0x9b, 0xfa, 0x1f, 0x42, 0x03, 0xa2, 0xb3, 0x4b, 0xbf, 0xf0, 0xb5, 0xb1, 0xb1, 0xb9, 0xd5, + 0x27, 0x80, 0xc2, 0xa6, 0xed, 0xec, 0x18, 0xfe, 0xc6, 0x7d, 0xef, 0x49, 0x11, 0x16, 0x17, 0x76, + 0x89, 0xe4, 0xd1, 0x59, 0x5e, 0x3c, 0x1f, 0x79, 0xa6, 0xd9, 0x65, 0x51, 0x17, 0xf1, 0xa3, 0x7a, + 0x03, 0x98, 0x65, 0xc1, 0x17, 0xab, 0xc8, 0xf5, 0x50, 0x9b, 0x45, 0xac, 0x10, 0x13, 0xd5, 0x73, + 0x60, 0x86, 0x25, 0x2c, 0x99, 0x1d, 0xe4, 0xb2, 0xa0, 0x15, 0x42, 0x9a, 0x7a, 0x1a, 0x14, 0x4c, + 0xf7, 0x69, 0xae, 0x6d, 0x11, 0xff, 0xff, 0x49, 0x9d, 0xbd, 0xa9, 0x37, 0x81, 0xe3, 0x2c, 0x5f, + 0x60, 0xac, 0xd2, 0x03, 0x3b, 0xbd, 0xc9, 0xf0, 0x33, 0xc3, 0x4c, 0x1c, 0x12, 0xc7, 0xe3, 0xc5, + 0x28, 0xec, 0xb6, 0x5a, 0x08, 0xb5, 0xd9, 0xc9, 0x26, 0xff, 0x35, 0x61, 0xa4, 0xde, 0xc4, 0xd3, + 0x8c, 0x23, 0x0a, 0xd5, 0xfb, 0xa1, 0x53, 0xa0, 0x40, 0xaf, 0xaf, 0x80, 0x2f, 0x99, 0xeb, 0xab, + 0x8c, 0x73, 0xa2, 0x32, 0x6e, 0x80, 0x19, 0xcb, 0xc6, 0xc5, 0xad, 0x1b, 0x8e, 0xb1, 0xe3, 0xc6, + 0xad, 0x22, 0x52, 0xba, 0xc1, 0x90, 0x51, 0xe5, 0x7e, 0x5b, 0x39, 0xa6, 0x0b, 0x64, 0xd4, 0xff, + 0x03, 0x1c, 0xbf, 0xc8, 0x22, 0x00, 0xb8, 0x8c, 0x72, 0x36, 0xda, 0xc7, 0xae, 0x87, 0xf2, 0x82, + 0xf8, 0xe7, 0xca, 0x31, 0xbd, 0x97, 0x98, 0xfa, 0x93, 0x60, 0x0e, 0xbf, 0xb6, 0xed, 0xcb, 0x3e, + 0xe3, 0x4a, 0xb4, 0xa1, 0xd1, 0x43, 0x7e, 0x4d, 0xf8, 0x71, 0xe5, 0x98, 0xde, 0x43, 0x4a, 0xad, + 0x01, 0xb0, 0xed, 0xed, 0x74, 0x18, 0xe1, 0x5c, 0xb4, 0x4a, 0xf6, 0x10, 0x5e, 0x09, 0x7e, 0x5a, + 0x39, 0xa6, 0x73, 0x24, 0xd4, 0x55, 0x30, 0xe5, 0x3d, 0xe8, 0x31, 0x7a, 0xf9, 0xe8, 0xcd, 0xed, + 0x1e, 0x7a, 0x0d, 0xff, 0x9f, 0x95, 0x63, 0x7a, 0x48, 0x40, 0xad, 0x80, 0xc9, 0xee, 0x45, 0x46, + 0xac, 0xd0, 0xe7, 0xca, 0xfe, 0xfe, 0xc4, 0xd6, 0x2f, 0x06, 0xb4, 0x82, 0xdf, 0x31, 0x63, 0x2d, + 0x77, 0x8f, 0xd1, 0x9a, 0x90, 0x66, 0xac, 0xec, 0xff, 0x83, 0x19, 0x0b, 0x08, 0xa8, 0x15, 0x30, + 0xe5, 0x5a, 0x46, 0xd7, 0xdd, 0xb6, 0x3d, 0xf7, 0xcc, 0x64, 0x8f, 0x1f, 0x64, 0x34, 0xb5, 0x3a, + 0xfb, 0x47, 0x0f, 0xff, 0x56, 0x9f, 0x00, 0x4e, 0xed, 0x92, 0x6b, 0x40, 0xb5, 0x07, 0x4d, 0xd7, + 0x33, 0xad, 0x2d, 0x3f, 0x86, 0x2c, 0xed, 0x4d, 0xfa, 0x7f, 0x54, 0xe7, 0xd9, 0x89, 0x28, 0x40, + 0xda, 0x26, 0xec, 0xdd, 0x8c, 0xa3, 0xc5, 0x72, 0x07, 0xa1, 0x9e, 0x02, 0x72, 0xf8, 0x13, 0x39, + 0xb3, 0x39, 0xd7, 0x7f, 0xa1, 0xaf, 0x57, 0x77, 0x48, 0x03, 0xc6, 0x3f, 0xe1, 0xb1, 0xd1, 0xb2, + 0xd7, 0x1d, 0x7b, 0xcb, 0x41, 0xae, 0xcb, 0x1c, 0x0e, 0xb9, 0x14, 0xdc, 0xc0, 0x4d, 0x77, 0xcd, + 0xdc, 0xa2, 0xd6, 0x13, 0xf3, 0x77, 0xe7, 0x93, 0xe8, 0x6c, 0xb3, 0x8a, 0x2e, 0x13, 0x87, 0x60, + 0x72, 0xfe, 0x86, 0xcc, 0x36, 0xfd, 0x14, 0x78, 0x23, 0x98, 0xe1, 0x1b, 0x19, 0xbd, 0x03, 0xcb, + 0x0c, 0x6d, 0x2f, 0xf6, 0x06, 0x6f, 0x00, 0x73, 0xa2, 0x4e, 0x73, 0x43, 0x8c, 0xe2, 0x77, 0x85, + 0xf0, 0x7a, 0x70, 0xbc, 0xa7, 0x61, 0xf9, 0x31, 0x45, 0x32, 0x61, 0x4c, 0x91, 0xeb, 0x00, 0x08, + 0xb5, 0xb8, 0x2f, 0x99, 0x6b, 0xc1, 0x54, 0xa0, 0x97, 0x7d, 0x33, 0x7c, 0x39, 0x03, 0x26, 0x7d, + 0x65, 0xeb, 0x97, 0x01, 0x8f, 0x2f, 0x16, 0xb7, 0x81, 0xc0, 0xa6, 0xd9, 0x42, 0x1a, 0x1e, 0x47, + 0x42, 0xb7, 0xdd, 0x86, 0xe9, 0x75, 0xfc, 0xa3, 0x6f, 0xbd, 0xc9, 0xea, 0x3a, 0x00, 0x26, 0xc1, + 0xa8, 0x11, 0x9e, 0x85, 0x7b, 0x5c, 0x82, 0xf6, 0x40, 0xf5, 0x81, 0xa3, 0x71, 0xee, 0x91, 0xec, + 0xa0, 0xda, 0x14, 0xc8, 0xd7, 0xd7, 0x4b, 0x65, 0xad, 0x78, 0x4c, 0x9d, 0x03, 0x40, 0x7b, 0xc6, + 0xba, 0xa6, 0x57, 0xb4, 0x6a, 0x59, 0x2b, 0x66, 0xe0, 0xcb, 0xb2, 0x60, 0x2a, 0x68, 0x04, 0x7d, + 0x2b, 0xa9, 0x31, 0xd5, 0x1a, 0x78, 0xcd, 0xd0, 0xc1, 0x46, 0xc5, 0x2b, 0xd9, 0x93, 0xc1, 0x95, + 0xbb, 0x2e, 0x5a, 0x32, 0x1d, 0xd7, 0xd3, 0xed, 0xcb, 0x4b, 0xb6, 0x13, 0x44, 0x4d, 0xf6, 0xaf, + 0xd3, 0x8f, 0xf8, 0x8c, 0x2d, 0x8a, 0x36, 0x22, 0x87, 0xa2, 0x90, 0xc3, 0x56, 0x86, 0xc3, 0x04, + 0x4c, 0xd7, 0xa3, 0xf7, 0xd7, 0xbb, 0x48, 0xb7, 0x2f, 0xbb, 0x25, 0xab, 0x5d, 0xb6, 0x3b, 0xbb, + 0x3b, 0x96, 0xcb, 0x6c, 0x82, 0xa8, 0xcf, 0x58, 0x3a, 0xe4, 0x12, 0xb1, 0x39, 0x00, 0xca, 0xb5, + 0xd5, 0x55, 0xad, 0xdc, 0xa8, 0xd4, 0xaa, 0xc5, 0x63, 0x58, 0x5a, 0x8d, 0xd2, 0xc2, 0x2a, 0x96, + 0xce, 0x4f, 0x81, 0x49, 0xbf, 0x4d, 0xb3, 0x30, 0x28, 0x19, 0x3f, 0x0c, 0x8a, 0x5a, 0x02, 0x93, + 0x7e, 0x2b, 0x67, 0x23, 0xc2, 0xa3, 0x7a, 0x8f, 0xbd, 0xee, 0x18, 0x8e, 0x47, 0xfc, 0xa5, 0x7d, + 0x22, 0x0b, 0x86, 0x8b, 0xf4, 0xe0, 0xb7, 0x73, 0x8f, 0x65, 0x1c, 0xa8, 0x60, 0xae, 0xb4, 0xba, + 0xda, 0xac, 0xe9, 0xcd, 0x6a, 0xad, 0xb1, 0x52, 0xa9, 0x2e, 0xd3, 0x11, 0xb2, 0xb2, 0x5c, 0xad, + 0xe9, 0x1a, 0x1d, 0x20, 0xeb, 0xc5, 0x0c, 0xbd, 0xc4, 0x6e, 0x61, 0x12, 0x14, 0xba, 0x44, 0xba, + 0xf0, 0x0b, 0x4a, 0xc2, 0xf3, 0xee, 0x01, 0x4e, 0x11, 0xd7, 0x6c, 0x09, 0x3e, 0xe7, 0xd9, 0x3e, + 0x67, 0x42, 0xcf, 0x81, 0x19, 0x6a, 0xcb, 0xb9, 0x64, 0xf9, 0x9e, 0xdd, 0x54, 0x2b, 0xa4, 0xc1, + 0x8f, 0x64, 0x13, 0x1c, 0x82, 0xef, 0xcb, 0x51, 0x32, 0xe3, 0xe2, 0x2f, 0x86, 0xb9, 0xb4, 0x4e, + 0x05, 0x73, 0x95, 0x6a, 0x43, 0xd3, 0xab, 0xa5, 0x55, 0x96, 0x45, 0x51, 0xcf, 0x80, 0x93, 0xd5, + 0x1a, 0x8b, 0xe9, 0x57, 0x27, 0xd7, 0x63, 0xaf, 0xad, 0xd7, 0xf4, 0x46, 0x31, 0xaf, 0x9e, 0x06, + 0x2a, 0x7d, 0x16, 0x6e, 0x97, 0x2f, 0xa8, 0x8f, 0x06, 0xd7, 0xaf, 0x56, 0xd6, 0x2a, 0x8d, 0x66, + 0x6d, 0xa9, 0xa9, 0xd7, 0x2e, 0xd4, 0x31, 0x82, 0xba, 0xb6, 0x5a, 0xc2, 0x8a, 0xc4, 0x5d, 0x66, + 0x37, 0xa1, 0x5e, 0x01, 0x8e, 0x93, 0x8b, 0x2a, 0xc9, 0x0d, 0xf5, 0xb4, 0xbc, 0x49, 0xf5, 0x1a, + 0x70, 0xa6, 0x52, 0xad, 0x6f, 0x2c, 0x2d, 0x55, 0xca, 0x15, 0xad, 0xda, 0x68, 0xae, 0x6b, 0xfa, + 0x5a, 0xa5, 0x5e, 0xc7, 0xff, 0x16, 0xa7, 0xe0, 0x87, 0x14, 0x50, 0xa0, 0x7d, 0x26, 0x7c, 0x9f, + 0x02, 0x66, 0xcf, 0x1b, 0x1d, 0x13, 0x0f, 0x14, 0xe4, 0x0e, 0xc1, 0x9e, 0xe3, 0x22, 0x1e, 0xb9, + 0x6b, 0x90, 0x39, 0x9c, 0x93, 0x17, 0xf8, 0x73, 0x4a, 0xc2, 0xe3, 0x22, 0x0c, 0x08, 0x5a, 0xe2, + 0xbc, 0x50, 0x5a, 0xc4, 0xe4, 0xe6, 0xd5, 0xd9, 0x04, 0xc7, 0x45, 0xe4, 0xc9, 0x27, 0x03, 0xff, + 0x37, 0x46, 0x05, 0x7e, 0x11, 0xcc, 0x6c, 0x54, 0x4b, 0x1b, 0x8d, 0x95, 0x9a, 0x5e, 0xf9, 0x09, + 0x12, 0x6d, 0x7c, 0x16, 0x4c, 0x2d, 0xd5, 0xf4, 0x85, 0xca, 0xe2, 0xa2, 0x56, 0x2d, 0xe6, 0xd5, + 0x2b, 0xc1, 0x15, 0x75, 0x4d, 0x3f, 0x5f, 0x29, 0x6b, 0xcd, 0x8d, 0x6a, 0xe9, 0x7c, 0xa9, 0xb2, + 0x4a, 0xfa, 0x88, 0x42, 0xcc, 0xfd, 0x87, 0x13, 0xf0, 0x67, 0x72, 0x00, 0xd0, 0xaa, 0x63, 0x4b, + 0x9a, 0xbf, 0x25, 0xef, 0x2f, 0x93, 0x4e, 0x1a, 0x42, 0x32, 0x11, 0xed, 0xb7, 0x02, 0x26, 0x1d, + 0xf6, 0x81, 0x2d, 0x9f, 0x0c, 0xa2, 0x43, 0x1f, 0x7d, 0x6a, 0x7a, 0xf0, 0x3b, 0x7c, 0x7f, 0x92, + 0x39, 0x42, 0x24, 0x63, 0xc9, 0x90, 0x5c, 0x1a, 0x0d, 0x90, 0xf0, 0x05, 0x19, 0x30, 0x27, 0x56, + 0x0c, 0x57, 0x82, 0x18, 0x53, 0x72, 0x95, 0x10, 0x7f, 0xe6, 0x8c, 0xac, 0x73, 0xb7, 0xb3, 0xe1, + 0x14, 0xf8, 0x2d, 0x93, 0x9e, 0xfc, 0xf6, 0x2d, 0x96, 0x62, 0x06, 0x33, 0x8f, 0x8d, 0x0e, 0x7a, + 0x45, 0x7a, 0xe3, 0x41, 0xaf, 0xa8, 0xc0, 0xf7, 0xe4, 0xc0, 0xac, 0x70, 0x0d, 0x1f, 0xfc, 0x76, + 0x46, 0xe6, 0x6a, 0x2d, 0xee, 0x82, 0xbf, 0xcc, 0x61, 0x2f, 0xf8, 0x3b, 0xf7, 0xb3, 0x19, 0x30, + 0xc1, 0x12, 0x89, 0x80, 0x6b, 0x55, 0x6c, 0x0b, 0x1c, 0x07, 0xd3, 0xcb, 0x5a, 0xa3, 0x59, 0x6f, + 0x94, 0xf4, 0x86, 0xb6, 0x58, 0xcc, 0xa8, 0xa7, 0xc0, 0x89, 0x75, 0x4d, 0xaf, 0xd7, 0xb0, 0x3c, + 0xd7, 0xf5, 0x1a, 0xe9, 0x08, 0xa9, 0x98, 0x31, 0x0c, 0xab, 0xda, 0xe2, 0xb2, 0xd6, 0x5c, 0x28, + 0xd5, 0xb5, 0xa2, 0x82, 0xff, 0xad, 0xd6, 0x1a, 0x5a, 0xbd, 0xb9, 0x58, 0x29, 0xe9, 0xf7, 0x17, + 0x73, 0xf8, 0xdf, 0x7a, 0x43, 0x2f, 0x35, 0xb4, 0xe5, 0x4a, 0x99, 0x5c, 0x2c, 0x8f, 0x5b, 0x40, + 0x1e, 0x0f, 0xa6, 0xda, 0xda, 0x7a, 0xe3, 0xfe, 0x62, 0x21, 0xb9, 0x57, 0x5f, 0x6f, 0xe5, 0xc6, + 0xec, 0xd5, 0x17, 0x57, 0xfc, 0x18, 0x6e, 0x20, 0x54, 0x40, 0x91, 0x72, 0xa0, 0x3d, 0xd8, 0x45, + 0x8e, 0x89, 0xac, 0x16, 0x82, 0x97, 0x64, 0xa2, 0x88, 0x1e, 0x88, 0xaf, 0x47, 0xc6, 0x08, 0xce, + 0xf2, 0xa4, 0x2f, 0x3d, 0x46, 0x7b, 0xee, 0x80, 0xd1, 0xfe, 0xc9, 0xa4, 0x6e, 0x7d, 0xbd, 0xec, + 0x8e, 0x04, 0xb2, 0x8f, 0x27, 0x71, 0xeb, 0x1b, 0xc0, 0xc1, 0x58, 0x82, 0x03, 0x47, 0x8c, 0xe9, + 0x45, 0x05, 0xbe, 0x7d, 0x0a, 0x14, 0x29, 0xa3, 0x9c, 0xaf, 0xd4, 0xaf, 0xb0, 0xbb, 0x10, 0x9b, + 0x09, 0x42, 0xd3, 0xf9, 0x87, 0xfd, 0xb3, 0xe2, 0x61, 0x7f, 0x61, 0xe9, 0x4d, 0xe9, 0xdd, 0xdf, + 0x4e, 0xda, 0xfc, 0x38, 0xc7, 0xa8, 0xe8, 0x68, 0xa0, 0xe9, 0x35, 0xbf, 0xd8, 0xe2, 0xc7, 0x73, + 0x5f, 0x17, 0xbb, 0x91, 0x4f, 0x93, 0x45, 0x26, 0xfe, 0x5a, 0xc2, 0xa4, 0x5e, 0xb2, 0x82, 0x63, + 0x5a, 0xcc, 0x5d, 0x7d, 0xe9, 0x79, 0xc9, 0x0e, 0xe2, 0x20, 0x7d, 0x14, 0x7e, 0x90, 0x05, 0xb9, + 0xba, 0xed, 0x78, 0xa3, 0xc2, 0x20, 0xe9, 0xce, 0x1e, 0x27, 0x81, 0x7a, 0xf4, 0xcc, 0x29, 0xbd, + 0x9d, 0xbd, 0xf8, 0xf2, 0xc7, 0x10, 0xdd, 0xef, 0x38, 0x98, 0xa3, 0x9c, 0x04, 0x57, 0x5f, 0x7c, + 0x3f, 0x4b, 0xfb, 0xab, 0xfb, 0x64, 0x11, 0x39, 0x07, 0x66, 0xb8, 0x9d, 0xb5, 0xe0, 0xfa, 0x66, + 0x3e, 0x0d, 0xbe, 0x91, 0xc7, 0x65, 0x51, 0xc4, 0xa5, 0xdf, 0xbc, 0x31, 0xb8, 0x3d, 0x62, 0x54, + 0x3d, 0x53, 0x92, 0x40, 0x81, 0x31, 0x85, 0xa7, 0x8f, 0xc8, 0x73, 0x14, 0x50, 0x60, 0x9e, 0x4d, + 0x23, 0x45, 0x20, 0x69, 0xcb, 0x08, 0x84, 0x20, 0xe7, 0x01, 0xa5, 0x8c, 0xba, 0x65, 0xc4, 0x97, + 0x9f, 0x3e, 0x0e, 0xff, 0xca, 0x5c, 0xf6, 0x4a, 0x7b, 0x86, 0xd9, 0x31, 0x2e, 0x76, 0x12, 0x04, + 0xe8, 0xfd, 0x48, 0xc2, 0x43, 0x4a, 0x41, 0x55, 0x85, 0xf2, 0x22, 0x24, 0xfe, 0xe3, 0x60, 0xca, + 0x09, 0x16, 0xd6, 0xfc, 0x33, 0xdc, 0x3d, 0xee, 0x92, 0xec, 0xbb, 0x1e, 0xe6, 0x4c, 0x74, 0x22, + 0x49, 0x8a, 0x9f, 0xb1, 0x9c, 0xa0, 0x98, 0x2e, 0xb5, 0xdb, 0x4b, 0xc8, 0xf0, 0x76, 0x1d, 0xd4, + 0x4e, 0x34, 0x44, 0x88, 0x22, 0x9a, 0xe2, 0x25, 0x21, 0x84, 0xc8, 0x5b, 0x15, 0xd1, 0x79, 0xe2, + 0x80, 0xde, 0xc0, 0xe7, 0x65, 0x24, 0x5d, 0xd2, 0xdb, 0x02, 0x48, 0x6a, 0x02, 0x24, 0x4f, 0x19, + 0x8e, 0x89, 0xf4, 0x01, 0xf9, 0x55, 0x05, 0xcc, 0x51, 0x3b, 0x61, 0xd4, 0x98, 0xfc, 0x6e, 0x42, + 0x4f, 0x08, 0xee, 0x72, 0x21, 0x9e, 0x9d, 0x91, 0xc0, 0x92, 0xc4, 0x6f, 0x42, 0x8e, 0x8f, 0xf4, + 0x91, 0xf9, 0x4c, 0x01, 0x00, 0xce, 0xbb, 0xed, 0x23, 0x85, 0x30, 0x5c, 0x1d, 0x7c, 0x07, 0x9b, + 0x7f, 0xd4, 0x85, 0xd8, 0xc9, 0x9c, 0xe7, 0x5a, 0xb0, 0xad, 0x22, 0x26, 0x4a, 0x8d, 0x2a, 0x7f, + 0x91, 0xd0, 0xe6, 0x65, 0xbe, 0x65, 0x03, 0x07, 0xf7, 0x21, 0x7b, 0xb9, 0x8f, 0x26, 0x30, 0x7e, + 0x07, 0xb1, 0x92, 0x0c, 0xb5, 0xd5, 0x21, 0xe6, 0x92, 0x67, 0xc0, 0x49, 0x5d, 0x2b, 0x2d, 0xd6, + 0xaa, 0xab, 0xf7, 0xf3, 0x37, 0xcd, 0x14, 0x15, 0x7e, 0x72, 0x92, 0x0a, 0x6c, 0xaf, 0x4d, 0xd8, + 0x07, 0x8a, 0xb2, 0x8a, 0x9b, 0xad, 0x70, 0xd3, 0xf9, 0xc1, 0xbd, 0x9a, 0x04, 0xd9, 0xa3, 0x44, + 0xe1, 0xcd, 0x53, 0x5c, 0x33, 0x7a, 0xbe, 0x02, 0x8a, 0xe1, 0x65, 0xe7, 0xec, 0x4a, 0xb1, 0x9a, + 0xe8, 0xfc, 0xd6, 0xa5, 0xbb, 0x28, 0xa1, 0xf3, 0x9b, 0x9f, 0xa0, 0xde, 0x08, 0xe6, 0x5a, 0xdb, + 0xa8, 0x75, 0xa9, 0x62, 0xf9, 0xbb, 0xc3, 0x74, 0x2b, 0xb1, 0x27, 0x55, 0x04, 0xe6, 0x3e, 0x11, + 0x18, 0x71, 0x12, 0x2d, 0x0c, 0xd2, 0x3c, 0x53, 0x11, 0xb8, 0xfc, 0x51, 0x80, 0x4b, 0x55, 0xc0, + 0xe5, 0xce, 0xa1, 0xa8, 0x26, 0x83, 0xa5, 0x3a, 0x04, 0x2c, 0x10, 0x9c, 0xae, 0xad, 0x37, 0x2a, + 0xb5, 0x6a, 0x73, 0xa3, 0xae, 0x2d, 0x36, 0x17, 0x7c, 0x70, 0xea, 0x45, 0x05, 0x7e, 0x23, 0x0b, + 0x26, 0x28, 0x5b, 0x6e, 0xcf, 0xe5, 0xe4, 0xf1, 0x5e, 0x7f, 0xf0, 0xed, 0xd2, 0x67, 0xf8, 0x03, + 0x41, 0xb0, 0x72, 0x22, 0xfa, 0xa9, 0x27, 0x83, 0x09, 0x0a, 0xb2, 0xef, 0x34, 0x72, 0x36, 0xa2, + 0x97, 0x62, 0x64, 0x74, 0x3f, 0xbb, 0xe4, 0x79, 0xfe, 0x01, 0x6c, 0xa4, 0x3f, 0xb2, 0xbc, 0x41, + 0xa1, 0x66, 0xf0, 0x05, 0xd3, 0xdb, 0x26, 0x4e, 0x81, 0xf0, 0xe9, 0x32, 0x4b, 0x94, 0xb7, 0x80, + 0xfc, 0x1e, 0xce, 0x3d, 0xc0, 0xc1, 0x92, 0x66, 0x82, 0x7f, 0x20, 0x1d, 0xe9, 0x4a, 0xd0, 0xcf, + 0x80, 0xa7, 0xe8, 0x0d, 0xcf, 0x41, 0x3d, 0xa1, 0x0a, 0x85, 0x43, 0x4d, 0xca, 0x4d, 0x4a, 0xe2, + 0x78, 0x8d, 0x52, 0x2c, 0xa5, 0x0f, 0xd4, 0xff, 0x7b, 0x1c, 0x4c, 0xac, 0x98, 0xae, 0x67, 0x3b, + 0xfb, 0xf0, 0xf5, 0x19, 0x30, 0x71, 0x1e, 0x39, 0xae, 0x69, 0x5b, 0x07, 0x76, 0xb5, 0xaf, 0x03, + 0xd3, 0x5d, 0x07, 0xed, 0x99, 0xf6, 0xae, 0x1b, 0xae, 0xa0, 0xf0, 0x49, 0x58, 0x24, 0xc6, 0xae, + 0xb7, 0x6d, 0x3b, 0x61, 0x60, 0x03, 0xff, 0x5d, 0x3d, 0x0b, 0x00, 0x7d, 0xae, 0x1a, 0x3b, 0x88, + 0xed, 0xd5, 0x73, 0x29, 0xaa, 0x0a, 0x72, 0x9e, 0xb9, 0x83, 0x58, 0xa4, 0x53, 0xf2, 0x8c, 0xb5, + 0x84, 0x44, 0x0d, 0x63, 0xd1, 0xd9, 0x14, 0xdd, 0x7f, 0x85, 0x9f, 0x53, 0xc0, 0xf4, 0x32, 0xf2, + 0x18, 0xab, 0x2e, 0x7c, 0x61, 0x46, 0xea, 0x72, 0x01, 0x3c, 0x10, 0x76, 0x0c, 0xd7, 0xff, 0x2f, + 0x58, 0x27, 0x15, 0x13, 0xc3, 0xb0, 0xab, 0x0a, 0x1f, 0x73, 0x99, 0xc4, 0xe0, 0xf2, 0x2a, 0xd4, + 0xc5, 0x8f, 0x65, 0x66, 0x6b, 0xe3, 0x07, 0x3f, 0xc0, 0xf7, 0x64, 0x65, 0xcf, 0xaf, 0x32, 0xd9, + 0xcf, 0x73, 0xf5, 0x89, 0xec, 0x33, 0x26, 0xf7, 0x58, 0x8e, 0x03, 0xe1, 0xb4, 0x79, 0x4a, 0x8c, + 0x8c, 0x1e, 0xe4, 0x96, 0x3c, 0xf9, 0x3a, 0x98, 0x93, 0xf4, 0xb5, 0xf1, 0xbb, 0x0a, 0x98, 0xae, + 0x6f, 0xdb, 0x97, 0x7d, 0x39, 0xfe, 0x94, 0x1c, 0xb0, 0xd7, 0x80, 0xa9, 0xbd, 0x1e, 0x50, 0xc3, + 0x84, 0xe8, 0xeb, 0xbe, 0xe1, 0x43, 0x4a, 0x52, 0x98, 0x38, 0xe6, 0x46, 0x7e, 0x19, 0xb7, 0xfa, + 0x44, 0x30, 0xc1, 0xb8, 0x66, 0xeb, 0x22, 0xf1, 0x00, 0xfb, 0x99, 0xf9, 0x0a, 0xe6, 0xc4, 0x0a, + 0x26, 0x43, 0x3e, 0xba, 0x72, 0xe9, 0x23, 0xff, 0xa7, 0x59, 0x12, 0xf7, 0xc0, 0x07, 0xbe, 0x3c, + 0x02, 0xe0, 0xe1, 0xf7, 0x32, 0xb2, 0xab, 0x87, 0x81, 0x04, 0x02, 0x0e, 0x0e, 0x75, 0x71, 0xc8, + 0x40, 0x72, 0xe9, 0xcb, 0xf3, 0x65, 0x39, 0x30, 0xb3, 0x68, 0x6e, 0x6e, 0x06, 0x9d, 0xe4, 0x8b, + 0x24, 0x3b, 0xc9, 0xe8, 0x9d, 0x67, 0x6c, 0x8c, 0xee, 0x3a, 0x0e, 0xb2, 0xfc, 0x4a, 0xb1, 0xe6, + 0xd4, 0x93, 0xaa, 0xde, 0x04, 0x8e, 0xfb, 0xe3, 0x02, 0xdf, 0x51, 0x4e, 0xe9, 0xbd, 0xc9, 0xf0, + 0x3b, 0xd2, 0x5b, 0x4f, 0xbe, 0x44, 0xf9, 0x2a, 0x45, 0x34, 0xc0, 0xbb, 0xc0, 0xec, 0x36, 0xcd, + 0x4d, 0xe6, 0xe7, 0x7e, 0x67, 0x79, 0xba, 0x27, 0xae, 0xec, 0x1a, 0x72, 0x5d, 0x63, 0x0b, 0xe9, + 0x62, 0xe6, 0x9e, 0xe6, 0xab, 0x24, 0xb9, 0x25, 0x49, 0x6e, 0x17, 0x4b, 0xa2, 0x26, 0xe9, 0x6b, + 0xc7, 0x57, 0x1e, 0x09, 0x72, 0x4b, 0x66, 0x07, 0xc1, 0x9f, 0xcf, 0x82, 0x29, 0x1d, 0xb5, 0x6c, + 0xab, 0x85, 0xdf, 0x38, 0x3f, 0x94, 0x7f, 0xcc, 0xc8, 0xde, 0x0e, 0x88, 0xe9, 0xcc, 0x07, 0x34, + 0x22, 0xda, 0x8d, 0xdc, 0x2d, 0x80, 0xb1, 0xa4, 0xc6, 0x70, 0x97, 0x03, 0x9e, 0x1f, 0x6c, 0x6e, + 0x76, 0x6c, 0x43, 0x58, 0xa1, 0xea, 0x35, 0x85, 0x6e, 0x06, 0x45, 0xff, 0x38, 0x81, 0xed, 0xad, + 0x9b, 0x96, 0x15, 0x9c, 0x57, 0x3d, 0x90, 0x2e, 0x6e, 0xae, 0xc6, 0x86, 0xfc, 0x20, 0x75, 0x67, + 0xa5, 0x47, 0x68, 0xf6, 0x8d, 0x60, 0xee, 0xe2, 0xbe, 0x87, 0x5c, 0x96, 0x8b, 0x15, 0x9b, 0xd3, + 0x7b, 0x52, 0xb9, 0x80, 0xbd, 0x71, 0xa1, 0x41, 0x62, 0x0a, 0x4c, 0x26, 0xea, 0x95, 0x21, 0xa6, + 0x69, 0x27, 0x41, 0xb1, 0x5a, 0x5b, 0xd4, 0x88, 0x5b, 0x94, 0xef, 0x67, 0xb2, 0x05, 0x5f, 0xac, + 0x80, 0x19, 0xe2, 0x63, 0xe0, 0xa3, 0x70, 0xbd, 0xc4, 0xa4, 0x01, 0x7e, 0x51, 0xda, 0x65, 0x8a, + 0x54, 0x99, 0x2f, 0x20, 0x5a, 0xd0, 0x9b, 0x66, 0xa7, 0x57, 0xd0, 0x79, 0xbd, 0x27, 0xb5, 0x0f, + 0x20, 0x4a, 0x5f, 0x40, 0x7e, 0x5b, 0xca, 0x6f, 0x6a, 0x10, 0x77, 0x47, 0x85, 0xca, 0xef, 0x28, + 0x60, 0x1a, 0x4f, 0x52, 0x7c, 0x50, 0x6a, 0x02, 0x28, 0xb6, 0xd5, 0xd9, 0x0f, 0xd7, 0x2e, 0xfc, + 0xd7, 0x44, 0x8d, 0xe4, 0xaf, 0xa5, 0xa7, 0xd7, 0x44, 0x44, 0x1c, 0x2f, 0x63, 0xc2, 0xef, 0x03, + 0x52, 0x93, 0xee, 0x01, 0xcc, 0x1d, 0x15, 0x7c, 0x6f, 0xc9, 0x83, 0xc2, 0x46, 0x97, 0x20, 0xf7, + 0xd5, 0xac, 0x4c, 0xf0, 0xeb, 0x03, 0x3e, 0xf3, 0xd8, 0xcc, 0xea, 0xd8, 0x2d, 0xa3, 0xb3, 0x1e, + 0x1e, 0x3e, 0x0a, 0x13, 0xd4, 0x3b, 0x99, 0x1b, 0x1d, 0x3d, 0xb9, 0x75, 0x63, 0x6c, 0x5c, 0x68, + 0x22, 0x23, 0xee, 0x7c, 0xc2, 0x2d, 0xe0, 0x44, 0xdb, 0x74, 0x8d, 0x8b, 0x1d, 0xa4, 0x59, 0x2d, + 0x67, 0x9f, 0x8a, 0x83, 0x4d, 0xab, 0x0e, 0x7c, 0x50, 0xef, 0x06, 0x79, 0xd7, 0xdb, 0xef, 0xd0, + 0x79, 0x22, 0x7f, 0x9c, 0x21, 0xb2, 0xa8, 0x3a, 0xce, 0xae, 0xd3, 0xbf, 0xf8, 0xab, 0x81, 0x27, + 0x24, 0xaf, 0x06, 0xbe, 0x1d, 0x14, 0x6c, 0xc7, 0xdc, 0x32, 0xe9, 0x55, 0x2f, 0x73, 0x07, 0xc2, + 0x9f, 0x51, 0x53, 0xa0, 0x46, 0xb2, 0xe8, 0x2c, 0x2b, 0xfc, 0x40, 0x56, 0x36, 0xd6, 0x0a, 0xe1, + 0x91, 0x82, 0x33, 0x9e, 0x9b, 0xfc, 0x5f, 0x29, 0x15, 0x05, 0x25, 0x9a, 0xad, 0xf4, 0x07, 0xe1, + 0xcf, 0x66, 0xc1, 0xe4, 0xa2, 0x7d, 0xd9, 0x22, 0x0a, 0x7b, 0x87, 0x9c, 0xcd, 0xda, 0xe7, 0x5c, + 0x9c, 0x78, 0x93, 0x60, 0xac, 0x13, 0x3c, 0xa9, 0xad, 0x5f, 0x64, 0x04, 0x0c, 0xb1, 0x2d, 0x40, + 0xf2, 0x7e, 0xb7, 0xb8, 0x72, 0xd2, 0x97, 0xeb, 0x9f, 0x29, 0x20, 0xb7, 0xe8, 0xd8, 0x5d, 0xf8, + 0xb6, 0x4c, 0x02, 0xff, 0x80, 0xb6, 0x63, 0x77, 0x1b, 0xe4, 0x82, 0xa6, 0xd0, 0xf3, 0x9f, 0x4f, + 0x53, 0xef, 0x00, 0x93, 0x5d, 0xdb, 0x35, 0x3d, 0x7f, 0x3a, 0x30, 0x77, 0xdb, 0x23, 0xfa, 0xb6, + 0xca, 0x75, 0x96, 0x49, 0x0f, 0xb2, 0xe3, 0xde, 0x97, 0x88, 0x10, 0xcb, 0x05, 0x8b, 0xd1, 0xbf, + 0xa4, 0xaa, 0x27, 0x15, 0xbe, 0x84, 0x47, 0xf2, 0x29, 0x22, 0x92, 0x8f, 0xea, 0x23, 0x61, 0xc7, + 0xee, 0x8e, 0x64, 0x47, 0xef, 0xe5, 0x01, 0xaa, 0x4f, 0x15, 0x50, 0xbd, 0x59, 0xaa, 0xcc, 0xf4, + 0x11, 0xfd, 0x40, 0x0e, 0x00, 0x62, 0x2e, 0x6c, 0xe0, 0x89, 0x8c, 0x9c, 0xad, 0xf4, 0xdc, 0x1c, + 0x27, 0xcb, 0x92, 0x28, 0xcb, 0xc7, 0x44, 0x58, 0x23, 0x84, 0x7c, 0x84, 0x44, 0x4b, 0x20, 0xbf, + 0x8b, 0x3f, 0x33, 0x89, 0x4a, 0x92, 0x20, 0xaf, 0x3a, 0xfd, 0x13, 0xfe, 0x69, 0x06, 0xe4, 0x49, + 0x82, 0x7a, 0x16, 0x00, 0x32, 0x40, 0xd3, 0x33, 0x24, 0x19, 0x32, 0x14, 0x73, 0x29, 0x44, 0x5b, + 0xcd, 0x36, 0xfb, 0x4c, 0x4d, 0xdf, 0x30, 0x01, 0xff, 0x4d, 0x86, 0x6d, 0x42, 0x8b, 0x0d, 0xe4, + 0x5c, 0x0a, 0xfe, 0x9b, 0xbc, 0xad, 0xa2, 0x4d, 0x1a, 0x3b, 0x37, 0xa7, 0x87, 0x09, 0xc1, 0xdf, + 0xab, 0xc1, 0x8d, 0x4b, 0xfe, 0xdf, 0x24, 0x05, 0x4f, 0x6a, 0x89, 0x5a, 0x2e, 0x84, 0x45, 0x14, + 0x48, 0xa6, 0xde, 0x64, 0xf8, 0xda, 0x40, 0x6d, 0x16, 0x05, 0xb5, 0x79, 0x5c, 0x02, 0xf1, 0xa6, + 0xaf, 0x3c, 0x5f, 0xce, 0x83, 0xa9, 0xaa, 0xdd, 0x66, 0xba, 0xc3, 0x4d, 0xfc, 0x3e, 0x9e, 0x4f, + 0x34, 0xf1, 0x0b, 0x68, 0x44, 0x28, 0xc8, 0xbd, 0xa2, 0x82, 0xc8, 0x51, 0xe0, 0xf5, 0x43, 0x5d, + 0x00, 0x05, 0xa2, 0xbd, 0x07, 0xaf, 0xf2, 0x89, 0x23, 0x41, 0x44, 0xab, 0xb3, 0x3f, 0xff, 0xcd, + 0xe9, 0xd8, 0x7f, 0x04, 0x79, 0x52, 0xc1, 0x98, 0xad, 0x14, 0xb1, 0xa2, 0xd9, 0xf8, 0x8a, 0x2a, + 0xf1, 0x15, 0xcd, 0xf5, 0x56, 0x34, 0xc9, 0x7c, 0x3e, 0x4a, 0x43, 0xd2, 0xd7, 0xf1, 0xff, 0x3e, + 0x01, 0x40, 0xd5, 0xd8, 0x33, 0xb7, 0xe8, 0x56, 0xec, 0xe7, 0xfc, 0x79, 0x0c, 0xdb, 0x34, 0xfd, + 0x4f, 0xdc, 0x40, 0x78, 0x07, 0x98, 0x60, 0xe3, 0x1e, 0xab, 0xc8, 0xb5, 0x42, 0x45, 0x42, 0x2a, + 0xd4, 0xbc, 0x7c, 0xd0, 0xd3, 0xfd, 0xfc, 0xc2, 0xad, 0xa3, 0xd9, 0x9e, 0x5b, 0x47, 0xfb, 0xef, + 0x25, 0x44, 0xdc, 0x45, 0x0a, 0xdf, 0x2b, 0xbd, 0x9f, 0xc5, 0xf1, 0xc3, 0xd5, 0x28, 0xa2, 0x09, + 0xde, 0x0e, 0x26, 0xec, 0x60, 0xf7, 0x58, 0x89, 0x5c, 0xcf, 0xaa, 0x58, 0x9b, 0xb6, 0xee, 0xe7, + 0x94, 0xdc, 0xc4, 0x92, 0xe2, 0x63, 0x2c, 0x67, 0x22, 0x4e, 0x2f, 0xfb, 0x71, 0x88, 0x70, 0x3d, + 0x2e, 0x98, 0xde, 0xf6, 0xaa, 0x69, 0x5d, 0x72, 0xe1, 0xbf, 0x97, 0xb3, 0x20, 0x39, 0xfc, 0xb3, + 0xc9, 0xf0, 0x17, 0xc3, 0x3c, 0xd4, 0x45, 0xd4, 0xee, 0x8e, 0xa2, 0xd2, 0x9f, 0xdb, 0x08, 0x00, + 0xef, 0x04, 0x05, 0xca, 0x28, 0xeb, 0x44, 0xcf, 0x45, 0xe2, 0x17, 0x50, 0xd2, 0xd9, 0x1f, 0xf0, + 0x3d, 0x01, 0x8e, 0xe7, 0x05, 0x1c, 0x17, 0x0e, 0xc5, 0x59, 0xea, 0x90, 0x9e, 0x7b, 0x3c, 0x98, + 0x60, 0x92, 0x56, 0xe7, 0xf8, 0x56, 0x5c, 0x3c, 0xa6, 0x02, 0x50, 0x58, 0xb3, 0xf7, 0x50, 0xc3, + 0x2e, 0x66, 0xf0, 0x33, 0xe6, 0xaf, 0x61, 0x17, 0xb3, 0xf0, 0x15, 0x93, 0x60, 0x32, 0x08, 0x00, + 0xf3, 0xd9, 0x2c, 0x28, 0x96, 0x1d, 0x64, 0x78, 0x68, 0xc9, 0xb1, 0x77, 0x68, 0x8d, 0xe4, 0x5d, + 0x31, 0x7f, 0x55, 0xda, 0x9f, 0x22, 0x08, 0xcc, 0xd2, 0x5b, 0x58, 0x04, 0x96, 0x74, 0x31, 0x31, + 0xeb, 0x2f, 0x26, 0xc2, 0xb7, 0x4a, 0xf9, 0x57, 0xc8, 0x96, 0x92, 0x7e, 0x53, 0xfb, 0x64, 0x16, + 0xe4, 0xcb, 0x1d, 0xdb, 0x42, 0xfc, 0xa5, 0xfa, 0x03, 0x0f, 0xa6, 0xf4, 0xdf, 0x51, 0x80, 0xcf, + 0xca, 0xca, 0xda, 0x1a, 0xa1, 0x00, 0x70, 0xd9, 0x92, 0xb2, 0x95, 0x1b, 0xa4, 0x62, 0x49, 0xa7, + 0x2f, 0xd0, 0x6f, 0x64, 0xc1, 0x14, 0x0d, 0xa5, 0x52, 0xea, 0x74, 0xe0, 0x23, 0x42, 0xa1, 0xf6, + 0x09, 0xa2, 0x03, 0x7f, 0x5b, 0xda, 0x1f, 0x3e, 0xa8, 0x55, 0x40, 0x3b, 0x41, 0x4c, 0x99, 0x64, + 0xee, 0xd9, 0x72, 0x7b, 0x62, 0x03, 0x19, 0x4a, 0x5f, 0xd4, 0x7f, 0x99, 0xc5, 0x06, 0x80, 0x75, + 0x69, 0xdd, 0x41, 0x7b, 0x26, 0xba, 0x0c, 0xaf, 0x0e, 0x85, 0x7d, 0x30, 0x4e, 0xc4, 0x9b, 0xa4, + 0x17, 0x71, 0x38, 0x92, 0x91, 0x5b, 0x52, 0xd3, 0x9d, 0x30, 0x13, 0xeb, 0xc5, 0x7b, 0x83, 0x77, + 0x70, 0x64, 0x74, 0x3e, 0xbb, 0xe4, 0x9a, 0x4d, 0x34, 0x17, 0xe9, 0x0b, 0xf6, 0xa1, 0x09, 0x30, + 0xb9, 0x61, 0xb9, 0xdd, 0x8e, 0xe1, 0x6e, 0xc3, 0xef, 0x2b, 0xa0, 0x40, 0x2f, 0x90, 0x82, 0x3f, + 0x2e, 0x1c, 0x47, 0xff, 0xe9, 0x5d, 0xe4, 0xf8, 0xee, 0x55, 0xf4, 0xa5, 0xff, 0xfd, 0xd6, 0xf0, + 0x03, 0x8a, 0xec, 0x24, 0xd5, 0x2f, 0x34, 0xfe, 0xc6, 0xfe, 0x0a, 0x98, 0xec, 0x9a, 0x2d, 0x6f, + 0xd7, 0x09, 0x6e, 0x4b, 0x7e, 0xac, 0x1c, 0x95, 0x75, 0xfa, 0x97, 0x1e, 0xfc, 0x0e, 0x0d, 0x30, + 0xc1, 0x12, 0x0f, 0x6c, 0x0b, 0x1d, 0x3c, 0x5e, 0x79, 0x1a, 0x14, 0x0c, 0xc7, 0x33, 0x5d, 0xff, + 0x36, 0x7a, 0xf6, 0x86, 0xbb, 0x4b, 0xfa, 0xb4, 0xe1, 0x74, 0xfc, 0xc0, 0x15, 0x41, 0x02, 0xfc, + 0x1d, 0xa9, 0xf9, 0x63, 0x7c, 0xcd, 0x93, 0x41, 0x7e, 0xdf, 0x10, 0x6b, 0xcd, 0x57, 0x82, 0x2b, + 0xf4, 0x52, 0x43, 0x6b, 0xd2, 0x38, 0x07, 0x41, 0x48, 0x83, 0x36, 0xfc, 0x3e, 0xbf, 0x7e, 0x27, + 0x8e, 0x11, 0x4c, 0x8a, 0xe1, 0x18, 0x11, 0x24, 0xc4, 0x8c, 0x11, 0x6f, 0x91, 0xde, 0xdd, 0x09, + 0x44, 0x32, 0x60, 0x2d, 0x2f, 0xee, 0xa2, 0x98, 0x0f, 0x4a, 0xed, 0xd4, 0x0c, 0x2a, 0xe9, 0x08, + 0xc5, 0xff, 0xc6, 0x09, 0x30, 0xb1, 0x6c, 0x74, 0x3a, 0xc8, 0xd9, 0xc7, 0x43, 0x4b, 0xd1, 0xe7, + 0x70, 0xcd, 0xb0, 0xcc, 0x4d, 0x3c, 0xbf, 0x8f, 0xed, 0xf4, 0xde, 0x2b, 0x1d, 0x84, 0x94, 0x95, + 0x31, 0xdf, 0x4b, 0x3f, 0x42, 0xe6, 0xb7, 0x82, 0x9c, 0x69, 0x6d, 0xda, 0xac, 0xeb, 0xeb, 0x5d, + 0x45, 0xf7, 0x7f, 0x26, 0x53, 0x10, 0x92, 0x51, 0x32, 0x0e, 0xa9, 0x24, 0x17, 0xe9, 0xf7, 0x80, + 0xbf, 0x95, 0x03, 0xb3, 0x3e, 0x13, 0x15, 0xab, 0x8d, 0x1e, 0xe4, 0x97, 0x54, 0x5e, 0x9c, 0x93, + 0x3d, 0x43, 0xd5, 0x5b, 0x1f, 0x42, 0x2a, 0x42, 0xa4, 0x0d, 0x00, 0x5a, 0x86, 0x87, 0xb6, 0x6c, + 0xc7, 0x0c, 0xfa, 0xb5, 0x27, 0x24, 0xa1, 0x56, 0xa6, 0x7f, 0xef, 0xeb, 0x1c, 0x1d, 0xf5, 0x6e, + 0x30, 0x8d, 0x82, 0x63, 0xd2, 0xfe, 0x92, 0x4b, 0x2c, 0x5e, 0x7c, 0x7e, 0xf8, 0x97, 0x52, 0x47, + 0xb5, 0x64, 0xaa, 0x99, 0x0c, 0xb3, 0xe6, 0x70, 0x6d, 0x68, 0xa3, 0xba, 0x56, 0xd2, 0xeb, 0x2b, + 0xa5, 0xd5, 0xd5, 0x4a, 0x75, 0x39, 0x88, 0xf9, 0xa1, 0x82, 0xb9, 0xc5, 0xda, 0x85, 0x2a, 0x17, + 0x94, 0x25, 0x07, 0xd7, 0xc1, 0xa4, 0x2f, 0xaf, 0x7e, 0xbe, 0x91, 0xbc, 0xcc, 0x98, 0x6f, 0x24, + 0x97, 0x84, 0x8d, 0x2c, 0xb3, 0x15, 0x38, 0xcc, 0x90, 0x67, 0xf8, 0xc7, 0x06, 0xc8, 0x93, 0xb5, + 0x71, 0xf8, 0x4e, 0x72, 0x5d, 0x7d, 0xb7, 0x63, 0xb4, 0x10, 0xdc, 0x49, 0x60, 0x55, 0xfb, 0x51, + 0xf1, 0xb3, 0x07, 0xa2, 0xe2, 0x93, 0x47, 0x66, 0xbd, 0x9d, 0xec, 0xb7, 0x1e, 0xaf, 0xd3, 0x2c, + 0xe2, 0xa9, 0xa6, 0xd8, 0x5d, 0x12, 0xba, 0x8c, 0xcf, 0xd8, 0x8c, 0x50, 0xc9, 0x68, 0x9e, 0x92, + 0x59, 0x94, 0x72, 0xfb, 0x29, 0x71, 0x1c, 0x8d, 0xe1, 0xe6, 0xe6, 0x1c, 0xc8, 0xd7, 0xbb, 0x1d, + 0xd3, 0x83, 0xbf, 0x9e, 0x1d, 0x09, 0x66, 0xf4, 0x26, 0x03, 0x65, 0xe0, 0x4d, 0x06, 0xe1, 0x2e, + 0x68, 0x4e, 0x62, 0x17, 0xb4, 0x81, 0x1e, 0xf4, 0xc4, 0x5d, 0xd0, 0x3b, 0x58, 0xdc, 0x2e, 0xba, + 0x87, 0xfa, 0xa8, 0x3e, 0x22, 0x25, 0xd5, 0xea, 0x13, 0x10, 0xee, 0xdc, 0xe3, 0x59, 0x5c, 0x2a, + 0x00, 0x0a, 0x0b, 0xb5, 0x46, 0xa3, 0xb6, 0x56, 0x3c, 0x46, 0x02, 0x9a, 0xd4, 0xd6, 0x8b, 0x19, + 0x75, 0x0a, 0xe4, 0x2b, 0xd5, 0xaa, 0xa6, 0x17, 0xb3, 0x24, 0x52, 0x56, 0xa5, 0xb1, 0xaa, 0x15, + 0x15, 0x31, 0xac, 0x75, 0xac, 0x19, 0x2d, 0x96, 0x9d, 0xa6, 0x7a, 0xc9, 0x19, 0xd4, 0xd1, 0xfc, + 0xa4, 0xaf, 0x5c, 0xff, 0x59, 0x01, 0xf9, 0x35, 0xe4, 0x6c, 0x21, 0xf8, 0xd3, 0x09, 0x36, 0xeb, + 0x36, 0x4d, 0xc7, 0xa5, 0x71, 0xc5, 0xc2, 0xcd, 0x3a, 0x3e, 0x4d, 0xbd, 0x01, 0xcc, 0xba, 0xa8, + 0x65, 0x5b, 0x6d, 0x3f, 0x13, 0xed, 0x8f, 0xc4, 0x44, 0xf1, 0x4a, 0x71, 0x09, 0xc8, 0x08, 0xa3, + 0x23, 0xd9, 0x71, 0x4b, 0x02, 0x4c, 0xbf, 0x52, 0xd3, 0x07, 0xe6, 0x3b, 0x0a, 0xfe, 0xa9, 0xbb, + 0x0f, 0x5f, 0x2a, 0xbd, 0x8b, 0x7a, 0x0b, 0x28, 0x10, 0x35, 0xf5, 0xc7, 0xe8, 0xfe, 0xfd, 0x31, + 0xcb, 0xa3, 0x2e, 0x80, 0x13, 0x2e, 0xea, 0xa0, 0x96, 0x87, 0xda, 0xb8, 0xe9, 0xea, 0x03, 0x3b, + 0x85, 0x83, 0xd9, 0xe1, 0x9f, 0xf3, 0x00, 0xde, 0x25, 0x02, 0x78, 0x63, 0x1f, 0x51, 0xe2, 0x0a, + 0x45, 0xdb, 0xca, 0xb8, 0x1a, 0xf5, 0x8e, 0x1d, 0x2c, 0x6e, 0xfb, 0xef, 0xf8, 0xdb, 0xb6, 0xb7, + 0xd3, 0x21, 0xdf, 0x98, 0xc3, 0xbf, 0xff, 0xae, 0xce, 0x83, 0x09, 0xc3, 0xda, 0x27, 0x9f, 0x72, + 0x31, 0xb5, 0xf6, 0x33, 0xc1, 0x57, 0x04, 0xc8, 0xdf, 0x23, 0x20, 0xff, 0x18, 0x39, 0x76, 0xd3, + 0x07, 0xfe, 0xe7, 0x26, 0x40, 0x7e, 0xdd, 0x70, 0x3d, 0x04, 0xff, 0x1f, 0x45, 0x16, 0xf9, 0x1b, + 0xc1, 0xdc, 0xa6, 0xdd, 0xda, 0x75, 0x51, 0x5b, 0x6c, 0x94, 0x3d, 0xa9, 0xa3, 0xc0, 0x5c, 0xbd, + 0x19, 0x14, 0xfd, 0x44, 0x46, 0xd6, 0xdf, 0x4e, 0x3f, 0x90, 0x4e, 0x82, 0x24, 0xbb, 0xeb, 0x86, + 0xe3, 0xd5, 0x36, 0x49, 0x5a, 0x10, 0x24, 0x99, 0x4f, 0x14, 0xa0, 0x2f, 0xc4, 0x40, 0x3f, 0x11, + 0x0d, 0xfd, 0xa4, 0x04, 0xf4, 0x6a, 0x09, 0x4c, 0x6e, 0x9a, 0x1d, 0x44, 0x7e, 0x98, 0x22, 0x3f, + 0xf4, 0x1b, 0x93, 0x88, 0xec, 0x83, 0x31, 0x69, 0xc9, 0xec, 0x20, 0x3d, 0xf8, 0xcd, 0x9f, 0xc8, + 0x80, 0x70, 0x22, 0xb3, 0x4a, 0xfd, 0x5b, 0xb1, 0xe1, 0x65, 0x19, 0x3b, 0xc8, 0x5f, 0x44, 0xb3, + 0xd8, 0x61, 0x93, 0xb6, 0xe1, 0x19, 0x04, 0x8c, 0x19, 0x9d, 0x3c, 0x8b, 0xfe, 0x1d, 0x4a, 0xaf, + 0x7f, 0xc7, 0xf3, 0x94, 0x64, 0x3d, 0xa2, 0xcf, 0x6c, 0x44, 0x8b, 0xba, 0xe8, 0x03, 0x44, 0x2d, + 0xc5, 0xe0, 0x1d, 0x03, 0xd3, 0x32, 0x1c, 0xe4, 0xad, 0xf3, 0x1e, 0x15, 0x79, 0x5d, 0x4c, 0x24, + 0xae, 0x75, 0x6e, 0xdd, 0xd8, 0x41, 0xa4, 0xb0, 0x32, 0xfe, 0xc6, 0x5c, 0xa6, 0x0e, 0xa4, 0x87, + 0xfd, 0x6f, 0x7e, 0xd4, 0xfd, 0x6f, 0xbf, 0x3a, 0xa6, 0xdf, 0x0c, 0x5f, 0x9d, 0x03, 0x4a, 0x79, + 0xd7, 0x7b, 0x58, 0x77, 0xbf, 0x3f, 0x90, 0xf6, 0x57, 0x61, 0xfd, 0x59, 0xe4, 0x1d, 0xe2, 0x63, + 0xea, 0x7d, 0x13, 0x6a, 0x89, 0x9c, 0x5f, 0x4c, 0x54, 0xdd, 0xd2, 0xd7, 0x91, 0xb7, 0x29, 0x81, + 0xc3, 0xe3, 0x73, 0x32, 0x87, 0x37, 0xcd, 0x21, 0xed, 0x9f, 0xb8, 0x9e, 0x21, 0x78, 0xf7, 0x3b, + 0x9e, 0x9c, 0x10, 0x52, 0x8d, 0x6c, 0x93, 0x13, 0x51, 0xce, 0xe8, 0xf4, 0x05, 0xbe, 0x4c, 0xda, + 0x0d, 0x9c, 0x8a, 0x2d, 0xd6, 0x25, 0x30, 0x99, 0x4d, 0x25, 0x77, 0x4f, 0x64, 0x4c, 0xb1, 0xe9, + 0x03, 0xf6, 0xad, 0xe8, 0x25, 0xc3, 0x61, 0x10, 0x83, 0xaf, 0x94, 0xde, 0x56, 0xa2, 0xd5, 0x1e, + 0xb0, 0x5e, 0x98, 0x4c, 0xde, 0x72, 0x9b, 0x4e, 0xb1, 0x05, 0xa7, 0x2f, 0xf1, 0x6f, 0x2a, 0xa0, + 0x40, 0xb7, 0x12, 0xe1, 0x9b, 0x33, 0x09, 0x2e, 0xd8, 0xf6, 0x44, 0x57, 0xc0, 0xe0, 0x3d, 0xc9, + 0x9a, 0x83, 0xe0, 0x32, 0x98, 0x4b, 0xe4, 0x32, 0x28, 0x9e, 0xab, 0x94, 0x68, 0x47, 0xb4, 0x8e, + 0x29, 0x4f, 0x27, 0x93, 0xb4, 0xb0, 0xbe, 0x0c, 0xa5, 0x8f, 0xf7, 0xf3, 0xf3, 0x60, 0x86, 0x16, + 0x7d, 0xc1, 0x6c, 0x6f, 0x21, 0x0f, 0xbe, 0x3b, 0xfb, 0xc3, 0x83, 0xba, 0x5a, 0x05, 0x33, 0x97, + 0x09, 0xdb, 0xab, 0xc6, 0xbe, 0xbd, 0xeb, 0xb1, 0x95, 0x8b, 0x9b, 0x63, 0xd7, 0x3d, 0x68, 0x3d, + 0xe7, 0xe9, 0x1f, 0xba, 0xf0, 0x3f, 0x96, 0x31, 0x5d, 0xf0, 0xa7, 0x8e, 0x58, 0x05, 0x62, 0x64, + 0xf1, 0x49, 0xea, 0x69, 0x50, 0xd8, 0x33, 0xd1, 0xe5, 0x4a, 0x9b, 0x59, 0xb7, 0xec, 0x4d, 0x3c, + 0x71, 0x1e, 0xbb, 0xff, 0xca, 0xc3, 0xcd, 0x78, 0x49, 0x57, 0x0b, 0xe5, 0x76, 0x61, 0x07, 0xb2, + 0x35, 0x86, 0x33, 0xbe, 0xe2, 0x3d, 0x8c, 0x49, 0xee, 0xf7, 0x8f, 0x32, 0x9c, 0xc5, 0xf8, 0x17, + 0xb1, 0x27, 0x48, 0xa8, 0x00, 0x46, 0x7c, 0x45, 0xa3, 0x5c, 0x50, 0x86, 0x01, 0x45, 0xa7, 0x2f, + 0xf9, 0xd7, 0x2a, 0x60, 0xaa, 0x8e, 0xbc, 0x25, 0x13, 0x75, 0xda, 0x2e, 0x74, 0x0e, 0x6f, 0x1a, + 0xdd, 0x0a, 0x0a, 0x9b, 0x84, 0xd8, 0xa0, 0xf3, 0x07, 0x2c, 0x1b, 0x7c, 0x75, 0x56, 0x76, 0x67, + 0x97, 0xad, 0xbe, 0xf9, 0xdc, 0x8e, 0x04, 0x26, 0x39, 0xcf, 0xdc, 0xf8, 0x92, 0xd3, 0x47, 0xe9, + 0xed, 0x0a, 0x98, 0x61, 0x17, 0xb7, 0x95, 0x3a, 0xe6, 0x96, 0x05, 0x77, 0x47, 0xd0, 0x42, 0xd4, + 0xc7, 0x81, 0xbc, 0x81, 0xa9, 0x31, 0x27, 0x7d, 0xd8, 0xb7, 0xf3, 0x24, 0xe5, 0xe9, 0x34, 0x63, + 0x82, 0xd8, 0x8b, 0xa1, 0x62, 0xfb, 0x3c, 0x8f, 0x31, 0xf6, 0xe2, 0xc0, 0xc2, 0xd3, 0x47, 0xec, + 0x4b, 0x0a, 0x38, 0xc9, 0x18, 0x38, 0x8f, 0x1c, 0xcf, 0x6c, 0x19, 0x1d, 0x8a, 0xdc, 0x0b, 0x32, + 0xa3, 0x80, 0x6e, 0x05, 0xcc, 0xee, 0xf1, 0x64, 0x19, 0x84, 0xe7, 0xfa, 0x42, 0x28, 0x30, 0xa0, + 0x8b, 0x3f, 0x26, 0x88, 0x61, 0x27, 0x48, 0x55, 0xa0, 0x39, 0xc6, 0x18, 0x76, 0xd2, 0x4c, 0xa4, + 0x0f, 0xf1, 0x4b, 0x72, 0x34, 0x9e, 0x4d, 0xd8, 0x7d, 0x7e, 0x4e, 0x1a, 0xdb, 0x0d, 0x30, 0x4d, + 0xb0, 0xa4, 0x3f, 0xb2, 0x65, 0x88, 0x18, 0x25, 0x0e, 0xfa, 0x1d, 0x76, 0x57, 0x54, 0xf0, 0xaf, + 0xce, 0xd3, 0x81, 0x17, 0x00, 0x08, 0x3f, 0xf1, 0x9d, 0x74, 0x26, 0xaa, 0x93, 0xce, 0xca, 0x75, + 0xd2, 0x6f, 0x92, 0x0e, 0x5e, 0xd2, 0x9f, 0xed, 0xc3, 0xab, 0x87, 0x5c, 0xd8, 0x8a, 0xc1, 0xa5, + 0xa7, 0xaf, 0x17, 0xaf, 0xc8, 0xf5, 0xde, 0xd0, 0xfd, 0x91, 0x91, 0xcc, 0xa7, 0xf8, 0xfe, 0x40, + 0xe9, 0xe9, 0x0f, 0x0e, 0x61, 0x49, 0xdf, 0x04, 0x8e, 0xd3, 0x22, 0xca, 0x01, 0x5b, 0x79, 0x1a, + 0x9a, 0xa1, 0x27, 0x19, 0x7e, 0x74, 0x08, 0x25, 0x18, 0x74, 0x7d, 0x78, 0x5c, 0x27, 0x97, 0xcc, + 0xd8, 0x4d, 0xaa, 0x20, 0x47, 0x77, 0xeb, 0xf8, 0x37, 0x72, 0xd4, 0xda, 0xdd, 0x20, 0xd7, 0x79, + 0xc1, 0xbf, 0xca, 0x8d, 0x62, 0x44, 0xb8, 0x17, 0xe4, 0x88, 0xab, 0xba, 0x12, 0xb9, 0xa4, 0x11, + 0x16, 0x19, 0xde, 0xb5, 0x86, 0x1e, 0xf4, 0x56, 0x8e, 0xe9, 0xe4, 0x4f, 0xf5, 0x66, 0x70, 0xfc, + 0xa2, 0xd1, 0xba, 0xb4, 0xe5, 0xd8, 0xbb, 0xe4, 0xe2, 0x23, 0x9b, 0xdd, 0xa0, 0x44, 0x6e, 0xa2, + 0x13, 0x3f, 0xa8, 0xb7, 0xf9, 0xa6, 0x43, 0x7e, 0x90, 0xe9, 0xb0, 0x72, 0x8c, 0x19, 0x0f, 0xea, + 0xe3, 0x83, 0x4e, 0xa7, 0x10, 0xdb, 0xe9, 0xac, 0x1c, 0xf3, 0xbb, 0x1d, 0x75, 0x11, 0x4c, 0xb6, + 0xcd, 0x3d, 0xb2, 0x55, 0x4d, 0x66, 0x5d, 0x83, 0x8e, 0x12, 0x2f, 0x9a, 0x7b, 0x74, 0x63, 0x7b, + 0xe5, 0x98, 0x1e, 0xfc, 0xa9, 0x2e, 0x83, 0x29, 0xb2, 0x2d, 0x40, 0xc8, 0x4c, 0x26, 0x3a, 0x26, + 0xbc, 0x72, 0x4c, 0x0f, 0xff, 0xc5, 0xd6, 0x47, 0x8e, 0x9c, 0xe1, 0xb8, 0xc7, 0xdf, 0x6e, 0xcf, + 0x24, 0xda, 0x6e, 0xc7, 0xb2, 0xa0, 0x1b, 0xee, 0xa7, 0x41, 0xbe, 0x45, 0x24, 0x9c, 0x65, 0x12, + 0xa6, 0xaf, 0xea, 0x5d, 0x20, 0xb7, 0x63, 0x38, 0xfe, 0xe4, 0xf9, 0xc6, 0xc1, 0x74, 0xd7, 0x0c, + 0xe7, 0x12, 0x46, 0x10, 0xff, 0xb5, 0x30, 0x01, 0xf2, 0x44, 0x70, 0xc1, 0x03, 0x7c, 0x5b, 0x8e, + 0x9a, 0x21, 0x65, 0xdb, 0xc2, 0xc3, 0x7e, 0xc3, 0xf6, 0x0f, 0xba, 0xfc, 0x41, 0x66, 0x34, 0x16, + 0x64, 0xdf, 0x2b, 0xad, 0x95, 0xc8, 0x2b, 0xad, 0x7b, 0xee, 0x56, 0xcd, 0xf5, 0xde, 0xad, 0x1a, + 0x2e, 0x1f, 0xe4, 0x07, 0x3b, 0xaa, 0xfc, 0xf9, 0x10, 0xa6, 0x4b, 0xaf, 0x20, 0xa2, 0x67, 0xe0, + 0x1d, 0xd3, 0xe2, 0xea, 0xec, 0xbf, 0x26, 0xec, 0x94, 0x92, 0x1a, 0x35, 0x03, 0xd8, 0x4b, 0xbf, + 0x6f, 0xfa, 0xcd, 0x1c, 0x38, 0x43, 0x6f, 0xf0, 0xdd, 0x43, 0x0d, 0x5b, 0xbc, 0x6a, 0x10, 0xfe, + 0xc9, 0x48, 0x94, 0xa6, 0xcf, 0x80, 0xa3, 0xf4, 0x1d, 0x70, 0x0e, 0x1c, 0x36, 0xce, 0x0d, 0x38, + 0x6c, 0x9c, 0x4f, 0xb6, 0x72, 0xf8, 0x7b, 0xbc, 0xfe, 0xac, 0x8b, 0xfa, 0x73, 0x67, 0x04, 0x40, + 0xfd, 0xe4, 0x32, 0x12, 0xfb, 0xe6, 0x9d, 0x81, 0xa6, 0xd4, 0x05, 0x4d, 0xb9, 0x67, 0x78, 0x46, + 0xd2, 0xd7, 0x96, 0xdf, 0xcd, 0x81, 0x2b, 0x42, 0x66, 0xaa, 0xe8, 0x32, 0x53, 0x94, 0xcf, 0x8e, + 0x44, 0x51, 0x92, 0xc7, 0x32, 0x48, 0x5b, 0x63, 0xfe, 0x54, 0xfa, 0x0c, 0x50, 0x2f, 0x50, 0x81, + 0x6c, 0x22, 0x94, 0xe5, 0x34, 0x28, 0xd0, 0x1e, 0x86, 0x41, 0xc3, 0xde, 0x12, 0x76, 0x37, 0x72, + 0x27, 0x87, 0x64, 0x79, 0x1b, 0x83, 0xfe, 0xb0, 0x75, 0x8d, 0xc6, 0xae, 0x63, 0x55, 0x2c, 0xcf, + 0x86, 0x3f, 0x3b, 0x12, 0xc5, 0x09, 0xbc, 0xe1, 0x94, 0x61, 0xbc, 0xe1, 0x86, 0x5a, 0xe5, 0xf0, + 0x6b, 0x70, 0x24, 0xab, 0x1c, 0x11, 0x85, 0xa7, 0x8f, 0xdf, 0x3b, 0x14, 0x7a, 0x9b, 0x7f, 0x1d, + 0x79, 0x0b, 0xa2, 0x85, 0x08, 0xef, 0x1f, 0x05, 0x90, 0x27, 0x7d, 0x33, 0x89, 0x5d, 0x46, 0x45, + 0x5e, 0xc4, 0x13, 0x4f, 0xb1, 0x97, 0x22, 0x08, 0xd3, 0xc1, 0x1e, 0x0e, 0x47, 0x82, 0x94, 0xdc, + 0x5d, 0x08, 0x09, 0xd8, 0x48, 0x1f, 0xb3, 0x17, 0x29, 0xa0, 0xc0, 0x6e, 0x6e, 0xdf, 0x48, 0xc5, + 0x61, 0x42, 0x0c, 0x8d, 0x2c, 0xb1, 0x23, 0x97, 0xf8, 0x7e, 0xf3, 0xf4, 0xf6, 0xe2, 0x8e, 0xe8, + 0x02, 0xf3, 0xef, 0x64, 0xc1, 0x74, 0x1d, 0x79, 0x65, 0xc3, 0x71, 0x4c, 0x63, 0x6b, 0x54, 0x1e, + 0xdf, 0xb2, 0xde, 0xc3, 0xf0, 0xbb, 0x19, 0xd9, 0xf3, 0x34, 0xc1, 0x42, 0xb8, 0xcf, 0x6a, 0x44, + 0x6c, 0x3f, 0xb9, 0x9b, 0xe3, 0x07, 0x51, 0x1b, 0x83, 0xc7, 0x76, 0x16, 0x4c, 0xf8, 0x67, 0xea, + 0x6e, 0x15, 0xce, 0x59, 0x6e, 0x7b, 0x3b, 0xfe, 0x31, 0x18, 0xf2, 0x7c, 0xf0, 0x2c, 0x17, 0x7c, + 0x79, 0x42, 0x47, 0xf9, 0xf8, 0x03, 0x81, 0xc9, 0xda, 0x58, 0x12, 0x77, 0xf8, 0xa3, 0x3a, 0x02, + 0xf8, 0xdb, 0x13, 0x6c, 0x39, 0x72, 0xd5, 0xf0, 0xd0, 0x83, 0xf0, 0x73, 0x0a, 0x98, 0xa8, 0x23, + 0x0f, 0x8f, 0xb7, 0x98, 0xfd, 0x43, 0x6b, 0xb8, 0xca, 0xad, 0x78, 0x4c, 0xb1, 0x35, 0x8c, 0xa7, + 0x81, 0xa9, 0xae, 0x63, 0xb7, 0x90, 0xeb, 0xb2, 0xd5, 0x0b, 0xde, 0x51, 0xad, 0xdf, 0xe8, 0x4f, + 0x58, 0x9b, 0x5f, 0xf7, 0xff, 0xd1, 0xc3, 0xdf, 0x93, 0x9a, 0x01, 0x94, 0x12, 0xab, 0xe0, 0xb8, + 0xcd, 0x80, 0xb8, 0xc2, 0xd3, 0x07, 0xfa, 0xd3, 0x0a, 0x98, 0xa9, 0x23, 0x2f, 0x90, 0x62, 0x82, + 0x4d, 0x8e, 0x68, 0x78, 0x05, 0x28, 0x95, 0xc3, 0x41, 0x29, 0x7f, 0x9f, 0x9e, 0x28, 0xcd, 0x80, + 0xd8, 0x18, 0xef, 0xd3, 0x93, 0xe3, 0x60, 0x0c, 0xc7, 0xd7, 0x1e, 0x05, 0xa6, 0x08, 0x2f, 0xa4, + 0xc1, 0xfe, 0x62, 0x2e, 0x6c, 0xbc, 0x9f, 0x4f, 0xa9, 0xf1, 0xde, 0x0d, 0xf2, 0xe4, 0x9e, 0x7e, + 0xd2, 0x70, 0xa7, 0x65, 0xcc, 0xf6, 0x35, 0x9c, 0x5d, 0xa7, 0x7f, 0xf5, 0xf7, 0xd3, 0xcc, 0x27, + 0xf3, 0xd3, 0x7c, 0x7d, 0x36, 0xd1, 0x48, 0x48, 0xe7, 0x0e, 0x23, 0x6c, 0xf2, 0x09, 0xc6, 0xcd, + 0x98, 0xb2, 0xd3, 0x57, 0x8e, 0x17, 0x28, 0x60, 0x12, 0x8f, 0xdb, 0xc4, 0x1e, 0xbf, 0x70, 0x78, + 0x75, 0xe8, 0x6f, 0xe8, 0x27, 0xec, 0x81, 0x7d, 0x89, 0x8c, 0xce, 0xbc, 0x4f, 0xd0, 0x03, 0xc7, + 0x15, 0x9e, 0x3e, 0x1e, 0xef, 0xa2, 0x78, 0x90, 0xf6, 0x00, 0xdf, 0xa0, 0x00, 0x65, 0x19, 0x79, + 0xe3, 0xb6, 0x22, 0xdf, 0x2e, 0x1d, 0xaa, 0x48, 0x10, 0x18, 0xe1, 0x79, 0x7e, 0x19, 0x8d, 0xa6, + 0x01, 0xc9, 0xc5, 0x28, 0x92, 0x62, 0x20, 0x7d, 0xd4, 0xde, 0x47, 0x51, 0xa3, 0x9b, 0x0b, 0x3f, + 0x33, 0x82, 0x5e, 0x75, 0xbc, 0x0b, 0x1f, 0xbe, 0x00, 0x09, 0x8d, 0xa3, 0x6a, 0x6f, 0xfd, 0x0a, + 0x1f, 0xcb, 0xfd, 0x75, 0x00, 0x37, 0xf6, 0x6d, 0xd4, 0xba, 0x84, 0xda, 0xf0, 0x27, 0x0f, 0x0f, + 0xdd, 0x19, 0x30, 0xd1, 0xa2, 0xd4, 0x08, 0x78, 0x93, 0xba, 0xff, 0x9a, 0xe0, 0x32, 0x66, 0xb1, + 0x23, 0xa2, 0xbf, 0x8f, 0xf1, 0x32, 0x66, 0x89, 0xe2, 0xc7, 0x60, 0xb6, 0xd0, 0x59, 0x46, 0xa5, + 0x65, 0x5b, 0xf0, 0x3f, 0x1c, 0x1e, 0x96, 0x6b, 0xc0, 0x94, 0xd9, 0xb2, 0xad, 0xca, 0x8e, 0x1f, + 0xdc, 0x6f, 0x4a, 0x0f, 0x13, 0xfc, 0xaf, 0xda, 0x8e, 0xfd, 0x80, 0xc9, 0x76, 0xcd, 0xc3, 0x84, + 0x61, 0x8d, 0x09, 0xcc, 0xfa, 0x51, 0x19, 0x13, 0x7d, 0xca, 0x4e, 0x1f, 0xb2, 0x8f, 0x86, 0xde, + 0x6d, 0xb4, 0x2b, 0x7c, 0x58, 0xac, 0x02, 0x0f, 0x33, 0x9c, 0xf1, 0xb5, 0x38, 0x92, 0xe1, 0x2c, + 0x86, 0x81, 0x31, 0xdc, 0x2f, 0x12, 0xe2, 0x98, 0xfa, 0x1a, 0xf0, 0x21, 0xd0, 0x19, 0x9d, 0x79, + 0x38, 0x24, 0x3a, 0x47, 0x63, 0x22, 0x7e, 0x90, 0x85, 0xba, 0x64, 0x16, 0x0f, 0xfc, 0x8f, 0xa3, + 0x00, 0xe7, 0xce, 0x61, 0xfc, 0x15, 0xa8, 0xb7, 0x42, 0x82, 0x6b, 0xa4, 0x0f, 0x48, 0x10, 0x53, + 0x19, 0xe3, 0x05, 0xeb, 0x32, 0xe5, 0xa7, 0x0f, 0xe0, 0x2f, 0x28, 0x60, 0x8e, 0xf8, 0x08, 0x74, + 0x90, 0xe1, 0xd0, 0x8e, 0x72, 0x24, 0x8e, 0xf2, 0xef, 0x92, 0x0e, 0xf0, 0x23, 0xca, 0x21, 0xe4, + 0x63, 0x24, 0x50, 0xc8, 0x45, 0xf7, 0x91, 0x64, 0x61, 0x2c, 0xdb, 0x28, 0xc5, 0x80, 0x05, 0xa6, + 0xe2, 0xa3, 0xc1, 0x23, 0xa1, 0x47, 0xae, 0x28, 0x0c, 0xbf, 0xb1, 0x8d, 0xd9, 0x23, 0x57, 0x86, + 0x89, 0x31, 0xdc, 0x30, 0xf9, 0x38, 0xb6, 0xe0, 0xdc, 0x20, 0xb7, 0xac, 0xbf, 0x32, 0x17, 0x9c, + 0x68, 0xfb, 0xf4, 0x48, 0x3c, 0x30, 0x0f, 0x11, 0xd8, 0x5e, 0x05, 0x39, 0xc7, 0xbe, 0x4c, 0x97, + 0xb6, 0x66, 0x75, 0xf2, 0x4c, 0x4c, 0x7e, 0xbb, 0xb3, 0xbb, 0x63, 0xd1, 0x93, 0xa1, 0xb3, 0xba, + 0xff, 0xaa, 0xde, 0x00, 0x66, 0x2f, 0x9b, 0xde, 0xf6, 0x0a, 0x32, 0xda, 0xc8, 0xd1, 0xed, 0xcb, + 0xc4, 0x63, 0x6e, 0x52, 0x17, 0x13, 0x45, 0xff, 0x15, 0x09, 0xfb, 0x92, 0x5c, 0xbd, 0x3e, 0x96, + 0xe3, 0x6f, 0x49, 0x2c, 0xcf, 0x68, 0xae, 0xd2, 0x57, 0x98, 0xf7, 0x2b, 0x60, 0x4a, 0xb7, 0x2f, + 0x33, 0x25, 0xf9, 0xbf, 0x8e, 0x56, 0x47, 0x12, 0x4f, 0xf4, 0xe8, 0x55, 0xfa, 0x3e, 0xfb, 0x63, + 0x9f, 0xe8, 0xc5, 0x16, 0x3f, 0x96, 0x93, 0x4b, 0x33, 0xba, 0x7d, 0xb9, 0x8e, 0x3c, 0xda, 0x22, + 0x60, 0x73, 0x44, 0x4e, 0xd6, 0xa6, 0x4b, 0x09, 0xb2, 0x79, 0x78, 0xf0, 0x9e, 0x74, 0x17, 0x21, + 0x10, 0x50, 0xc0, 0xe2, 0xb8, 0x77, 0x11, 0x06, 0x72, 0x30, 0x86, 0x18, 0x29, 0x0a, 0x98, 0xd6, + 0xed, 0xcb, 0x78, 0x68, 0x58, 0x32, 0x3b, 0x9d, 0xd1, 0x8c, 0x90, 0x49, 0x8d, 0x7f, 0x5f, 0x0c, + 0x3e, 0x17, 0x63, 0x37, 0xfe, 0x07, 0x30, 0x90, 0x3e, 0x0c, 0xcf, 0xa3, 0x8d, 0xc5, 0x1f, 0xa1, + 0xad, 0xd1, 0xe0, 0x30, 0x6c, 0x83, 0x08, 0xd8, 0x38, 0xb2, 0x06, 0x11, 0xc5, 0xc1, 0x58, 0x76, + 0x4e, 0xe6, 0xca, 0x64, 0x98, 0x1f, 0x6d, 0x9b, 0x78, 0x4f, 0x32, 0xd7, 0x44, 0x36, 0xec, 0x0a, + 0x8c, 0x8c, 0x04, 0x8d, 0x04, 0x2e, 0x88, 0x12, 0x3c, 0xa4, 0x8f, 0xc7, 0x87, 0x14, 0x30, 0x43, + 0x59, 0x78, 0x98, 0x58, 0x01, 0x43, 0x35, 0x2a, 0xbe, 0x06, 0x47, 0xd3, 0xa8, 0x62, 0x38, 0x18, + 0xcb, 0x2d, 0x9d, 0xd8, 0x8e, 0x1b, 0xe2, 0xf8, 0x78, 0x14, 0x82, 0x43, 0x1b, 0x63, 0x23, 0x3c, + 0x42, 0x3e, 0x8c, 0x31, 0x76, 0x44, 0xc7, 0xc8, 0x9f, 0x17, 0xb4, 0xa2, 0x51, 0x62, 0x70, 0x88, + 0xa6, 0x30, 0x42, 0x18, 0x86, 0x6c, 0x0a, 0x47, 0x84, 0xc4, 0x97, 0x15, 0x00, 0x28, 0x03, 0x6b, + 0xf6, 0x1e, 0xb9, 0x94, 0x67, 0x04, 0xdd, 0x59, 0xaf, 0x5b, 0xbd, 0x32, 0xc0, 0xad, 0x3e, 0x61, + 0x08, 0x97, 0xa4, 0x2b, 0x81, 0x9c, 0x94, 0x71, 0x25, 0xc7, 0xbe, 0x12, 0x18, 0x5f, 0x7e, 0xfa, + 0x18, 0x7f, 0x91, 0x5a, 0x73, 0xe1, 0x01, 0xd3, 0x5f, 0x1b, 0x09, 0xca, 0xdc, 0xec, 0x5f, 0x11, + 0x67, 0xff, 0x87, 0xc0, 0x76, 0x58, 0x1b, 0x71, 0xd0, 0xc1, 0xd1, 0xf4, 0x6d, 0xc4, 0xa3, 0x3b, + 0x20, 0xfa, 0x33, 0x39, 0x70, 0x9c, 0x75, 0x22, 0x3f, 0x0c, 0x10, 0x27, 0x3c, 0x87, 0x27, 0x74, + 0x92, 0x03, 0x50, 0x1e, 0xd5, 0x82, 0x54, 0x92, 0xa5, 0x4c, 0x09, 0xf6, 0xc6, 0xb2, 0xba, 0x51, + 0xd0, 0x1e, 0xec, 0x1a, 0x56, 0x5b, 0x3e, 0xdc, 0xef, 0x00, 0xe0, 0xfd, 0xb5, 0x46, 0x45, 0x5c, + 0x6b, 0xec, 0xb3, 0x32, 0x99, 0x78, 0xe7, 0x9a, 0x88, 0x8c, 0xb2, 0x3b, 0xf6, 0x9d, 0xeb, 0xe8, + 0xb2, 0xd3, 0x47, 0xe9, 0x3d, 0x0a, 0xc8, 0xd5, 0x6d, 0xc7, 0x83, 0x0f, 0x25, 0x69, 0x9d, 0x54, + 0xf2, 0x21, 0x48, 0xfe, 0xbb, 0x5a, 0x16, 0x6e, 0x4d, 0xbe, 0x35, 0xfe, 0xa8, 0xb3, 0xe1, 0x19, + 0xc4, 0xab, 0x1b, 0x97, 0xcf, 0x5d, 0x9f, 0x9c, 0x34, 0x9e, 0x0e, 0x95, 0x5f, 0x3d, 0xfa, 0x00, + 0x46, 0x6a, 0xf1, 0x74, 0x22, 0x4b, 0x4e, 0x1f, 0xb7, 0xff, 0x36, 0xc7, 0x7c, 0x5b, 0x97, 0xcc, + 0x0e, 0x82, 0x0f, 0x51, 0x97, 0x91, 0xaa, 0xb1, 0x83, 0xe4, 0x8f, 0xc4, 0xc4, 0xba, 0xb6, 0x92, + 0xf8, 0xb2, 0x4a, 0x18, 0x5f, 0x36, 0x69, 0x83, 0xa2, 0x07, 0xd0, 0x29, 0x4b, 0xe3, 0x6e, 0x50, + 0x31, 0x65, 0x8f, 0x25, 0x4e, 0xe7, 0x89, 0x3a, 0xf2, 0xa8, 0x51, 0x59, 0xf3, 0x6f, 0x60, 0xf9, + 0xa9, 0x91, 0x44, 0xec, 0x0c, 0x2e, 0x78, 0x51, 0x7a, 0x2e, 0x78, 0x79, 0x3f, 0x0f, 0xce, 0x9a, + 0x08, 0xce, 0x93, 0xa2, 0x05, 0x24, 0x32, 0x39, 0x12, 0x98, 0xde, 0x1e, 0xc0, 0xb4, 0x2e, 0xc0, + 0x74, 0xd7, 0x90, 0x5c, 0xa4, 0x0f, 0xd8, 0xe7, 0xb1, 0xa9, 0x42, 0x26, 0xfd, 0x25, 0xab, 0xcd, + 0x22, 0xac, 0xfe, 0xd3, 0x51, 0x6f, 0xb6, 0x1d, 0x0c, 0xc1, 0x2a, 0xc4, 0x72, 0xce, 0xf7, 0xde, + 0x56, 0xbf, 0x40, 0xc3, 0xb9, 0xe2, 0x4e, 0x94, 0xec, 0xb4, 0xc9, 0xdf, 0x58, 0x1f, 0xfc, 0x07, + 0xff, 0x2c, 0xd9, 0xfa, 0x1b, 0x21, 0xd1, 0x23, 0xb8, 0x94, 0x6d, 0xa0, 0x04, 0x2b, 0x73, 0x12, + 0xdc, 0xfd, 0x68, 0xb8, 0x85, 0x85, 0x91, 0x40, 0x86, 0x74, 0x0b, 0x23, 0x04, 0x8e, 0xd2, 0x2d, + 0x6c, 0x10, 0x03, 0x63, 0xb8, 0x65, 0x3e, 0xcf, 0x76, 0xe5, 0x89, 0xcf, 0x24, 0xfc, 0x9b, 0x6c, + 0xea, 0xa3, 0xed, 0xf7, 0x32, 0x89, 0xfc, 0x98, 0x09, 0x5f, 0xf1, 0xc3, 0x6d, 0x12, 0xcf, 0xe4, + 0x38, 0x72, 0x63, 0x58, 0xff, 0xc9, 0x12, 0x9f, 0xf2, 0x0b, 0x66, 0xdb, 0xdb, 0x1e, 0xd1, 0xc9, + 0x8c, 0xcb, 0x98, 0x96, 0x7f, 0x5d, 0x31, 0x79, 0x81, 0xff, 0x92, 0x49, 0x14, 0x0a, 0x2a, 0x10, + 0x09, 0x61, 0x2b, 0x42, 0xc4, 0x09, 0x02, 0x38, 0xc5, 0xd2, 0x1b, 0xa3, 0x46, 0x9f, 0x37, 0xdb, + 0xc8, 0x7e, 0x18, 0x6a, 0x34, 0xe1, 0x6b, 0x74, 0x1a, 0x1d, 0x47, 0xee, 0x47, 0x54, 0xa3, 0x03, + 0x91, 0x8c, 0x48, 0xa3, 0x63, 0xe9, 0xa5, 0x2f, 0xe3, 0x97, 0xcf, 0xb0, 0x09, 0xd1, 0xaa, 0x69, + 0x5d, 0x82, 0xdf, 0x2e, 0xf8, 0x17, 0x25, 0x5f, 0x30, 0xbd, 0x6d, 0x16, 0xd3, 0xe5, 0x77, 0xa5, + 0xef, 0x38, 0x19, 0x22, 0x6e, 0x8b, 0x18, 0x16, 0x2a, 0x7f, 0x20, 0x2c, 0x54, 0x09, 0xcc, 0x9a, + 0x96, 0x87, 0x1c, 0xcb, 0xe8, 0x2c, 0x75, 0x8c, 0x2d, 0xf7, 0xcc, 0x44, 0xdf, 0x4b, 0xe8, 0x2a, + 0x5c, 0x1e, 0x5d, 0xfc, 0x83, 0xbf, 0x4e, 0x72, 0x52, 0xbc, 0x16, 0x3f, 0x22, 0x8a, 0xd5, 0x54, + 0x74, 0x14, 0xab, 0x20, 0x4a, 0x15, 0x18, 0x1c, 0xe4, 0x5a, 0xd6, 0xc6, 0x4d, 0x18, 0xb6, 0xef, + 0x56, 0xc9, 0x68, 0x6a, 0x41, 0x08, 0xc7, 0x57, 0x29, 0x89, 0x56, 0xe9, 0xb0, 0x22, 0xcc, 0xf7, + 0x2a, 0x41, 0x62, 0x0b, 0x95, 0xaf, 0xbc, 0xd2, 0x53, 0xf9, 0xc0, 0xe4, 0xc9, 0x49, 0x98, 0x3c, + 0xbc, 0x52, 0xe5, 0xe5, 0x94, 0x2a, 0xc9, 0xa2, 0x9f, 0x4c, 0x6d, 0xc7, 0x70, 0xaa, 0x28, 0x0f, + 0x4e, 0xf8, 0x51, 0x6b, 0xbb, 0x5d, 0x64, 0x38, 0x86, 0xd5, 0x42, 0xf0, 0xa3, 0xd9, 0x51, 0x98, + 0xbd, 0x4b, 0x60, 0xd2, 0x6c, 0xd9, 0x56, 0xdd, 0x7c, 0xa6, 0x7f, 0x49, 0x5c, 0x7c, 0xb0, 0x74, + 0x22, 0x91, 0x0a, 0xfb, 0x43, 0x0f, 0xfe, 0x55, 0x2b, 0x60, 0xaa, 0x65, 0x38, 0x6d, 0x1a, 0x4c, + 0x2f, 0xdf, 0x73, 0x21, 0x53, 0x24, 0xa1, 0xb2, 0xff, 0x8b, 0x1e, 0xfe, 0xad, 0xd6, 0x44, 0x21, + 0x16, 0x7a, 0xa2, 0x72, 0x44, 0x12, 0x5b, 0x0c, 0x7f, 0x12, 0x64, 0x8e, 0xa5, 0xe3, 0xa0, 0x0e, + 0xb9, 0x13, 0x9e, 0xf6, 0x10, 0x53, 0x7a, 0x98, 0x90, 0x74, 0x9a, 0x4f, 0x8a, 0x3a, 0x80, 0xc6, + 0xb8, 0xa7, 0xf9, 0x52, 0x5c, 0xa4, 0xaf, 0x99, 0xef, 0x2c, 0x80, 0x59, 0xda, 0xab, 0x31, 0x71, + 0xc2, 0x5f, 0x20, 0x57, 0x3a, 0x7b, 0xf7, 0xa1, 0x7d, 0x58, 0x3f, 0xfc, 0x98, 0x5c, 0x04, 0xca, + 0xa5, 0x20, 0x70, 0x20, 0x7e, 0x4c, 0xba, 0xff, 0xee, 0xf3, 0x35, 0x4f, 0x79, 0x1a, 0xf7, 0xfe, + 0x7b, 0x7c, 0xf1, 0xe9, 0xe3, 0xf3, 0xcb, 0x0a, 0x50, 0x4a, 0xed, 0x36, 0x6c, 0x1d, 0x1e, 0x8a, + 0xeb, 0xc0, 0xb4, 0xdf, 0x66, 0xc2, 0x58, 0x8e, 0x7c, 0x52, 0xd2, 0xc5, 0xcc, 0x40, 0x36, 0xa5, + 0xf6, 0xd8, 0x77, 0x07, 0x62, 0xca, 0x4e, 0x1f, 0x94, 0x5f, 0x9b, 0x60, 0x8d, 0x66, 0xc1, 0xb6, + 0x2f, 0x91, 0x23, 0x2f, 0x0f, 0x29, 0x20, 0xbf, 0x84, 0xbc, 0xd6, 0xf6, 0x88, 0xda, 0xcc, 0xae, + 0xd3, 0xf1, 0xdb, 0xcc, 0x81, 0xfb, 0xe9, 0x07, 0xdb, 0xb0, 0x3e, 0x5b, 0xf3, 0x84, 0xa5, 0x71, + 0x47, 0x69, 0x8e, 0x2d, 0x3d, 0x7d, 0x70, 0xfe, 0x45, 0x01, 0x73, 0xc1, 0x0a, 0x17, 0xc5, 0xe4, + 0x97, 0x1e, 0x76, 0xeb, 0x96, 0xf0, 0xb3, 0xc9, 0x42, 0x9d, 0x05, 0x32, 0x15, 0x6b, 0x96, 0xf2, + 0xc2, 0x62, 0x82, 0x20, 0x68, 0x72, 0x0c, 0x8e, 0x61, 0x06, 0xaf, 0x80, 0x49, 0xc2, 0xd0, 0xa2, + 0xb9, 0x47, 0x5c, 0x00, 0x85, 0x85, 0xc6, 0x67, 0x8d, 0x64, 0xa1, 0xf1, 0x2e, 0x71, 0xa1, 0x51, + 0x32, 0x72, 0xb1, 0xbf, 0xce, 0x98, 0xd0, 0x27, 0x06, 0xff, 0x3f, 0xf2, 0x65, 0xc6, 0x04, 0x3e, + 0x31, 0x03, 0xca, 0x4f, 0x1f, 0xd1, 0x57, 0xfd, 0x3b, 0xd6, 0xd9, 0xfa, 0x1b, 0xa3, 0xf0, 0xbf, + 0x9d, 0x00, 0xb9, 0xf3, 0xf8, 0xe1, 0x7f, 0x86, 0x37, 0x5b, 0xbd, 0x74, 0x04, 0x41, 0x16, 0x9e, + 0x0a, 0x72, 0x98, 0x3e, 0x9b, 0xb6, 0xdc, 0x2c, 0xb7, 0x4b, 0x8b, 0x19, 0xd1, 0xc9, 0x7f, 0xea, + 0x69, 0x50, 0x70, 0xed, 0x5d, 0xa7, 0x85, 0xcd, 0x67, 0xac, 0x31, 0xec, 0x2d, 0x69, 0x70, 0x51, + 0x81, 0xf4, 0xfc, 0xe8, 0x5c, 0x3f, 0xb9, 0x8b, 0x8e, 0x14, 0xe1, 0xa2, 0xa3, 0x04, 0xfb, 0x07, + 0x12, 0xbc, 0xa5, 0xaf, 0x11, 0x7f, 0x43, 0xee, 0xfc, 0x6b, 0x8f, 0x0a, 0xf6, 0x08, 0xb1, 0x1c, + 0x56, 0x1d, 0x92, 0x3a, 0x6e, 0x8b, 0xa2, 0x0d, 0xe2, 0xb9, 0x8f, 0xd5, 0x71, 0x5b, 0x82, 0x87, + 0xb1, 0x9c, 0x36, 0x2f, 0x30, 0x67, 0xd3, 0xfb, 0x47, 0x89, 0x6e, 0x4e, 0x50, 0xfa, 0x43, 0xa1, + 0x33, 0x42, 0x27, 0xd4, 0xa1, 0xd1, 0x39, 0x22, 0x37, 0xd4, 0x3f, 0x54, 0x48, 0x44, 0x4b, 0xdf, + 0xc8, 0x91, 0xbf, 0xb0, 0x28, 0x31, 0x44, 0x78, 0x0c, 0x16, 0xe2, 0x39, 0xcf, 0x0e, 0x1f, 0xe2, + 0x5b, 0x14, 0x1d, 0xc7, 0xff, 0xb8, 0x43, 0x7c, 0xcb, 0x32, 0x92, 0x3e, 0x90, 0xaf, 0xa3, 0x17, + 0x84, 0x95, 0x5a, 0x9e, 0xb9, 0x37, 0xe2, 0x96, 0x26, 0x0e, 0x2f, 0x09, 0xa3, 0xfa, 0x1e, 0x90, + 0x10, 0xe5, 0x70, 0xdc, 0x51, 0x7d, 0xe5, 0xd8, 0x48, 0x1f, 0xa6, 0xaf, 0x15, 0xb0, 0xf4, 0xd8, + 0xda, 0xcc, 0x1b, 0xd8, 0x6a, 0x00, 0x3a, 0x3c, 0x5a, 0xe7, 0xc0, 0x0c, 0x37, 0xf5, 0xf7, 0x2f, + 0x9e, 0x11, 0xd2, 0x92, 0x1e, 0x58, 0x0f, 0x44, 0x36, 0xf2, 0x85, 0x81, 0x04, 0x0b, 0xbe, 0x32, + 0x4c, 0x8c, 0xe5, 0x5e, 0x37, 0x7f, 0x0c, 0x1b, 0x13, 0x56, 0xbf, 0xcb, 0x63, 0x55, 0x13, 0xb1, + 0xba, 0x43, 0x46, 0x4c, 0x72, 0x63, 0x9a, 0xd4, 0xbc, 0xf1, 0x1d, 0x01, 0x5c, 0xba, 0x00, 0xd7, + 0x53, 0x87, 0xe6, 0x23, 0x7d, 0xc4, 0x7e, 0x9d, 0x76, 0x87, 0x75, 0x6a, 0xb2, 0x8f, 0xa6, 0x3b, + 0x64, 0xb3, 0x01, 0x45, 0x98, 0x0d, 0x24, 0xf4, 0x9b, 0x0f, 0xdd, 0x41, 0x7d, 0xe6, 0x06, 0x41, + 0x94, 0x1b, 0xb1, 0xdf, 0xfc, 0x40, 0x0e, 0xd2, 0x07, 0xe7, 0x1f, 0x15, 0x00, 0x96, 0x1d, 0x7b, + 0xb7, 0x5b, 0x73, 0xda, 0xc8, 0x81, 0x7f, 0x17, 0x4e, 0x00, 0x5e, 0x3c, 0x82, 0x09, 0xc0, 0x3a, + 0x00, 0x5b, 0x01, 0x71, 0xa6, 0xe1, 0x8f, 0x93, 0x33, 0xf7, 0x43, 0xa6, 0x74, 0x8e, 0x86, 0x78, + 0x75, 0xec, 0xd3, 0x45, 0x8c, 0xe3, 0xfa, 0xac, 0x90, 0xdc, 0x28, 0x27, 0x00, 0xef, 0x0a, 0xb0, + 0x6e, 0x08, 0x58, 0xdf, 0x7b, 0x08, 0x4e, 0xd2, 0xc7, 0xfc, 0x9f, 0x26, 0xc0, 0x34, 0xdd, 0xae, + 0xa3, 0x32, 0xfd, 0x87, 0x10, 0xf4, 0x5f, 0x1b, 0x01, 0xe8, 0x1b, 0x60, 0xc6, 0x0e, 0xa9, 0xd3, + 0x3e, 0x95, 0x5f, 0x80, 0x89, 0x85, 0x9d, 0xe3, 0x4b, 0x17, 0xc8, 0xc0, 0x0f, 0xf3, 0xc8, 0xeb, + 0x22, 0xf2, 0x77, 0xc5, 0xc8, 0x9b, 0xa3, 0x38, 0x4a, 0xe8, 0xdf, 0x1d, 0x40, 0xbf, 0x21, 0x40, + 0x5f, 0x3a, 0x0c, 0x2b, 0x63, 0x08, 0x9b, 0xaf, 0x80, 0x1c, 0x39, 0xe5, 0xf6, 0x9b, 0x29, 0xce, + 0xef, 0xcf, 0x80, 0x09, 0xd2, 0x64, 0x83, 0x79, 0x87, 0xff, 0x8a, 0xbf, 0x18, 0x9b, 0x1e, 0x72, + 0x02, 0x8f, 0x05, 0xff, 0x15, 0xf3, 0xe0, 0x7b, 0x17, 0xbb, 0x67, 0x0a, 0x74, 0x23, 0x32, 0x48, + 0x18, 0x7a, 0x52, 0xc2, 0x4b, 0x7c, 0x64, 0xe7, 0xde, 0x86, 0x99, 0x94, 0x0c, 0x60, 0x24, 0x7d, + 0xe0, 0xff, 0x2a, 0x07, 0xce, 0xd0, 0x55, 0xa5, 0x25, 0xc7, 0xde, 0xe9, 0xb9, 0xa5, 0xca, 0x3c, + 0xbc, 0x2e, 0xdc, 0x08, 0xe6, 0x3c, 0xc1, 0xaf, 0x9a, 0xe9, 0x44, 0x4f, 0x2a, 0xfc, 0x73, 0xde, + 0xa7, 0xe2, 0x19, 0x22, 0x92, 0x0b, 0x31, 0x02, 0x8c, 0xe2, 0x3d, 0xf1, 0x42, 0xbd, 0x24, 0xa3, + 0xdc, 0x22, 0x95, 0x32, 0xd4, 0x9a, 0x65, 0xa0, 0x53, 0x79, 0x19, 0x9d, 0xfa, 0x40, 0xa0, 0x53, + 0x3f, 0x29, 0xe8, 0xd4, 0xf2, 0xe1, 0x45, 0x92, 0xbe, 0x6e, 0xbd, 0x32, 0xd8, 0x18, 0x0a, 0xb6, + 0xed, 0x76, 0x52, 0xd8, 0xac, 0xe3, 0xfd, 0x91, 0x72, 0x82, 0x3f, 0x92, 0x78, 0xaf, 0x44, 0x82, + 0x99, 0xb0, 0xc8, 0x75, 0x84, 0x2e, 0xcd, 0x81, 0xac, 0xe9, 0x73, 0x97, 0x35, 0xdb, 0x43, 0xcd, + 0x75, 0x63, 0x0b, 0x1a, 0xc3, 0xda, 0xd2, 0x1c, 0x28, 0x2c, 0x99, 0x1d, 0x0f, 0x39, 0xf0, 0x8b, + 0x6c, 0xa6, 0xfb, 0xca, 0x14, 0x07, 0x80, 0x45, 0x50, 0xd8, 0x24, 0xa5, 0x31, 0x93, 0xf9, 0x16, + 0xb9, 0xd6, 0x43, 0x39, 0xd4, 0xd9, 0xbf, 0x49, 0xa3, 0xec, 0xf5, 0x90, 0x19, 0xd9, 0x14, 0x39, + 0x41, 0x94, 0xbd, 0xc1, 0x2c, 0x8c, 0xe5, 0x82, 0xa9, 0x82, 0x8e, 0x76, 0xf0, 0x18, 0x7f, 0x29, + 0x3d, 0x84, 0x8b, 0x40, 0x31, 0xdb, 0x2e, 0xe9, 0x1c, 0xa7, 0x74, 0xfc, 0x98, 0xd4, 0x57, 0xa8, + 0x57, 0x54, 0x94, 0xe5, 0x71, 0xfb, 0x0a, 0x49, 0x71, 0x91, 0x3e, 0x66, 0xdf, 0x23, 0x8e, 0xa2, + 0xdd, 0x8e, 0xd1, 0x42, 0x98, 0xfb, 0xd4, 0x50, 0xa3, 0x3d, 0x59, 0xce, 0xef, 0xc9, 0xb8, 0x76, + 0x9a, 0x3f, 0x44, 0x3b, 0x1d, 0x76, 0x19, 0x32, 0x90, 0x39, 0xa9, 0xf8, 0x91, 0x2d, 0x43, 0xc6, + 0xb2, 0x31, 0x86, 0xeb, 0x43, 0xfd, 0x03, 0xb1, 0x63, 0x6d, 0xad, 0xc3, 0x6e, 0xd2, 0x30, 0x61, + 0x8d, 0xec, 0xf0, 0xeb, 0x30, 0x9b, 0x34, 0xd1, 0x3c, 0x8c, 0x01, 0xad, 0x39, 0x86, 0xd6, 0x67, + 0xd8, 0x30, 0x9a, 0xf2, 0x3e, 0xa9, 0x6b, 0x3b, 0x5e, 0xb2, 0x7d, 0x52, 0xcc, 0x9d, 0x4e, 0xfe, + 0x4b, 0x7a, 0xf0, 0x4a, 0x3c, 0x1f, 0x3d, 0xaa, 0xe1, 0x33, 0xc1, 0xc1, 0xab, 0x41, 0x0c, 0xa4, + 0x0f, 0xef, 0x5b, 0x8f, 0x68, 0xf0, 0x1c, 0xb6, 0x39, 0xb2, 0x36, 0x30, 0xb2, 0xa1, 0x73, 0x98, + 0xe6, 0x18, 0xcd, 0x43, 0xfa, 0x78, 0x7d, 0x8b, 0x1b, 0x38, 0xdf, 0x34, 0xc6, 0x81, 0xd3, 0x6f, + 0x99, 0xf9, 0x21, 0x5b, 0xe6, 0xb0, 0xfb, 0x3f, 0x4c, 0xd6, 0xa3, 0x1b, 0x30, 0x87, 0xd9, 0xff, + 0x89, 0x61, 0x22, 0x7d, 0xc4, 0xdf, 0xac, 0x80, 0x7c, 0x7d, 0xfc, 0xe3, 0xe5, 0xb0, 0x73, 0x11, + 0x22, 0xab, 0xfa, 0xc8, 0x86, 0xcb, 0x61, 0xe6, 0x22, 0x91, 0x2c, 0x8c, 0x21, 0x80, 0xfe, 0x71, + 0x30, 0x43, 0x96, 0x44, 0xfc, 0x6d, 0xd6, 0x6f, 0xb1, 0x51, 0xf3, 0xf5, 0x29, 0xb6, 0xd5, 0xa7, + 0x81, 0x49, 0x7f, 0xff, 0x8e, 0x8d, 0x9c, 0xf3, 0x72, 0xed, 0xd3, 0xe7, 0x52, 0x0f, 0xfe, 0x3f, + 0x94, 0x33, 0xc4, 0xc8, 0xf7, 0x6a, 0x87, 0x75, 0x86, 0x38, 0xd2, 0xfd, 0xda, 0x3f, 0x0b, 0x47, + 0xd4, 0xff, 0x90, 0x1e, 0xe6, 0xbd, 0xfb, 0xb8, 0xb9, 0x3e, 0xfb, 0xb8, 0x1f, 0xe5, 0xb1, 0xac, + 0x8b, 0x58, 0xde, 0x2d, 0x2b, 0xc2, 0x11, 0x8e, 0xb5, 0xef, 0x09, 0xe0, 0x3c, 0x2f, 0xc0, 0xb9, + 0x70, 0x28, 0x5e, 0xc6, 0x70, 0xf0, 0x31, 0x17, 0x8e, 0xb9, 0x1f, 0x4b, 0xb1, 0x1d, 0xf7, 0x9c, + 0xaa, 0xc8, 0x1d, 0x38, 0x55, 0x21, 0xb4, 0xf4, 0xfc, 0x21, 0x5b, 0xfa, 0xc7, 0x78, 0xed, 0x68, + 0x88, 0xda, 0xf1, 0x54, 0x79, 0x44, 0x46, 0x37, 0x32, 0xbf, 0x37, 0x50, 0x8f, 0x0b, 0x82, 0x7a, + 0x94, 0x0f, 0xc7, 0x4c, 0xfa, 0xfa, 0xf1, 0x47, 0xfe, 0x84, 0xf6, 0x88, 0xdb, 0xfb, 0xb0, 0x5b, + 0xc5, 0x82, 0x10, 0x47, 0x36, 0x72, 0x0f, 0xb3, 0x55, 0x3c, 0x88, 0x93, 0x31, 0xc4, 0x54, 0x9b, + 0x05, 0xd3, 0x84, 0xa7, 0x0b, 0x66, 0x7b, 0x0b, 0x79, 0xf0, 0x55, 0xd4, 0x47, 0xd1, 0x8f, 0x60, + 0x39, 0xa2, 0x30, 0x43, 0x51, 0xe7, 0x5d, 0x93, 0x7a, 0x74, 0x50, 0x26, 0xe7, 0x39, 0x06, 0xc7, + 0x1d, 0x09, 0x71, 0x20, 0x07, 0xe9, 0x43, 0xf6, 0x61, 0xea, 0x6e, 0xb3, 0x6a, 0xec, 0xdb, 0xbb, + 0x1e, 0x7c, 0xce, 0x08, 0x3a, 0xe8, 0x05, 0x50, 0xe8, 0x10, 0x6a, 0xec, 0x58, 0x46, 0xfc, 0x74, + 0x87, 0x89, 0x80, 0x96, 0xaf, 0xb3, 0x3f, 0x93, 0x9e, 0xcd, 0x08, 0xe5, 0x48, 0xe9, 0x8c, 0xfb, + 0x6c, 0xc6, 0x80, 0xf2, 0xc7, 0x72, 0x57, 0xce, 0x24, 0x2e, 0xdd, 0xdc, 0x31, 0xbd, 0x11, 0x45, + 0x70, 0xe8, 0x60, 0x5a, 0x7e, 0x04, 0x07, 0xf2, 0x92, 0xf4, 0xc4, 0x28, 0x27, 0x15, 0xfc, 0xfb, + 0xb8, 0x4f, 0x8c, 0xc6, 0x17, 0x9f, 0x3e, 0x26, 0xff, 0x99, 0xb6, 0xac, 0xf3, 0xd4, 0xf9, 0x36, + 0x45, 0xbf, 0xde, 0xa1, 0x1b, 0x0b, 0x65, 0xed, 0xe8, 0x1a, 0x4b, 0xdf, 0xf2, 0xd3, 0x07, 0xe6, + 0x37, 0x6e, 0x00, 0xf9, 0x45, 0x74, 0x71, 0x77, 0x0b, 0xde, 0x05, 0x26, 0x1b, 0x0e, 0x42, 0x15, + 0x6b, 0xd3, 0xc6, 0xd2, 0xf5, 0xf0, 0xb3, 0x0f, 0x09, 0x7b, 0xc3, 0x78, 0x6c, 0x23, 0xa3, 0x1d, + 0x9e, 0x3f, 0xf3, 0x5f, 0xe1, 0x4b, 0xb3, 0x20, 0x57, 0xf7, 0x0c, 0x0f, 0x4e, 0x05, 0xd8, 0xc2, + 0xe7, 0xf0, 0x58, 0xdc, 0x25, 0x62, 0x71, 0xa3, 0x20, 0x0b, 0xc2, 0xc1, 0x3c, 0xfe, 0x3f, 0x02, + 0x00, 0x08, 0x26, 0x1f, 0x70, 0x6d, 0x0b, 0xe7, 0xf0, 0x8f, 0x40, 0xfa, 0xef, 0xf0, 0x15, 0x81, + 0xb8, 0xef, 0x11, 0xc4, 0xfd, 0x18, 0xb9, 0x22, 0xc6, 0xb0, 0xd2, 0x96, 0x05, 0x53, 0x58, 0xb4, + 0x2b, 0xc8, 0x68, 0xbb, 0xf0, 0x91, 0xa1, 0xf2, 0x47, 0x88, 0x19, 0x7e, 0x50, 0x3a, 0xa8, 0x26, + 0xad, 0x55, 0x40, 0x3c, 0xda, 0xa3, 0xc3, 0xdf, 0xfc, 0xcf, 0x8a, 0xc1, 0x48, 0x6e, 0x05, 0x39, + 0xd3, 0xda, 0xb4, 0x99, 0x7f, 0xe1, 0xd5, 0x11, 0xb4, 0xb1, 0x4e, 0xe8, 0x24, 0xa3, 0x64, 0xc4, + 0xcd, 0x78, 0xb6, 0xc6, 0x72, 0x79, 0x5d, 0x0e, 0x97, 0x0e, 0xff, 0xcf, 0x81, 0xc2, 0x56, 0x55, + 0x90, 0xeb, 0x1a, 0xde, 0x36, 0x2b, 0x9a, 0x3c, 0x63, 0x1b, 0x79, 0xd7, 0x32, 0x2c, 0xdb, 0xda, + 0xdf, 0x31, 0x9f, 0x19, 0xdc, 0x91, 0x2b, 0xa4, 0x61, 0xce, 0xb7, 0x90, 0x85, 0x1c, 0xc3, 0x43, + 0xf5, 0xbd, 0x2d, 0x32, 0xc7, 0x9a, 0xd4, 0xf9, 0xa4, 0xc4, 0xfa, 0x8f, 0x39, 0x8e, 0xd6, 0xff, + 0x4d, 0xb3, 0x83, 0x48, 0xa4, 0x26, 0xa6, 0xff, 0xfe, 0x7b, 0x22, 0xfd, 0xef, 0x53, 0x44, 0xfa, + 0x68, 0x7c, 0x3f, 0x0b, 0x66, 0xea, 0x58, 0xe1, 0xea, 0xbb, 0x3b, 0x3b, 0x86, 0xb3, 0x0f, 0xaf, + 0x0f, 0x51, 0xe1, 0x54, 0x33, 0x23, 0xfa, 0xa5, 0xfc, 0xa1, 0xf4, 0xf5, 0xd0, 0xac, 0x69, 0x73, + 0x25, 0x24, 0x6e, 0x07, 0x8f, 0x07, 0x79, 0xac, 0xde, 0xbe, 0xc7, 0x65, 0x6c, 0x43, 0xa0, 0x39, + 0x25, 0x23, 0x5a, 0x0d, 0xe4, 0x6d, 0x0c, 0xd1, 0x34, 0xb2, 0xe0, 0x78, 0xdd, 0x33, 0x5a, 0x97, + 0x96, 0x6d, 0xc7, 0xde, 0xf5, 0x4c, 0x0b, 0xb9, 0xf0, 0x11, 0x21, 0x02, 0xbe, 0xfe, 0x67, 0x42, + 0xfd, 0x87, 0xff, 0x9a, 0x91, 0x1d, 0x45, 0x83, 0x6e, 0x95, 0x27, 0x1f, 0x11, 0xa0, 0x4a, 0x6e, + 0x5c, 0x94, 0xa1, 0x98, 0xbe, 0xd0, 0xde, 0xa4, 0x80, 0xa2, 0xf6, 0x60, 0xd7, 0x76, 0xbc, 0x55, + 0xbb, 0x65, 0x74, 0x5c, 0xcf, 0x76, 0x10, 0xac, 0xc5, 0x4a, 0x0d, 0xf7, 0x30, 0x6d, 0xbb, 0x15, + 0x0e, 0x8e, 0xec, 0x8d, 0x57, 0x3b, 0x45, 0xd4, 0xf1, 0x0f, 0x4b, 0xef, 0x32, 0x52, 0xa9, 0xf4, + 0x72, 0x14, 0xa1, 0xe7, 0xfd, 0xba, 0xb4, 0x64, 0x87, 0x25, 0xe4, 0x76, 0x1e, 0xa5, 0x98, 0x1a, + 0xc3, 0x52, 0x79, 0x16, 0xcc, 0xd6, 0x77, 0x2f, 0x06, 0x44, 0x5c, 0xde, 0x08, 0x79, 0xb5, 0x74, + 0x94, 0x0a, 0xa6, 0x78, 0x3c, 0xa1, 0x08, 0xf9, 0xde, 0x00, 0x66, 0x5d, 0x3e, 0x1b, 0xc3, 0x5b, + 0x4c, 0x94, 0x8c, 0x4e, 0x31, 0xb8, 0xd4, 0xf4, 0x05, 0xf8, 0xde, 0x2c, 0x98, 0xad, 0x75, 0x91, + 0x85, 0xda, 0xd4, 0x0b, 0x52, 0x10, 0xe0, 0x4b, 0x13, 0x0a, 0x50, 0x20, 0x14, 0x21, 0xc0, 0xd0, + 0x63, 0x79, 0xd1, 0x17, 0x5e, 0x98, 0x90, 0x48, 0x70, 0x71, 0xa5, 0xa5, 0x2f, 0xb8, 0x2f, 0x64, + 0xc1, 0xb4, 0xbe, 0x6b, 0xad, 0x3b, 0x36, 0x1e, 0x8d, 0x1d, 0x78, 0x77, 0xd8, 0x41, 0xdc, 0x02, + 0x4e, 0xb4, 0x77, 0x1d, 0xb2, 0xfe, 0x54, 0xb1, 0xea, 0xa8, 0x65, 0x5b, 0x6d, 0x97, 0xd4, 0x23, + 0xaf, 0x1f, 0xfc, 0x70, 0x67, 0xee, 0xa1, 0xaf, 0x2b, 0x19, 0xf8, 0x0b, 0xd2, 0xa1, 0x6e, 0x68, + 0xe5, 0xb9, 0xa2, 0xe5, 0x7b, 0x02, 0xc9, 0x80, 0x36, 0x83, 0x4a, 0x48, 0x5f, 0xb8, 0x9f, 0xc9, + 0x02, 0xb5, 0xd4, 0x6a, 0xd9, 0xbb, 0x96, 0x57, 0x47, 0x1d, 0xd4, 0xf2, 0x1a, 0x8e, 0xd1, 0x42, + 0xbc, 0xfd, 0x5c, 0x04, 0x4a, 0xdb, 0x74, 0x58, 0x1f, 0x8c, 0x1f, 0x99, 0x1c, 0x5f, 0x2a, 0xbd, + 0xe3, 0x48, 0x6b, 0x79, 0xb0, 0x94, 0x04, 0xe2, 0x94, 0xdb, 0x57, 0x94, 0x2c, 0x68, 0x0c, 0xb7, + 0xb9, 0x64, 0x41, 0x6e, 0xdd, 0xb4, 0xb6, 0xf8, 0x98, 0x40, 0x27, 0xb1, 0xf5, 0xd3, 0x46, 0x0f, + 0x32, 0xfd, 0xa4, 0x2f, 0xea, 0x6d, 0xe0, 0xa4, 0xb5, 0xbb, 0x73, 0x11, 0x39, 0xb5, 0x4d, 0x32, + 0x36, 0xb8, 0x0d, 0xbb, 0x8e, 0x2c, 0x6a, 0x3a, 0xe5, 0xf5, 0xbe, 0xdf, 0x44, 0xc3, 0x41, 0xc2, + 0xe4, 0xc5, 0x9c, 0x44, 0xc8, 0x3a, 0x60, 0x2a, 0xcb, 0x31, 0x95, 0xc8, 0xd8, 0xed, 0x43, 0x3c, + 0x7d, 0xf9, 0xfe, 0x71, 0x1e, 0x9c, 0x2a, 0x59, 0xfb, 0x64, 0x24, 0xa4, 0xdd, 0x52, 0x79, 0xdb, + 0xb0, 0xb6, 0x10, 0xe9, 0xd6, 0x02, 0x89, 0xf3, 0x01, 0xe2, 0x33, 0x62, 0x80, 0x78, 0x55, 0x07, + 0x13, 0xb6, 0xd3, 0x46, 0xce, 0xc2, 0x3e, 0xe1, 0xa9, 0x77, 0xb1, 0x94, 0x69, 0x52, 0xbf, 0x22, + 0xe6, 0x19, 0xf9, 0xf9, 0x1a, 0xfd, 0x5f, 0xf7, 0x09, 0x9d, 0xbb, 0x05, 0x4c, 0xb0, 0x34, 0x75, + 0x06, 0x4c, 0xd6, 0xf4, 0x45, 0x4d, 0x6f, 0x56, 0x16, 0x8b, 0xc7, 0xd4, 0x2b, 0xc0, 0xf1, 0x4a, + 0x43, 0xd3, 0x4b, 0x8d, 0x4a, 0xad, 0xda, 0x24, 0xe9, 0xc5, 0x0c, 0x7c, 0x5e, 0x4e, 0xd6, 0x1f, + 0x35, 0x9e, 0x99, 0x7e, 0xb0, 0xea, 0x60, 0xa2, 0x45, 0x33, 0x90, 0x8e, 0x7f, 0x3a, 0x51, 0xed, + 0x18, 0x41, 0x9a, 0xa0, 0xfb, 0x84, 0xd4, 0xb3, 0x00, 0x5c, 0x76, 0x6c, 0x6b, 0x2b, 0x3c, 0x2b, + 0x37, 0xa9, 0x73, 0x29, 0xf0, 0x39, 0x19, 0x50, 0xa0, 0xff, 0x90, 0x0b, 0x31, 0xc8, 0x53, 0x28, + 0x78, 0xff, 0x1d, 0xdb, 0x69, 0x44, 0x5e, 0xe1, 0xf4, 0x80, 0xbd, 0x62, 0x5d, 0xa4, 0x32, 0xa0, + 0xf6, 0x1b, 0xab, 0xca, 0xad, 0xa0, 0x40, 0xff, 0x65, 0x7b, 0xe5, 0xd1, 0x41, 0x31, 0x69, 0x36, + 0x49, 0xef, 0x5a, 0x79, 0x99, 0xa6, 0xaf, 0xcd, 0x5f, 0xcd, 0x82, 0x89, 0x35, 0xe4, 0x39, 0x66, + 0xcb, 0x85, 0x9f, 0xc7, 0x66, 0x16, 0xf2, 0xd6, 0x0d, 0xc7, 0xd8, 0x41, 0x1e, 0x72, 0x5c, 0xa8, + 0x09, 0x0a, 0xdd, 0xed, 0x18, 0xde, 0xa6, 0xed, 0xec, 0xf8, 0x72, 0xf5, 0xdf, 0xb1, 0x5c, 0xf7, + 0x90, 0xe3, 0x86, 0x6c, 0xf9, 0xaf, 0xac, 0xbb, 0x96, 0x9f, 0x6d, 0x30, 0x56, 0xe6, 0x05, 0x36, + 0x0e, 0x35, 0xdb, 0x90, 0xa1, 0x38, 0x96, 0xfb, 0x77, 0x94, 0x55, 0x7b, 0x0b, 0xbe, 0x4c, 0x01, + 0x39, 0xd2, 0x8f, 0xbe, 0x39, 0x23, 0x4c, 0x91, 0x77, 0x90, 0xeb, 0x1a, 0x5b, 0xc8, 0x9f, 0x22, + 0xb3, 0x57, 0xf5, 0x0e, 0x90, 0xef, 0xa0, 0x3d, 0xd4, 0x61, 0xfd, 0xc4, 0xf5, 0x42, 0xcd, 0x56, + 0xed, 0xad, 0x79, 0x4c, 0x2b, 0xe8, 0x14, 0x56, 0x71, 0x56, 0x9d, 0xfe, 0x71, 0xee, 0x69, 0x20, + 0x4f, 0xde, 0xd5, 0x29, 0x90, 0x5f, 0xd4, 0x16, 0x36, 0x96, 0x8b, 0xc7, 0xf0, 0xa3, 0xcf, 0xdf, + 0x14, 0xc8, 0x2f, 0x95, 0x1a, 0xa5, 0xd5, 0x62, 0x16, 0xd7, 0xa3, 0x52, 0x5d, 0xaa, 0x15, 0x15, + 0x9c, 0xb8, 0x5e, 0xaa, 0x56, 0xca, 0xc5, 0x9c, 0x3a, 0x0d, 0x26, 0x2e, 0x94, 0xf4, 0x6a, 0xa5, + 0xba, 0x5c, 0xcc, 0xc3, 0xaf, 0xf1, 0xf8, 0xdd, 0x29, 0xe2, 0x77, 0x43, 0x14, 0x4f, 0xfd, 0x20, + 0xfb, 0x8d, 0x00, 0xb2, 0xbb, 0x05, 0xc8, 0x7e, 0x4c, 0x86, 0xc8, 0x18, 0x50, 0xca, 0x82, 0x89, + 0x75, 0xc7, 0x6e, 0x21, 0xd7, 0x85, 0xbf, 0x9a, 0x05, 0x85, 0xb2, 0x61, 0xb5, 0x50, 0x07, 0x5e, + 0x15, 0x42, 0x45, 0x7d, 0xdd, 0x32, 0xc1, 0x71, 0x97, 0x7f, 0xe4, 0x25, 0x73, 0xaf, 0x28, 0x99, + 0x9b, 0x85, 0x4a, 0x31, 0xba, 0xf3, 0x94, 0x66, 0x84, 0x7c, 0x5e, 0x13, 0xc8, 0xa7, 0x2c, 0xc8, + 0xe7, 0x56, 0x79, 0x52, 0xe9, 0x4b, 0xe9, 0xbb, 0x19, 0x70, 0x72, 0x19, 0x59, 0xc8, 0x31, 0x5b, + 0x94, 0x79, 0xbf, 0xfe, 0x77, 0x8b, 0xf5, 0x7f, 0xb4, 0xc0, 0x74, 0xbf, 0x3f, 0xc4, 0xca, 0xbf, + 0x32, 0xa8, 0xfc, 0xbd, 0x42, 0xe5, 0x6f, 0x91, 0xa4, 0x33, 0x86, 0xcb, 0x76, 0xa7, 0xc0, 0x4c, + 0xd5, 0xf6, 0xcc, 0x4d, 0xb3, 0x45, 0x1d, 0x23, 0x7e, 0x5d, 0x01, 0xb9, 0x55, 0xd3, 0xf5, 0x60, + 0x29, 0x54, 0x91, 0xeb, 0xc0, 0xb4, 0x69, 0xb5, 0x3a, 0xbb, 0x6d, 0xa4, 0x23, 0x83, 0xea, 0xca, + 0xa4, 0xce, 0x27, 0x85, 0xfb, 0x4d, 0x98, 0x2d, 0xc5, 0xdf, 0x6f, 0xfa, 0xa4, 0xf4, 0xdc, 0x80, + 0x67, 0x81, 0x44, 0x49, 0x8b, 0x18, 0x89, 0x4b, 0x60, 0xd6, 0xe2, 0xb2, 0xfa, 0xe3, 0x71, 0x6f, + 0x94, 0x6b, 0x9e, 0x9c, 0x2e, 0xfe, 0x01, 0xdf, 0x2f, 0x35, 0x95, 0x18, 0xc4, 0x50, 0x32, 0x64, + 0x96, 0x92, 0x23, 0xa3, 0xaa, 0x60, 0xae, 0x52, 0x6d, 0x68, 0x7a, 0xb5, 0xb4, 0xca, 0xb2, 0x28, + 0xf0, 0xfb, 0x59, 0x90, 0xd7, 0x51, 0xb7, 0xb3, 0xcf, 0x87, 0x31, 0x65, 0xde, 0x8b, 0x99, 0xc0, + 0x7b, 0x51, 0x5d, 0x02, 0xc0, 0x68, 0xe1, 0x82, 0xc9, 0x7d, 0x2d, 0xd9, 0xbe, 0xc1, 0xf5, 0x84, + 0x0a, 0x96, 0x82, 0xdc, 0x3a, 0xf7, 0x27, 0x7c, 0x81, 0xf4, 0x72, 0xa6, 0x40, 0x8d, 0x70, 0x18, + 0xd1, 0x1d, 0x7c, 0x40, 0x6a, 0x05, 0x72, 0x20, 0xb9, 0xa3, 0x11, 0xff, 0x97, 0xb2, 0x20, 0xd7, + 0x40, 0xae, 0xb0, 0x61, 0xf4, 0x27, 0xc3, 0xe9, 0x38, 0x26, 0x13, 0xa1, 0xe3, 0xf7, 0x80, 0x19, + 0x5e, 0x63, 0xd9, 0xfe, 0x5d, 0xac, 0x8a, 0x0b, 0x3f, 0x0c, 0xa3, 0xe1, 0x7d, 0xd8, 0x39, 0x1a, + 0x11, 0x7f, 0xfc, 0x31, 0x00, 0xac, 0x21, 0x3c, 0x4b, 0x73, 0xb7, 0xcd, 0x2e, 0xfc, 0x7b, 0x05, + 0x4c, 0x2d, 0x23, 0xaf, 0xee, 0x19, 0xde, 0xae, 0xdb, 0xb3, 0x06, 0x6f, 0xd9, 0x65, 0xa3, 0xb5, + 0x8d, 0x58, 0x77, 0xe4, 0xbf, 0xc2, 0x77, 0x2b, 0xb2, 0x9b, 0xdc, 0x61, 0x39, 0xf3, 0x41, 0x19, + 0x11, 0x98, 0x3c, 0x16, 0xe4, 0xda, 0x86, 0x67, 0x30, 0x2c, 0xae, 0xea, 0xc1, 0x22, 0x24, 0xa4, + 0x93, 0x6c, 0xf0, 0xb7, 0xb2, 0x32, 0xbb, 0xdc, 0x12, 0xe5, 0x27, 0x03, 0xe1, 0xfd, 0x99, 0x21, + 0x50, 0x38, 0x01, 0x66, 0xab, 0xb5, 0x46, 0x73, 0xb5, 0xb6, 0xbc, 0xac, 0xe1, 0xd4, 0xa2, 0xa2, + 0x9e, 0x06, 0xea, 0x7a, 0xe9, 0xfe, 0x35, 0xad, 0xda, 0x68, 0x56, 0x6b, 0x8b, 0x1a, 0xfb, 0x33, + 0xa7, 0x1e, 0x07, 0xd3, 0xe5, 0x52, 0x79, 0xc5, 0x4f, 0xc8, 0xab, 0x67, 0xc0, 0xc9, 0x35, 0x6d, + 0x6d, 0x41, 0xd3, 0xeb, 0x2b, 0x95, 0xf5, 0x26, 0x26, 0xb3, 0x54, 0xdb, 0xa8, 0x2e, 0x16, 0x0b, + 0x2a, 0x04, 0xa7, 0xb9, 0x2f, 0x17, 0xf4, 0x5a, 0x75, 0xb9, 0x59, 0x6f, 0x94, 0x1a, 0x5a, 0x71, + 0x02, 0xcf, 0xdf, 0xca, 0xa5, 0x2a, 0xc9, 0x5e, 0xae, 0x55, 0xab, 0x5a, 0xb9, 0x51, 0x9c, 0x84, + 0xff, 0x9a, 0x03, 0xd3, 0x15, 0xb7, 0x6a, 0xec, 0xa0, 0xf3, 0x46, 0xc7, 0x6c, 0xc3, 0x5f, 0xe0, + 0xac, 0xc9, 0x1b, 0xc0, 0xac, 0x43, 0x1f, 0x51, 0xbb, 0x61, 0x22, 0x8a, 0xe6, 0xac, 0x2e, 0x26, + 0xaa, 0xa7, 0x41, 0xc1, 0x22, 0x04, 0x98, 0x68, 0xd8, 0x9b, 0xba, 0x00, 0x00, 0x7d, 0x6a, 0x84, + 0x37, 0x07, 0x9e, 0xeb, 0x6d, 0x4d, 0xc6, 0x0e, 0x72, 0x91, 0xb3, 0x67, 0xb6, 0x90, 0x9f, 0x53, + 0xe7, 0xfe, 0x82, 0x5f, 0x56, 0x64, 0x17, 0xbd, 0x39, 0x50, 0xb9, 0xea, 0x44, 0xf4, 0x86, 0x3f, + 0xaf, 0xc8, 0x2c, 0x59, 0x4b, 0x91, 0x4c, 0xa6, 0x29, 0x2f, 0xca, 0x0e, 0xa1, 0x29, 0xb3, 0x60, + 0xaa, 0x51, 0xab, 0x35, 0xeb, 0x2b, 0x35, 0xbd, 0x51, 0x54, 0xf0, 0xa4, 0x1c, 0xbf, 0xae, 0xd6, + 0xaa, 0xcb, 0xc5, 0x9c, 0x7a, 0x0a, 0x9c, 0x58, 0x29, 0xd5, 0x9b, 0x95, 0xea, 0xf9, 0xd2, 0x6a, + 0x65, 0xb1, 0x59, 0x5e, 0x29, 0xe9, 0xf5, 0x62, 0x5e, 0xbd, 0x0a, 0x9c, 0x6a, 0x54, 0x34, 0xbd, + 0xb9, 0xa4, 0x95, 0x1a, 0x1b, 0xba, 0x56, 0x6f, 0x56, 0x6b, 0xcd, 0x6a, 0x69, 0x4d, 0x2b, 0x16, + 0x70, 0xf3, 0x27, 0x9f, 0x42, 0xb5, 0x99, 0x38, 0xa8, 0x8c, 0x93, 0x11, 0xca, 0x38, 0xd5, 0xab, + 0x8c, 0x80, 0x57, 0x2b, 0x5d, 0xab, 0x6b, 0xfa, 0x79, 0xad, 0x38, 0xdd, 0x4f, 0xd7, 0x66, 0xd4, + 0x93, 0xa0, 0x88, 0x79, 0x68, 0x56, 0xea, 0x7e, 0xce, 0xc5, 0xe2, 0x2c, 0xfc, 0x58, 0x01, 0x9c, + 0xd6, 0xd1, 0x96, 0xe9, 0x7a, 0xc8, 0x59, 0x37, 0xf6, 0x77, 0x90, 0xe5, 0xf9, 0x9d, 0xfc, 0xff, + 0x4a, 0xac, 0x8c, 0x6b, 0x60, 0xb6, 0x4b, 0x69, 0xac, 0x21, 0x6f, 0xdb, 0x6e, 0xb3, 0x51, 0xf8, + 0xd1, 0x91, 0x3d, 0xc7, 0xfc, 0x3a, 0x9f, 0x5d, 0x17, 0xff, 0xe6, 0x74, 0x5b, 0x89, 0xd1, 0xed, + 0xdc, 0x30, 0xba, 0xad, 0x5e, 0x03, 0xa6, 0x76, 0x5d, 0xe4, 0x68, 0x3b, 0x86, 0xd9, 0xf1, 0x6f, + 0x7e, 0x0b, 0x12, 0xe0, 0x3b, 0x72, 0xb2, 0x6e, 0xd4, 0x5c, 0x5d, 0xfa, 0x8b, 0x31, 0xa2, 0x6f, + 0x3d, 0x0b, 0x00, 0xab, 0xec, 0x86, 0xd3, 0x61, 0xca, 0xca, 0xa5, 0x60, 0xfe, 0x2e, 0x9a, 0x9d, + 0x8e, 0x69, 0x6d, 0x05, 0x9b, 0x51, 0x61, 0x02, 0x7c, 0x91, 0x22, 0xe3, 0x56, 0x9d, 0x94, 0xb7, + 0x64, 0xad, 0xe9, 0x05, 0xd9, 0x31, 0xf7, 0xbb, 0x07, 0x9b, 0x4e, 0x41, 0x2d, 0x82, 0x19, 0x92, + 0xc6, 0x5a, 0x60, 0x71, 0x02, 0xf7, 0xc1, 0x3e, 0xb9, 0x35, 0xad, 0xb1, 0x52, 0x5b, 0x0c, 0xbe, + 0x4d, 0x62, 0x92, 0x98, 0x99, 0x52, 0xf5, 0x7e, 0xd2, 0x1a, 0xa7, 0xd4, 0x47, 0x80, 0xab, 0xb8, + 0x0e, 0xbb, 0xb4, 0xaa, 0x6b, 0xa5, 0xc5, 0xfb, 0x9b, 0xda, 0x33, 0x2a, 0xf5, 0x46, 0x5d, 0x6c, + 0x5c, 0x7e, 0x3b, 0x9a, 0xc6, 0xfc, 0x6a, 0x6b, 0xa5, 0xca, 0x2a, 0xeb, 0xdf, 0x97, 0x6a, 0xfa, + 0x5a, 0xa9, 0x51, 0x9c, 0x81, 0x2f, 0x53, 0x40, 0x71, 0x19, 0x79, 0xeb, 0xb6, 0xe3, 0x19, 0x9d, + 0x55, 0xd3, 0xba, 0xb4, 0xe1, 0x74, 0x78, 0x9b, 0xe9, 0x5f, 0xa4, 0xcf, 0x8e, 0x8b, 0x43, 0xa4, + 0x40, 0x30, 0x7a, 0x9b, 0xa6, 0x4b, 0xb2, 0x85, 0xca, 0x14, 0x26, 0xc0, 0x67, 0x65, 0x65, 0x56, + 0xb3, 0xe4, 0x4b, 0x4d, 0xa6, 0x27, 0xcf, 0x1e, 0xf7, 0xf8, 0xdc, 0x07, 0xb5, 0x02, 0x7c, 0x28, + 0x07, 0x26, 0x97, 0x4c, 0xcb, 0xe8, 0x98, 0xcf, 0x14, 0x82, 0xea, 0x85, 0x7d, 0x4c, 0x26, 0xa6, + 0x8f, 0xc9, 0x0e, 0x35, 0x7e, 0xfe, 0x8a, 0x22, 0xbb, 0x21, 0xc7, 0xc9, 0xde, 0x67, 0x32, 0x62, + 0xf0, 0xfc, 0xfd, 0xac, 0xcc, 0x96, 0xdb, 0x60, 0x7a, 0xc9, 0x30, 0xfc, 0xc4, 0x0f, 0x87, 0x8d, + 0xd5, 0xd3, 0xbe, 0x27, 0xfb, 0xa9, 0xc2, 0x14, 0xfc, 0x0b, 0x05, 0xc0, 0x65, 0xe4, 0x9d, 0x47, + 0x4e, 0x30, 0x15, 0x20, 0xbd, 0x3e, 0xb3, 0xb7, 0xb9, 0x26, 0xfb, 0x66, 0x1e, 0xc0, 0x0b, 0x22, + 0x80, 0xa5, 0x98, 0xc6, 0x13, 0x41, 0x3a, 0xa2, 0xf1, 0x56, 0x40, 0xc1, 0x25, 0xdf, 0x99, 0x9a, + 0x3d, 0x3e, 0x7a, 0xb8, 0x24, 0xc4, 0x78, 0xea, 0x94, 0xb0, 0xce, 0x08, 0xc0, 0xef, 0x05, 0x93, + 0xa0, 0x9f, 0x10, 0xb4, 0x63, 0xe9, 0xd0, 0xcc, 0x26, 0xd3, 0x17, 0x27, 0x5d, 0x75, 0xe9, 0x67, + 0xdf, 0xc0, 0xdf, 0xcf, 0x83, 0x93, 0xfd, 0xaa, 0x03, 0x7f, 0x3b, 0x23, 0x6c, 0xa0, 0x21, 0x32, + 0xe4, 0x67, 0xd8, 0xfe, 0x00, 0x7e, 0x51, 0x9f, 0x00, 0x4e, 0x31, 0x8f, 0x80, 0x8b, 0xa8, 0x61, + 0x57, 0xd1, 0x65, 0xb7, 0x83, 0x3c, 0x0f, 0x39, 0xa4, 0x6a, 0x93, 0x7a, 0xff, 0x8f, 0xea, 0x93, + 0xc1, 0x95, 0xa6, 0xe5, 0x9a, 0x6d, 0xe4, 0x34, 0xcc, 0xae, 0x5b, 0xb2, 0xda, 0x8d, 0x5d, 0xcf, + 0x76, 0x4c, 0x83, 0xdd, 0x6f, 0x36, 0xa9, 0x47, 0x7d, 0x56, 0x6f, 0x06, 0x45, 0xd3, 0xad, 0x59, + 0x17, 0x6d, 0xc3, 0x69, 0x9b, 0xd6, 0xd6, 0xaa, 0xe9, 0x7a, 0xcc, 0x2d, 0xed, 0x40, 0x3a, 0xfc, + 0x07, 0x45, 0xf6, 0x84, 0xc7, 0x00, 0x58, 0x23, 0x3a, 0x94, 0xe7, 0x2b, 0x32, 0x67, 0x36, 0x92, + 0xd1, 0x4e, 0xa6, 0x2c, 0xcf, 0x1b, 0xb7, 0x21, 0xd1, 0x7f, 0x04, 0x27, 0x5d, 0x0b, 0x4d, 0xf7, + 0x0d, 0x81, 0xf3, 0x9a, 0x5e, 0x59, 0xaa, 0x68, 0xd8, 0xac, 0x38, 0x05, 0x4e, 0x84, 0xdf, 0x16, + 0xef, 0x6f, 0xd6, 0xb5, 0x6a, 0xa3, 0x38, 0x89, 0xfb, 0x29, 0x9a, 0xbc, 0x54, 0xaa, 0xac, 0x6a, + 0x8b, 0xcd, 0x46, 0x0d, 0x7f, 0x59, 0x1c, 0xce, 0xb4, 0x80, 0xcf, 0xc9, 0x81, 0xe3, 0x44, 0xb6, + 0xfb, 0x44, 0xaa, 0x58, 0x28, 0x3d, 0x0e, 0x60, 0x01, 0x40, 0x53, 0x54, 0xbc, 0xf0, 0xd3, 0xd2, + 0xd7, 0xb7, 0x71, 0x10, 0xf6, 0x94, 0x11, 0xa1, 0x19, 0xdf, 0xcd, 0xca, 0x1c, 0x9b, 0x96, 0x26, + 0x9b, 0x4c, 0x29, 0xfe, 0x79, 0xdc, 0x23, 0x4e, 0x34, 0xf8, 0xc4, 0xca, 0x2c, 0x93, 0x9f, 0x9f, + 0xb1, 0x5e, 0xd1, 0x89, 0x3a, 0xcc, 0x01, 0x40, 0x52, 0x88, 0x06, 0x51, 0x3d, 0xe8, 0x3b, 0x5e, + 0x45, 0xe9, 0x41, 0xa9, 0xdc, 0xa8, 0x9c, 0xd7, 0xa2, 0xf4, 0xe0, 0x53, 0x0a, 0x98, 0x5c, 0x46, + 0x1e, 0x9e, 0x53, 0xb9, 0xf0, 0x29, 0x12, 0xeb, 0x3f, 0xd8, 0x8c, 0x21, 0xf7, 0x56, 0x07, 0xcb, + 0x00, 0xf4, 0x0d, 0x3e, 0x77, 0x18, 0x13, 0xc4, 0x2f, 0x3a, 0x62, 0xbc, 0x7a, 0x12, 0xc8, 0x7b, + 0xf8, 0x33, 0x5b, 0x86, 0x7e, 0x64, 0xe4, 0x70, 0x85, 0x89, 0x2c, 0x1a, 0x9e, 0xa1, 0xd3, 0xfc, + 0xdc, 0xe8, 0x24, 0x69, 0xbb, 0x44, 0x30, 0xf2, 0xc3, 0x68, 0x7f, 0x7e, 0x4d, 0x01, 0xa7, 0x68, + 0xfb, 0x28, 0x75, 0xbb, 0x75, 0xcf, 0x76, 0x90, 0x8e, 0x5a, 0xc8, 0xec, 0x7a, 0x3d, 0xeb, 0x7b, + 0x0e, 0x4d, 0xf5, 0x37, 0x10, 0xd9, 0x2b, 0x7c, 0x83, 0x22, 0x1b, 0x18, 0xf4, 0x40, 0x7b, 0xec, + 0x29, 0x2f, 0xa2, 0xb1, 0x7f, 0x34, 0x2b, 0x13, 0xea, 0x33, 0x21, 0xf1, 0x64, 0x40, 0x7d, 0xe8, + 0x08, 0x80, 0xf2, 0x57, 0x6e, 0x74, 0xad, 0xac, 0x55, 0xd6, 0xf1, 0x20, 0x70, 0x2d, 0xb8, 0x7a, + 0x7d, 0x43, 0x2f, 0xaf, 0x94, 0xea, 0x5a, 0x53, 0xd7, 0x96, 0x2b, 0xf5, 0x06, 0xf3, 0xb9, 0xa0, + 0x7f, 0x4d, 0xa8, 0xd7, 0x80, 0x33, 0xf5, 0x8d, 0x85, 0x7a, 0x59, 0xaf, 0xac, 0x93, 0x74, 0x5d, + 0xab, 0x6a, 0x17, 0xd8, 0xd7, 0x49, 0xf8, 0xc1, 0x22, 0x98, 0xc6, 0x13, 0x80, 0x3a, 0x9d, 0x17, + 0xc0, 0x6f, 0xe6, 0xc0, 0xb4, 0x8e, 0x5c, 0xbb, 0xb3, 0x47, 0xe6, 0x08, 0xe3, 0x9a, 0x7a, 0x7c, + 0x47, 0x91, 0x3d, 0x54, 0xc8, 0x31, 0x3b, 0xcf, 0x31, 0x1a, 0x3d, 0xd1, 0x34, 0xf6, 0x0c, 0xb3, + 0x63, 0x5c, 0x64, 0x5d, 0xcd, 0xa4, 0x1e, 0x26, 0xa8, 0xf3, 0x40, 0xb5, 0x2f, 0x5b, 0xc8, 0xa9, + 0xb7, 0x2e, 0x6b, 0xde, 0x76, 0xa9, 0xdd, 0x76, 0x90, 0xeb, 0xb2, 0xd5, 0x8b, 0x3e, 0x5f, 0xd4, + 0x9b, 0xc0, 0x71, 0x92, 0xca, 0x65, 0xa6, 0x27, 0xa0, 0x7b, 0x93, 0x83, 0x9c, 0x25, 0x6b, 0xdf, + 0xcf, 0x99, 0xe7, 0x72, 0x86, 0xc9, 0xbc, 0x0f, 0x6f, 0x41, 0x74, 0x1d, 0xbf, 0x0e, 0x4c, 0x5b, + 0xc6, 0x0e, 0xd2, 0x1e, 0xec, 0x9a, 0x0e, 0x72, 0xcf, 0x4c, 0x90, 0x4d, 0x3b, 0x3e, 0x09, 0xfe, + 0xbe, 0xd4, 0x21, 0x48, 0x39, 0x89, 0x25, 0xd3, 0xfd, 0xe5, 0x21, 0x54, 0xbf, 0x4f, 0x3f, 0xa3, + 0xc0, 0x0f, 0x2a, 0x60, 0x86, 0x31, 0x55, 0xb2, 0xf6, 0x2b, 0x6d, 0x78, 0xad, 0x60, 0xfc, 0x1a, + 0x38, 0xcd, 0x37, 0x7e, 0xc9, 0x0b, 0xfc, 0x45, 0x45, 0xd6, 0x07, 0xaf, 0x4f, 0xc5, 0x49, 0x19, + 0xd1, 0x7e, 0x61, 0x9b, 0xf6, 0x2e, 0xf3, 0x43, 0x9b, 0xd4, 0xe9, 0x4b, 0x9a, 0x8b, 0x7a, 0xf0, + 0x0f, 0xa4, 0x3c, 0xfc, 0x24, 0xab, 0x71, 0x44, 0x00, 0x7e, 0x5c, 0x01, 0x73, 0x8c, 0xab, 0x3a, + 0x73, 0x3e, 0x97, 0x3a, 0x85, 0xf1, 0x4b, 0xd2, 0x86, 0x60, 0x9f, 0xfa, 0xb3, 0x92, 0x1e, 0x36, + 0x40, 0x7e, 0x58, 0x2a, 0x62, 0x8f, 0x74, 0x45, 0x8e, 0x08, 0xca, 0x77, 0xe6, 0xc0, 0xf4, 0x86, + 0x8b, 0x1c, 0xe6, 0x4c, 0x0a, 0x5f, 0x93, 0x03, 0xca, 0x32, 0x12, 0x36, 0x52, 0x5f, 0x28, 0xed, + 0xc0, 0xc7, 0x57, 0x96, 0x23, 0x8a, 0x6d, 0xa4, 0x08, 0xd8, 0x6e, 0x04, 0x73, 0x54, 0xa4, 0x25, + 0xcf, 0xc3, 0x46, 0xa2, 0xef, 0x2c, 0xd7, 0x93, 0x3a, 0x8a, 0xad, 0x22, 0x52, 0x16, 0xce, 0x52, + 0xc6, 0x3c, 0xad, 0xa2, 0x4d, 0x3a, 0x9f, 0xcd, 0xe9, 0x3d, 0xa9, 0xe4, 0x4e, 0xed, 0x2e, 0xa2, + 0x4e, 0xd5, 0x5c, 0xe6, 0x3c, 0xc9, 0xdc, 0xef, 0x13, 0xfc, 0xa6, 0x94, 0x2b, 0x9e, 0xbc, 0x74, + 0x92, 0xe9, 0x42, 0x77, 0x34, 0x26, 0xc9, 0x49, 0x50, 0xc4, 0x39, 0xc8, 0xfe, 0x8b, 0xae, 0xd5, + 0x6b, 0xab, 0xe7, 0xb5, 0xfe, 0xcb, 0x18, 0x79, 0xf8, 0x3c, 0x05, 0x4c, 0x2d, 0x38, 0xb6, 0xd1, + 0x6e, 0x19, 0xae, 0x07, 0xbf, 0x97, 0x05, 0x33, 0xeb, 0xc6, 0x7e, 0xc7, 0x36, 0xda, 0xc4, 0x7d, + 0xb7, 0xa7, 0x2f, 0xe8, 0xd2, 0x4f, 0x7e, 0x5f, 0xc0, 0x5e, 0xc5, 0xd3, 0x2a, 0xc1, 0x79, 0x92, + 0x8c, 0xcc, 0x2d, 0x6f, 0xc1, 0x36, 0x5f, 0xb6, 0x5f, 0x04, 0x3d, 0x9f, 0xaf, 0x79, 0x9e, 0xa7, + 0x08, 0x8b, 0xf2, 0x83, 0x72, 0x31, 0xf1, 0x64, 0x48, 0x1e, 0xcd, 0xae, 0xfc, 0x43, 0x93, 0xa0, + 0xb0, 0x88, 0x88, 0x15, 0xf7, 0x5f, 0xb3, 0x60, 0xa2, 0x8e, 0x3c, 0x62, 0xc1, 0xdd, 0x21, 0xf8, + 0x52, 0xb6, 0x49, 0x86, 0xd0, 0x47, 0xd5, 0x7f, 0xc7, 0x93, 0x75, 0xee, 0x10, 0x20, 0x79, 0x4e, + 0xe0, 0x65, 0x46, 0xcb, 0x9d, 0x67, 0x65, 0x1e, 0xca, 0xcb, 0x2c, 0x96, 0x54, 0xfa, 0xbe, 0x56, + 0xef, 0xce, 0x32, 0xd7, 0x2a, 0xae, 0xd7, 0x7b, 0x15, 0xaf, 0x9f, 0xb1, 0xde, 0x66, 0x8c, 0xf9, + 0x18, 0xe7, 0xa8, 0xdb, 0xc1, 0x04, 0x95, 0xb9, 0x3f, 0x1f, 0xed, 0xf5, 0x53, 0xa0, 0x24, 0xc8, + 0x81, 0x40, 0x3f, 0xa7, 0xa4, 0x8b, 0x5a, 0x74, 0xe1, 0x63, 0x39, 0x18, 0x3b, 0x53, 0x45, 0xde, + 0x65, 0xdb, 0xb9, 0x54, 0xf7, 0x0c, 0x0f, 0xc1, 0x7f, 0xce, 0x02, 0xa5, 0x8e, 0x3c, 0xfe, 0x48, + 0x7e, 0x15, 0x9c, 0xa0, 0x15, 0x62, 0x19, 0x49, 0xff, 0x4d, 0x2b, 0x72, 0x5d, 0x5f, 0x21, 0x70, + 0xf9, 0xf4, 0x83, 0xbf, 0xc2, 0x5f, 0xed, 0x1b, 0x89, 0x24, 0xdb, 0x67, 0xd2, 0xc0, 0x24, 0xc3, + 0x33, 0x88, 0x15, 0x2c, 0x42, 0x4f, 0x7f, 0x4f, 0xca, 0xac, 0x96, 0xa3, 0x79, 0x34, 0x5d, 0xc1, + 0x2b, 0xae, 0x02, 0xb9, 0xf2, 0xb6, 0xe1, 0xc1, 0x77, 0x29, 0x00, 0x94, 0xda, 0xed, 0x35, 0xea, + 0xd7, 0xcb, 0x3b, 0xa4, 0x9d, 0x03, 0x33, 0xad, 0x6d, 0x23, 0x0c, 0xb8, 0x4f, 0xfb, 0x03, 0x21, + 0x4d, 0x7d, 0x42, 0xe8, 0x20, 0x4c, 0xa5, 0x0a, 0x7b, 0x60, 0xc2, 0x65, 0x30, 0xda, 0x81, 0xf3, + 0xb0, 0x18, 0x9f, 0x2d, 0xf6, 0x90, 0x39, 0xfe, 0x7d, 0x3e, 0x64, 0x2f, 0x7a, 0x0e, 0xc7, 0x48, + 0x07, 0xfe, 0xf3, 0x61, 0x42, 0xc2, 0xe3, 0x87, 0x72, 0xa7, 0xcc, 0xe3, 0xf9, 0x1a, 0x4b, 0x3c, + 0x45, 0x55, 0x6b, 0x9b, 0xbe, 0x68, 0x59, 0x14, 0x17, 0xf8, 0x82, 0x4c, 0x32, 0xf8, 0xe2, 0x05, + 0x77, 0x2f, 0x98, 0x45, 0x6d, 0xd3, 0x43, 0x7e, 0x2d, 0x99, 0x00, 0xe3, 0x20, 0x16, 0x7f, 0x80, + 0xcf, 0x96, 0x8e, 0x04, 0x44, 0x04, 0x7a, 0xb0, 0x46, 0x11, 0xed, 0x4f, 0x2e, 0xb6, 0x8f, 0x1c, + 0xcd, 0xf4, 0xc1, 0x7a, 0xae, 0x02, 0x4e, 0x35, 0xec, 0xad, 0xad, 0x0e, 0xf2, 0xc5, 0x84, 0xa8, + 0x77, 0x26, 0x34, 0x46, 0x09, 0x17, 0xd9, 0x09, 0xb2, 0x1f, 0x30, 0x83, 0x93, 0x22, 0xf8, 0x05, + 0x3e, 0x5f, 0x3a, 0x66, 0x29, 0x11, 0x57, 0x5f, 0x3e, 0x23, 0x50, 0x90, 0x8b, 0x42, 0x2a, 0x4d, + 0x36, 0x7d, 0x20, 0x3e, 0x9f, 0x05, 0xb3, 0xf4, 0x3a, 0x35, 0x5f, 0x41, 0xef, 0x1b, 0x21, 0x00, + 0xf0, 0x7b, 0x19, 0x59, 0x3f, 0x5b, 0x22, 0x13, 0x81, 0x93, 0x08, 0x11, 0xcb, 0x9d, 0xf4, 0x1f, + 0x48, 0x2e, 0x7d, 0xd1, 0xfe, 0x17, 0x05, 0x4c, 0x2f, 0x23, 0xbf, 0xa5, 0xb9, 0xfc, 0xdd, 0x34, + 0x32, 0x82, 0xbd, 0x01, 0xcc, 0x5e, 0x44, 0x9b, 0xb6, 0x83, 0x6a, 0xc2, 0x29, 0x28, 0x31, 0x31, + 0x22, 0x1c, 0x92, 0x10, 0x77, 0x67, 0x41, 0x14, 0xfb, 0x2d, 0x07, 0xe5, 0xc4, 0x71, 0x19, 0x31, + 0x9c, 0x3c, 0x11, 0x4c, 0x32, 0x50, 0x7d, 0x0b, 0x2c, 0xae, 0xcb, 0x0b, 0xf2, 0xc2, 0xd7, 0x05, + 0x60, 0x69, 0x02, 0x58, 0x8f, 0x4f, 0xc2, 0xc4, 0x58, 0xee, 0x13, 0x2e, 0x72, 0xe5, 0x2f, 0xec, + 0x57, 0xda, 0x2e, 0x5c, 0x4b, 0x86, 0xd7, 0x59, 0x00, 0x02, 0xbd, 0xf7, 0x8f, 0x51, 0x73, 0x29, + 0x62, 0xa4, 0xe4, 0xd8, 0x73, 0x55, 0xbd, 0xe2, 0x20, 0xec, 0x8c, 0x18, 0x18, 0xb9, 0xf3, 0x58, + 0x32, 0x9c, 0xa4, 0x8f, 0xce, 0x27, 0x15, 0x70, 0xaa, 0xee, 0xef, 0xce, 0xaf, 0x1a, 0x6e, 0xd8, + 0xa4, 0xca, 0xc9, 0x20, 0x12, 0xce, 0x72, 0x04, 0x8d, 0xe5, 0x5b, 0xc9, 0x86, 0x83, 0xbe, 0x9c, + 0x8c, 0x16, 0x1d, 0xf5, 0x16, 0x70, 0xc2, 0xda, 0xdd, 0x09, 0xa4, 0x4e, 0x5a, 0x3c, 0x6b, 0xe1, + 0x07, 0x3f, 0x24, 0x19, 0x74, 0x64, 0x98, 0x1f, 0xcb, 0x74, 0x71, 0x7a, 0xc3, 0x0a, 0x1c, 0x2e, + 0xe0, 0x63, 0x13, 0xc1, 0x08, 0xbf, 0x9d, 0x49, 0xd4, 0xbb, 0x71, 0x25, 0x45, 0x0c, 0x29, 0x09, + 0x7a, 0xa9, 0x68, 0x62, 0xa9, 0x8b, 0xed, 0xdc, 0x04, 0xc8, 0x6b, 0x3b, 0x5d, 0x6f, 0xff, 0xdc, + 0xa3, 0xc0, 0x6c, 0xdd, 0x73, 0x90, 0xb1, 0xc3, 0x2d, 0xfa, 0x7b, 0xf6, 0x25, 0x64, 0xf9, 0x8b, + 0xfe, 0xe4, 0xe5, 0xce, 0x3b, 0xc0, 0x84, 0x65, 0x37, 0x8d, 0x5d, 0x6f, 0x5b, 0xbd, 0xf6, 0xc0, + 0x61, 0x58, 0x06, 0x7e, 0x8d, 0xc5, 0xcc, 0xf8, 0xf2, 0x5d, 0x64, 0xd9, 0xb7, 0x60, 0xd9, 0xa5, + 0x5d, 0x6f, 0x7b, 0xe1, 0x9a, 0x8f, 0xff, 0xdd, 0xd9, 0xcc, 0xa7, 0xfe, 0xee, 0x6c, 0xe6, 0x4b, + 0x7f, 0x77, 0x36, 0xf3, 0x4b, 0x5f, 0x39, 0x7b, 0xec, 0x53, 0x5f, 0x39, 0x7b, 0xec, 0xf3, 0x5f, + 0x39, 0x7b, 0xec, 0x27, 0xb2, 0xdd, 0x8b, 0x17, 0x0b, 0x84, 0xca, 0xed, 0xff, 0x7f, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x3a, 0x08, 0xa6, 0xb0, 0x3f, 0xf4, 0x01, 0x00, } func (m *Rpc) Marshal() (dAtA []byte, err error) { @@ -76341,6 +77300,16 @@ func (m *RpcObjectCreateRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if m.WithChat { + i-- + if m.WithChat { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if len(m.ObjectTypeUniqueKey) > 0 { i -= len(m.ObjectTypeUniqueKey) copy(dAtA[i:], m.ObjectTypeUniqueKey) @@ -76535,6 +77504,16 @@ func (m *RpcObjectCreateBookmarkRequest) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if m.WithChat { + i-- + if m.WithChat { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if len(m.SpaceId) > 0 { i -= len(m.SpaceId) copy(dAtA[i:], m.SpaceId) @@ -77004,6 +77983,16 @@ func (m *RpcObjectCreateSetRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if m.WithChat { + i-- + if m.WithChat { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if len(m.SpaceId) > 0 { i -= len(m.SpaceId) copy(dAtA[i:], m.SpaceId) @@ -77368,6 +78357,16 @@ func (m *RpcObjectCreateFromUrlRequest) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if m.WithChat { + i-- + if m.WithChat { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if m.AddPageContent { i-- if m.AddPageContent { @@ -77434,6 +78433,13 @@ func (m *RpcObjectCreateFromUrlResponse) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.ChatId) > 0 { + i -= len(m.ChatId) + copy(dAtA[i:], m.ChatId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.ChatId))) + i-- + dAtA[i] = 0x22 + } if m.Details != nil { { size, err := m.Details.MarshalToSizedBuffer(dAtA[:i]) @@ -78508,6 +79514,13 @@ func (m *RpcObjectSearchRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0x42 + } if len(m.Keys) > 0 { for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Keys[iNdEx]) @@ -78701,6 +79714,13 @@ func (m *RpcObjectSearchWithMetaRequest) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0x5a + } if m.ReturnHTMLHighlightsInsteadOfRanges { i-- if m.ReturnHTMLHighlightsInsteadOfRanges { @@ -79208,6 +80228,13 @@ func (m *RpcObjectSearchSubscribeRequest) MarshalToSizedBuffer(dAtA []byte) (int _ = i var l int _ = l + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0x7a + } if len(m.CollectionId) > 0 { i -= len(m.CollectionId) copy(dAtA[i:], m.CollectionId) @@ -79225,13 +80252,6 @@ func (m *RpcObjectSearchSubscribeRequest) MarshalToSizedBuffer(dAtA []byte) (int i-- dAtA[i] = 0x68 } - if len(m.IgnoreWorkspace) > 0 { - i -= len(m.IgnoreWorkspace) - copy(dAtA[i:], m.IgnoreWorkspace) - i = encodeVarintCommands(dAtA, i, uint64(len(m.IgnoreWorkspace))) - i-- - dAtA[i] = 0x62 - } if len(m.Source) > 0 { for iNdEx := len(m.Source) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Source[iNdEx]) @@ -79394,7 +80414,240 @@ func (m *RpcObjectSearchSubscribeResponse) MarshalToSizedBuffer(dAtA []byte) (in return len(dAtA) - i, nil } -func (m *RpcObjectSearchSubscribeResponseError) Marshal() (dAtA []byte, err error) { +func (m *RpcObjectSearchSubscribeResponseError) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectSearchSubscribeResponseError) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectSearchSubscribeResponseError) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintCommands(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if m.Code != 0 { + i = encodeVarintCommands(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribe) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribe) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchSubscribe) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.CollectionId) > 0 { + i -= len(m.CollectionId) + copy(dAtA[i:], m.CollectionId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.CollectionId))) + i-- + dAtA[i] = 0x72 + } + if m.NoDepSubscription { + i-- + if m.NoDepSubscription { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x68 + } + if len(m.Source) > 0 { + for iNdEx := len(m.Source) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Source[iNdEx]) + copy(dAtA[i:], m.Source[iNdEx]) + i = encodeVarintCommands(dAtA, i, uint64(len(m.Source[iNdEx]))) + i-- + dAtA[i] = 0x52 + } + } + if len(m.Keys) > 0 { + for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Keys[iNdEx]) + copy(dAtA[i:], m.Keys[iNdEx]) + i = encodeVarintCommands(dAtA, i, uint64(len(m.Keys[iNdEx]))) + i-- + dAtA[i] = 0x3a + } + } + if len(m.Sorts) > 0 { + for iNdEx := len(m.Sorts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Sorts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Filters) > 0 { + for iNdEx := len(m.Filters) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Filters[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.SubId) > 0 { + i -= len(m.SubId) + copy(dAtA[i:], m.SubId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SubId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Counters != nil { + { + size, err := m.Counters.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.SubId) > 0 { + i -= len(m.SubId) + copy(dAtA[i:], m.SubId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SubId))) + i-- + dAtA[i] = 0x22 + } + if len(m.Dependencies) > 0 { + for iNdEx := len(m.Dependencies) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Dependencies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Records) > 0 { + for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Records[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Error != nil { + { + size, err := m.Error.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -79404,12 +80657,135 @@ func (m *RpcObjectSearchSubscribeResponseError) Marshal() (dAtA []byte, err erro return dAtA[:n], nil } -func (m *RpcObjectSearchSubscribeResponseError) MarshalTo(dAtA []byte) (int, error) { +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RpcObjectSearchSubscribeResponseError) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintCommands(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if m.Code != 0 { + i = encodeVarintCommands(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribe) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribe) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribe) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SubId) > 0 { + i -= len(m.SubId) + copy(dAtA[i:], m.SubId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SubId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Error != nil { + { + size, err := m.Error.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -79660,6 +81036,13 @@ func (m *RpcObjectSubscribeIdsRequest) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l + if len(m.SpaceId) > 0 { + i -= len(m.SpaceId) + copy(dAtA[i:], m.SpaceId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.SpaceId))) + i-- + dAtA[i] = 0x6a + } if m.NoDepSubscription { i-- if m.NoDepSubscription { @@ -79670,13 +81053,6 @@ func (m *RpcObjectSubscribeIdsRequest) MarshalToSizedBuffer(dAtA []byte) (int, e i-- dAtA[i] = 0x60 } - if len(m.IgnoreWorkspace) > 0 { - i -= len(m.IgnoreWorkspace) - copy(dAtA[i:], m.IgnoreWorkspace) - i = encodeVarintCommands(dAtA, i, uint64(len(m.IgnoreWorkspace))) - i-- - dAtA[i] = 0x5a - } if len(m.Keys) > 0 { for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Keys[iNdEx]) @@ -86270,21 +87646,21 @@ func (m *RpcRelationListWithValueResponse) MarshalToSizedBuffer(dAtA []byte) (in var l int _ = l if len(m.Counters) > 0 { - dAtA182 := make([]byte, len(m.Counters)*10) - var j181 int + dAtA185 := make([]byte, len(m.Counters)*10) + var j184 int for _, num1 := range m.Counters { num := uint64(num1) for num >= 1<<7 { - dAtA182[j181] = uint8(uint64(num)&0x7f | 0x80) + dAtA185[j184] = uint8(uint64(num)&0x7f | 0x80) num >>= 7 - j181++ + j184++ } - dAtA182[j181] = uint8(num) - j181++ + dAtA185[j184] = uint8(num) + j184++ } - i -= j181 - copy(dAtA[i:], dAtA182[:j181]) - i = encodeVarintCommands(dAtA, i, uint64(j181)) + i -= j184 + copy(dAtA[i:], dAtA185[:j184]) + i = encodeVarintCommands(dAtA, i, uint64(j184)) i-- dAtA[i] = 0x1a } @@ -107380,6 +108756,214 @@ func (m *RpcDebugPingResponseError) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } +func (m *RpcDebugAnystoreObjectChanges) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcDebugAnystoreObjectChanges) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcDebugAnystoreObjectChanges) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *RpcDebugAnystoreObjectChangesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcDebugAnystoreObjectChangesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcDebugAnystoreObjectChangesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.OrderBy != 0 { + i = encodeVarintCommands(dAtA, i, uint64(m.OrderBy)) + i-- + dAtA[i] = 0x10 + } + if len(m.ObjectId) > 0 { + i -= len(m.ObjectId) + copy(dAtA[i:], m.ObjectId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.ObjectId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcDebugAnystoreObjectChangesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcDebugAnystoreObjectChangesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcDebugAnystoreObjectChangesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.WrongOrder { + i-- + if m.WrongOrder { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Changes) > 0 { + for iNdEx := len(m.Changes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Changes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Error != nil { + { + size, err := m.Error.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Change != nil { + { + size, err := m.Change.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintCommands(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintCommands(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x1a + } + if len(m.OrderId) > 0 { + i -= len(m.OrderId) + copy(dAtA[i:], m.OrderId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.OrderId))) + i-- + dAtA[i] = 0x12 + } + if len(m.ChangeId) > 0 { + i -= len(m.ChangeId) + copy(dAtA[i:], m.ChangeId) + i = encodeVarintCommands(dAtA, i, uint64(len(m.ChangeId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RpcDebugAnystoreObjectChangesResponseError) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RpcDebugAnystoreObjectChangesResponseError) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RpcDebugAnystoreObjectChangesResponseError) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintCommands(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if m.Code != 0 { + i = encodeVarintCommands(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *RpcMetrics) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -109194,6 +110778,26 @@ func (m *RpcMembershipGetVerificationEmailRequest) MarshalToSizedBuffer(dAtA []b _ = i var l int _ = l + if m.IsOnboardingList { + i-- + if m.IsOnboardingList { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.InsiderTipsAndTutorials { + i-- + if m.InsiderTipsAndTutorials { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } if m.SubscribeToNewsletter { i-- if m.SubscribeToNewsletter { @@ -115068,6 +116672,9 @@ func (m *RpcObjectCreateRequest) Size() (n int) { if l > 0 { n += 1 + l + sovCommands(uint64(l)) } + if m.WithChat { + n += 2 + } return n } @@ -115135,6 +116742,9 @@ func (m *RpcObjectCreateBookmarkRequest) Size() (n int) { if l > 0 { n += 1 + l + sovCommands(uint64(l)) } + if m.WithChat { + n += 2 + } return n } @@ -115344,6 +116954,9 @@ func (m *RpcObjectCreateSetRequest) Size() (n int) { if l > 0 { n += 1 + l + sovCommands(uint64(l)) } + if m.WithChat { + n += 2 + } return n } @@ -115491,6 +117104,9 @@ func (m *RpcObjectCreateFromUrlRequest) Size() (n int) { if m.AddPageContent { n += 2 } + if m.WithChat { + n += 2 + } return n } @@ -115512,6 +117128,10 @@ func (m *RpcObjectCreateFromUrlResponse) Size() (n int) { l = m.Details.Size() n += 1 + l + sovCommands(uint64(l)) } + l = len(m.ChatId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } return n } @@ -115987,6 +117607,10 @@ func (m *RpcObjectSearchRequest) Size() (n int) { n += 1 + l + sovCommands(uint64(l)) } } + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } return n } @@ -116083,6 +117707,10 @@ func (m *RpcObjectSearchWithMetaRequest) Size() (n int) { if m.ReturnHTMLHighlightsInsteadOfRanges { n += 2 } + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } return n } @@ -116311,10 +117939,6 @@ func (m *RpcObjectSearchSubscribeRequest) Size() (n int) { n += 1 + l + sovCommands(uint64(l)) } } - l = len(m.IgnoreWorkspace) - if l > 0 { - n += 1 + l + sovCommands(uint64(l)) - } if m.NoDepSubscription { n += 2 } @@ -116322,6 +117946,10 @@ func (m *RpcObjectSearchSubscribeRequest) Size() (n int) { if l > 0 { n += 1 + l + sovCommands(uint64(l)) } + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } return n } @@ -116374,6 +118002,159 @@ func (m *RpcObjectSearchSubscribeResponseError) Size() (n int) { return n } +func (m *RpcObjectCrossSpaceSearchSubscribe) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SubId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + if len(m.Filters) > 0 { + for _, e := range m.Filters { + l = e.Size() + n += 1 + l + sovCommands(uint64(l)) + } + } + if len(m.Sorts) > 0 { + for _, e := range m.Sorts { + l = e.Size() + n += 1 + l + sovCommands(uint64(l)) + } + } + if len(m.Keys) > 0 { + for _, s := range m.Keys { + l = len(s) + n += 1 + l + sovCommands(uint64(l)) + } + } + if len(m.Source) > 0 { + for _, s := range m.Source { + l = len(s) + n += 1 + l + sovCommands(uint64(l)) + } + } + if m.NoDepSubscription { + n += 2 + } + l = len(m.CollectionId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Error != nil { + l = m.Error.Size() + n += 1 + l + sovCommands(uint64(l)) + } + if len(m.Records) > 0 { + for _, e := range m.Records { + l = e.Size() + n += 1 + l + sovCommands(uint64(l)) + } + } + if len(m.Dependencies) > 0 { + for _, e := range m.Dependencies { + l = e.Size() + n += 1 + l + sovCommands(uint64(l)) + } + } + l = len(m.SubId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + if m.Counters != nil { + l = m.Counters.Size() + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + sovCommands(uint64(m.Code)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribe) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SubId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Error != nil { + l = m.Error.Size() + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + sovCommands(uint64(m.Code)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + func (m *RpcObjectGroupsSubscribe) Size() (n int) { if m == nil { return 0 @@ -116490,13 +118271,13 @@ func (m *RpcObjectSubscribeIdsRequest) Size() (n int) { n += 1 + l + sovCommands(uint64(l)) } } - l = len(m.IgnoreWorkspace) - if l > 0 { - n += 1 + l + sovCommands(uint64(l)) - } if m.NoDepSubscription { n += 2 } + l = len(m.SpaceId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } return n } @@ -128284,6 +130065,94 @@ func (m *RpcDebugPingResponseError) Size() (n int) { return n } +func (m *RpcDebugAnystoreObjectChanges) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *RpcDebugAnystoreObjectChangesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ObjectId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + if m.OrderBy != 0 { + n += 1 + sovCommands(uint64(m.OrderBy)) + } + return n +} + +func (m *RpcDebugAnystoreObjectChangesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Error != nil { + l = m.Error.Size() + n += 1 + l + sovCommands(uint64(l)) + } + if len(m.Changes) > 0 { + for _, e := range m.Changes { + l = e.Size() + n += 1 + l + sovCommands(uint64(l)) + } + } + if m.WrongOrder { + n += 2 + } + return n +} + +func (m *RpcDebugAnystoreObjectChangesResponseChange) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ChangeId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + l = len(m.OrderId) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + if m.Change != nil { + l = m.Change.Size() + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + +func (m *RpcDebugAnystoreObjectChangesResponseError) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + sovCommands(uint64(m.Code)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovCommands(uint64(l)) + } + return n +} + func (m *RpcMetrics) Size() (n int) { if m == nil { return 0 @@ -129044,6 +130913,12 @@ func (m *RpcMembershipGetVerificationEmailRequest) Size() (n int) { if m.SubscribeToNewsletter { n += 2 } + if m.InsiderTipsAndTutorials { + n += 2 + } + if m.IsOnboardingList { + n += 2 + } return n } @@ -148876,6 +150751,26 @@ func (m *RpcObjectCreateRequest) Unmarshal(dAtA []byte) error { } m.ObjectTypeUniqueKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WithChat", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WithChat = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -149335,6 +151230,26 @@ func (m *RpcObjectCreateBookmarkRequest) Unmarshal(dAtA []byte) error { } m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WithChat", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WithChat = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -150734,6 +152649,26 @@ func (m *RpcObjectCreateSetRequest) Unmarshal(dAtA []byte) error { } m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WithChat", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WithChat = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -151734,6 +153669,26 @@ func (m *RpcObjectCreateFromUrlRequest) Unmarshal(dAtA []byte) error { } } m.AddPageContent = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WithChat", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WithChat = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -151888,6 +153843,38 @@ func (m *RpcObjectCreateFromUrlResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChatId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChatId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -152119,7 +154106,226 @@ func (m *RpcObjectChatAddRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectId = string(dAtA[iNdEx:postIndex]) + m.ObjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectChatAddResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Response: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &RpcObjectChatAddResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChatId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChatId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectChatAddResponseError) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Error: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= RpcObjectChatAddResponseErrorCode(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -152142,7 +154348,7 @@ func (m *RpcObjectChatAddRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectChatAddResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectBookmarkFetch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152165,17 +154371,67 @@ func (m *RpcObjectChatAddResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") + return fmt.Errorf("proto: BookmarkFetch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BookmarkFetch: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectBookmarkFetchRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Request: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -152185,31 +154441,27 @@ func (m *RpcObjectChatAddResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcObjectChatAddResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ContextId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChatId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -152237,7 +154489,7 @@ func (m *RpcObjectChatAddResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChatId = string(dAtA[iNdEx:postIndex]) + m.Url = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -152260,7 +154512,93 @@ func (m *RpcObjectChatAddResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectChatAddResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectBookmarkFetchResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Response: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &RpcObjectBookmarkFetchResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152303,7 +154641,7 @@ func (m *RpcObjectChatAddResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectChatAddResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectBookmarkFetchResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -152361,7 +154699,7 @@ func (m *RpcObjectChatAddResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectBookmarkFetch) Unmarshal(dAtA []byte) error { +func (m *RpcObjectToBookmark) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152384,10 +154722,10 @@ func (m *RpcObjectBookmarkFetch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: BookmarkFetch: wiretype end group for non-group") + return fmt.Errorf("proto: ToBookmark: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: BookmarkFetch: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ToBookmark: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -152411,7 +154749,7 @@ func (m *RpcObjectBookmarkFetch) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectBookmarkFetchRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectToBookmarkRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152525,7 +154863,7 @@ func (m *RpcObjectBookmarkFetchRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectBookmarkFetchResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectToBookmarkResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152584,12 +154922,44 @@ func (m *RpcObjectBookmarkFetchResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcObjectBookmarkFetchResponseError{} + m.Error = &RpcObjectToBookmarkResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -152611,7 +154981,7 @@ func (m *RpcObjectBookmarkFetchResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectToBookmarkResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152654,7 +155024,7 @@ func (m *RpcObjectBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectBookmarkFetchResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectToBookmarkResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -152712,7 +155082,7 @@ func (m *RpcObjectBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectToBookmark) Unmarshal(dAtA []byte) error { +func (m *RpcObjectDuplicate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152735,10 +155105,10 @@ func (m *RpcObjectToBookmark) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ToBookmark: wiretype end group for non-group") + return fmt.Errorf("proto: Duplicate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ToBookmark: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Duplicate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -152762,7 +155132,7 @@ func (m *RpcObjectToBookmark) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectToBookmarkRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectDuplicateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152823,38 +155193,6 @@ func (m *RpcObjectToBookmarkRequest) Unmarshal(dAtA []byte) error { } m.ContextId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Url = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -152876,7 +155214,7 @@ func (m *RpcObjectToBookmarkRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectToBookmarkResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectDuplicateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -152935,7 +155273,7 @@ func (m *RpcObjectToBookmarkResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcObjectToBookmarkResponseError{} + m.Error = &RpcObjectDuplicateResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -152943,7 +155281,7 @@ func (m *RpcObjectToBookmarkResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -152971,7 +155309,7 @@ func (m *RpcObjectToBookmarkResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectId = string(dAtA[iNdEx:postIndex]) + m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -152994,7 +155332,7 @@ func (m *RpcObjectToBookmarkResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectToBookmarkResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectDuplicateResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153037,7 +155375,7 @@ func (m *RpcObjectToBookmarkResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectToBookmarkResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectDuplicateResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -153095,7 +155433,7 @@ func (m *RpcObjectToBookmarkResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectDuplicate) Unmarshal(dAtA []byte) error { +func (m *RpcObjectOpenBreadcrumbs) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153118,10 +155456,10 @@ func (m *RpcObjectDuplicate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Duplicate: wiretype end group for non-group") + return fmt.Errorf("proto: OpenBreadcrumbs: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Duplicate: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OpenBreadcrumbs: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -153145,7 +155483,7 @@ func (m *RpcObjectDuplicate) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectDuplicateRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectOpenBreadcrumbsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153206,6 +155544,38 @@ func (m *RpcObjectDuplicateRequest) Unmarshal(dAtA []byte) error { } m.ContextId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TraceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TraceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -153227,7 +155597,7 @@ func (m *RpcObjectDuplicateRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectDuplicateResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectOpenBreadcrumbsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153286,7 +155656,7 @@ func (m *RpcObjectDuplicateResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcObjectDuplicateResponseError{} + m.Error = &RpcObjectOpenBreadcrumbsResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -153294,7 +155664,7 @@ func (m *RpcObjectDuplicateResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -153322,7 +155692,79 @@ func (m *RpcObjectDuplicateResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Id = string(dAtA[iNdEx:postIndex]) + m.ObjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Event == nil { + m.Event = &ResponseEvent{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectView", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ObjectView == nil { + m.ObjectView = &model.ObjectView{} + } + if err := m.ObjectView.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -153345,7 +155787,7 @@ func (m *RpcObjectDuplicateResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectDuplicateResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectOpenBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153388,7 +155830,7 @@ func (m *RpcObjectDuplicateResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectDuplicateResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectOpenBreadcrumbsResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -153446,7 +155888,7 @@ func (m *RpcObjectDuplicateResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectOpenBreadcrumbs) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSetBreadcrumbs) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153469,10 +155911,10 @@ func (m *RpcObjectOpenBreadcrumbs) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OpenBreadcrumbs: wiretype end group for non-group") + return fmt.Errorf("proto: SetBreadcrumbs: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OpenBreadcrumbs: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetBreadcrumbs: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -153496,7 +155938,7 @@ func (m *RpcObjectOpenBreadcrumbs) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectOpenBreadcrumbsRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSetBreadcrumbsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153527,7 +155969,7 @@ func (m *RpcObjectOpenBreadcrumbsRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BreadcrumbsId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -153555,11 +155997,11 @@ func (m *RpcObjectOpenBreadcrumbsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ContextId = string(dAtA[iNdEx:postIndex]) + m.BreadcrumbsId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TraceId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -153587,7 +156029,7 @@ func (m *RpcObjectOpenBreadcrumbsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TraceId = string(dAtA[iNdEx:postIndex]) + m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -153610,7 +156052,7 @@ func (m *RpcObjectOpenBreadcrumbsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectOpenBreadcrumbsResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSetBreadcrumbsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153669,45 +156111,13 @@ func (m *RpcObjectOpenBreadcrumbsResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcObjectOpenBreadcrumbsResponseError{} + m.Error = &RpcObjectSetBreadcrumbsResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ObjectId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -153743,42 +156153,6 @@ func (m *RpcObjectOpenBreadcrumbsResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectView", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.ObjectView == nil { - m.ObjectView = &model.ObjectView{} - } - if err := m.ObjectView.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -153800,7 +156174,7 @@ func (m *RpcObjectOpenBreadcrumbsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectOpenBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSetBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153843,7 +156217,7 @@ func (m *RpcObjectOpenBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectOpenBreadcrumbsResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectSetBreadcrumbsResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -153901,7 +156275,7 @@ func (m *RpcObjectOpenBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSetBreadcrumbs) Unmarshal(dAtA []byte) error { +func (m *RpcObjectShareByLink) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153924,10 +156298,10 @@ func (m *RpcObjectSetBreadcrumbs) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetBreadcrumbs: wiretype end group for non-group") + return fmt.Errorf("proto: ShareByLink: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetBreadcrumbs: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ShareByLink: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -153951,7 +156325,7 @@ func (m *RpcObjectSetBreadcrumbs) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSetBreadcrumbsRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectShareByLinkRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -153982,39 +156356,7 @@ func (m *RpcObjectSetBreadcrumbsRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BreadcrumbsId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BreadcrumbsId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -154042,7 +156384,7 @@ func (m *RpcObjectSetBreadcrumbsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) + m.ObjectId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -154065,7 +156407,7 @@ func (m *RpcObjectSetBreadcrumbsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSetBreadcrumbsResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectShareByLinkResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154096,9 +156438,9 @@ func (m *RpcObjectSetBreadcrumbsResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Link", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -154108,31 +156450,27 @@ func (m *RpcObjectSetBreadcrumbsResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcObjectSetBreadcrumbsResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Link = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -154159,10 +156497,10 @@ func (m *RpcObjectSetBreadcrumbsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} + if m.Error == nil { + m.Error = &RpcObjectShareByLinkResponseError{} } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -154187,7 +156525,7 @@ func (m *RpcObjectSetBreadcrumbsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSetBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectShareByLinkResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154230,7 +156568,7 @@ func (m *RpcObjectSetBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectSetBreadcrumbsResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectShareByLinkResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -154288,7 +156626,7 @@ func (m *RpcObjectSetBreadcrumbsResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectShareByLink) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154311,10 +156649,10 @@ func (m *RpcObjectShareByLink) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ShareByLink: wiretype end group for non-group") + return fmt.Errorf("proto: Search: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ShareByLink: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Search: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -154338,7 +156676,7 @@ func (m *RpcObjectShareByLink) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectShareByLinkRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154369,7 +156707,75 @@ func (m *RpcObjectShareByLinkRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Filters = append(m.Filters, &model.BlockContentDataviewFilter{}) + if err := m.Filters[len(m.Filters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sorts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sorts = append(m.Sorts, &model.BlockContentDataviewSort{}) + if err := m.Sorts[len(m.Sorts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FullText", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -154397,7 +156803,141 @@ func (m *RpcObjectShareByLinkRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectId = string(dAtA[iNdEx:postIndex]) + m.FullText = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectTypeFilter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObjectTypeFilter = append(m.ObjectTypeFilter, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -154420,7 +156960,7 @@ func (m *RpcObjectShareByLinkRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectShareByLinkResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154451,9 +156991,9 @@ func (m *RpcObjectShareByLinkResponse) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Link", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -154463,27 +157003,31 @@ func (m *RpcObjectShareByLinkResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Link = string(dAtA[iNdEx:postIndex]) + if m.Error == nil { + m.Error = &RpcObjectSearchResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -154510,10 +157054,8 @@ func (m *RpcObjectShareByLinkResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcObjectShareByLinkResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Records = append(m.Records, &types.Struct{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -154538,7 +157080,7 @@ func (m *RpcObjectShareByLinkResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectShareByLinkResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154581,7 +157123,7 @@ func (m *RpcObjectShareByLinkResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectShareByLinkResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectSearchResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -154639,7 +157181,7 @@ func (m *RpcObjectShareByLinkResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearch) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchWithMeta) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154662,10 +157204,10 @@ func (m *RpcObjectSearch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Search: wiretype end group for non-group") + return fmt.Errorf("proto: SearchWithMeta: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Search: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SearchWithMeta: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -154689,7 +157231,7 @@ func (m *RpcObjectSearch) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -154920,6 +157462,98 @@ func (m *RpcObjectSearchRequest) Unmarshal(dAtA []byte) error { } m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReturnMeta", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ReturnMeta = bool(v != 0) + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReturnMetaRelationDetails", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ReturnMetaRelationDetails = bool(v != 0) + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReturnHTMLHighlightsInsteadOfRanges", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.ReturnHTMLHighlightsInsteadOfRanges = bool(v != 0) + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -154941,7 +157575,7 @@ func (m *RpcObjectSearchRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchWithMetaResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155000,7 +157634,7 @@ func (m *RpcObjectSearchResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcObjectSearchResponseError{} + m.Error = &RpcObjectSearchWithMetaResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -155008,7 +157642,7 @@ func (m *RpcObjectSearchResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -155035,8 +157669,8 @@ func (m *RpcObjectSearchResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Records = append(m.Records, &types.Struct{}) - if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Results = append(m.Results, &model.SearchResult{}) + if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -155061,7 +157695,7 @@ func (m *RpcObjectSearchResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchWithMetaResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155104,7 +157738,7 @@ func (m *RpcObjectSearchResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectSearchResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectSearchWithMetaResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -155162,7 +157796,7 @@ func (m *RpcObjectSearchResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchWithMeta) Unmarshal(dAtA []byte) error { +func (m *RpcObjectGraph) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155185,10 +157819,10 @@ func (m *RpcObjectSearchWithMeta) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SearchWithMeta: wiretype end group for non-group") + return fmt.Errorf("proto: Graph: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SearchWithMeta: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Graph: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -155212,7 +157846,7 @@ func (m *RpcObjectSearchWithMeta) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155276,10 +157910,29 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sorts", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectTypeFilter", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155289,29 +157942,59 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Sorts = append(m.Sorts, &model.BlockContentDataviewSort{}) - if err := m.Sorts[len(m.Sorts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ObjectTypeFilter = append(m.ObjectTypeFilter, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FullText", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -155339,13 +158022,13 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.FullText = string(dAtA[iNdEx:postIndex]) + m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CollectionId", wireType) } - m.Offset = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155355,16 +158038,29 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Offset |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands } - m.Limit = 0 + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CollectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SetSource", wireType) + } + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155374,14 +158070,77 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Limit |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 6: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SetSource = append(m.SetSource, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Edge: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Edge: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectTypeFilter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -155409,11 +158168,11 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectTypeFilter = append(m.ObjectTypeFilter, string(dAtA[iNdEx:postIndex])) + m.Source = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -155441,13 +158200,13 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + m.Target = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReturnMeta", wireType) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155457,17 +158216,29 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.ReturnMeta = bool(v != 0) - case 9: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReturnMetaRelationDetails", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } - var v int + m.Type = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155477,15 +158248,110 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + m.Type |= RpcObjectGraphEdgeType(b&0x7F) << shift if b < 0x80 { break } } - m.ReturnMetaRelationDetails = bool(v != 0) - case 10: + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IconImage", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IconImage = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IconEmoji", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IconEmoji = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ReturnHTMLHighlightsInsteadOfRanges", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hidden", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -155502,7 +158368,7 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { break } } - m.ReturnHTMLHighlightsInsteadOfRanges = bool(v != 0) + m.Hidden = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -155524,7 +158390,7 @@ func (m *RpcObjectSearchWithMetaRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchWithMetaResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectGraphResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155583,7 +158449,7 @@ func (m *RpcObjectSearchWithMetaResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcObjectSearchWithMetaResponseError{} + m.Error = &RpcObjectGraphResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -155591,7 +158457,41 @@ func (m *RpcObjectSearchWithMetaResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Results", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Nodes = append(m.Nodes, &types.Struct{}) + if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Edges", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -155618,8 +158518,8 @@ func (m *RpcObjectSearchWithMetaResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Results = append(m.Results, &model.SearchResult{}) - if err := m.Results[len(m.Results)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Edges = append(m.Edges, &RpcObjectGraphEdge{}) + if err := m.Edges[len(m.Edges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -155644,7 +158544,7 @@ func (m *RpcObjectSearchWithMetaResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchWithMetaResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectGraphResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155687,7 +158587,7 @@ func (m *RpcObjectSearchWithMetaResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectSearchWithMetaResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectGraphResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -155745,7 +158645,7 @@ func (m *RpcObjectSearchWithMetaResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectGraph) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchSubscribe) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155768,10 +158668,10 @@ func (m *RpcObjectGraph) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Graph: wiretype end group for non-group") + return fmt.Errorf("proto: SearchSubscribe: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Graph: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SearchSubscribe: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -155795,7 +158695,7 @@ func (m *RpcObjectGraph) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -155826,9 +158726,9 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SubId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155838,50 +158738,29 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Filters = append(m.Filters, &model.BlockContentDataviewFilter{}) - if err := m.Filters[len(m.Filters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.SubId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) - } - m.Limit = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Limit |= int32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectTypeFilter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Filters", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155891,29 +158770,31 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectTypeFilter = append(m.ObjectTypeFilter, string(dAtA[iNdEx:postIndex])) + m.Filters = append(m.Filters, &model.BlockContentDataviewFilter{}) + if err := m.Filters[len(m.Filters)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sorts", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155923,29 +158804,31 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + m.Sorts = append(m.Sorts, &model.BlockContentDataviewSort{}) + if err := m.Sorts[len(m.Sorts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) } - var stringLen uint64 + m.Limit = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155955,29 +158838,16 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Limit |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CollectionId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) } - var stringLen uint64 + m.Offset = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -155987,27 +158857,14 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Offset |= int64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CollectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SetSource", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156035,61 +158892,11 @@ func (m *RpcObjectGraphRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SetSource = append(m.SetSource, string(dAtA[iNdEx:postIndex])) + m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Edge: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Edge: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: + case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field AfterId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156117,11 +158924,11 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = string(dAtA[iNdEx:postIndex]) + m.AfterId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BeforeId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156149,11 +158956,11 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Target = string(dAtA[iNdEx:postIndex]) + m.BeforeId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156181,32 +158988,13 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) + m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 4: + case 13: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= RpcObjectGraphEdgeType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NoDepSubscription", wireType) } - var stringLen uint64 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156216,27 +159004,15 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: + m.NoDepSubscription = bool(v != 0) + case 14: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IconImage", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CollectionId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156264,11 +159040,11 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.IconImage = string(dAtA[iNdEx:postIndex]) + m.CollectionId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 15: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IconEmoji", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156296,28 +159072,8 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.IconEmoji = string(dAtA[iNdEx:postIndex]) + m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Hidden", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Hidden = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -156339,7 +159095,7 @@ func (m *RpcObjectGraphEdge) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectGraphResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -156397,18 +159153,86 @@ func (m *RpcObjectGraphResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcObjectGraphResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Error == nil { + m.Error = &RpcObjectSearchSubscribeResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Records = append(m.Records, &types.Struct{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Dependencies = append(m.Dependencies, &types.Struct{}) + if err := m.Dependencies[len(m.Dependencies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SubId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156418,29 +159242,27 @@ func (m *RpcObjectGraphResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Nodes = append(m.Nodes, &types.Struct{}) - if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.SubId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Edges", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Counters", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -156467,8 +159289,10 @@ func (m *RpcObjectGraphResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Edges = append(m.Edges, &RpcObjectGraphEdge{}) - if err := m.Edges[len(m.Edges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Counters == nil { + m.Counters = &EventObjectSubscriptionCounters{} + } + if err := m.Counters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -156493,7 +159317,7 @@ func (m *RpcObjectGraphResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectGraphResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectSearchSubscribeResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -156536,7 +159360,7 @@ func (m *RpcObjectGraphResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectGraphResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectSearchSubscribeResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -156594,7 +159418,7 @@ func (m *RpcObjectGraphResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchSubscribe) Unmarshal(dAtA []byte) error { +func (m *RpcObjectCrossSpaceSearchSubscribe) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -156617,10 +159441,10 @@ func (m *RpcObjectSearchSubscribe) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SearchSubscribe: wiretype end group for non-group") + return fmt.Errorf("proto: CrossSpaceSearchSubscribe: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SearchSubscribe: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CrossSpaceSearchSubscribe: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -156644,7 +159468,7 @@ func (m *RpcObjectSearchSubscribe) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { +func (m *RpcObjectCrossSpaceSearchSubscribeRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -156773,11 +159597,11 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) } - m.Limit = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156787,33 +159611,27 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Limit |= int64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands } - m.Offset = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Offset |= int64(b&0x7F) << shift - if b < 0x80 { - break - } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands } - case 7: + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 10: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Keys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156841,11 +159659,31 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) + m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 8: + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoDepSubscription", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NoDepSubscription = bool(v != 0) + case 14: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AfterId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field CollectionId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -156873,13 +159711,63 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.AfterId = string(dAtA[iNdEx:postIndex]) + m.CollectionId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectCrossSpaceSearchSubscribeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Response: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BeforeId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156889,29 +159777,33 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.BeforeId = string(dAtA[iNdEx:postIndex]) + if m.Error == nil { + m.Error = &RpcObjectCrossSpaceSearchSubscribeResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 10: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156921,29 +159813,31 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) + m.Records = append(m.Records, &types.Struct{}) + if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 12: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IgnoreWorkspace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156953,29 +159847,31 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.IgnoreWorkspace = string(dAtA[iNdEx:postIndex]) + m.Dependencies = append(m.Dependencies, &types.Struct{}) + if err := m.Dependencies[len(m.Dependencies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex - case 13: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NoDepSubscription", wireType) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubId", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -156985,17 +159881,29 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.NoDepSubscription = bool(v != 0) - case 14: + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CollectionId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Counters", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -157005,23 +159913,27 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.CollectionId = string(dAtA[iNdEx:postIndex]) + if m.Counters == nil { + m.Counters = &EventObjectSubscriptionCounters{} + } + if err := m.Counters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -157044,7 +159956,7 @@ func (m *RpcObjectSearchSubscribeRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { +func (m *RpcObjectCrossSpaceSearchSubscribeResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -157067,17 +159979,17 @@ func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") + return fmt.Errorf("proto: Error: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) } - var msglen int + m.Code = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -157087,33 +159999,16 @@ func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Code |= RpcObjectCrossSpaceSearchSubscribeResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Error == nil { - m.Error = &RpcObjectSearchSubscribeResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -157123,61 +160018,125 @@ func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Records = append(m.Records, &types.Struct{}) - if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { return err } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if msglen < 0 { - return ErrInvalidLengthCommands + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectCrossSpaceSearchUnsubscribe) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands } - postIndex := iNdEx + msglen - if postIndex < 0 { + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CrossSpaceSearchUnsubscribe: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CrossSpaceSearchUnsubscribe: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthCommands } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.Dependencies = append(m.Dependencies, &types.Struct{}) - if err := m.Dependencies[len(m.Dependencies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands } - iNdEx = postIndex - case 4: + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Request: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SubId", wireType) } @@ -157209,9 +160168,59 @@ func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { } m.SubId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Response: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Counters", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -157238,10 +160247,10 @@ func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Counters == nil { - m.Counters = &EventObjectSubscriptionCounters{} + if m.Error == nil { + m.Error = &RpcObjectCrossSpaceSearchUnsubscribeResponseError{} } - if err := m.Counters.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -157266,7 +160275,7 @@ func (m *RpcObjectSearchSubscribeResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcObjectSearchSubscribeResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcObjectCrossSpaceSearchUnsubscribeResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -157309,7 +160318,7 @@ func (m *RpcObjectSearchSubscribeResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcObjectSearchSubscribeResponseErrorCode(b&0x7F) << shift + m.Code |= RpcObjectCrossSpaceSearchUnsubscribeResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -158089,9 +161098,29 @@ func (m *RpcObjectSubscribeIdsRequest) Unmarshal(dAtA []byte) error { } m.Keys = append(m.Keys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 11: + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoDepSubscription", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NoDepSubscription = bool(v != 0) + case 13: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field IgnoreWorkspace", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -158119,28 +161148,8 @@ func (m *RpcObjectSubscribeIdsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.IgnoreWorkspace = string(dAtA[iNdEx:postIndex]) + m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 12: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NoDepSubscription", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.NoDepSubscription = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -213090,11 +216099,437 @@ func (m *RpcBlockLinkCreateWithObjectResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockId = string(dAtA[iNdEx:postIndex]) + m.BlockId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Event == nil { + m.Event = &ResponseEvent{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Details == nil { + m.Details = &types.Struct{} + } + if err := m.Details.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockLinkCreateWithObjectResponseError) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Error: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= RpcBlockLinkCreateWithObjectResponseErrorCode(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockLinkListSetAppearance) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListSetAppearance: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListSetAppearance: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockLinkListSetAppearanceRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Request: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContextId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockIds = append(m.BlockIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 3: + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IconSize", wireType) + } + m.IconSize = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.IconSize |= model.BlockContentLinkIconSize(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CardStyle", wireType) + } + m.CardStyle = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CardStyle |= model.BlockContentLinkCardStyle(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + m.Description = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Description |= model.BlockContentLinkDescription(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Relations", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -213122,11 +216557,61 @@ func (m *RpcBlockLinkCreateWithObjectResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TargetId = string(dAtA[iNdEx:postIndex]) + m.Relations = append(m.Relations, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 4: + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockLinkListSetAppearanceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Response: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -213153,16 +216638,16 @@ func (m *RpcBlockLinkCreateWithObjectResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} + if m.Error == nil { + m.Error = &RpcBlockLinkListSetAppearanceResponseError{} } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -213189,10 +216674,10 @@ func (m *RpcBlockLinkCreateWithObjectResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Details == nil { - m.Details = &types.Struct{} + if m.Event == nil { + m.Event = &ResponseEvent{} } - if err := m.Details.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -213217,7 +216702,7 @@ func (m *RpcBlockLinkCreateWithObjectResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockLinkCreateWithObjectResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockLinkListSetAppearanceResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213260,7 +216745,7 @@ func (m *RpcBlockLinkCreateWithObjectResponseError) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockLinkCreateWithObjectResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockLinkListSetAppearanceResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -213318,7 +216803,7 @@ func (m *RpcBlockLinkCreateWithObjectResponseError) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockLinkListSetAppearance) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelation) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213341,10 +216826,10 @@ func (m *RpcBlockLinkListSetAppearance) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ListSetAppearance: wiretype end group for non-group") + return fmt.Errorf("proto: BlockRelation: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ListSetAppearance: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockRelation: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -213368,7 +216853,57 @@ func (m *RpcBlockLinkListSetAppearance) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockLinkListSetAppearanceRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationSetKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SetKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SetKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockRelationSetKeyRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213431,7 +216966,7 @@ func (m *RpcBlockLinkListSetAppearanceRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -213459,68 +216994,11 @@ func (m *RpcBlockLinkListSetAppearanceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockIds = append(m.BlockIds, string(dAtA[iNdEx:postIndex])) + m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field IconSize", wireType) - } - m.IconSize = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.IconSize |= model.BlockContentLinkIconSize(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field CardStyle", wireType) - } - m.CardStyle = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.CardStyle |= model.BlockContentLinkCardStyle(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - m.Description = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Description |= model.BlockContentLinkDescription(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 7: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Relations", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -213548,7 +217026,7 @@ func (m *RpcBlockLinkListSetAppearanceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Relations = append(m.Relations, string(dAtA[iNdEx:postIndex])) + m.Key = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -213571,7 +217049,7 @@ func (m *RpcBlockLinkListSetAppearanceRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockLinkListSetAppearanceResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationSetKeyResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213630,7 +217108,7 @@ func (m *RpcBlockLinkListSetAppearanceResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockLinkListSetAppearanceResponseError{} + m.Error = &RpcBlockRelationSetKeyResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -213693,7 +217171,7 @@ func (m *RpcBlockLinkListSetAppearanceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockLinkListSetAppearanceResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationSetKeyResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213736,7 +217214,7 @@ func (m *RpcBlockLinkListSetAppearanceResponseError) Unmarshal(dAtA []byte) erro } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockLinkListSetAppearanceResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockRelationSetKeyResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -213794,57 +217272,7 @@ func (m *RpcBlockLinkListSetAppearanceResponseError) Unmarshal(dAtA []byte) erro } return nil } -func (m *RpcBlockRelation) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: BlockRelation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: BlockRelation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockRelationSetKey) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationAdd) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213867,10 +217295,10 @@ func (m *RpcBlockRelationSetKey) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetKey: wiretype end group for non-group") + return fmt.Errorf("proto: Add: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetKey: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -213894,7 +217322,7 @@ func (m *RpcBlockRelationSetKey) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationSetKeyRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationAddRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -213989,7 +217417,7 @@ func (m *RpcBlockRelationSetKeyRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RelationKey", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -214017,7 +217445,7 @@ func (m *RpcBlockRelationSetKeyRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Key = string(dAtA[iNdEx:postIndex]) + m.RelationKey = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -214040,7 +217468,7 @@ func (m *RpcBlockRelationSetKeyRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationSetKeyResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationAddResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214099,7 +217527,7 @@ func (m *RpcBlockRelationSetKeyResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockRelationSetKeyResponseError{} + m.Error = &RpcBlockRelationAddResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -214162,7 +217590,7 @@ func (m *RpcBlockRelationSetKeyResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationSetKeyResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockRelationAddResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214205,7 +217633,7 @@ func (m *RpcBlockRelationSetKeyResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockRelationSetKeyResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockRelationAddResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -214263,7 +217691,7 @@ func (m *RpcBlockRelationSetKeyResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationAdd) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmark) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214286,10 +217714,10 @@ func (m *RpcBlockRelationAdd) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Add: wiretype end group for non-group") + return fmt.Errorf("proto: BlockBookmark: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockBookmark: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -214313,7 +217741,57 @@ func (m *RpcBlockRelationAdd) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationAddRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkFetch) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Fetch: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Fetch: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockBookmarkFetchRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214408,7 +217886,7 @@ func (m *RpcBlockRelationAddRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelationKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -214436,7 +217914,7 @@ func (m *RpcBlockRelationAddRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RelationKey = string(dAtA[iNdEx:postIndex]) + m.Url = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -214459,7 +217937,7 @@ func (m *RpcBlockRelationAddRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationAddResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkFetchResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214518,7 +217996,7 @@ func (m *RpcBlockRelationAddResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockRelationAddResponseError{} + m.Error = &RpcBlockBookmarkFetchResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -214581,7 +218059,7 @@ func (m *RpcBlockRelationAddResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockRelationAddResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214624,7 +218102,7 @@ func (m *RpcBlockRelationAddResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockRelationAddResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockBookmarkFetchResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -214682,57 +218160,7 @@ func (m *RpcBlockRelationAddResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmark) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: BlockBookmark: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: BlockBookmark: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockBookmarkFetch) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkCreateAndFetch) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214755,10 +218183,10 @@ func (m *RpcBlockBookmarkFetch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Fetch: wiretype end group for non-group") + return fmt.Errorf("proto: CreateAndFetch: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Fetch: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CreateAndFetch: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -214782,7 +218210,7 @@ func (m *RpcBlockBookmarkFetch) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkFetchRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkCreateAndFetchRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214845,7 +218273,7 @@ func (m *RpcBlockBookmarkFetchRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TargetId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -214873,9 +218301,28 @@ func (m *RpcBlockBookmarkFetchRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockId = string(dAtA[iNdEx:postIndex]) + m.TargetId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + m.Position = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Position |= model.BlockPosition(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) } @@ -214928,7 +218375,7 @@ func (m *RpcBlockBookmarkFetchRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkFetchResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkCreateAndFetchResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -214987,13 +218434,45 @@ func (m *RpcBlockBookmarkFetchResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockBookmarkFetchResponseError{} + m.Error = &RpcBlockBookmarkCreateAndFetchResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -215050,7 +218529,7 @@ func (m *RpcBlockBookmarkFetchResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockBookmarkCreateAndFetchResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215093,7 +218572,7 @@ func (m *RpcBlockBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockBookmarkFetchResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockBookmarkCreateAndFetchResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -215151,7 +218630,7 @@ func (m *RpcBlockBookmarkFetchResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkCreateAndFetch) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDiv) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215174,10 +218653,10 @@ func (m *RpcBlockBookmarkCreateAndFetch) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CreateAndFetch: wiretype end group for non-group") + return fmt.Errorf("proto: BlockDiv: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CreateAndFetch: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockDiv: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -215201,7 +218680,57 @@ func (m *RpcBlockBookmarkCreateAndFetch) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkCreateAndFetchRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDivListSetStyle) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListSetStyle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListSetStyle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockDivListSetStyleRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215264,7 +218793,7 @@ func (m *RpcBlockBookmarkCreateAndFetchRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -215292,32 +218821,13 @@ func (m *RpcBlockBookmarkCreateAndFetchRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TargetId = string(dAtA[iNdEx:postIndex]) + m.BlockIds = append(m.BlockIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - m.Position = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Position |= model.BlockPosition(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Style", wireType) } - var stringLen uint64 + m.Style = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -215327,24 +218837,11 @@ func (m *RpcBlockBookmarkCreateAndFetchRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Style |= model.BlockContentDivStyle(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Url = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -215366,7 +218863,7 @@ func (m *RpcBlockBookmarkCreateAndFetchRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkCreateAndFetchResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDivListSetStyleResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215425,45 +218922,13 @@ func (m *RpcBlockBookmarkCreateAndFetchResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockBookmarkCreateAndFetchResponseError{} + m.Error = &RpcBlockDivListSetStyleResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BlockId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -215520,7 +218985,7 @@ func (m *RpcBlockBookmarkCreateAndFetchResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockBookmarkCreateAndFetchResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDivListSetStyleResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215563,7 +219028,7 @@ func (m *RpcBlockBookmarkCreateAndFetchResponseError) Unmarshal(dAtA []byte) err } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockBookmarkCreateAndFetchResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDivListSetStyleResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -215621,7 +219086,7 @@ func (m *RpcBlockBookmarkCreateAndFetchResponseError) Unmarshal(dAtA []byte) err } return nil } -func (m *RpcBlockDiv) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataview) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215644,10 +219109,10 @@ func (m *RpcBlockDiv) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: BlockDiv: wiretype end group for non-group") + return fmt.Errorf("proto: BlockDataview: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: BlockDiv: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockDataview: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -215671,7 +219136,7 @@ func (m *RpcBlockDiv) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDivListSetStyle) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewView) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215694,10 +219159,10 @@ func (m *RpcBlockDivListSetStyle) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ListSetStyle: wiretype end group for non-group") + return fmt.Errorf("proto: View: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ListSetStyle: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: View: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -215721,7 +219186,57 @@ func (m *RpcBlockDivListSetStyle) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDivListSetStyleRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewCreate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Create: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Create: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockDataviewViewCreateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215784,7 +219299,7 @@ func (m *RpcBlockDivListSetStyleRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -215812,13 +219327,13 @@ func (m *RpcBlockDivListSetStyleRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockIds = append(m.BlockIds, string(dAtA[iNdEx:postIndex])) + m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Style", wireType) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) } - m.Style = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -215828,11 +219343,60 @@ func (m *RpcBlockDivListSetStyleRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Style |= model.BlockContentDivStyle(b&0x7F) << shift + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.View == nil { + m.View = &model.BlockContentDataviewView{} + } + if err := m.View.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -215854,7 +219418,7 @@ func (m *RpcBlockDivListSetStyleRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDivListSetStyleResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewCreateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -215912,18 +219476,54 @@ func (m *RpcBlockDivListSetStyleResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcBlockDivListSetStyleResponseError{} + if m.Error == nil { + m.Error = &RpcBlockDataviewViewCreateResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Event == nil { + m.Event = &ResponseEvent{} } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -215933,27 +219533,23 @@ func (m *RpcBlockDivListSetStyleResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} - } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -215976,7 +219572,7 @@ func (m *RpcBlockDivListSetStyleResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDivListSetStyleResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewCreateResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216019,7 +219615,7 @@ func (m *RpcBlockDivListSetStyleResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDivListSetStyleResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewCreateResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -216077,107 +219673,7 @@ func (m *RpcBlockDivListSetStyleResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataview) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: BlockDataview: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: BlockDataview: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockDataviewView) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: View: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: View: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockDataviewViewCreate) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216200,10 +219696,10 @@ func (m *RpcBlockDataviewViewCreate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Create: wiretype end group for non-group") + return fmt.Errorf("proto: Update: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Create: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Update: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -216227,7 +219723,7 @@ func (m *RpcBlockDataviewViewCreate) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewCreateRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewUpdateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216320,11 +219816,11 @@ func (m *RpcBlockDataviewViewCreateRequest) Unmarshal(dAtA []byte) error { } m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -216334,33 +219830,29 @@ func (m *RpcBlockDataviewViewCreateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.View == nil { - m.View = &model.BlockContentDataviewView{} - } - if err := m.View.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -216370,23 +219862,27 @@ func (m *RpcBlockDataviewViewCreateRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) + if m.View == nil { + m.View = &model.BlockContentDataviewView{} + } + if err := m.View.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -216409,7 +219905,7 @@ func (m *RpcBlockDataviewViewCreateRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewCreateResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewUpdateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216468,7 +219964,7 @@ func (m *RpcBlockDataviewViewCreateResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewCreateResponseError{} + m.Error = &RpcBlockDataviewViewUpdateResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -216510,38 +220006,6 @@ func (m *RpcBlockDataviewViewCreateResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ViewId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -216563,7 +220027,7 @@ func (m *RpcBlockDataviewViewCreateResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewCreateResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewUpdateResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216606,7 +220070,7 @@ func (m *RpcBlockDataviewViewCreateResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewCreateResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewUpdateResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -216664,7 +220128,7 @@ func (m *RpcBlockDataviewViewCreateResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewUpdate) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216687,10 +220151,10 @@ func (m *RpcBlockDataviewViewUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Update: wiretype end group for non-group") + return fmt.Errorf("proto: Delete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Update: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Delete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -216714,7 +220178,7 @@ func (m *RpcBlockDataviewViewUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewUpdateRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewDeleteRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216807,7 +220271,7 @@ func (m *RpcBlockDataviewViewUpdateRequest) Unmarshal(dAtA []byte) error { } m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } @@ -216839,42 +220303,6 @@ func (m *RpcBlockDataviewViewUpdateRequest) Unmarshal(dAtA []byte) error { } m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.View == nil { - m.View = &model.BlockContentDataviewView{} - } - if err := m.View.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -216896,7 +220324,7 @@ func (m *RpcBlockDataviewViewUpdateRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewUpdateResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewDeleteResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -216955,7 +220383,7 @@ func (m *RpcBlockDataviewViewUpdateResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewUpdateResponseError{} + m.Error = &RpcBlockDataviewViewDeleteResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -217018,7 +220446,7 @@ func (m *RpcBlockDataviewViewUpdateResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewUpdateResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewDeleteResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217061,7 +220489,7 @@ func (m *RpcBlockDataviewViewUpdateResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewUpdateResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewDeleteResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -217119,7 +220547,7 @@ func (m *RpcBlockDataviewViewUpdateResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewDelete) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetPosition) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217142,10 +220570,10 @@ func (m *RpcBlockDataviewViewDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Delete: wiretype end group for non-group") + return fmt.Errorf("proto: SetPosition: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Delete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetPosition: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -217169,7 +220597,7 @@ func (m *RpcBlockDataviewViewDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewDeleteRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetPositionRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217294,6 +220722,25 @@ func (m *RpcBlockDataviewViewDeleteRequest) Unmarshal(dAtA []byte) error { } m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) + } + m.Position = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Position |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -217315,7 +220762,7 @@ func (m *RpcBlockDataviewViewDeleteRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewDeleteResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetPositionResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217374,7 +220821,7 @@ func (m *RpcBlockDataviewViewDeleteResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewDeleteResponseError{} + m.Error = &RpcBlockDataviewViewSetPositionResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -217437,7 +220884,7 @@ func (m *RpcBlockDataviewViewDeleteResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewDeleteResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetPositionResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217480,7 +220927,7 @@ func (m *RpcBlockDataviewViewDeleteResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewDeleteResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewSetPositionResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -217538,7 +220985,7 @@ func (m *RpcBlockDataviewViewDeleteResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetPosition) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetActive) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217561,10 +221008,10 @@ func (m *RpcBlockDataviewViewSetPosition) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetPosition: wiretype end group for non-group") + return fmt.Errorf("proto: SetActive: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetPosition: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetActive: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -217588,7 +221035,7 @@ func (m *RpcBlockDataviewViewSetPosition) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetPositionRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetActiveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217681,7 +221128,7 @@ func (m *RpcBlockDataviewViewSetPositionRequest) Unmarshal(dAtA []byte) error { } m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } @@ -217713,25 +221160,6 @@ func (m *RpcBlockDataviewViewSetPositionRequest) Unmarshal(dAtA []byte) error { } m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Position", wireType) - } - m.Position = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Position |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -217753,7 +221181,7 @@ func (m *RpcBlockDataviewViewSetPositionRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetPositionResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetActiveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217812,7 +221240,7 @@ func (m *RpcBlockDataviewViewSetPositionResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewSetPositionResponseError{} + m.Error = &RpcBlockDataviewViewSetActiveResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -217875,7 +221303,7 @@ func (m *RpcBlockDataviewViewSetPositionResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetPositionResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewSetActiveResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217918,7 +221346,7 @@ func (m *RpcBlockDataviewViewSetPositionResponseError) Unmarshal(dAtA []byte) er } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewSetPositionResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewSetActiveResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -217976,7 +221404,7 @@ func (m *RpcBlockDataviewViewSetPositionResponseError) Unmarshal(dAtA []byte) er } return nil } -func (m *RpcBlockDataviewViewSetActive) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelation) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -217999,10 +221427,10 @@ func (m *RpcBlockDataviewViewSetActive) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetActive: wiretype end group for non-group") + return fmt.Errorf("proto: Relation: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetActive: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Relation: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -218026,7 +221454,7 @@ func (m *RpcBlockDataviewViewSetActive) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetActiveRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationAdd) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218049,108 +221477,12 @@ func (m *RpcBlockDataviewViewSetActiveRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Request: wiretype end group for non-group") + return fmt.Errorf("proto: Add: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContextId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BlockId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ViewId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -218172,7 +221504,7 @@ func (m *RpcBlockDataviewViewSetActiveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetActiveResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationAddRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218195,17 +221527,17 @@ func (m *RpcBlockDataviewViewSetActiveResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") + return fmt.Errorf("proto: Request: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -218215,33 +221547,29 @@ func (m *RpcBlockDataviewViewSetActiveResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcBlockDataviewViewSetActiveResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ContextId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -218251,27 +221579,55 @@ func (m *RpcBlockDataviewViewSetActiveResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} + m.BlockId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field RelationKeys", wireType) } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.RelationKeys = append(m.RelationKeys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -218294,7 +221650,7 @@ func (m *RpcBlockDataviewViewSetActiveResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewSetActiveResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationAddResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218317,17 +221673,17 @@ func (m *RpcBlockDataviewViewSetActiveResponseError) Unmarshal(dAtA []byte) erro fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Error: wiretype end group for non-group") + return fmt.Errorf("proto: Response: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - m.Code = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -218337,16 +221693,33 @@ func (m *RpcBlockDataviewViewSetActiveResponseError) Unmarshal(dAtA []byte) erro } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewSetActiveResponseErrorCode(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &RpcBlockDataviewRelationAddResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -218356,23 +221729,27 @@ func (m *RpcBlockDataviewViewSetActiveResponseError) Unmarshal(dAtA []byte) erro } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) + if m.Event == nil { + m.Event = &ResponseEvent{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -218395,7 +221772,7 @@ func (m *RpcBlockDataviewViewSetActiveResponseError) Unmarshal(dAtA []byte) erro } return nil } -func (m *RpcBlockDataviewRelation) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationAddResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218418,12 +221795,63 @@ func (m *RpcBlockDataviewRelation) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Relation: wiretype end group for non-group") + return fmt.Errorf("proto: Error: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Relation: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= RpcBlockDataviewRelationAddResponseErrorCode(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -218445,7 +221873,7 @@ func (m *RpcBlockDataviewRelation) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationAdd) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationDelete) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218468,10 +221896,10 @@ func (m *RpcBlockDataviewRelationAdd) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Add: wiretype end group for non-group") + return fmt.Errorf("proto: Delete: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Delete: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -218495,7 +221923,7 @@ func (m *RpcBlockDataviewRelationAdd) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationAddRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationDeleteRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218641,7 +222069,7 @@ func (m *RpcBlockDataviewRelationAddRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationAddResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationDeleteResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218700,13 +222128,13 @@ func (m *RpcBlockDataviewRelationAddResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewRelationAddResponseError{} + m.Error = &RpcBlockDataviewRelationDeleteResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -218763,7 +222191,7 @@ func (m *RpcBlockDataviewRelationAddResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationAddResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewRelationDeleteResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218806,7 +222234,7 @@ func (m *RpcBlockDataviewRelationAddResponseError) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewRelationAddResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewRelationDeleteResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -218864,7 +222292,7 @@ func (m *RpcBlockDataviewRelationAddResponseError) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewRelationDelete) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSetSource) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -218887,10 +222315,10 @@ func (m *RpcBlockDataviewRelationDelete) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Delete: wiretype end group for non-group") + return fmt.Errorf("proto: SetSource: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Delete: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetSource: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -218914,7 +222342,7 @@ func (m *RpcBlockDataviewRelationDelete) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationDeleteRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSetSourceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219009,7 +222437,7 @@ func (m *RpcBlockDataviewRelationDeleteRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelationKeys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -219037,7 +222465,7 @@ func (m *RpcBlockDataviewRelationDeleteRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RelationKeys = append(m.RelationKeys, string(dAtA[iNdEx:postIndex])) + m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -219060,7 +222488,7 @@ func (m *RpcBlockDataviewRelationDeleteRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationDeleteResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSetSourceResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219119,13 +222547,13 @@ func (m *RpcBlockDataviewRelationDeleteResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewRelationDeleteResponseError{} + m.Error = &RpcBlockDataviewSetSourceResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -219182,7 +222610,7 @@ func (m *RpcBlockDataviewRelationDeleteResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewRelationDeleteResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSetSourceResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219225,7 +222653,7 @@ func (m *RpcBlockDataviewRelationDeleteResponseError) Unmarshal(dAtA []byte) err } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewRelationDeleteResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewSetSourceResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -219283,7 +222711,7 @@ func (m *RpcBlockDataviewRelationDeleteResponseError) Unmarshal(dAtA []byte) err } return nil } -func (m *RpcBlockDataviewSetSource) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewGroupOrder) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219306,10 +222734,10 @@ func (m *RpcBlockDataviewSetSource) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetSource: wiretype end group for non-group") + return fmt.Errorf("proto: GroupOrder: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetSource: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GroupOrder: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -219333,7 +222761,57 @@ func (m *RpcBlockDataviewSetSource) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSetSourceRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewGroupOrderUpdate) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Update: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Update: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockDataviewGroupOrderUpdateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219428,9 +222906,9 @@ func (m *RpcBlockDataviewSetSourceRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Source", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field GroupOrder", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -219440,23 +222918,27 @@ func (m *RpcBlockDataviewSetSourceRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Source = append(m.Source, string(dAtA[iNdEx:postIndex])) + if m.GroupOrder == nil { + m.GroupOrder = &model.BlockContentDataviewGroupOrder{} + } + if err := m.GroupOrder.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -219479,7 +222961,7 @@ func (m *RpcBlockDataviewSetSourceRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSetSourceResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewGroupOrderUpdateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219538,13 +223020,13 @@ func (m *RpcBlockDataviewSetSourceResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewSetSourceResponseError{} + m.Error = &RpcBlockDataviewGroupOrderUpdateResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -219601,7 +223083,7 @@ func (m *RpcBlockDataviewSetSourceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSetSourceResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewGroupOrderUpdateResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219644,7 +223126,7 @@ func (m *RpcBlockDataviewSetSourceResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewSetSourceResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewGroupOrderUpdateResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -219702,7 +223184,7 @@ func (m *RpcBlockDataviewSetSourceResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewGroupOrder) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrder) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219725,10 +223207,10 @@ func (m *RpcBlockDataviewGroupOrder) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GroupOrder: wiretype end group for non-group") + return fmt.Errorf("proto: ObjectOrder: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GroupOrder: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ObjectOrder: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -219752,7 +223234,7 @@ func (m *RpcBlockDataviewGroupOrder) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewGroupOrderUpdate) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219802,7 +223284,7 @@ func (m *RpcBlockDataviewGroupOrderUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewGroupOrderUpdateRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderUpdateRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -219897,7 +223379,7 @@ func (m *RpcBlockDataviewGroupOrderUpdateRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupOrder", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectOrders", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -219924,10 +223406,8 @@ func (m *RpcBlockDataviewGroupOrderUpdateRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.GroupOrder == nil { - m.GroupOrder = &model.BlockContentDataviewGroupOrder{} - } - if err := m.GroupOrder.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ObjectOrders = append(m.ObjectOrders, &model.BlockContentDataviewObjectOrder{}) + if err := m.ObjectOrders[len(m.ObjectOrders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -219952,7 +223432,7 @@ func (m *RpcBlockDataviewGroupOrderUpdateRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewGroupOrderUpdateResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderUpdateResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220011,7 +223491,7 @@ func (m *RpcBlockDataviewGroupOrderUpdateResponse) Unmarshal(dAtA []byte) error return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewGroupOrderUpdateResponseError{} + m.Error = &RpcBlockDataviewObjectOrderUpdateResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -220074,7 +223554,7 @@ func (m *RpcBlockDataviewGroupOrderUpdateResponse) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewGroupOrderUpdateResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderUpdateResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220117,7 +223597,7 @@ func (m *RpcBlockDataviewGroupOrderUpdateResponseError) Unmarshal(dAtA []byte) e } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewGroupOrderUpdateResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewObjectOrderUpdateResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -220175,57 +223655,7 @@ func (m *RpcBlockDataviewGroupOrderUpdateResponseError) Unmarshal(dAtA []byte) e } return nil } -func (m *RpcBlockDataviewObjectOrder) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ObjectOrder: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ObjectOrder: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockDataviewObjectOrderUpdate) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderMove) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220248,10 +223678,10 @@ func (m *RpcBlockDataviewObjectOrderUpdate) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Update: wiretype end group for non-group") + return fmt.Errorf("proto: Move: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Update: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Move: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -220275,7 +223705,7 @@ func (m *RpcBlockDataviewObjectOrderUpdate) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewObjectOrderUpdateRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderMoveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220370,9 +223800,9 @@ func (m *RpcBlockDataviewObjectOrderUpdateRequest) Unmarshal(dAtA []byte) error iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectOrders", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -220382,25 +223812,119 @@ func (m *RpcBlockDataviewObjectOrderUpdateRequest) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectOrders = append(m.ObjectOrders, &model.BlockContentDataviewObjectOrder{}) - if err := m.ObjectOrders[len(m.ObjectOrders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.ViewId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AfterId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AfterId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObjectIds = append(m.ObjectIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -220423,7 +223947,7 @@ func (m *RpcBlockDataviewObjectOrderUpdateRequest) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewObjectOrderUpdateResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderMoveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220482,7 +224006,7 @@ func (m *RpcBlockDataviewObjectOrderUpdateResponse) Unmarshal(dAtA []byte) error return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewObjectOrderUpdateResponseError{} + m.Error = &RpcBlockDataviewObjectOrderMoveResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -220545,7 +224069,7 @@ func (m *RpcBlockDataviewObjectOrderUpdateResponse) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewObjectOrderUpdateResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewObjectOrderMoveResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220588,7 +224112,7 @@ func (m *RpcBlockDataviewObjectOrderUpdateResponseError) Unmarshal(dAtA []byte) } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewObjectOrderUpdateResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewObjectOrderMoveResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -220646,7 +224170,7 @@ func (m *RpcBlockDataviewObjectOrderUpdateResponseError) Unmarshal(dAtA []byte) } return nil } -func (m *RpcBlockDataviewObjectOrderMove) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateFromExistingObject) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220669,10 +224193,10 @@ func (m *RpcBlockDataviewObjectOrderMove) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Move: wiretype end group for non-group") + return fmt.Errorf("proto: CreateFromExistingObject: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Move: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CreateFromExistingObject: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -220696,7 +224220,7 @@ func (m *RpcBlockDataviewObjectOrderMove) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewObjectOrderMoveRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateFromExistingObjectRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220787,107 +224311,11 @@ func (m *RpcBlockDataviewObjectOrderMoveRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ViewId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GroupId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AfterId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AfterId = string(dAtA[iNdEx:postIndex]) + m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TargetObjectId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -220915,7 +224343,7 @@ func (m *RpcBlockDataviewObjectOrderMoveRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectIds = append(m.ObjectIds, string(dAtA[iNdEx:postIndex])) + m.TargetObjectId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -220938,7 +224366,7 @@ func (m *RpcBlockDataviewObjectOrderMoveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewObjectOrderMoveResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateFromExistingObjectResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -220997,13 +224425,111 @@ func (m *RpcBlockDataviewObjectOrderMoveResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewObjectOrderMoveResponseError{} + m.Error = &RpcBlockDataviewCreateFromExistingObjectResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetObjectId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetObjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.View = append(m.View, &model.BlockContentDataviewView{}) + if err := m.View[len(m.View)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } @@ -221060,7 +224586,7 @@ func (m *RpcBlockDataviewObjectOrderMoveResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewObjectOrderMoveResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateFromExistingObjectResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221103,7 +224629,7 @@ func (m *RpcBlockDataviewObjectOrderMoveResponseError) Unmarshal(dAtA []byte) er } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewObjectOrderMoveResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewCreateFromExistingObjectResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -221161,7 +224687,7 @@ func (m *RpcBlockDataviewObjectOrderMoveResponseError) Unmarshal(dAtA []byte) er } return nil } -func (m *RpcBlockDataviewCreateFromExistingObject) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateBookmark) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221184,10 +224710,10 @@ func (m *RpcBlockDataviewCreateFromExistingObject) Unmarshal(dAtA []byte) error fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CreateFromExistingObject: wiretype end group for non-group") + return fmt.Errorf("proto: CreateBookmark: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CreateFromExistingObject: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: CreateBookmark: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -221211,7 +224737,7 @@ func (m *RpcBlockDataviewCreateFromExistingObject) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewCreateFromExistingObjectRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateBookmarkRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221306,7 +224832,7 @@ func (m *RpcBlockDataviewCreateFromExistingObjectRequest) Unmarshal(dAtA []byte) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetObjectId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -221334,7 +224860,39 @@ func (m *RpcBlockDataviewCreateFromExistingObjectRequest) Unmarshal(dAtA []byte) if postIndex > l { return io.ErrUnexpectedEOF } - m.TargetObjectId = string(dAtA[iNdEx:postIndex]) + m.Url = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -221357,7 +224915,7 @@ func (m *RpcBlockDataviewCreateFromExistingObjectRequest) Unmarshal(dAtA []byte) } return nil } -func (m *RpcBlockDataviewCreateFromExistingObjectResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateBookmarkResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221415,116 +224973,18 @@ func (m *RpcBlockDataviewCreateFromExistingObjectResponse) Unmarshal(dAtA []byte if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcBlockDataviewCreateFromExistingObjectResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BlockId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetObjectId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TargetObjectId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field View", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.View = append(m.View, &model.BlockContentDataviewView{}) - if err := m.View[len(m.View)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Error == nil { + m.Error = &RpcBlockDataviewCreateBookmarkResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 5: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -221534,27 +224994,23 @@ func (m *RpcBlockDataviewCreateFromExistingObjectResponse) Unmarshal(dAtA []byte } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} - } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -221577,7 +225033,7 @@ func (m *RpcBlockDataviewCreateFromExistingObjectResponse) Unmarshal(dAtA []byte } return nil } -func (m *RpcBlockDataviewCreateFromExistingObjectResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewCreateBookmarkResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221620,7 +225076,7 @@ func (m *RpcBlockDataviewCreateFromExistingObjectResponseError) Unmarshal(dAtA [ } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewCreateFromExistingObjectResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewCreateBookmarkResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -221678,7 +225134,7 @@ func (m *RpcBlockDataviewCreateFromExistingObjectResponseError) Unmarshal(dAtA [ } return nil } -func (m *RpcBlockDataviewCreateBookmark) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilter) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221701,10 +225157,10 @@ func (m *RpcBlockDataviewCreateBookmark) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: CreateBookmark: wiretype end group for non-group") + return fmt.Errorf("proto: Filter: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: CreateBookmark: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Filter: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -221728,7 +225184,57 @@ func (m *RpcBlockDataviewCreateBookmark) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewCreateBookmarkRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterAdd) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Add: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockDataviewFilterAddRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221823,7 +225329,7 @@ func (m *RpcBlockDataviewCreateBookmarkRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -221851,13 +225357,13 @@ func (m *RpcBlockDataviewCreateBookmarkRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Url = string(dAtA[iNdEx:postIndex]) + m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -221867,23 +225373,27 @@ func (m *RpcBlockDataviewCreateBookmarkRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.SpaceId = string(dAtA[iNdEx:postIndex]) + if m.Filter == nil { + m.Filter = &model.BlockContentDataviewFilter{} + } + if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -221906,7 +225416,7 @@ func (m *RpcBlockDataviewCreateBookmarkRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewCreateBookmarkResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterAddResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -221965,7 +225475,7 @@ func (m *RpcBlockDataviewCreateBookmarkResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewCreateBookmarkResponseError{} + m.Error = &RpcBlockDataviewFilterAddResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -221973,9 +225483,9 @@ func (m *RpcBlockDataviewCreateBookmarkResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -221985,23 +225495,27 @@ func (m *RpcBlockDataviewCreateBookmarkResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Id = string(dAtA[iNdEx:postIndex]) + if m.Event == nil { + m.Event = &ResponseEvent{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -222024,7 +225538,7 @@ func (m *RpcBlockDataviewCreateBookmarkResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewCreateBookmarkResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterAddResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222067,7 +225581,7 @@ func (m *RpcBlockDataviewCreateBookmarkResponseError) Unmarshal(dAtA []byte) err } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewCreateBookmarkResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewFilterAddResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -222125,57 +225639,7 @@ func (m *RpcBlockDataviewCreateBookmarkResponseError) Unmarshal(dAtA []byte) err } return nil } -func (m *RpcBlockDataviewFilter) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Filter: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Filter: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockDataviewFilterAdd) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterRemove) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222198,10 +225662,10 @@ func (m *RpcBlockDataviewFilterAdd) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Add: wiretype end group for non-group") + return fmt.Errorf("proto: Remove: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Remove: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -222225,7 +225689,7 @@ func (m *RpcBlockDataviewFilterAdd) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterAddRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterRemoveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222352,9 +225816,9 @@ func (m *RpcBlockDataviewFilterAddRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -222364,27 +225828,23 @@ func (m *RpcBlockDataviewFilterAddRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Filter == nil { - m.Filter = &model.BlockContentDataviewFilter{} - } - if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -222407,7 +225867,7 @@ func (m *RpcBlockDataviewFilterAddRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterAddResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterRemoveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222466,7 +225926,7 @@ func (m *RpcBlockDataviewFilterAddResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewFilterAddResponseError{} + m.Error = &RpcBlockDataviewFilterRemoveResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -222529,7 +225989,7 @@ func (m *RpcBlockDataviewFilterAddResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterAddResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterRemoveResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222572,7 +226032,7 @@ func (m *RpcBlockDataviewFilterAddResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewFilterAddResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewFilterRemoveResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -222630,7 +226090,7 @@ func (m *RpcBlockDataviewFilterAddResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterRemove) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterReplace) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222653,10 +226113,10 @@ func (m *RpcBlockDataviewFilterRemove) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Remove: wiretype end group for non-group") + return fmt.Errorf("proto: Replace: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Remove: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Replace: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -222680,7 +226140,7 @@ func (m *RpcBlockDataviewFilterRemove) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterRemoveRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterReplaceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222807,7 +226267,7 @@ func (m *RpcBlockDataviewFilterRemoveRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -222835,7 +226295,43 @@ func (m *RpcBlockDataviewFilterRemoveRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) + m.Id = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Filter == nil { + m.Filter = &model.BlockContentDataviewFilter{} + } + if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -222858,7 +226354,7 @@ func (m *RpcBlockDataviewFilterRemoveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterRemoveResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterReplaceResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -222917,7 +226413,7 @@ func (m *RpcBlockDataviewFilterRemoveResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewFilterRemoveResponseError{} + m.Error = &RpcBlockDataviewFilterReplaceResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -222980,7 +226476,7 @@ func (m *RpcBlockDataviewFilterRemoveResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterRemoveResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterReplaceResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223023,7 +226519,7 @@ func (m *RpcBlockDataviewFilterRemoveResponseError) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewFilterRemoveResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewFilterReplaceResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -223081,7 +226577,7 @@ func (m *RpcBlockDataviewFilterRemoveResponseError) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewFilterReplace) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterSort) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223104,10 +226600,10 @@ func (m *RpcBlockDataviewFilterReplace) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Replace: wiretype end group for non-group") + return fmt.Errorf("proto: Sort: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Replace: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Sort: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -223131,7 +226627,7 @@ func (m *RpcBlockDataviewFilterReplace) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterReplaceRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterSortRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223258,7 +226754,7 @@ func (m *RpcBlockDataviewFilterReplaceRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -223286,43 +226782,7 @@ func (m *RpcBlockDataviewFilterReplaceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Filter", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Filter == nil { - m.Filter = &model.BlockContentDataviewFilter{} - } - if err := m.Filter.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -223345,7 +226805,7 @@ func (m *RpcBlockDataviewFilterReplaceRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterReplaceResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterSortResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223404,7 +226864,7 @@ func (m *RpcBlockDataviewFilterReplaceResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewFilterReplaceResponseError{} + m.Error = &RpcBlockDataviewFilterSortResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -223467,7 +226927,7 @@ func (m *RpcBlockDataviewFilterReplaceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterReplaceResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewFilterSortResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223510,7 +226970,7 @@ func (m *RpcBlockDataviewFilterReplaceResponseError) Unmarshal(dAtA []byte) erro } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewFilterReplaceResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewFilterSortResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -223568,7 +227028,7 @@ func (m *RpcBlockDataviewFilterReplaceResponseError) Unmarshal(dAtA []byte) erro } return nil } -func (m *RpcBlockDataviewFilterSort) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSort) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223618,7 +227078,57 @@ func (m *RpcBlockDataviewFilterSort) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterSortRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortAdd) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Add: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockDataviewSortAddRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223745,9 +227255,9 @@ func (m *RpcBlockDataviewFilterSortRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sort", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -223757,23 +227267,27 @@ func (m *RpcBlockDataviewFilterSortRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) + if m.Sort == nil { + m.Sort = &model.BlockContentDataviewSort{} + } + if err := m.Sort.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -223796,7 +227310,7 @@ func (m *RpcBlockDataviewFilterSortRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterSortResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortAddResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223855,7 +227369,7 @@ func (m *RpcBlockDataviewFilterSortResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewFilterSortResponseError{} + m.Error = &RpcBlockDataviewSortAddResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -223918,7 +227432,7 @@ func (m *RpcBlockDataviewFilterSortResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewFilterSortResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortAddResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -223961,7 +227475,7 @@ func (m *RpcBlockDataviewFilterSortResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewFilterSortResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewSortAddResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -224019,57 +227533,7 @@ func (m *RpcBlockDataviewFilterSortResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSort) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Sort: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Sort: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockDataviewSortAdd) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortRemove) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224092,10 +227556,10 @@ func (m *RpcBlockDataviewSortAdd) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Add: wiretype end group for non-group") + return fmt.Errorf("proto: Remove: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Remove: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -224119,7 +227583,7 @@ func (m *RpcBlockDataviewSortAdd) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortAddRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224246,9 +227710,9 @@ func (m *RpcBlockDataviewSortAddRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sort", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -224258,27 +227722,23 @@ func (m *RpcBlockDataviewSortAddRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Sort == nil { - m.Sort = &model.BlockContentDataviewSort{} - } - if err := m.Sort.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -224301,7 +227761,7 @@ func (m *RpcBlockDataviewSortAddRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortAddResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortRemoveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224360,7 +227820,7 @@ func (m *RpcBlockDataviewSortAddResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewSortAddResponseError{} + m.Error = &RpcBlockDataviewSortRemoveResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -224423,7 +227883,7 @@ func (m *RpcBlockDataviewSortAddResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortAddResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortRemoveResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224466,7 +227926,7 @@ func (m *RpcBlockDataviewSortAddResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewSortAddResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewSortRemoveResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -224524,7 +227984,7 @@ func (m *RpcBlockDataviewSortAddResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortRemove) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortReplace) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224547,10 +228007,10 @@ func (m *RpcBlockDataviewSortRemove) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Remove: wiretype end group for non-group") + return fmt.Errorf("proto: Replace: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Remove: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Replace: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -224574,7 +228034,7 @@ func (m *RpcBlockDataviewSortRemove) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortReplaceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224633,11 +228093,43 @@ func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ContextId = string(dAtA[iNdEx:postIndex]) + m.ContextId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -224665,11 +228157,11 @@ func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BlockId = string(dAtA[iNdEx:postIndex]) + m.ViewId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -224697,13 +228189,13 @@ func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ViewId = string(dAtA[iNdEx:postIndex]) + m.Id = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sort", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -224713,23 +228205,27 @@ func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) + if m.Sort == nil { + m.Sort = &model.BlockContentDataviewSort{} + } + if err := m.Sort.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -224752,7 +228248,7 @@ func (m *RpcBlockDataviewSortRemoveRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortRemoveResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortReplaceResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224811,7 +228307,7 @@ func (m *RpcBlockDataviewSortRemoveResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewSortRemoveResponseError{} + m.Error = &RpcBlockDataviewSortReplaceResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -224874,7 +228370,7 @@ func (m *RpcBlockDataviewSortRemoveResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortRemoveResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortReplaceResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224917,7 +228413,7 @@ func (m *RpcBlockDataviewSortRemoveResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewSortRemoveResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewSortReplaceResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -224975,7 +228471,7 @@ func (m *RpcBlockDataviewSortRemoveResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortReplace) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortSSort) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -224998,10 +228494,10 @@ func (m *RpcBlockDataviewSortReplace) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Replace: wiretype end group for non-group") + return fmt.Errorf("proto: SSort: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Replace: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SSort: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -225025,7 +228521,7 @@ func (m *RpcBlockDataviewSortReplace) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortReplaceRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortSSortRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225152,7 +228648,7 @@ func (m *RpcBlockDataviewSortReplaceRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -225180,43 +228676,7 @@ func (m *RpcBlockDataviewSortReplaceRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Id = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sort", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Sort == nil { - m.Sort = &model.BlockContentDataviewSort{} - } - if err := m.Sort.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -225239,7 +228699,7 @@ func (m *RpcBlockDataviewSortReplaceRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortReplaceResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortSSortResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225298,7 +228758,7 @@ func (m *RpcBlockDataviewSortReplaceResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewSortReplaceResponseError{} + m.Error = &RpcBlockDataviewSortSSortResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -225361,7 +228821,7 @@ func (m *RpcBlockDataviewSortReplaceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortReplaceResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewSortSSortResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225404,7 +228864,7 @@ func (m *RpcBlockDataviewSortReplaceResponseError) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewSortReplaceResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewSortSSortResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -225462,7 +228922,7 @@ func (m *RpcBlockDataviewSortReplaceResponseError) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewSortSSort) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelation) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225485,10 +228945,10 @@ func (m *RpcBlockDataviewSortSSort) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SSort: wiretype end group for non-group") + return fmt.Errorf("proto: ViewRelation: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SSort: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ViewRelation: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -225512,7 +228972,57 @@ func (m *RpcBlockDataviewSortSSort) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortSSortRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationAdd) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Add: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcBlockDataviewViewRelationAddRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225639,9 +229149,9 @@ func (m *RpcBlockDataviewSortSSortRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Relation", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -225651,23 +229161,27 @@ func (m *RpcBlockDataviewSortSSortRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Ids = append(m.Ids, string(dAtA[iNdEx:postIndex])) + if m.Relation == nil { + m.Relation = &model.BlockContentDataviewRelation{} + } + if err := m.Relation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -225690,7 +229204,7 @@ func (m *RpcBlockDataviewSortSSortRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortSSortResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationAddResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225749,7 +229263,7 @@ func (m *RpcBlockDataviewSortSSortResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewSortSSortResponseError{} + m.Error = &RpcBlockDataviewViewRelationAddResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -225812,7 +229326,7 @@ func (m *RpcBlockDataviewSortSSortResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewSortSSortResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationAddResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225855,7 +229369,7 @@ func (m *RpcBlockDataviewSortSSortResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewSortSSortResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewRelationAddResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -225913,57 +229427,7 @@ func (m *RpcBlockDataviewSortSSortResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelation) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ViewRelation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ViewRelation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcBlockDataviewViewRelationAdd) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationRemove) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -225986,10 +229450,10 @@ func (m *RpcBlockDataviewViewRelationAdd) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Add: wiretype end group for non-group") + return fmt.Errorf("proto: Remove: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Add: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Remove: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -226013,7 +229477,7 @@ func (m *RpcBlockDataviewViewRelationAdd) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationAddRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationRemoveRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226140,9 +229604,9 @@ func (m *RpcBlockDataviewViewRelationAddRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Relation", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RelationKeys", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -226152,27 +229616,23 @@ func (m *RpcBlockDataviewViewRelationAddRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Relation == nil { - m.Relation = &model.BlockContentDataviewRelation{} - } - if err := m.Relation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.RelationKeys = append(m.RelationKeys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -226195,7 +229655,7 @@ func (m *RpcBlockDataviewViewRelationAddRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationAddResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationRemoveResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226254,7 +229714,7 @@ func (m *RpcBlockDataviewViewRelationAddResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewRelationAddResponseError{} + m.Error = &RpcBlockDataviewViewRelationRemoveResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -226317,7 +229777,7 @@ func (m *RpcBlockDataviewViewRelationAddResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationAddResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationRemoveResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226360,7 +229820,7 @@ func (m *RpcBlockDataviewViewRelationAddResponseError) Unmarshal(dAtA []byte) er } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewRelationAddResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewRelationRemoveResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -226418,7 +229878,7 @@ func (m *RpcBlockDataviewViewRelationAddResponseError) Unmarshal(dAtA []byte) er } return nil } -func (m *RpcBlockDataviewViewRelationRemove) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationReplace) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226441,10 +229901,10 @@ func (m *RpcBlockDataviewViewRelationRemove) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Remove: wiretype end group for non-group") + return fmt.Errorf("proto: Replace: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Remove: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Replace: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -226468,7 +229928,7 @@ func (m *RpcBlockDataviewViewRelationRemove) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationRemoveRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationReplaceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226595,7 +230055,7 @@ func (m *RpcBlockDataviewViewRelationRemoveRequest) Unmarshal(dAtA []byte) error iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelationKeys", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RelationKey", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -226623,7 +230083,43 @@ func (m *RpcBlockDataviewViewRelationRemoveRequest) Unmarshal(dAtA []byte) error if postIndex > l { return io.ErrUnexpectedEOF } - m.RelationKeys = append(m.RelationKeys, string(dAtA[iNdEx:postIndex])) + m.RelationKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Relation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Relation == nil { + m.Relation = &model.BlockContentDataviewRelation{} + } + if err := m.Relation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -226646,7 +230142,7 @@ func (m *RpcBlockDataviewViewRelationRemoveRequest) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewViewRelationRemoveResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationReplaceResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226705,7 +230201,7 @@ func (m *RpcBlockDataviewViewRelationRemoveResponse) Unmarshal(dAtA []byte) erro return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewRelationRemoveResponseError{} + m.Error = &RpcBlockDataviewViewRelationReplaceResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -226768,7 +230264,7 @@ func (m *RpcBlockDataviewViewRelationRemoveResponse) Unmarshal(dAtA []byte) erro } return nil } -func (m *RpcBlockDataviewViewRelationRemoveResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationReplaceResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226811,7 +230307,7 @@ func (m *RpcBlockDataviewViewRelationRemoveResponseError) Unmarshal(dAtA []byte) } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewRelationRemoveResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewRelationReplaceResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -226869,7 +230365,7 @@ func (m *RpcBlockDataviewViewRelationRemoveResponseError) Unmarshal(dAtA []byte) } return nil } -func (m *RpcBlockDataviewViewRelationReplace) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationSort) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -226892,10 +230388,10 @@ func (m *RpcBlockDataviewViewRelationReplace) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Replace: wiretype end group for non-group") + return fmt.Errorf("proto: Sort: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Replace: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Sort: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -226919,7 +230415,7 @@ func (m *RpcBlockDataviewViewRelationReplace) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationReplaceRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationSortRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227046,7 +230542,7 @@ func (m *RpcBlockDataviewViewRelationReplaceRequest) Unmarshal(dAtA []byte) erro iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelationKey", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RelationKeys", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -227074,43 +230570,7 @@ func (m *RpcBlockDataviewViewRelationReplaceRequest) Unmarshal(dAtA []byte) erro if postIndex > l { return io.ErrUnexpectedEOF } - m.RelationKey = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Relation", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Relation == nil { - m.Relation = &model.BlockContentDataviewRelation{} - } - if err := m.Relation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.RelationKeys = append(m.RelationKeys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -227133,7 +230593,7 @@ func (m *RpcBlockDataviewViewRelationReplaceRequest) Unmarshal(dAtA []byte) erro } return nil } -func (m *RpcBlockDataviewViewRelationReplaceResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationSortResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227192,7 +230652,7 @@ func (m *RpcBlockDataviewViewRelationReplaceResponse) Unmarshal(dAtA []byte) err return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockDataviewViewRelationReplaceResponseError{} + m.Error = &RpcBlockDataviewViewRelationSortResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -227255,7 +230715,7 @@ func (m *RpcBlockDataviewViewRelationReplaceResponse) Unmarshal(dAtA []byte) err } return nil } -func (m *RpcBlockDataviewViewRelationReplaceResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockDataviewViewRelationSortResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227298,7 +230758,7 @@ func (m *RpcBlockDataviewViewRelationReplaceResponseError) Unmarshal(dAtA []byte } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewRelationReplaceResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockDataviewViewRelationSortResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -227356,7 +230816,7 @@ func (m *RpcBlockDataviewViewRelationReplaceResponseError) Unmarshal(dAtA []byte } return nil } -func (m *RpcBlockDataviewViewRelationSort) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidget) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227379,10 +230839,10 @@ func (m *RpcBlockDataviewViewRelationSort) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Sort: wiretype end group for non-group") + return fmt.Errorf("proto: BlockWidget: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Sort: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: BlockWidget: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -227406,7 +230866,7 @@ func (m *RpcBlockDataviewViewRelationSort) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationSortRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetTargetId) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227429,140 +230889,12 @@ func (m *RpcBlockDataviewViewRelationSortRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Request: wiretype end group for non-group") + return fmt.Errorf("proto: SetTargetId: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetTargetId: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ContextId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BlockId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ViewId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RelationKeys", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.RelationKeys = append(m.RelationKeys, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -227584,7 +230916,7 @@ func (m *RpcBlockDataviewViewRelationSortRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockDataviewViewRelationSortResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetTargetIdRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227607,17 +230939,17 @@ func (m *RpcBlockDataviewViewRelationSortResponse) Unmarshal(dAtA []byte) error fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") + return fmt.Errorf("proto: Request: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -227627,33 +230959,29 @@ func (m *RpcBlockDataviewViewRelationSortResponse) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcBlockDataviewViewRelationSortResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ContextId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -227663,27 +230991,55 @@ func (m *RpcBlockDataviewViewRelationSortResponse) Unmarshal(dAtA []byte) error } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} + m.BlockId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TargetId", wireType) } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TargetId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -227706,7 +231062,7 @@ func (m *RpcBlockDataviewViewRelationSortResponse) Unmarshal(dAtA []byte) error } return nil } -func (m *RpcBlockDataviewViewRelationSortResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetTargetIdResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227729,17 +231085,17 @@ func (m *RpcBlockDataviewViewRelationSortResponseError) Unmarshal(dAtA []byte) e fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Error: wiretype end group for non-group") + return fmt.Errorf("proto: Response: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - m.Code = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -227749,16 +231105,33 @@ func (m *RpcBlockDataviewViewRelationSortResponseError) Unmarshal(dAtA []byte) e } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockDataviewViewRelationSortResponseErrorCode(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &RpcBlockWidgetSetTargetIdResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -227768,23 +231141,27 @@ func (m *RpcBlockDataviewViewRelationSortResponseError) Unmarshal(dAtA []byte) e } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) + if m.Event == nil { + m.Event = &ResponseEvent{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -227807,7 +231184,7 @@ func (m *RpcBlockDataviewViewRelationSortResponseError) Unmarshal(dAtA []byte) e } return nil } -func (m *RpcBlockWidget) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetTargetIdResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227830,12 +231207,63 @@ func (m *RpcBlockWidget) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: BlockWidget: wiretype end group for non-group") + return fmt.Errorf("proto: Error: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: BlockWidget: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= RpcBlockWidgetSetTargetIdResponseErrorCode(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -227857,7 +231285,7 @@ func (m *RpcBlockWidget) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetTargetId) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLayout) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -227880,10 +231308,10 @@ func (m *RpcBlockWidgetSetTargetId) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetTargetId: wiretype end group for non-group") + return fmt.Errorf("proto: SetLayout: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetTargetId: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetLayout: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -227907,7 +231335,7 @@ func (m *RpcBlockWidgetSetTargetId) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetTargetIdRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLayoutRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228001,10 +231429,10 @@ func (m *RpcBlockWidgetSetTargetIdRequest) Unmarshal(dAtA []byte) error { m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Layout", wireType) } - var stringLen uint64 + m.Layout = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -228014,24 +231442,11 @@ func (m *RpcBlockWidgetSetTargetIdRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Layout |= model.BlockContentWidgetLayout(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TargetId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -228053,7 +231468,7 @@ func (m *RpcBlockWidgetSetTargetIdRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetTargetIdResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLayoutResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228112,7 +231527,7 @@ func (m *RpcBlockWidgetSetTargetIdResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockWidgetSetTargetIdResponseError{} + m.Error = &RpcBlockWidgetSetLayoutResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -228175,7 +231590,7 @@ func (m *RpcBlockWidgetSetTargetIdResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetTargetIdResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLayoutResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228218,7 +231633,7 @@ func (m *RpcBlockWidgetSetTargetIdResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockWidgetSetTargetIdResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockWidgetSetLayoutResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -228276,7 +231691,7 @@ func (m *RpcBlockWidgetSetTargetIdResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLayout) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLimit) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228299,10 +231714,10 @@ func (m *RpcBlockWidgetSetLayout) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetLayout: wiretype end group for non-group") + return fmt.Errorf("proto: SetLimit: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetLayout: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetLimit: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -228326,7 +231741,7 @@ func (m *RpcBlockWidgetSetLayout) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLayoutRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLimitRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228421,9 +231836,9 @@ func (m *RpcBlockWidgetSetLayoutRequest) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Layout", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) } - m.Layout = 0 + m.Limit = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -228433,7 +231848,7 @@ func (m *RpcBlockWidgetSetLayoutRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Layout |= model.BlockContentWidgetLayout(b&0x7F) << shift + m.Limit |= int32(b&0x7F) << shift if b < 0x80 { break } @@ -228459,7 +231874,7 @@ func (m *RpcBlockWidgetSetLayoutRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLayoutResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLimitResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228518,7 +231933,7 @@ func (m *RpcBlockWidgetSetLayoutResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockWidgetSetLayoutResponseError{} + m.Error = &RpcBlockWidgetSetLimitResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -228581,7 +231996,7 @@ func (m *RpcBlockWidgetSetLayoutResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLayoutResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetLimitResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228624,7 +232039,7 @@ func (m *RpcBlockWidgetSetLayoutResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockWidgetSetLayoutResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockWidgetSetLimitResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -228682,7 +232097,7 @@ func (m *RpcBlockWidgetSetLayoutResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLimit) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetViewId) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228705,10 +232120,10 @@ func (m *RpcBlockWidgetSetLimit) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetLimit: wiretype end group for non-group") + return fmt.Errorf("proto: SetViewId: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetLimit: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SetViewId: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -228732,7 +232147,7 @@ func (m *RpcBlockWidgetSetLimit) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLimitRequest) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetViewIdRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228826,10 +232241,10 @@ func (m *RpcBlockWidgetSetLimitRequest) Unmarshal(dAtA []byte) error { m.BlockId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) } - m.Limit = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -228839,11 +232254,24 @@ func (m *RpcBlockWidgetSetLimitRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Limit |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ViewId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -228865,7 +232293,7 @@ func (m *RpcBlockWidgetSetLimitRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLimitResponse) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetViewIdResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -228924,7 +232352,7 @@ func (m *RpcBlockWidgetSetLimitResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcBlockWidgetSetLimitResponseError{} + m.Error = &RpcBlockWidgetSetViewIdResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -228987,7 +232415,7 @@ func (m *RpcBlockWidgetSetLimitResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetLimitResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcBlockWidgetSetViewIdResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229030,7 +232458,7 @@ func (m *RpcBlockWidgetSetLimitResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockWidgetSetLimitResponseErrorCode(b&0x7F) << shift + m.Code |= RpcBlockWidgetSetViewIdResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -229088,7 +232516,7 @@ func (m *RpcBlockWidgetSetLimitResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetViewId) Unmarshal(dAtA []byte) error { +func (m *RpcDebug) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229111,10 +232539,10 @@ func (m *RpcBlockWidgetSetViewId) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SetViewId: wiretype end group for non-group") + return fmt.Errorf("proto: Debug: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SetViewId: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Debug: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -229138,7 +232566,7 @@ func (m *RpcBlockWidgetSetViewId) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetViewIdRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229161,15 +232589,15 @@ func (m *RpcBlockWidgetSetViewIdRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Request: wiretype end group for non-group") + return fmt.Errorf("proto: TreeInfo: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: TreeInfo: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ContextId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -229197,43 +232625,11 @@ func (m *RpcBlockWidgetSetViewIdRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ContextId = string(dAtA[iNdEx:postIndex]) + m.TreeId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BlockId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ViewId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field HeadIds", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -229261,7 +232657,7 @@ func (m *RpcBlockWidgetSetViewIdRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ViewId = string(dAtA[iNdEx:postIndex]) + m.HeadIds = append(m.HeadIds, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -229284,7 +232680,7 @@ func (m *RpcBlockWidgetSetViewIdRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetViewIdResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStat) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229307,84 +232703,62 @@ func (m *RpcBlockWidgetSetViewIdResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") + return fmt.Errorf("proto: Stat: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Stat: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + msglen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthCommands } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcBlockWidgetSetViewIdResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcDebugStatRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands } - if postIndex > l { + if iNdEx >= l { return io.ErrUnexpectedEOF } - if m.Event == nil { - m.Event = &ResponseEvent{} - } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - iNdEx = postIndex + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Request: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -229406,7 +232780,7 @@ func (m *RpcBlockWidgetSetViewIdResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcBlockWidgetSetViewIdResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStatResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229429,17 +232803,17 @@ func (m *RpcBlockWidgetSetViewIdResponseError) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Error: wiretype end group for non-group") + return fmt.Errorf("proto: Response: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - m.Code = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -229449,14 +232823,31 @@ func (m *RpcBlockWidgetSetViewIdResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcBlockWidgetSetViewIdResponseErrorCode(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &RpcDebugStatResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field JsonStat", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -229484,7 +232875,7 @@ func (m *RpcBlockWidgetSetViewIdResponseError) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) + m.JsonStat = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -229507,57 +232898,7 @@ func (m *RpcBlockWidgetSetViewIdResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebug) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Debug: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Debug: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipCommands(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCommands - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RpcDebugTreeInfo) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStatResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229580,17 +232921,17 @@ func (m *RpcDebugTreeInfo) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: TreeInfo: wiretype end group for non-group") + return fmt.Errorf("proto: Error: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: TreeInfo: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) } - var stringLen uint64 + m.Code = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -229600,27 +232941,14 @@ func (m *RpcDebugTreeInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Code |= RpcDebugStatResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TreeId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field HeadIds", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -229648,7 +232976,7 @@ func (m *RpcDebugTreeInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.HeadIds = append(m.HeadIds, string(dAtA[iNdEx:postIndex])) + m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -229671,7 +232999,7 @@ func (m *RpcDebugTreeInfo) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStat) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeHeads) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229694,10 +233022,10 @@ func (m *RpcDebugStat) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Stat: wiretype end group for non-group") + return fmt.Errorf("proto: TreeHeads: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Stat: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: TreeHeads: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -229721,7 +233049,7 @@ func (m *RpcDebugStat) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStatRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeHeadsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229750,6 +233078,38 @@ func (m *RpcDebugStatRequest) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TreeId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -229771,7 +233131,7 @@ func (m *RpcDebugStatRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStatResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeHeadsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229830,7 +233190,7 @@ func (m *RpcDebugStatResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugStatResponseError{} + m.Error = &RpcDebugTreeHeadsResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -229838,7 +233198,7 @@ func (m *RpcDebugStatResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field JsonStat", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -229866,7 +233226,43 @@ func (m *RpcDebugStatResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.JsonStat = string(dAtA[iNdEx:postIndex]) + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Info == nil { + m.Info = &RpcDebugTreeInfo{} + } + if err := m.Info.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -229889,7 +233285,7 @@ func (m *RpcDebugStatResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStatResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeHeadsResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -229932,7 +233328,7 @@ func (m *RpcDebugStatResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugStatResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugTreeHeadsResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -229990,7 +233386,7 @@ func (m *RpcDebugStatResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeHeads) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTree) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230013,10 +233409,10 @@ func (m *RpcDebugTreeHeads) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: TreeHeads: wiretype end group for non-group") + return fmt.Errorf("proto: Tree: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: TreeHeads: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Tree: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -230040,7 +233436,7 @@ func (m *RpcDebugTreeHeads) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeHeadsRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230101,6 +233497,78 @@ func (m *RpcDebugTreeHeadsRequest) Unmarshal(dAtA []byte) error { } m.TreeId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Unanonymized", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Unanonymized = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GenerateSvg", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.GenerateSvg = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -230122,7 +233590,7 @@ func (m *RpcDebugTreeHeadsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeHeadsResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230180,81 +233648,45 @@ func (m *RpcDebugTreeHeadsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcDebugTreeHeadsResponseError{} - } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Info == nil { - m.Info = &RpcDebugTreeInfo{} + if m.Error == nil { + m.Error = &RpcDebugTreeResponseError{} } - if err := m.Info.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Filename", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Filename = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -230276,7 +233708,7 @@ func (m *RpcDebugTreeHeadsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeHeadsResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugTreeResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230319,7 +233751,7 @@ func (m *RpcDebugTreeHeadsResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugTreeHeadsResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugTreeResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -230377,7 +233809,7 @@ func (m *RpcDebugTreeHeadsResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTree) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSpaceSummary) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230400,10 +233832,10 @@ func (m *RpcDebugTree) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Tree: wiretype end group for non-group") + return fmt.Errorf("proto: SpaceSummary: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Tree: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SpaceSummary: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -230427,7 +233859,7 @@ func (m *RpcDebugTree) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSpaceSummaryRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230458,39 +233890,7 @@ func (m *RpcDebugTreeRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TreeId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.TreeId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -230518,48 +233918,8 @@ func (m *RpcDebugTreeRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) + m.SpaceId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Unanonymized", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.Unanonymized = bool(v != 0) - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field GenerateSvg", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.GenerateSvg = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -230581,7 +233941,7 @@ func (m *RpcDebugTreeRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSpaceSummaryResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230640,7 +234000,7 @@ func (m *RpcDebugTreeResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugTreeResponseError{} + m.Error = &RpcDebugSpaceSummaryResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -230648,7 +234008,7 @@ func (m *RpcDebugTreeResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Filename", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -230676,7 +234036,41 @@ func (m *RpcDebugTreeResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Filename = string(dAtA[iNdEx:postIndex]) + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Infos", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Infos = append(m.Infos, &RpcDebugTreeInfo{}) + if err := m.Infos[len(m.Infos)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex default: iNdEx = preIndex @@ -230699,7 +234093,7 @@ func (m *RpcDebugTreeResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugTreeResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSpaceSummaryResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230742,7 +234136,7 @@ func (m *RpcDebugTreeResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugTreeResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugSpaceSummaryResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -230800,7 +234194,7 @@ func (m *RpcDebugTreeResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSpaceSummary) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStackGoroutines) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230823,10 +234217,10 @@ func (m *RpcDebugSpaceSummary) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: SpaceSummary: wiretype end group for non-group") + return fmt.Errorf("proto: StackGoroutines: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: SpaceSummary: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: StackGoroutines: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -230850,7 +234244,7 @@ func (m *RpcDebugSpaceSummary) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSpaceSummaryRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStackGoroutinesRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230881,7 +234275,7 @@ func (m *RpcDebugSpaceSummaryRequest) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -230909,7 +234303,7 @@ func (m *RpcDebugSpaceSummaryRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.SpaceId = string(dAtA[iNdEx:postIndex]) + m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -230932,7 +234326,7 @@ func (m *RpcDebugSpaceSummaryRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSpaceSummaryResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStackGoroutinesResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -230991,78 +234385,12 @@ func (m *RpcDebugSpaceSummaryResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugSpaceSummaryResponseError{} + m.Error = &RpcDebugStackGoroutinesResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Infos", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Infos = append(m.Infos, &RpcDebugTreeInfo{}) - if err := m.Infos[len(m.Infos)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -231084,7 +234412,7 @@ func (m *RpcDebugSpaceSummaryResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSpaceSummaryResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugStackGoroutinesResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231127,7 +234455,7 @@ func (m *RpcDebugSpaceSummaryResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugSpaceSummaryResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugStackGoroutinesResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -231185,7 +234513,7 @@ func (m *RpcDebugSpaceSummaryResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStackGoroutines) Unmarshal(dAtA []byte) error { +func (m *RpcDebugExportLocalstore) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231208,10 +234536,10 @@ func (m *RpcDebugStackGoroutines) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: StackGoroutines: wiretype end group for non-group") + return fmt.Errorf("proto: ExportLocalstore: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: StackGoroutines: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: ExportLocalstore: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -231235,7 +234563,7 @@ func (m *RpcDebugStackGoroutines) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStackGoroutinesRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugExportLocalstoreRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231296,6 +234624,70 @@ func (m *RpcDebugStackGoroutinesRequest) Unmarshal(dAtA []byte) error { } m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DocIds", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DocIds = append(m.DocIds, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SpaceId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -231317,7 +234709,7 @@ func (m *RpcDebugStackGoroutinesRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStackGoroutinesResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugExportLocalstoreResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231376,12 +234768,80 @@ func (m *RpcDebugStackGoroutinesResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugStackGoroutinesResponseError{} + m.Error = &RpcDebugExportLocalstoreResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Event == nil { + m.Event = &ResponseEvent{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -231403,7 +234863,7 @@ func (m *RpcDebugStackGoroutinesResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugStackGoroutinesResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugExportLocalstoreResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231446,7 +234906,7 @@ func (m *RpcDebugStackGoroutinesResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugStackGoroutinesResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugExportLocalstoreResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -231504,7 +234964,7 @@ func (m *RpcDebugStackGoroutinesResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugExportLocalstore) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSubscriptions) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231527,10 +234987,10 @@ func (m *RpcDebugExportLocalstore) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: ExportLocalstore: wiretype end group for non-group") + return fmt.Errorf("proto: Subscriptions: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: ExportLocalstore: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Subscriptions: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -231554,7 +235014,7 @@ func (m *RpcDebugExportLocalstore) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugExportLocalstoreRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSubscriptionsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231583,102 +235043,6 @@ func (m *RpcDebugExportLocalstoreRequest) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DocIds", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.DocIds = append(m.DocIds, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SpaceId", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SpaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -231700,7 +235064,7 @@ func (m *RpcDebugExportLocalstoreRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugExportLocalstoreResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSubscriptionsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231759,7 +235123,7 @@ func (m *RpcDebugExportLocalstoreResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugExportLocalstoreResponseError{} + m.Error = &RpcDebugSubscriptionsResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -231767,7 +235131,7 @@ func (m *RpcDebugExportLocalstoreResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Subscriptions", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -231795,43 +235159,7 @@ func (m *RpcDebugExportLocalstoreResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Path = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCommands - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Event == nil { - m.Event = &ResponseEvent{} - } - if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Subscriptions = append(m.Subscriptions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -231854,7 +235182,7 @@ func (m *RpcDebugExportLocalstoreResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugExportLocalstoreResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugSubscriptionsResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231897,7 +235225,7 @@ func (m *RpcDebugExportLocalstoreResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugExportLocalstoreResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugSubscriptionsResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -231955,7 +235283,7 @@ func (m *RpcDebugExportLocalstoreResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSubscriptions) Unmarshal(dAtA []byte) error { +func (m *RpcDebugOpenedObjects) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -231978,10 +235306,10 @@ func (m *RpcDebugSubscriptions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Subscriptions: wiretype end group for non-group") + return fmt.Errorf("proto: OpenedObjects: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Subscriptions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: OpenedObjects: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -232005,7 +235333,7 @@ func (m *RpcDebugSubscriptions) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSubscriptionsRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugOpenedObjectsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232055,7 +235383,7 @@ func (m *RpcDebugSubscriptionsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSubscriptionsResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugOpenedObjectsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232114,7 +235442,7 @@ func (m *RpcDebugSubscriptionsResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugSubscriptionsResponseError{} + m.Error = &RpcDebugOpenedObjectsResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -232122,7 +235450,7 @@ func (m *RpcDebugSubscriptionsResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subscriptions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ObjectIDs", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -232150,7 +235478,7 @@ func (m *RpcDebugSubscriptionsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Subscriptions = append(m.Subscriptions, string(dAtA[iNdEx:postIndex])) + m.ObjectIDs = append(m.ObjectIDs, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex @@ -232173,7 +235501,7 @@ func (m *RpcDebugSubscriptionsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugSubscriptionsResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugOpenedObjectsResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232216,7 +235544,7 @@ func (m *RpcDebugSubscriptionsResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugSubscriptionsResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugOpenedObjectsResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -232274,7 +235602,7 @@ func (m *RpcDebugSubscriptionsResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugOpenedObjects) Unmarshal(dAtA []byte) error { +func (m *RpcDebugRunProfiler) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232297,10 +235625,10 @@ func (m *RpcDebugOpenedObjects) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: OpenedObjects: wiretype end group for non-group") + return fmt.Errorf("proto: RunProfiler: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: OpenedObjects: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: RunProfiler: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -232324,7 +235652,7 @@ func (m *RpcDebugOpenedObjects) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugOpenedObjectsRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugRunProfilerRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232353,6 +235681,25 @@ func (m *RpcDebugOpenedObjectsRequest) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DurationInSeconds", wireType) + } + m.DurationInSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DurationInSeconds |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -232374,7 +235721,7 @@ func (m *RpcDebugOpenedObjectsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugOpenedObjectsResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugRunProfilerResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232433,7 +235780,7 @@ func (m *RpcDebugOpenedObjectsResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugOpenedObjectsResponseError{} + m.Error = &RpcDebugRunProfilerResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -232441,7 +235788,7 @@ func (m *RpcDebugOpenedObjectsResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ObjectIDs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -232469,7 +235816,7 @@ func (m *RpcDebugOpenedObjectsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ObjectIDs = append(m.ObjectIDs, string(dAtA[iNdEx:postIndex])) + m.Path = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -232492,7 +235839,7 @@ func (m *RpcDebugOpenedObjectsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugOpenedObjectsResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugRunProfilerResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232535,7 +235882,7 @@ func (m *RpcDebugOpenedObjectsResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugOpenedObjectsResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugRunProfilerResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -232593,7 +235940,7 @@ func (m *RpcDebugOpenedObjectsResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugRunProfiler) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAccountSelectTrace) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232616,10 +235963,10 @@ func (m *RpcDebugRunProfiler) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RunProfiler: wiretype end group for non-group") + return fmt.Errorf("proto: AccountSelectTrace: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RunProfiler: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AccountSelectTrace: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -232643,7 +235990,7 @@ func (m *RpcDebugRunProfiler) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugRunProfilerRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAccountSelectTraceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232673,10 +236020,10 @@ func (m *RpcDebugRunProfilerRequest) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DurationInSeconds", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dir", wireType) } - m.DurationInSeconds = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -232686,11 +236033,24 @@ func (m *RpcDebugRunProfilerRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.DurationInSeconds |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Dir = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -232712,7 +236072,7 @@ func (m *RpcDebugRunProfilerRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugRunProfilerResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAccountSelectTraceResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232771,7 +236131,7 @@ func (m *RpcDebugRunProfilerResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugRunProfilerResponseError{} + m.Error = &RpcDebugAccountSelectTraceResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -232830,7 +236190,7 @@ func (m *RpcDebugRunProfilerResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugRunProfilerResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAccountSelectTraceResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232873,7 +236233,7 @@ func (m *RpcDebugRunProfilerResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugRunProfilerResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugAccountSelectTraceResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -232931,7 +236291,7 @@ func (m *RpcDebugRunProfilerResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugAccountSelectTrace) Unmarshal(dAtA []byte) error { +func (m *RpcDebugPing) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -232954,10 +236314,10 @@ func (m *RpcDebugAccountSelectTrace) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: AccountSelectTrace: wiretype end group for non-group") + return fmt.Errorf("proto: Ping: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: AccountSelectTrace: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Ping: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -232981,7 +236341,7 @@ func (m *RpcDebugAccountSelectTrace) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugAccountSelectTraceRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugPingRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233011,10 +236371,10 @@ func (m *RpcDebugAccountSelectTraceRequest) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Dir", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) } - var stringLen uint64 + m.Index = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -233024,24 +236384,30 @@ func (m *RpcDebugAccountSelectTraceRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Index |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumberOfEventsToSend", wireType) } - if postIndex > l { - return io.ErrUnexpectedEOF + m.NumberOfEventsToSend = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumberOfEventsToSend |= int32(b&0x7F) << shift + if b < 0x80 { + break + } } - m.Dir = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -233063,7 +236429,7 @@ func (m *RpcDebugAccountSelectTraceRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugAccountSelectTraceResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugPingResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233122,17 +236488,17 @@ func (m *RpcDebugAccountSelectTraceResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Error == nil { - m.Error = &RpcDebugAccountSelectTraceResponseError{} + m.Error = &RpcDebugPingResponseError{} } if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) } - var stringLen uint64 + m.Index = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -233142,24 +236508,11 @@ func (m *RpcDebugAccountSelectTraceResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Index |= int32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthCommands - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthCommands - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Path = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -233181,7 +236534,7 @@ func (m *RpcDebugAccountSelectTraceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugAccountSelectTraceResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugPingResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233224,7 +236577,7 @@ func (m *RpcDebugAccountSelectTraceResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugAccountSelectTraceResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugPingResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -233282,7 +236635,57 @@ func (m *RpcDebugAccountSelectTraceResponseError) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugPing) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAnystoreObjectChanges) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AnystoreObjectChanges: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AnystoreObjectChanges: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipCommands(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthCommands + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RpcDebugAnystoreObjectChangesRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233305,12 +236708,63 @@ func (m *RpcDebugPing) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Ping: wiretype end group for non-group") + return fmt.Errorf("proto: Request: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Ping: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ObjectId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderBy", wireType) + } + m.OrderBy = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OrderBy |= RpcDebugAnystoreObjectChangesRequestOrderBy(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -233332,7 +236786,7 @@ func (m *RpcDebugPing) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugPingRequest) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAnystoreObjectChangesResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233355,17 +236809,17 @@ func (m *RpcDebugPingRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Request: wiretype end group for non-group") + return fmt.Errorf("proto: Response: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - m.Index = 0 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -233375,16 +236829,67 @@ func (m *RpcDebugPingRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Index |= int32(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &RpcDebugAnystoreObjectChangesResponseError{} + } + if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Changes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Changes = append(m.Changes, &RpcDebugAnystoreObjectChangesResponseChange{}) + if err := m.Changes[len(m.Changes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field NumberOfEventsToSend", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field WrongOrder", wireType) } - m.NumberOfEventsToSend = 0 + var v int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -233394,11 +236899,12 @@ func (m *RpcDebugPingRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.NumberOfEventsToSend |= int32(b&0x7F) << shift + v |= int(b&0x7F) << shift if b < 0x80 { break } } + m.WrongOrder = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -233420,7 +236926,7 @@ func (m *RpcDebugPingRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugPingResponse) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAnystoreObjectChangesResponseChange) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233443,17 +236949,17 @@ func (m *RpcDebugPingResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Response: wiretype end group for non-group") + return fmt.Errorf("proto: Change: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Response: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Change: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ChangeId", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -233463,33 +236969,61 @@ func (m *RpcDebugPingResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthCommands } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthCommands } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Error == nil { - m.Error = &RpcDebugPingResponseError{} + m.ChangeId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderId", wireType) } - if err := m.Error.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF } + m.OrderId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) } - m.Index = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowCommands @@ -233499,11 +237033,60 @@ func (m *RpcDebugPingResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Index |= int32(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Change", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } + if msglen < 0 { + return ErrInvalidLengthCommands + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthCommands + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Change == nil { + m.Change = &types.Struct{} + } + if err := m.Change.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) @@ -233525,7 +237108,7 @@ func (m *RpcDebugPingResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *RpcDebugPingResponseError) Unmarshal(dAtA []byte) error { +func (m *RpcDebugAnystoreObjectChangesResponseError) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -233568,7 +237151,7 @@ func (m *RpcDebugPingResponseError) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Code |= RpcDebugPingResponseErrorCode(b&0x7F) << shift + m.Code |= RpcDebugAnystoreObjectChangesResponseErrorCode(b&0x7F) << shift if b < 0x80 { break } @@ -238358,6 +241941,46 @@ func (m *RpcMembershipGetVerificationEmailRequest) Unmarshal(dAtA []byte) error } } m.SubscribeToNewsletter = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InsiderTipsAndTutorials", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.InsiderTipsAndTutorials = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsOnboardingList", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCommands + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsOnboardingList = bool(v != 0) default: iNdEx = preIndex skippy, err := skipCommands(dAtA[iNdEx:]) diff --git a/pb/protos/changes.proto b/pb/protos/changes.proto index 07a9318ac2..11f3c8bb51 100644 --- a/pb/protos/changes.proto +++ b/pb/protos/changes.proto @@ -180,3 +180,52 @@ message Change { string name = 2; } } + + +message StoreChange { + repeated StoreChangeContent changeSet = 1; +} + +message StoreChangeContent { + oneof change { + DocumentCreate create = 1; + DocumentModify modify = 2; + DocumentDelete delete = 3; + } +} + +message DocumentCreate { + string collection = 1; + string documentId = 2; + // json + string value = 3; +} + +message DocumentModify { + string collection = 1; + string documentId = 2; + repeated KeyModify keys = 4; +} + +message KeyModify { + // key path; example: [user, email] + repeated string keyPath = 1; + // modify op: set, unset, inc, etc. + ModifyOp modifyOp = 3; + // json value; example: '"new@email.com"' + string modifyValue = 4; +} + +enum ModifyOp { + Set = 0; + Unset = 1; + Inc = 2; + AddToSet = 3; + Pull = 4; +} + +message DocumentDelete { + string collection = 1; + string documentId = 2; +} + diff --git a/pb/protos/commands.proto b/pb/protos/commands.proto index 105b5104be..015cdfe07a 100644 --- a/pb/protos/commands.proto +++ b/pb/protos/commands.proto @@ -1413,6 +1413,7 @@ message Rpc { string templateId = 3; string spaceId = 4; string objectTypeUniqueKey = 5; + bool withChat = 6; } message Response { @@ -1439,6 +1440,7 @@ message Rpc { message Request { google.protobuf.Struct details = 1; string spaceId = 2; + bool withChat = 3; } message Response { @@ -1516,6 +1518,7 @@ message Rpc { string templateId = 3; // optional template id for creating from template repeated anytype.model.InternalFlag internalFlags = 4; string spaceId = 5; + bool withChat = 6; } message Response { @@ -1571,12 +1574,14 @@ message Rpc { string url = 3; google.protobuf.Struct details = 4; bool addPageContent = 5; + bool withChat = 6; } message Response { Error error = 1; string objectId = 2; google.protobuf.Struct details = 3; + string chatId = 4; message Error { Code code = 1; @@ -1604,6 +1609,7 @@ message Rpc { message Error { Code code = 1; string description = 2; + enum Code { NULL = 0; UNKNOWN_ERROR = 1; @@ -1762,6 +1768,7 @@ message Rpc { // deprecated in favor of SearchWithMeta message Search { message Request { + string spaceId = 8; repeated anytype.model.Block.Content.Dataview.Filter filters = 1; repeated anytype.model.Block.Content.Dataview.Sort sorts = 2; string fullText = 3; @@ -1790,6 +1797,7 @@ message Rpc { } message SearchWithMeta { message Request { + string spaceId = 11; repeated anytype.model.Block.Content.Dataview.Filter filters = 1; repeated anytype.model.Block.Content.Dataview.Sort sorts = 2; string fullText = 3; @@ -1868,6 +1876,7 @@ message Rpc { message SearchSubscribe { message Request { + string spaceId = 15; // (optional) subscription identifier // client can provide some string or middleware will generate it automatically // if subId is already registered on middleware, the new query will replace previous subscription @@ -1890,7 +1899,6 @@ message Rpc { repeated string source = 10; - string ignoreWorkspace = 12; // disable dependent subscription bool noDepSubscription = 13; string collectionId = 14; @@ -1920,6 +1928,72 @@ message Rpc { } } + message CrossSpaceSearchSubscribe { + message Request { + // (optional) subscription identifier + // client can provide some string or middleware will generate it automatically + // if subId is already registered on middleware, the new query will replace previous subscription + string subId = 1; + // filters + repeated anytype.model.Block.Content.Dataview.Filter filters = 2; + // sorts + repeated anytype.model.Block.Content.Dataview.Sort sorts = 3; + // (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent + repeated string keys = 7; + + repeated string source = 10; + + // disable dependent subscription + bool noDepSubscription = 13; + string collectionId = 14; + } + + message Response { + Error error = 1; + + repeated google.protobuf.Struct records = 2; + repeated google.protobuf.Struct dependencies = 3; + + string subId = 4; + + Event.Object.Subscription.Counters counters = 5; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + } + } + } + } + + message CrossSpaceSearchUnsubscribe { + message Request { + string subId = 1; + } + + message Response { + Error error = 1; + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + // ... + } + } + } + } + message GroupsSubscribe { message Request { string spaceId = 6; @@ -1952,6 +2026,7 @@ message Rpc { message SubscribeIds { message Request { + string spaceId = 13; // (optional) subscription identifier // client can provide some string or middleware will generate it automatically // if subId is already registered on middleware, the new query will replace previous subscription @@ -1962,7 +2037,6 @@ message Rpc { // (required) needed keys in details for return, for object fields mw will return (and subscribe) objects as dependent repeated string keys = 3; - string ignoreWorkspace = 11; // disable dependent subscription bool noDepSubscription = 12; } @@ -6471,6 +6545,42 @@ message Rpc { } } } + + message AnystoreObjectChanges { + message Request { + string objectId = 1; + OrderBy orderBy = 2; + + enum OrderBy { + ORDER_ID = 0; + ITERATION_ORDER = 1; + } + } + + message Response { + Error error = 1; + repeated Change changes = 2; + bool wrongOrder = 3; + + message Change { + string changeId = 1; + string orderId = 2; + string error = 3; + google.protobuf.Struct change = 4; + } + + message Error { + Code code = 1; + string description = 2; + + enum Code { + NULL = 0; + UNKNOWN_ERROR = 1; + BAD_INPUT = 2; + } + } + } + } } message Metrics { @@ -6894,6 +7004,11 @@ message Rpc { string email = 1; bool subscribeToNewsletter = 2; + + bool insiderTipsAndTutorials = 3; + + // if we are coming from the onboarding list + bool isOnboardingList = 4; } message Response { diff --git a/pb/protos/service/service.proto b/pb/protos/service/service.proto index c8453dc185..1f74aedca9 100644 --- a/pb/protos/service/service.proto +++ b/pb/protos/service/service.proto @@ -73,7 +73,6 @@ service ClientCommands { rpc ObjectCreate (anytype.Rpc.Object.Create.Request) returns (anytype.Rpc.Object.Create.Response); rpc ObjectCreateBookmark (anytype.Rpc.Object.CreateBookmark.Request) returns (anytype.Rpc.Object.CreateBookmark.Response); rpc ObjectCreateFromUrl (anytype.Rpc.Object.CreateFromUrl.Request) returns (anytype.Rpc.Object.CreateFromUrl.Response); - rpc ObjectChatAdd (anytype.Rpc.Object.ChatAdd.Request) returns (anytype.Rpc.Object.ChatAdd.Response); // ObjectCreateSet just creates the new set, without adding the link to it from some other page rpc ObjectCreateSet (anytype.Rpc.Object.CreateSet.Request) returns (anytype.Rpc.Object.CreateSet.Response); @@ -81,6 +80,8 @@ service ClientCommands { rpc ObjectSearch (anytype.Rpc.Object.Search.Request) returns (anytype.Rpc.Object.Search.Response); rpc ObjectSearchWithMeta (anytype.Rpc.Object.SearchWithMeta.Request) returns (anytype.Rpc.Object.SearchWithMeta.Response); rpc ObjectSearchSubscribe (anytype.Rpc.Object.SearchSubscribe.Request) returns (anytype.Rpc.Object.SearchSubscribe.Response); + rpc ObjectCrossSpaceSearchSubscribe (anytype.Rpc.Object.CrossSpaceSearchSubscribe.Request) returns (anytype.Rpc.Object.CrossSpaceSearchSubscribe.Response); + rpc ObjectCrossSpaceSearchUnsubscribe (anytype.Rpc.Object.CrossSpaceSearchUnsubscribe.Request) returns (anytype.Rpc.Object.CrossSpaceSearchUnsubscribe.Response); rpc ObjectSubscribeIds (anytype.Rpc.Object.SubscribeIds.Request) returns (anytype.Rpc.Object.SubscribeIds.Response); rpc ObjectGroupsSubscribe (anytype.Rpc.Object.GroupsSubscribe.Request) returns (anytype.Rpc.Object.GroupsSubscribe.Response); rpc ObjectSearchUnsubscribe (anytype.Rpc.Object.SearchUnsubscribe.Request) returns (anytype.Rpc.Object.SearchUnsubscribe.Response); @@ -309,6 +310,7 @@ service ClientCommands { rpc DebugOpenedObjects (anytype.Rpc.Debug.OpenedObjects.Request) returns (anytype.Rpc.Debug.OpenedObjects.Response); rpc DebugRunProfiler (anytype.Rpc.Debug.RunProfiler.Request) returns (anytype.Rpc.Debug.RunProfiler.Response); rpc DebugAccountSelectTrace (anytype.Rpc.Debug.AccountSelectTrace.Request) returns (anytype.Rpc.Debug.AccountSelectTrace.Response); + rpc DebugAnystoreObjectChanges (anytype.Rpc.Debug.AnystoreObjectChanges.Request) returns (anytype.Rpc.Debug.AnystoreObjectChanges.Response); rpc MetricsSetParameters (anytype.Rpc.Metrics.SetParameters.Request) returns (anytype.Rpc.Metrics.SetParameters.Response); @@ -359,7 +361,7 @@ service ClientCommands { rpc DeviceList (anytype.Rpc.Device.List.Request) returns (anytype.Rpc.Device.List.Response); rpc DeviceNetworkStateSet (anytype.Rpc.Device.NetworkState.Set.Request) returns (anytype.Rpc.Device.NetworkState.Set.Response); - // Chats dummy impl + // Chats rpc ChatAddMessage (anytype.Rpc.Chat.AddMessage.Request) returns (anytype.Rpc.Chat.AddMessage.Response); rpc ChatEditMessageContent (anytype.Rpc.Chat.EditMessageContent.Request) returns (anytype.Rpc.Chat.EditMessageContent.Response); rpc ChatToggleMessageReaction (anytype.Rpc.Chat.ToggleMessageReaction.Request) returns (anytype.Rpc.Chat.ToggleMessageReaction.Response); @@ -368,4 +370,6 @@ service ClientCommands { rpc ChatGetMessagesByIds (anytype.Rpc.Chat.GetMessagesByIds.Request) returns (anytype.Rpc.Chat.GetMessagesByIds.Response); rpc ChatSubscribeLastMessages (anytype.Rpc.Chat.SubscribeLastMessages.Request) returns (anytype.Rpc.Chat.SubscribeLastMessages.Response); rpc ChatUnsubscribe (anytype.Rpc.Chat.Unsubscribe.Request) returns (anytype.Rpc.Chat.Unsubscribe.Response); + rpc ObjectChatAdd (anytype.Rpc.Object.ChatAdd.Request) returns (anytype.Rpc.Object.ChatAdd.Response); + } diff --git a/pb/service/service.pb.go b/pb/service/service.pb.go index e746cd0fd1..ebaede39a6 100644 --- a/pb/service/service.pb.go +++ b/pb/service/service.pb.go @@ -26,326 +26,330 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) } var fileDescriptor_93a29dc403579097 = []byte{ - // 5097 bytes of a gzipped FileDescriptorProto + // 5164 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0x5b, 0x6f, 0x24, 0x49, - 0x56, 0xf8, 0xa7, 0x5e, 0xfe, 0xf3, 0x27, 0x97, 0x1d, 0xa0, 0x06, 0x86, 0xd9, 0x61, 0xb7, 0xef, - 0xdd, 0xee, 0x6e, 0xdb, 0xe5, 0x9e, 0xee, 0xb9, 0xac, 0x76, 0x91, 0x90, 0xdb, 0x6e, 0x7b, 0xcc, - 0xda, 0x6e, 0xe3, 0x2a, 0x77, 0x4b, 0x23, 0x21, 0x11, 0xce, 0x3a, 0x2e, 0x27, 0xce, 0xca, 0xc8, - 0xcd, 0x8c, 0x2a, 0x77, 0x2d, 0x02, 0x81, 0x40, 0x20, 0x10, 0x88, 0x15, 0xb7, 0x57, 0x24, 0x3e, - 0x0d, 0x8f, 0xfb, 0xc8, 0xe3, 0x6a, 0xe6, 0x4b, 0xf0, 0x88, 0x32, 0x32, 0x32, 0x2e, 0x27, 0xe3, - 0x44, 0xa6, 0xf7, 0xa9, 0x5b, 0x75, 0x7e, 0xe7, 0x9c, 0x88, 0x8c, 0x13, 0x11, 0x27, 0x2e, 0x99, - 0x8e, 0x6e, 0xe7, 0xe7, 0x5b, 0x79, 0xc1, 0x05, 0x2f, 0xb7, 0x4a, 0x28, 0x96, 0x49, 0x0c, 0xcd, - 0xbf, 0x23, 0xf9, 0xf3, 0xf0, 0x7d, 0x96, 0xad, 0xc4, 0x2a, 0x87, 0x4f, 0x3e, 0x36, 0x64, 0xcc, - 0xe7, 0x73, 0x96, 0x4d, 0xcb, 0x1a, 0xf9, 0xe4, 0x23, 0x23, 0x81, 0x25, 0x64, 0x42, 0xfd, 0xfe, - 0xfc, 0x7f, 0x7f, 0x39, 0x88, 0x3e, 0xd8, 0x49, 0x13, 0xc8, 0xc4, 0x8e, 0xd2, 0x18, 0x7e, 0x1d, - 0x7d, 0x77, 0x3b, 0xcf, 0xf7, 0x41, 0xbc, 0x81, 0xa2, 0x4c, 0x78, 0x36, 0xbc, 0x3f, 0x52, 0x0e, - 0x46, 0xa7, 0x79, 0x3c, 0xda, 0xce, 0xf3, 0x91, 0x11, 0x8e, 0x4e, 0xe1, 0xa7, 0x0b, 0x28, 0xc5, - 0x27, 0x0f, 0xc2, 0x50, 0x99, 0xf3, 0xac, 0x84, 0xe1, 0x45, 0xf4, 0x5b, 0xdb, 0x79, 0x3e, 0x06, - 0xb1, 0x0b, 0x55, 0x05, 0xc6, 0x82, 0x09, 0x18, 0xae, 0xb5, 0x54, 0x5d, 0x40, 0xfb, 0x78, 0xdc, - 0x0d, 0x2a, 0x3f, 0x93, 0xe8, 0x3b, 0x95, 0x9f, 0xcb, 0x85, 0x98, 0xf2, 0xeb, 0x6c, 0x78, 0xb7, - 0xad, 0xa8, 0x44, 0xda, 0xf6, 0xbd, 0x10, 0xa2, 0xac, 0xbe, 0x8d, 0x7e, 0xfd, 0x2d, 0x4b, 0x53, - 0x10, 0x3b, 0x05, 0x54, 0x05, 0x77, 0x75, 0x6a, 0xd1, 0xa8, 0x96, 0x69, 0xbb, 0xf7, 0x83, 0x8c, - 0x32, 0xfc, 0x75, 0xf4, 0xdd, 0x5a, 0x72, 0x0a, 0x31, 0x5f, 0x42, 0x31, 0xf4, 0x6a, 0x29, 0x21, - 0xf1, 0xc8, 0x5b, 0x10, 0xb6, 0xbd, 0xc3, 0xb3, 0x25, 0x14, 0xc2, 0x6f, 0x5b, 0x09, 0xc3, 0xb6, - 0x0d, 0xa4, 0x6c, 0xff, 0xfd, 0x20, 0xfa, 0xfe, 0x76, 0x1c, 0xf3, 0x45, 0x26, 0x0e, 0x79, 0xcc, - 0xd2, 0xc3, 0x24, 0xbb, 0x3a, 0x86, 0xeb, 0x9d, 0xcb, 0x8a, 0xcf, 0x66, 0x30, 0x7c, 0xe1, 0x3e, - 0xd5, 0x1a, 0x1d, 0x69, 0x76, 0x64, 0xc3, 0xda, 0xf7, 0x67, 0x37, 0x53, 0x52, 0x65, 0xf9, 0xe7, - 0x41, 0x74, 0x0b, 0x97, 0x65, 0xcc, 0xd3, 0x25, 0x98, 0xd2, 0x7c, 0xde, 0x61, 0xd8, 0xc5, 0x75, - 0x79, 0xbe, 0xb8, 0xa9, 0x9a, 0x2a, 0x51, 0x1a, 0x7d, 0x68, 0x87, 0xcb, 0x18, 0x4a, 0xd9, 0x9d, - 0x9e, 0xd0, 0x11, 0xa1, 0x10, 0xed, 0xf9, 0x69, 0x1f, 0x54, 0x79, 0x4b, 0xa2, 0xa1, 0xf2, 0x96, - 0xf2, 0x52, 0x3b, 0x7b, 0xec, 0xb5, 0x60, 0x11, 0xda, 0xd7, 0x93, 0x1e, 0xa4, 0x72, 0xf5, 0x27, - 0xd1, 0x6f, 0xbc, 0xe5, 0xc5, 0x55, 0x99, 0xb3, 0x18, 0x54, 0x57, 0x78, 0xe8, 0x6a, 0x37, 0x52, - 0xdc, 0x1b, 0x1e, 0x75, 0x61, 0x56, 0xd0, 0x36, 0xc2, 0xd7, 0x39, 0xe0, 0x31, 0xc8, 0x28, 0x56, - 0x42, 0x2a, 0x68, 0x31, 0xa4, 0x6c, 0x5f, 0x45, 0x43, 0x63, 0xfb, 0xfc, 0x4f, 0x21, 0x16, 0xdb, - 0xd3, 0x29, 0x6e, 0x15, 0xa3, 0x2b, 0x89, 0xd1, 0xf6, 0x74, 0x4a, 0xb5, 0x8a, 0x1f, 0x55, 0xce, - 0xae, 0xa3, 0x8f, 0x90, 0xb3, 0xc3, 0xa4, 0x94, 0x0e, 0x37, 0xc3, 0x56, 0x14, 0xa6, 0x9d, 0x8e, - 0xfa, 0xe2, 0xca, 0xf1, 0x5f, 0x0e, 0xa2, 0xef, 0x79, 0x3c, 0x9f, 0xc2, 0x9c, 0x2f, 0x61, 0xf8, - 0xac, 0xdb, 0x5a, 0x4d, 0x6a, 0xff, 0x9f, 0xde, 0x40, 0xc3, 0x13, 0x26, 0x63, 0x48, 0x21, 0x16, - 0x64, 0x98, 0xd4, 0xe2, 0xce, 0x30, 0xd1, 0x98, 0xd5, 0xc3, 0x1a, 0xe1, 0x3e, 0x88, 0x9d, 0x45, - 0x51, 0x40, 0x26, 0xc8, 0xb6, 0x34, 0x48, 0x67, 0x5b, 0x3a, 0xa8, 0xa7, 0x3e, 0xfb, 0x20, 0xb6, - 0xd3, 0x94, 0xac, 0x4f, 0x2d, 0xee, 0xac, 0x8f, 0xc6, 0x94, 0x87, 0x38, 0xfa, 0x4d, 0xeb, 0x89, - 0x89, 0x83, 0xec, 0x82, 0x0f, 0xe9, 0x67, 0x21, 0xe5, 0xda, 0xc7, 0x5a, 0x27, 0xe7, 0xa9, 0xc6, - 0xab, 0x77, 0x39, 0x2f, 0xe8, 0x66, 0xa9, 0xc5, 0x9d, 0xd5, 0xd0, 0x98, 0xf2, 0xf0, 0xc7, 0xd1, - 0x07, 0x6a, 0x94, 0x6c, 0xe6, 0xb3, 0x07, 0xde, 0x21, 0x14, 0x4f, 0x68, 0x0f, 0x3b, 0x28, 0x33, - 0x38, 0x28, 0x99, 0x1a, 0x7c, 0xee, 0x7b, 0xf5, 0xd0, 0xd0, 0xf3, 0x20, 0x0c, 0xb5, 0x6c, 0xef, - 0x42, 0x0a, 0xa4, 0xed, 0x5a, 0xd8, 0x61, 0x5b, 0x43, 0xca, 0x76, 0x11, 0xfd, 0x8e, 0x7e, 0x2c, - 0xd5, 0x3c, 0x2a, 0xe5, 0xd5, 0x20, 0xbd, 0x4e, 0xd4, 0xdb, 0x86, 0xb4, 0xaf, 0x8d, 0x7e, 0x70, - 0xab, 0x3e, 0xaa, 0x07, 0xfa, 0xeb, 0x83, 0xfa, 0xdf, 0x83, 0x30, 0xa4, 0x6c, 0xff, 0xc3, 0x20, - 0xfa, 0x81, 0x92, 0xbd, 0xca, 0xd8, 0x79, 0x0a, 0x72, 0x4a, 0x3c, 0x06, 0x71, 0xcd, 0x8b, 0xab, - 0xf1, 0x2a, 0x8b, 0x89, 0xe9, 0xdf, 0x0f, 0x77, 0x4c, 0xff, 0xa4, 0x92, 0x95, 0xf1, 0xa9, 0x8a, - 0x0a, 0x9e, 0xe3, 0x8c, 0xaf, 0xa9, 0x81, 0xe0, 0x39, 0x95, 0xf1, 0xb9, 0x48, 0xcb, 0xea, 0x51, - 0x35, 0x6c, 0xfa, 0xad, 0x1e, 0xd9, 0xe3, 0xe4, 0xbd, 0x10, 0x62, 0x86, 0xad, 0x26, 0x80, 0x79, - 0x76, 0x91, 0xcc, 0xce, 0xf2, 0x69, 0x15, 0xc6, 0x4f, 0xfc, 0x11, 0x6a, 0x21, 0xc4, 0xb0, 0x45, - 0xa0, 0xca, 0xdb, 0x3f, 0x99, 0xc4, 0x48, 0x75, 0xa5, 0xbd, 0x82, 0xcf, 0x0f, 0x61, 0xc6, 0xe2, - 0x95, 0xea, 0xff, 0x9f, 0x85, 0x3a, 0x1e, 0xa6, 0x75, 0x21, 0x3e, 0xbf, 0xa1, 0x96, 0x2a, 0xcf, - 0x7f, 0x0e, 0xa2, 0x07, 0x4d, 0xf5, 0x2f, 0x59, 0x36, 0x03, 0xd5, 0x9e, 0x75, 0xe9, 0xb7, 0xb3, - 0xe9, 0x29, 0x94, 0x82, 0x15, 0x62, 0xf8, 0x23, 0x7f, 0x25, 0x43, 0x3a, 0xba, 0x6c, 0x3f, 0xfe, - 0x95, 0x74, 0x4d, 0xab, 0x8f, 0xab, 0x81, 0x4d, 0x0d, 0x01, 0x6e, 0xab, 0x4b, 0x09, 0x1e, 0x00, - 0xee, 0x85, 0x10, 0xd3, 0xea, 0x52, 0x70, 0x90, 0x2d, 0x13, 0x01, 0xfb, 0x90, 0x41, 0xd1, 0x6e, - 0xf5, 0x5a, 0xd5, 0x45, 0x88, 0x56, 0x27, 0x50, 0x33, 0xd8, 0x38, 0xde, 0xf4, 0xe4, 0xb8, 0x1e, - 0x30, 0xd2, 0x9a, 0x1e, 0x37, 0xfa, 0xc1, 0x66, 0x75, 0x67, 0xf9, 0x3c, 0x85, 0x25, 0xbf, 0xc2, - 0xab, 0x3b, 0xdb, 0x44, 0x0d, 0x10, 0xab, 0x3b, 0x2f, 0x68, 0x66, 0x30, 0xcb, 0xcf, 0x9b, 0x04, - 0xae, 0xd1, 0x0c, 0x66, 0x2b, 0x57, 0x62, 0x62, 0x06, 0xf3, 0x60, 0xca, 0xc3, 0x71, 0xf4, 0x6b, - 0x52, 0xf8, 0x87, 0x3c, 0xc9, 0x86, 0xb7, 0x3d, 0x4a, 0x95, 0x40, 0x5b, 0xbd, 0x43, 0x03, 0xa8, - 0xc4, 0xd5, 0xaf, 0x3b, 0x2c, 0x8b, 0x21, 0xf5, 0x96, 0xd8, 0x88, 0x83, 0x25, 0x76, 0x30, 0x93, - 0x3a, 0x48, 0x61, 0x35, 0x7e, 0x8d, 0x2f, 0x59, 0x91, 0x64, 0xb3, 0xa1, 0x4f, 0xd7, 0x92, 0x13, - 0xa9, 0x83, 0x8f, 0x43, 0x21, 0xac, 0x14, 0xb7, 0xf3, 0xbc, 0xa8, 0x86, 0x45, 0x5f, 0x08, 0xbb, - 0x48, 0x30, 0x84, 0x5b, 0xa8, 0xdf, 0xdb, 0x2e, 0xc4, 0x69, 0x92, 0x05, 0xbd, 0x29, 0xa4, 0x8f, - 0x37, 0x83, 0xa2, 0xe0, 0x3d, 0x04, 0xb6, 0x84, 0xa6, 0x66, 0xbe, 0x27, 0x63, 0x03, 0xc1, 0xe0, - 0x45, 0xa0, 0x59, 0xa7, 0x49, 0xf1, 0x11, 0xbb, 0x82, 0xea, 0x01, 0x43, 0x35, 0xaf, 0x0d, 0x7d, - 0xfa, 0x0e, 0x41, 0xac, 0xd3, 0xfc, 0xa4, 0x72, 0xb5, 0x88, 0x3e, 0x92, 0xf2, 0x13, 0x56, 0x88, - 0x24, 0x4e, 0x72, 0x96, 0x35, 0xf9, 0xbf, 0xaf, 0x5f, 0xb7, 0x28, 0xed, 0x72, 0xb3, 0x27, 0xad, - 0xdc, 0xfe, 0xc7, 0x20, 0xba, 0x8b, 0xfd, 0x9e, 0x40, 0x31, 0x4f, 0xe4, 0x32, 0xb2, 0xac, 0x07, - 0xe1, 0xe1, 0x97, 0x61, 0xa3, 0x2d, 0x05, 0x5d, 0x9a, 0x1f, 0xde, 0x5c, 0x51, 0x15, 0xec, 0x8f, - 0xa2, 0xa8, 0x5e, 0xae, 0xc8, 0x25, 0xa5, 0xdb, 0x6b, 0xd5, 0x3a, 0xc6, 0x59, 0x4f, 0xde, 0x0d, - 0x10, 0x66, 0xaa, 0xa8, 0x7f, 0x97, 0x2b, 0xe5, 0xa1, 0x57, 0x43, 0x8a, 0x88, 0xa9, 0x02, 0x21, - 0xb8, 0xa0, 0xe3, 0x4b, 0x7e, 0xed, 0x2f, 0x68, 0x25, 0x09, 0x17, 0x54, 0x11, 0x66, 0xef, 0x4a, - 0x15, 0xd4, 0xb7, 0x77, 0xd5, 0x14, 0x23, 0xb4, 0x77, 0x85, 0x19, 0x65, 0x98, 0x47, 0xbf, 0x6d, - 0x1b, 0x7e, 0xc9, 0xf9, 0xd5, 0x9c, 0x15, 0x57, 0xc3, 0xa7, 0xb4, 0x72, 0xc3, 0x68, 0x47, 0xeb, - 0xbd, 0x58, 0x33, 0x2c, 0xd8, 0x0e, 0xab, 0x44, 0xe3, 0xac, 0x48, 0xd1, 0xb0, 0xe0, 0xd8, 0x50, - 0x08, 0x31, 0x2c, 0x10, 0xa8, 0x49, 0xa0, 0x95, 0xb7, 0x4b, 0x26, 0xd7, 0xed, 0xfe, 0x87, 0x52, - 0x0b, 0x89, 0x04, 0xba, 0x05, 0x99, 0x59, 0xc1, 0xae, 0xc9, 0x18, 0xf0, 0x4a, 0xcc, 0x29, 0xda, - 0x18, 0xa8, 0x95, 0x98, 0x07, 0xc3, 0xe1, 0xb9, 0x5f, 0xb0, 0xfc, 0xd2, 0x1f, 0x9e, 0x52, 0x14, - 0x0e, 0xcf, 0x06, 0xc1, 0xb1, 0x34, 0x06, 0x56, 0xc4, 0x97, 0xfe, 0x58, 0xaa, 0x65, 0xe1, 0x58, - 0xd2, 0x0c, 0x8e, 0xa5, 0x5a, 0xf0, 0x36, 0x11, 0x97, 0x47, 0x20, 0x98, 0x3f, 0x96, 0x5c, 0x26, - 0x1c, 0x4b, 0x2d, 0xd6, 0x64, 0x49, 0xb6, 0xc3, 0xf1, 0xe2, 0xbc, 0x8c, 0x8b, 0xe4, 0x1c, 0x86, - 0x01, 0x2b, 0x1a, 0x22, 0xb2, 0x24, 0x12, 0x36, 0x13, 0x80, 0xf2, 0xd9, 0xc8, 0x0e, 0xa6, 0x25, - 0x9a, 0x00, 0x1a, 0x1b, 0x16, 0x41, 0x4c, 0x00, 0x7e, 0x12, 0x57, 0x6f, 0xbf, 0xe0, 0x8b, 0xbc, - 0xec, 0xa8, 0x1e, 0x82, 0xc2, 0xd5, 0x6b, 0xc3, 0xca, 0xe7, 0xbb, 0xe8, 0x77, 0xed, 0x47, 0x7a, - 0x96, 0x95, 0xda, 0xeb, 0x26, 0xfd, 0x9c, 0x2c, 0x8c, 0xd8, 0xf2, 0x0a, 0xe0, 0x26, 0x05, 0x6a, - 0x3c, 0x8b, 0x5d, 0x10, 0x2c, 0x49, 0xcb, 0xe1, 0x23, 0xbf, 0x8d, 0x46, 0x4e, 0xa4, 0x40, 0x3e, - 0x0e, 0xf7, 0xd9, 0xdd, 0x45, 0x9e, 0x26, 0x71, 0x7b, 0xef, 0x53, 0xe9, 0x6a, 0x71, 0xb8, 0xcf, - 0xda, 0x18, 0x1e, 0xdf, 0xc6, 0x20, 0xea, 0xff, 0x4c, 0x56, 0x39, 0xf8, 0xc7, 0x37, 0x07, 0x09, - 0x8f, 0x6f, 0x18, 0xc5, 0xf5, 0x19, 0x83, 0x38, 0x64, 0x2b, 0xbe, 0x20, 0xc6, 0x20, 0x2d, 0x0e, - 0xd7, 0xc7, 0xc6, 0x4c, 0x16, 0xa2, 0x3d, 0x1c, 0x64, 0x02, 0x8a, 0x8c, 0xa5, 0x7b, 0x29, 0x9b, - 0x95, 0x43, 0xa2, 0xdf, 0xb8, 0x14, 0x91, 0x85, 0xd0, 0xb4, 0xe7, 0x31, 0x1e, 0x94, 0x7b, 0x6c, - 0xc9, 0x8b, 0x44, 0xd0, 0x8f, 0xd1, 0x20, 0x9d, 0x8f, 0xd1, 0x41, 0xbd, 0xde, 0xb6, 0x8b, 0xf8, - 0x32, 0x59, 0xc2, 0x34, 0xe0, 0xad, 0x41, 0x7a, 0x78, 0xb3, 0x50, 0x4f, 0xa3, 0x8d, 0xf9, 0xa2, - 0x88, 0x81, 0x6c, 0xb4, 0x5a, 0xdc, 0xd9, 0x68, 0x1a, 0x53, 0x1e, 0xfe, 0x66, 0x10, 0xfd, 0x5e, - 0x2d, 0xb5, 0x37, 0x24, 0x77, 0x59, 0x79, 0x79, 0xce, 0x59, 0x31, 0x1d, 0x7e, 0xea, 0xb3, 0xe3, - 0x45, 0xb5, 0xeb, 0xe7, 0x37, 0x51, 0xc1, 0x8f, 0xf5, 0x30, 0x29, 0xad, 0x1e, 0xe7, 0x7d, 0xac, - 0x0e, 0x12, 0x7e, 0xac, 0x18, 0xc5, 0x03, 0x88, 0x94, 0xd7, 0x8b, 0xff, 0x47, 0xa4, 0xbe, 0xbb, - 0x03, 0xb0, 0xd6, 0xc9, 0xe1, 0xf1, 0xb1, 0x12, 0xba, 0xd1, 0xb2, 0x49, 0xd9, 0xf0, 0x47, 0xcc, - 0xa8, 0x2f, 0x4e, 0x7a, 0xd6, 0xbd, 0x22, 0xec, 0xb9, 0xd5, 0x33, 0x46, 0x7d, 0x71, 0xc2, 0xb3, - 0x35, 0xac, 0x85, 0x3c, 0x7b, 0x86, 0xb6, 0x51, 0x5f, 0x1c, 0x67, 0x14, 0x8a, 0x69, 0xe6, 0x85, - 0xa7, 0x01, 0x3b, 0x78, 0x6e, 0x58, 0xef, 0xc5, 0x2a, 0x87, 0x7f, 0x37, 0x88, 0xbe, 0x6f, 0x3c, - 0x1e, 0xf1, 0x69, 0x72, 0xb1, 0xaa, 0xa1, 0x37, 0x2c, 0x5d, 0x40, 0x39, 0x7c, 0x4e, 0x59, 0x6b, - 0xb3, 0xba, 0x04, 0x2f, 0x6e, 0xa4, 0x83, 0xfb, 0xce, 0x76, 0x9e, 0xa7, 0xab, 0x09, 0xcc, 0xf3, - 0x94, 0xec, 0x3b, 0x0e, 0x12, 0xee, 0x3b, 0x18, 0xc5, 0x99, 0xe6, 0x84, 0x57, 0x79, 0xac, 0x37, - 0xd3, 0x94, 0xa2, 0x70, 0xa6, 0xd9, 0x20, 0x38, 0x57, 0x9a, 0xf0, 0x1d, 0x9e, 0xa6, 0x10, 0x8b, - 0xf6, 0xa1, 0xa6, 0xd6, 0x34, 0x44, 0x38, 0x57, 0x42, 0xa4, 0x59, 0xff, 0x37, 0x6b, 0x2e, 0x56, - 0xc0, 0xcb, 0xd5, 0x61, 0x92, 0x5d, 0x0d, 0xfd, 0x69, 0x81, 0x01, 0x88, 0xf5, 0xbf, 0x17, 0xc4, - 0x6b, 0xbb, 0xb3, 0x6c, 0xca, 0xfd, 0x6b, 0xbb, 0x4a, 0x12, 0x5e, 0xdb, 0x29, 0x02, 0x9b, 0x3c, - 0x05, 0xca, 0x64, 0x25, 0x09, 0x9b, 0x54, 0x84, 0x6f, 0x28, 0x54, 0xbb, 0xc4, 0xe4, 0x50, 0x88, - 0xf6, 0x85, 0xd7, 0x3a, 0x39, 0x1c, 0xa1, 0xcd, 0x22, 0x6f, 0x0f, 0x44, 0x7c, 0xe9, 0x8f, 0x50, - 0x07, 0x09, 0x47, 0x28, 0x46, 0x71, 0x95, 0x26, 0x5c, 0x2f, 0x52, 0x1f, 0xf9, 0xe3, 0xa3, 0xb5, - 0x40, 0x5d, 0xeb, 0xe4, 0xf0, 0xd2, 0xe8, 0x60, 0x2e, 0x9f, 0x99, 0x37, 0xc8, 0x6b, 0x59, 0x78, - 0x69, 0xa4, 0x19, 0x5c, 0xfa, 0x5a, 0x50, 0x3d, 0x4e, 0x7f, 0xe9, 0x8d, 0x3c, 0x5c, 0x7a, 0x87, - 0x53, 0x4e, 0xfe, 0x6d, 0x10, 0xdd, 0xb6, 0xbd, 0x1c, 0xf3, 0xaa, 0x8f, 0xbc, 0x61, 0x69, 0x32, - 0x65, 0x02, 0x26, 0xfc, 0x0a, 0x32, 0xb4, 0x6f, 0xe3, 0x96, 0xb6, 0xe6, 0x47, 0x8e, 0x02, 0xb1, - 0x6f, 0xd3, 0x4b, 0x11, 0xc7, 0x49, 0x4d, 0x9f, 0x95, 0xb0, 0xc3, 0x4a, 0x62, 0x24, 0x73, 0x90, - 0x70, 0x9c, 0x60, 0x14, 0xe7, 0xab, 0xb5, 0xfc, 0xd5, 0xbb, 0x1c, 0x8a, 0x04, 0xb2, 0x18, 0xfc, - 0xf9, 0x2a, 0xa6, 0xc2, 0xf9, 0xaa, 0x87, 0x6e, 0x6d, 0x6b, 0xe8, 0xc1, 0xa9, 0x7d, 0x2f, 0x01, - 0x13, 0x81, 0x7b, 0x09, 0x04, 0x8a, 0x2b, 0x69, 0x00, 0xef, 0xd6, 0x60, 0xcb, 0x4a, 0x70, 0x6b, - 0x90, 0xa6, 0x5b, 0x9b, 0x45, 0x9a, 0x19, 0x57, 0xdd, 0xa4, 0xa3, 0xe8, 0x63, 0xbb, 0xbb, 0xac, - 0xf7, 0x62, 0xfd, 0xbb, 0x53, 0xa7, 0x90, 0x32, 0x39, 0x85, 0x04, 0xb6, 0x80, 0x1a, 0xa6, 0xcf, - 0xee, 0x94, 0xc5, 0x2a, 0x87, 0x7f, 0x35, 0x88, 0x3e, 0xf1, 0x79, 0x7c, 0x9d, 0x4b, 0xbf, 0xcf, - 0xba, 0x6d, 0xd5, 0x24, 0x71, 0xf1, 0x22, 0xac, 0xa1, 0xca, 0xf0, 0x67, 0xd1, 0xc7, 0x8d, 0xc8, - 0xdc, 0xcb, 0x50, 0x05, 0x70, 0x13, 0x28, 0x5d, 0x7e, 0xcc, 0x69, 0xf7, 0x5b, 0xbd, 0x79, 0xb3, - 0x36, 0x71, 0xcb, 0x55, 0xa2, 0xb5, 0x89, 0xb6, 0xa1, 0xc4, 0xc4, 0xda, 0xc4, 0x83, 0x99, 0x5d, - 0x0d, 0xbb, 0x7a, 0x6f, 0x13, 0x71, 0x29, 0x73, 0x1f, 0xb4, 0xab, 0xe1, 0x94, 0x55, 0x43, 0xc4, - 0xae, 0x06, 0x09, 0xe3, 0xec, 0xa0, 0x01, 0xab, 0xbe, 0xe9, 0x1b, 0x57, 0xb5, 0x21, 0xbb, 0x67, - 0x3e, 0xee, 0x06, 0x71, 0xbc, 0x36, 0x62, 0xb5, 0x0c, 0x79, 0x1a, 0xb2, 0x80, 0x96, 0x22, 0xeb, - 0xbd, 0x58, 0xe5, 0xf0, 0x2f, 0xa2, 0xef, 0xb5, 0x2a, 0xb6, 0x07, 0x4c, 0x2c, 0x0a, 0x98, 0x0e, - 0xb7, 0x3a, 0xca, 0xdd, 0x80, 0xda, 0xf5, 0xb3, 0xfe, 0x0a, 0xad, 0x7c, 0xb9, 0xe1, 0xea, 0xb0, - 0xd2, 0x65, 0x78, 0x1e, 0x32, 0xe9, 0xb2, 0xc1, 0x7c, 0x99, 0xd6, 0x69, 0x2d, 0x79, 0xed, 0xe8, - 0xda, 0x5e, 0xb2, 0x24, 0x95, 0x47, 0x34, 0x9f, 0x86, 0x8c, 0x3a, 0x68, 0x70, 0xc9, 0x4b, 0xaa, - 0xb4, 0x46, 0x66, 0xd9, 0xc7, 0xad, 0xa5, 0xd2, 0x06, 0x3d, 0x12, 0x78, 0x56, 0x4a, 0x9b, 0x3d, - 0x69, 0xe5, 0x56, 0x34, 0x5b, 0x85, 0xd5, 0xcf, 0x76, 0x90, 0xfb, 0xbc, 0x2a, 0x55, 0x4f, 0xa4, - 0x6f, 0xf6, 0xa4, 0x95, 0xd7, 0x3f, 0x8f, 0x3e, 0x6e, 0x7b, 0x55, 0x13, 0xd1, 0x56, 0xa7, 0x29, - 0x34, 0x17, 0x3d, 0xeb, 0xaf, 0x60, 0x96, 0x17, 0x5f, 0x25, 0xa5, 0xe0, 0xc5, 0x6a, 0x7c, 0xc9, - 0xaf, 0x9b, 0xfb, 0xce, 0x6e, 0x6f, 0x55, 0xc0, 0xc8, 0x22, 0x88, 0xe5, 0x85, 0x9f, 0x6c, 0xb9, - 0x32, 0xf7, 0xa2, 0x4b, 0xc2, 0x95, 0x45, 0x74, 0xb8, 0x72, 0x49, 0x33, 0x56, 0x35, 0xb5, 0x32, - 0x97, 0xb8, 0xd7, 0xfc, 0x45, 0x6d, 0x5f, 0xe4, 0x7e, 0xdc, 0x0d, 0x9a, 0x8c, 0x45, 0x89, 0x77, - 0x93, 0x8b, 0x0b, 0x5d, 0x27, 0x7f, 0x49, 0x6d, 0x84, 0xc8, 0x58, 0x08, 0xd4, 0x24, 0xc0, 0x7b, - 0x49, 0x0a, 0xf2, 0xbc, 0xef, 0xf5, 0xc5, 0x45, 0xca, 0xd9, 0x14, 0x25, 0xc0, 0x95, 0x78, 0x64, - 0xcb, 0x89, 0x04, 0xd8, 0xc7, 0x99, 0xd3, 0x9e, 0x4a, 0x7a, 0x0a, 0x31, 0xcf, 0xe2, 0x24, 0xc5, - 0xd7, 0xbf, 0xa4, 0xa6, 0x16, 0x12, 0xa7, 0x3d, 0x2d, 0xc8, 0x4c, 0x8c, 0x95, 0xa8, 0xea, 0xf6, - 0x4d, 0xf9, 0x1f, 0xb6, 0x15, 0x2d, 0x31, 0x31, 0x31, 0x7a, 0x30, 0xb3, 0x0e, 0xac, 0x84, 0x67, - 0xb9, 0x34, 0x7e, 0xa7, 0xad, 0x55, 0x4b, 0x88, 0x75, 0xa0, 0x4b, 0x98, 0xf5, 0x4c, 0xf5, 0xfb, - 0x2e, 0xbf, 0xce, 0xa4, 0xd1, 0x7b, 0x6d, 0x95, 0x46, 0x46, 0xac, 0x67, 0x30, 0xa3, 0x0c, 0xff, - 0x24, 0xfa, 0xff, 0xd2, 0x70, 0xc1, 0xf3, 0xe1, 0x2d, 0x8f, 0x42, 0x61, 0xdd, 0xd4, 0xba, 0x4d, - 0xca, 0xcd, 0x85, 0x43, 0x1d, 0x1b, 0x67, 0x25, 0x9b, 0xc1, 0xf0, 0x01, 0xd1, 0xe2, 0x52, 0x4a, - 0x5c, 0x38, 0x6c, 0x53, 0x6e, 0x54, 0x1c, 0xf3, 0xa9, 0xb2, 0xee, 0xa9, 0xa1, 0x16, 0x86, 0xa2, - 0xc2, 0x86, 0x4c, 0x32, 0x73, 0xcc, 0x96, 0xc9, 0x4c, 0x4f, 0x38, 0xf5, 0xb8, 0x55, 0xa2, 0x64, - 0xc6, 0x30, 0x23, 0x0b, 0x22, 0x92, 0x19, 0x12, 0x56, 0x3e, 0xff, 0x75, 0x10, 0xdd, 0x31, 0xcc, - 0x7e, 0xb3, 0x73, 0x76, 0x90, 0x5d, 0xf0, 0x2a, 0xf5, 0x39, 0x4c, 0xb2, 0xab, 0x72, 0xf8, 0x05, - 0x65, 0xd2, 0xcf, 0xeb, 0xa2, 0x7c, 0x79, 0x63, 0x3d, 0x93, 0xb5, 0x36, 0xdb, 0x4a, 0xe6, 0x2c, - 0xb6, 0xd6, 0x40, 0x59, 0xab, 0xde, 0x7d, 0xc2, 0x1c, 0x91, 0xb5, 0x86, 0x78, 0xd3, 0xc4, 0xda, - 0x79, 0xca, 0x33, 0xdc, 0xc4, 0xc6, 0x42, 0x25, 0x24, 0x9a, 0xb8, 0x05, 0x99, 0xf1, 0xb8, 0x11, - 0xd5, 0x3b, 0x20, 0xdb, 0x69, 0x8a, 0xc6, 0x63, 0xad, 0xaa, 0x01, 0x62, 0x3c, 0xf6, 0x82, 0xca, - 0xcf, 0x69, 0xf4, 0x9d, 0xea, 0x91, 0x9e, 0x14, 0xb0, 0x4c, 0x00, 0x5f, 0x1b, 0xb0, 0x24, 0x44, - 0xff, 0x77, 0x09, 0xd3, 0xb3, 0xce, 0xb2, 0x32, 0x4f, 0x59, 0x79, 0xa9, 0x0e, 0x7b, 0xdd, 0x3a, - 0x37, 0x42, 0x7c, 0xdc, 0xfb, 0xb0, 0x83, 0x32, 0x83, 0x7a, 0x23, 0xd3, 0x43, 0xcc, 0x23, 0xbf, - 0x6a, 0x6b, 0x98, 0x59, 0xeb, 0xe4, 0xcc, 0xee, 0xf3, 0x3e, 0x4b, 0x53, 0x28, 0x56, 0x8d, 0xec, - 0x88, 0x65, 0xc9, 0x05, 0x94, 0x02, 0xed, 0x3e, 0x2b, 0x6a, 0x84, 0x31, 0x62, 0xf7, 0x39, 0x80, - 0x9b, 0x6c, 0x1e, 0x79, 0x3e, 0xc8, 0xa6, 0xf0, 0x0e, 0x65, 0xf3, 0xd8, 0x8e, 0x64, 0x88, 0x6c, - 0x9e, 0x62, 0xcd, 0x2e, 0xec, 0xcb, 0x94, 0xc7, 0x57, 0x6a, 0x0a, 0x70, 0x1b, 0x58, 0x4a, 0xf0, - 0x1c, 0x70, 0x2f, 0x84, 0x98, 0x49, 0x40, 0x0a, 0x4e, 0x21, 0x4f, 0x59, 0x8c, 0xef, 0x8e, 0xd4, - 0x3a, 0x4a, 0x46, 0x4c, 0x02, 0x98, 0x41, 0xc5, 0x55, 0x77, 0x52, 0x7c, 0xc5, 0x45, 0x57, 0x52, - 0xee, 0x85, 0x10, 0x33, 0x0d, 0x4a, 0xc1, 0x38, 0x4f, 0x13, 0x81, 0xba, 0x41, 0xad, 0x21, 0x25, - 0x44, 0x37, 0x70, 0x09, 0x64, 0xf2, 0x08, 0x8a, 0x19, 0x78, 0x4d, 0x4a, 0x49, 0xd0, 0x64, 0x43, - 0x98, 0x2b, 0x86, 0x75, 0xdd, 0x79, 0xbe, 0x42, 0x57, 0x0c, 0x55, 0xb5, 0x78, 0xbe, 0x22, 0xae, - 0x18, 0x3a, 0x00, 0x2a, 0xe2, 0x09, 0x2b, 0x85, 0xbf, 0x88, 0x52, 0x12, 0x2c, 0x62, 0x43, 0x98, - 0x39, 0xba, 0x2e, 0xe2, 0x42, 0xa0, 0x39, 0x5a, 0x15, 0xc0, 0x3a, 0x0d, 0xbe, 0x4d, 0xca, 0xcd, - 0x48, 0x52, 0xb7, 0x0a, 0x88, 0xbd, 0x04, 0xd2, 0x69, 0x89, 0x46, 0x12, 0xf5, 0xdc, 0x1b, 0x29, - 0x31, 0x92, 0xb4, 0x29, 0x14, 0x4a, 0x6a, 0xaf, 0xda, 0x57, 0x3b, 0xb4, 0x4d, 0x7d, 0x2f, 0x84, - 0x98, 0xf1, 0xa9, 0x29, 0xf4, 0x0e, 0x2b, 0x8a, 0xa4, 0x9a, 0xfc, 0x1f, 0xf9, 0x0b, 0xd4, 0xc8, - 0x89, 0xf1, 0xc9, 0xc7, 0xa1, 0xee, 0xd5, 0x0c, 0xdc, 0xbe, 0x82, 0xe1, 0xa1, 0xfb, 0x7e, 0x90, - 0x31, 0x19, 0xa7, 0x94, 0x58, 0xc7, 0x99, 0xbe, 0xa7, 0xe9, 0x39, 0xcd, 0x7c, 0xd4, 0x85, 0x59, - 0xaf, 0x00, 0x68, 0x17, 0x47, 0x7c, 0x09, 0x13, 0xfe, 0xea, 0x5d, 0x52, 0x8a, 0x24, 0x9b, 0xa9, - 0x99, 0xfb, 0x05, 0x61, 0xc9, 0x07, 0x13, 0xaf, 0x00, 0x74, 0x2a, 0x99, 0x04, 0x02, 0x95, 0xe5, - 0x18, 0xae, 0xbd, 0x09, 0x04, 0xb6, 0xa8, 0x39, 0x22, 0x81, 0x08, 0xf1, 0x66, 0x1f, 0x45, 0x3b, - 0x57, 0xef, 0x49, 0x4e, 0x78, 0x93, 0xcb, 0x51, 0xd6, 0x30, 0x48, 0x2c, 0x65, 0x83, 0x0a, 0x66, - 0x7d, 0xa9, 0xfd, 0x9b, 0x2e, 0xf6, 0x98, 0xb0, 0xd3, 0xee, 0x66, 0x4f, 0x7a, 0x90, 0x1e, 0x57, - 0xe6, 0x4c, 0x9e, 0x72, 0xd5, 0x3e, 0x92, 0x7f, 0xd2, 0x83, 0xb4, 0xf6, 0x64, 0xec, 0x6a, 0xbd, - 0x64, 0xf1, 0xd5, 0xac, 0xe0, 0x8b, 0x6c, 0xba, 0xc3, 0x53, 0x5e, 0xa0, 0x3d, 0x19, 0xa7, 0xd4, - 0x08, 0x25, 0xf6, 0x64, 0x3a, 0x54, 0x4c, 0x06, 0x67, 0x97, 0x62, 0x3b, 0x4d, 0x66, 0x78, 0x45, - 0xed, 0x18, 0x92, 0x00, 0x91, 0xc1, 0x79, 0x41, 0x4f, 0x10, 0xd5, 0x2b, 0x6e, 0x91, 0xc4, 0x2c, - 0xad, 0xfd, 0x6d, 0xd1, 0x66, 0x1c, 0xb0, 0x33, 0x88, 0x3c, 0x0a, 0x9e, 0x7a, 0x4e, 0x16, 0x45, - 0x76, 0x90, 0x09, 0x4e, 0xd6, 0xb3, 0x01, 0x3a, 0xeb, 0x69, 0x81, 0x68, 0x58, 0x9d, 0xc0, 0xbb, - 0xaa, 0x34, 0xd5, 0x3f, 0xbe, 0x61, 0xb5, 0xfa, 0x7d, 0xa4, 0xe4, 0xa1, 0x61, 0x15, 0x71, 0xa8, - 0x32, 0xca, 0x49, 0x1d, 0x30, 0x01, 0x6d, 0x37, 0x4c, 0x1e, 0x77, 0x83, 0x7e, 0x3f, 0x63, 0xb1, - 0x4a, 0x21, 0xe4, 0x47, 0x02, 0x7d, 0xfc, 0x34, 0xa0, 0xd9, 0x6e, 0x71, 0xea, 0x73, 0x09, 0xf1, - 0x55, 0xeb, 0x8a, 0x91, 0x5b, 0xd0, 0x1a, 0x21, 0xb6, 0x5b, 0x08, 0xd4, 0xdf, 0x44, 0x07, 0x31, - 0xcf, 0x42, 0x4d, 0x54, 0xc9, 0xfb, 0x34, 0x91, 0xe2, 0xcc, 0xe2, 0x57, 0x4b, 0x55, 0x64, 0xd6, - 0xcd, 0xb4, 0x4e, 0x58, 0xb0, 0x21, 0x62, 0xf1, 0x4b, 0xc2, 0x26, 0x27, 0xc7, 0x3e, 0x8f, 0xda, - 0xf7, 0x95, 0x5b, 0x56, 0x8e, 0xe8, 0xfb, 0xca, 0x14, 0x4b, 0x57, 0xb2, 0x8e, 0x91, 0x0e, 0x2b, - 0x6e, 0x9c, 0x6c, 0xf4, 0x83, 0xcd, 0x92, 0xc7, 0xf1, 0xb9, 0x93, 0x02, 0x2b, 0x6a, 0xaf, 0x9b, - 0x01, 0x43, 0x06, 0x23, 0x96, 0x3c, 0x01, 0x1c, 0x0d, 0x61, 0x8e, 0xe7, 0x1d, 0x9e, 0x09, 0xc8, - 0x84, 0x6f, 0x08, 0x73, 0x8d, 0x29, 0x30, 0x34, 0x84, 0x51, 0x0a, 0x28, 0x6e, 0xe5, 0x7e, 0x10, - 0x88, 0x63, 0x36, 0xf7, 0x66, 0x6c, 0xf5, 0x5e, 0x4f, 0x2d, 0x0f, 0xc5, 0x2d, 0xe2, 0xac, 0x43, - 0x3e, 0xdb, 0xcb, 0x84, 0x15, 0x33, 0xbd, 0xbb, 0x31, 0x1d, 0x3e, 0xa3, 0xed, 0xb8, 0x24, 0x71, - 0xc8, 0x17, 0xd6, 0x40, 0xc3, 0xce, 0xc1, 0x9c, 0xcd, 0x74, 0x4d, 0x3d, 0x35, 0x90, 0xf2, 0x56, - 0x55, 0x1f, 0x77, 0x83, 0xc8, 0xcf, 0x9b, 0x64, 0x0a, 0x3c, 0xe0, 0x47, 0xca, 0xfb, 0xf8, 0xc1, - 0x20, 0xca, 0xde, 0xaa, 0x7a, 0xd7, 0x2b, 0xba, 0xed, 0x6c, 0xaa, 0xd6, 0xb1, 0x23, 0xe2, 0xf1, - 0x20, 0x2e, 0x94, 0xbd, 0x11, 0x3c, 0xea, 0xa3, 0xcd, 0x06, 0x6d, 0xa8, 0x8f, 0xea, 0xfd, 0xd7, - 0x3e, 0x7d, 0xd4, 0x07, 0x2b, 0x9f, 0x3f, 0x53, 0x7d, 0x74, 0x97, 0x09, 0x56, 0xe5, 0xed, 0x6f, - 0x12, 0xb8, 0x56, 0x0b, 0x61, 0x4f, 0x7d, 0x1b, 0x6a, 0x24, 0x5f, 0x54, 0x43, 0xab, 0xe2, 0xad, - 0xde, 0x7c, 0xc0, 0xb7, 0x5a, 0x21, 0x74, 0xfa, 0x46, 0x4b, 0x85, 0xad, 0xde, 0x7c, 0xc0, 0xb7, - 0x7a, 0x03, 0xb6, 0xd3, 0x37, 0x7a, 0x0d, 0x76, 0xab, 0x37, 0xaf, 0x7c, 0xff, 0x75, 0xd3, 0x71, - 0x6d, 0xe7, 0x55, 0x1e, 0x16, 0x8b, 0x64, 0x09, 0xbe, 0x74, 0xd2, 0xb5, 0xa7, 0xd1, 0x50, 0x3a, - 0x49, 0xab, 0x58, 0x9f, 0x4d, 0xf1, 0x95, 0xe2, 0x84, 0x97, 0x89, 0x3c, 0xa4, 0x7f, 0xd1, 0xc3, - 0x68, 0x03, 0x87, 0x16, 0x4d, 0x21, 0x25, 0x73, 0xdc, 0xe8, 0xa0, 0xe6, 0x46, 0xf1, 0x46, 0xc0, - 0x5e, 0xfb, 0x62, 0xf1, 0x66, 0x4f, 0xda, 0x1c, 0xfc, 0x39, 0x8c, 0x7d, 0xe2, 0x18, 0x6a, 0x55, - 0xef, 0xa1, 0xe3, 0xb3, 0xfe, 0x0a, 0xca, 0xfd, 0xdf, 0x36, 0xeb, 0x0a, 0xec, 0x5f, 0x75, 0x82, - 0xe7, 0x7d, 0x2c, 0xa2, 0x8e, 0xf0, 0xe2, 0x46, 0x3a, 0xaa, 0x20, 0xff, 0xd8, 0x2c, 0xa0, 0x1b, - 0x54, 0xbe, 0x57, 0xf1, 0xba, 0x98, 0x42, 0xa1, 0xfa, 0x44, 0xa8, 0x59, 0x0d, 0x8c, 0x7b, 0xc6, - 0xe7, 0x37, 0xd4, 0xb2, 0x3e, 0xa2, 0xe3, 0xc0, 0xea, 0x7d, 0x39, 0xab, 0x3c, 0x21, 0xcb, 0x16, - 0x8d, 0x0b, 0xf4, 0xc5, 0x4d, 0xd5, 0xa8, 0xbe, 0x62, 0xc1, 0xf2, 0x9d, 0xfc, 0x17, 0x3d, 0x0d, - 0x3b, 0x6f, 0xe9, 0x7f, 0x76, 0x33, 0x25, 0x55, 0x96, 0xff, 0x1a, 0x44, 0x0f, 0x1d, 0xd6, 0x9c, - 0x27, 0xa0, 0x5d, 0x8f, 0x1f, 0x07, 0xec, 0x53, 0x4a, 0xba, 0x70, 0xbf, 0xff, 0xab, 0x29, 0x9b, - 0x2f, 0xce, 0x38, 0x2a, 0x7b, 0x49, 0x2a, 0xa0, 0x68, 0x7f, 0x71, 0xc6, 0xb5, 0x5b, 0x53, 0x23, - 0xfa, 0x8b, 0x33, 0x01, 0xdc, 0xfa, 0xe2, 0x8c, 0xc7, 0xb3, 0xf7, 0x8b, 0x33, 0x5e, 0x6b, 0xc1, - 0x2f, 0xce, 0x84, 0x35, 0xa8, 0xe1, 0xbd, 0x29, 0x42, 0xbd, 0x6f, 0xdd, 0xcb, 0xa2, 0xbb, 0x8d, - 0xfd, 0xfc, 0x26, 0x2a, 0xc4, 0x04, 0x57, 0x73, 0xf2, 0x9e, 0x5b, 0x8f, 0x67, 0xea, 0xdc, 0x75, - 0xdb, 0xea, 0xcd, 0x2b, 0xdf, 0x3f, 0x55, 0xab, 0x1b, 0x3d, 0x9c, 0xf3, 0x42, 0xbe, 0xb5, 0xb8, - 0x1e, 0x1a, 0x9e, 0x2b, 0x0b, 0x76, 0xcb, 0x6f, 0xf4, 0x83, 0x89, 0xea, 0x56, 0x84, 0x6a, 0xf4, - 0x51, 0x97, 0x21, 0xd4, 0xe4, 0x5b, 0xbd, 0x79, 0x62, 0x1a, 0xa9, 0x7d, 0xd7, 0xad, 0xdd, 0xc3, - 0x98, 0xdb, 0xd6, 0xcf, 0xfa, 0x2b, 0x28, 0xf7, 0x4b, 0x95, 0x36, 0xda, 0xee, 0x65, 0x3b, 0x6f, - 0x76, 0x99, 0x1a, 0x3b, 0xcd, 0x3c, 0xea, 0x8b, 0x87, 0x12, 0x08, 0x7b, 0x0a, 0xed, 0x4a, 0x20, - 0xbc, 0xd3, 0xe8, 0x67, 0x37, 0x53, 0x52, 0x65, 0xf9, 0x97, 0x41, 0x74, 0x9b, 0x2c, 0x8b, 0x8a, - 0x83, 0x2f, 0xfa, 0x5a, 0x46, 0xf1, 0xf0, 0xe5, 0x8d, 0xf5, 0x54, 0xa1, 0xfe, 0x7d, 0x10, 0xdd, - 0x09, 0x14, 0xaa, 0x0e, 0x90, 0x1b, 0x58, 0x77, 0x03, 0xe5, 0x87, 0x37, 0x57, 0xa4, 0xa6, 0x7b, - 0x1b, 0x1f, 0xb7, 0x3f, 0xc5, 0x12, 0xb0, 0x3d, 0xa6, 0x3f, 0xc5, 0xd2, 0xad, 0x85, 0x37, 0x79, - 0xd8, 0x79, 0xb3, 0xe8, 0xf2, 0x6e, 0xf2, 0xc8, 0x1b, 0x6a, 0x68, 0xcd, 0xb1, 0xd6, 0xc9, 0xf9, - 0x9c, 0xbc, 0x7a, 0x97, 0xb3, 0x6c, 0x4a, 0x3b, 0xa9, 0xe5, 0xdd, 0x4e, 0x34, 0x87, 0x37, 0xc7, - 0x2a, 0xe9, 0x29, 0x6f, 0x16, 0x52, 0x4f, 0x28, 0x7d, 0x8d, 0x04, 0x37, 0xc7, 0x5a, 0x28, 0xe1, - 0x4d, 0x65, 0x8d, 0x21, 0x6f, 0x28, 0x59, 0x7c, 0xda, 0x07, 0x45, 0x29, 0xba, 0xf6, 0xa6, 0xf7, - 0xdc, 0x37, 0x42, 0x56, 0x5a, 0xfb, 0xee, 0x9b, 0x3d, 0x69, 0xc2, 0xed, 0x18, 0xc4, 0x57, 0xc0, - 0xa6, 0x50, 0x04, 0xdd, 0x6a, 0xaa, 0x97, 0x5b, 0x9b, 0xf6, 0xb9, 0xdd, 0xe1, 0xe9, 0x62, 0x9e, - 0xa9, 0xc6, 0x24, 0xdd, 0xda, 0x54, 0xb7, 0x5b, 0x44, 0xe3, 0x6d, 0x41, 0xe3, 0x56, 0xa6, 0x97, - 0x4f, 0xc3, 0x66, 0x9c, 0xac, 0x72, 0xbd, 0x17, 0x4b, 0xd7, 0x53, 0x85, 0x51, 0x47, 0x3d, 0x51, - 0x24, 0x6d, 0xf6, 0xa4, 0xf1, 0xfe, 0x9c, 0xe5, 0x56, 0xc7, 0xd3, 0x56, 0x87, 0xad, 0x56, 0x48, - 0x3d, 0xeb, 0xaf, 0x80, 0x77, 0x43, 0x55, 0x54, 0x1d, 0x26, 0xa5, 0xd8, 0x4b, 0xd2, 0x74, 0xb8, - 0x1e, 0x08, 0x93, 0x06, 0x0a, 0xee, 0x86, 0x7a, 0x60, 0x22, 0x92, 0x9b, 0xdd, 0xc3, 0x6c, 0xd8, - 0x65, 0x47, 0x52, 0xbd, 0x22, 0xd9, 0xa6, 0xd1, 0x8e, 0x96, 0xf5, 0xa8, 0x75, 0x6d, 0x47, 0xe1, - 0x07, 0xd7, 0xaa, 0xf0, 0x56, 0x6f, 0x1e, 0x1d, 0xb7, 0x4b, 0x4a, 0xce, 0x2c, 0x0f, 0x28, 0x13, - 0xce, 0x4c, 0xf2, 0xb0, 0x83, 0x42, 0xbb, 0x82, 0x75, 0x37, 0x7a, 0x9b, 0x4c, 0x67, 0x20, 0xbc, - 0x27, 0x45, 0x36, 0x10, 0x3c, 0x29, 0x42, 0x20, 0x6a, 0xba, 0xfa, 0x77, 0xbd, 0x1d, 0x7a, 0x30, - 0xf5, 0x35, 0x9d, 0x52, 0xb6, 0xa8, 0x50, 0xd3, 0x79, 0x69, 0x34, 0x1a, 0x68, 0xb7, 0xea, 0xd5, - 0xf8, 0xa7, 0x21, 0x33, 0xe8, 0xfd, 0xf8, 0xf5, 0x5e, 0x2c, 0x9a, 0x51, 0x8c, 0xc3, 0x64, 0x9e, - 0x08, 0xdf, 0x8c, 0x62, 0xd9, 0xa8, 0x90, 0xd0, 0x8c, 0xd2, 0x46, 0xa9, 0xea, 0x55, 0x39, 0xc2, - 0xc1, 0x34, 0x5c, 0xbd, 0x9a, 0xe9, 0x57, 0x3d, 0xcd, 0xb6, 0x0e, 0x36, 0x33, 0x1d, 0x32, 0xe2, - 0x52, 0x2d, 0x96, 0x3d, 0xb1, 0x2d, 0x5f, 0x99, 0xc4, 0x60, 0x68, 0xd4, 0xa1, 0x14, 0xf0, 0x86, - 0x7d, 0xc5, 0x35, 0x67, 0xaf, 0x79, 0x0e, 0xac, 0x60, 0x59, 0xec, 0x5d, 0x9c, 0x4a, 0x83, 0x2d, - 0x32, 0xb4, 0x38, 0x25, 0x35, 0xd0, 0xb1, 0xb9, 0xfb, 0xb2, 0xa3, 0xa7, 0x2b, 0xe8, 0xb7, 0x0a, - 0xdd, 0x77, 0x1d, 0x9f, 0xf4, 0x20, 0xf1, 0xb1, 0x79, 0x03, 0xe8, 0x8d, 0xef, 0xda, 0xe9, 0xa7, - 0x01, 0x53, 0x2e, 0x1a, 0x5a, 0x08, 0xd3, 0x2a, 0x28, 0xa8, 0x75, 0x82, 0x0b, 0xe2, 0x27, 0xb0, - 0xf2, 0x05, 0xb5, 0xc9, 0x4f, 0x25, 0x12, 0x0a, 0xea, 0x36, 0x8a, 0xf2, 0x4c, 0x7b, 0x1d, 0xf4, - 0x28, 0xa0, 0x6f, 0x2f, 0x7d, 0xd6, 0x3a, 0x39, 0xd4, 0x73, 0x76, 0x93, 0xa5, 0x73, 0x4e, 0xe0, - 0x29, 0xe8, 0x6e, 0xb2, 0xf4, 0x1f, 0x13, 0xac, 0xf7, 0x62, 0xf1, 0x91, 0x3c, 0x13, 0xf0, 0xae, - 0x39, 0x2b, 0xf7, 0x14, 0x57, 0xca, 0x5b, 0x87, 0xe5, 0x8f, 0xbb, 0x41, 0x73, 0x01, 0xf6, 0xa4, - 0xe0, 0x31, 0x94, 0xa5, 0xfa, 0x3e, 0x9d, 0x7b, 0xc3, 0x48, 0xc9, 0x46, 0xe8, 0xeb, 0x74, 0x0f, - 0xc2, 0x90, 0xb2, 0xfd, 0x55, 0xf4, 0xfe, 0x21, 0x9f, 0x8d, 0x21, 0x9b, 0x0e, 0x7f, 0xe0, 0x5e, - 0x39, 0xe5, 0xb3, 0x51, 0xf5, 0xb3, 0xb6, 0x77, 0x8b, 0x12, 0x9b, 0x4b, 0x73, 0xbb, 0x70, 0xbe, - 0x98, 0x8d, 0x05, 0x13, 0xe8, 0xd2, 0x9c, 0xfc, 0x7d, 0x54, 0x09, 0x88, 0x4b, 0x73, 0x0e, 0x80, - 0xec, 0x4d, 0x0a, 0x00, 0xaf, 0xbd, 0x4a, 0x10, 0xb4, 0xa7, 0x00, 0x33, 0xeb, 0x6a, 0x7b, 0x55, - 0x62, 0x8b, 0x2f, 0xb9, 0x19, 0x1d, 0x29, 0x25, 0x66, 0xdd, 0x36, 0x65, 0x82, 0xa1, 0xae, 0xbe, - 0xfc, 0x62, 0xc6, 0x62, 0x3e, 0x67, 0xc5, 0x0a, 0x05, 0x83, 0xaa, 0xa5, 0x05, 0x10, 0xc1, 0xe0, - 0x05, 0x4d, 0x94, 0x37, 0x8f, 0x39, 0xbe, 0xda, 0xe7, 0x05, 0x5f, 0x88, 0x24, 0x03, 0xfc, 0xd5, - 0x04, 0xfd, 0x40, 0x6d, 0x86, 0x88, 0x72, 0x8a, 0x35, 0x59, 0xa1, 0x24, 0xea, 0xfb, 0x77, 0xf2, - 0x2b, 0xaf, 0xa5, 0xe0, 0x05, 0x3e, 0x7f, 0xab, 0xad, 0x60, 0x88, 0xc8, 0x0a, 0x49, 0x18, 0xb5, - 0xfd, 0x49, 0x92, 0xcd, 0xbc, 0x6d, 0x7f, 0x62, 0x7f, 0x23, 0xf1, 0x0e, 0x0d, 0x98, 0xf1, 0xbd, - 0x7e, 0x68, 0xf5, 0x97, 0x89, 0xd4, 0xbb, 0x8f, 0xde, 0x87, 0x6e, 0x13, 0xc4, 0xf8, 0xee, 0x27, - 0x91, 0xab, 0xd7, 0x39, 0x64, 0x30, 0x6d, 0x6e, 0x99, 0xf9, 0x5c, 0x39, 0x44, 0xd0, 0x15, 0x26, - 0xcd, 0xa8, 0x2a, 0xe5, 0xa7, 0x8b, 0xec, 0xa4, 0xe0, 0x17, 0x49, 0x0a, 0x05, 0x1a, 0x55, 0x6b, - 0x75, 0x4b, 0x4e, 0x8c, 0xaa, 0x3e, 0xce, 0x5c, 0x57, 0x90, 0x52, 0xe7, 0x53, 0xc5, 0x93, 0x82, - 0xc5, 0xf8, 0xba, 0x42, 0x6d, 0xa3, 0x8d, 0x11, 0x3b, 0x69, 0x01, 0xdc, 0x44, 0xfa, 0x11, 0x88, - 0x22, 0x89, 0xcb, 0x31, 0x88, 0x13, 0x56, 0xb0, 0x39, 0x08, 0x28, 0x70, 0xa4, 0x2b, 0x64, 0xe4, - 0x30, 0x44, 0xa4, 0x53, 0xac, 0x72, 0xf8, 0x07, 0xd1, 0x87, 0xd5, 0x40, 0x0f, 0x99, 0xfa, 0xaa, - 0xfe, 0x2b, 0xf9, 0xe7, 0x38, 0x86, 0x1f, 0x69, 0x1b, 0x63, 0x51, 0x00, 0x9b, 0x37, 0xb6, 0x3f, - 0xd0, 0xbf, 0x4b, 0xf0, 0xd9, 0xa0, 0x6a, 0x90, 0x63, 0x2e, 0x92, 0x8b, 0x6a, 0x5d, 0xa5, 0x5e, - 0x19, 0x41, 0x0d, 0x62, 0x8b, 0x47, 0x81, 0x0f, 0x01, 0xf8, 0x38, 0x33, 0xd0, 0xd8, 0xd2, 0x53, - 0xc8, 0x53, 0x3c, 0xd0, 0x38, 0xda, 0x12, 0x20, 0x06, 0x1a, 0x2f, 0x68, 0xa2, 0xcb, 0x16, 0x4f, - 0x20, 0x5c, 0x99, 0x09, 0xf4, 0xab, 0xcc, 0xc4, 0xb9, 0x85, 0x9f, 0x46, 0x1f, 0x1e, 0xc1, 0xfc, - 0x1c, 0x8a, 0xf2, 0x32, 0xc9, 0xf7, 0xab, 0x19, 0x96, 0x89, 0x05, 0x7e, 0x4f, 0xcd, 0x10, 0x23, - 0x8d, 0x10, 0x69, 0x08, 0x81, 0x9a, 0xa1, 0xcc, 0x00, 0x07, 0xe5, 0x31, 0x9b, 0x83, 0xfc, 0xac, - 0xc1, 0x70, 0x9d, 0x32, 0x62, 0x41, 0xc4, 0x50, 0x46, 0xc2, 0xd6, 0x0b, 0x3d, 0x86, 0x39, 0x85, - 0x59, 0x15, 0x61, 0xc5, 0x09, 0x5b, 0xcd, 0x21, 0x13, 0xca, 0x24, 0xda, 0x84, 0xb5, 0x4c, 0xfa, - 0x79, 0x62, 0x13, 0xb6, 0x8f, 0x9e, 0x95, 0x74, 0x3b, 0x0f, 0xfe, 0x84, 0x17, 0xa2, 0xfe, 0x9b, - 0x19, 0x67, 0x45, 0x8a, 0x92, 0x6e, 0xf7, 0xa1, 0x3a, 0x24, 0x91, 0x74, 0x87, 0x35, 0xac, 0x8f, - 0x4d, 0x3b, 0x65, 0x78, 0x03, 0x85, 0x8e, 0x93, 0x57, 0x73, 0x96, 0xa4, 0x2a, 0x1a, 0x7e, 0x14, - 0xb0, 0x4d, 0xe8, 0x10, 0x1f, 0x9b, 0xee, 0xab, 0x6b, 0x7d, 0x9e, 0x3b, 0x5c, 0x42, 0xb4, 0x27, - 0xdc, 0x61, 0x9f, 0xd8, 0x13, 0xee, 0xd6, 0x32, 0x4b, 0x35, 0xc3, 0x4a, 0x6e, 0x25, 0x89, 0x1d, - 0x3e, 0xc5, 0x1b, 0x44, 0x96, 0x4d, 0x04, 0x12, 0x4b, 0xb5, 0xa0, 0x82, 0x99, 0xdb, 0x0c, 0xb6, - 0x97, 0x64, 0x2c, 0x4d, 0x7e, 0x86, 0x6f, 0x17, 0x5b, 0x76, 0x1a, 0x82, 0x98, 0xdb, 0xfc, 0xa4, - 0xcf, 0xd5, 0x3e, 0x88, 0x49, 0x52, 0x0d, 0xfd, 0x8f, 0x03, 0xcf, 0x4d, 0x12, 0xdd, 0xae, 0x2c, - 0x52, 0xb9, 0xfa, 0xf9, 0x20, 0xba, 0x8d, 0x1f, 0xeb, 0x76, 0x9e, 0x8f, 0xab, 0x94, 0xe4, 0x14, - 0x62, 0x48, 0x72, 0x31, 0xfc, 0x3c, 0xfc, 0xac, 0x10, 0x4e, 0x9c, 0xac, 0xf7, 0x50, 0xb3, 0xce, - 0x6b, 0xab, 0xb1, 0x64, 0x5c, 0xff, 0x31, 0xa9, 0xb3, 0x12, 0x0a, 0x35, 0x53, 0xee, 0x83, 0x40, - 0xbd, 0xd3, 0xe2, 0x46, 0x16, 0x58, 0x55, 0x94, 0xe8, 0x9d, 0x61, 0x0d, 0xb3, 0xbb, 0x63, 0x71, - 0xa7, 0x50, 0xf2, 0x74, 0x09, 0xf2, 0x82, 0xd9, 0x06, 0x69, 0xcc, 0xa2, 0x88, 0xdd, 0x1d, 0x9a, - 0x36, 0xe9, 0x46, 0xdb, 0xed, 0x76, 0xb6, 0x3a, 0xc0, 0x67, 0xe4, 0x1e, 0x4b, 0x12, 0x23, 0xd2, - 0x8d, 0x00, 0x6e, 0xed, 0x7e, 0x16, 0x9c, 0x4d, 0x63, 0x56, 0x8a, 0x13, 0xb6, 0x4a, 0x39, 0x9b, - 0xca, 0x79, 0x1d, 0xef, 0x7e, 0x36, 0xcc, 0xc8, 0x86, 0xa8, 0xdd, 0x4f, 0x0a, 0x36, 0x2b, 0x3b, - 0xf5, 0x37, 0xb2, 0xd4, 0xe5, 0xbd, 0xfb, 0x28, 0x47, 0x92, 0xe5, 0xc5, 0x17, 0xf7, 0x1e, 0x84, - 0x21, 0xf3, 0xd2, 0x51, 0x2d, 0x92, 0x69, 0xc8, 0x1d, 0x9f, 0x8e, 0x93, 0x80, 0xdc, 0x0d, 0x10, - 0xe6, 0x43, 0x04, 0xf5, 0xef, 0xcd, 0x9f, 0x79, 0x10, 0xea, 0xd3, 0xb8, 0x1b, 0x3e, 0x5d, 0x1b, - 0x1a, 0xd9, 0x5f, 0x17, 0xdb, 0xec, 0x49, 0x9b, 0x85, 0x9b, 0xfa, 0x3c, 0xef, 0x11, 0x94, 0x9e, - 0x37, 0x88, 0x2b, 0xe1, 0xc8, 0x48, 0x89, 0x85, 0x5b, 0x9b, 0x32, 0x81, 0x5e, 0xc9, 0x5e, 0x4d, - 0x13, 0xa1, 0x64, 0xcd, 0x95, 0xd8, 0x8d, 0xb6, 0x81, 0x36, 0x45, 0xd4, 0x8a, 0xa6, 0xcd, 0x58, - 0x5e, 0x31, 0x13, 0x3e, 0x9b, 0xa5, 0xa0, 0xa0, 0x53, 0x60, 0xf5, 0x57, 0xd4, 0xb6, 0xda, 0xb6, - 0xbc, 0x20, 0x31, 0x96, 0x07, 0x15, 0x4c, 0x1a, 0x59, 0x61, 0xf5, 0x19, 0x44, 0xf3, 0x60, 0xd7, - 0xda, 0x66, 0x1c, 0x80, 0x48, 0x23, 0xbd, 0xa0, 0x79, 0xd1, 0xa9, 0x12, 0xef, 0x43, 0xf3, 0x24, - 0xf0, 0x37, 0x67, 0xa4, 0xb2, 0x25, 0x26, 0x5e, 0x74, 0xf2, 0x60, 0x66, 0x9d, 0x80, 0x3c, 0xbc, - 0x5c, 0x1d, 0x4c, 0xf1, 0x3a, 0x01, 0xeb, 0x4b, 0x86, 0x58, 0x27, 0x50, 0xac, 0xdb, 0x74, 0xfa, - 0x03, 0xbb, 0x87, 0xac, 0x34, 0x95, 0xf3, 0x34, 0x9d, 0x17, 0x0c, 0x35, 0x1d, 0xa5, 0xe0, 0x3e, - 0x52, 0xfb, 0xf3, 0xbd, 0x9e, 0x47, 0xea, 0xfb, 0x6c, 0xef, 0xa3, 0x2e, 0xac, 0xf6, 0xf0, 0xf2, - 0xee, 0x7f, 0x7f, 0x73, 0x6b, 0xf0, 0x8b, 0x6f, 0x6e, 0x0d, 0x7e, 0xf9, 0xcd, 0xad, 0xc1, 0xcf, - 0xbf, 0xbd, 0xf5, 0xde, 0x2f, 0xbe, 0xbd, 0xf5, 0xde, 0xff, 0x7c, 0x7b, 0xeb, 0xbd, 0xaf, 0xdf, - 0x57, 0x7f, 0xdf, 0xf0, 0xfc, 0xff, 0xc9, 0xbf, 0x52, 0xf8, 0xe2, 0xff, 0x02, 0x00, 0x00, 0xff, - 0xff, 0x06, 0x0c, 0x0e, 0xc0, 0x03, 0x71, 0x00, 0x00, + 0x56, 0xf8, 0xa7, 0x5e, 0xfe, 0xf3, 0x27, 0x97, 0x1d, 0xa0, 0x06, 0x86, 0xd9, 0x61, 0xb7, 0xbb, + 0xa7, 0x6f, 0xee, 0x6e, 0xdb, 0xe9, 0x9e, 0xee, 0xe9, 0x99, 0xd5, 0x2e, 0x12, 0x72, 0xdb, 0x6d, + 0x8f, 0x59, 0xdb, 0x6d, 0x5c, 0xe5, 0x6e, 0x69, 0x24, 0x24, 0xc2, 0x99, 0xe1, 0x72, 0xe2, 0xac, + 0x8c, 0xdc, 0xcc, 0xa8, 0x72, 0xd7, 0x22, 0x10, 0x08, 0x04, 0x02, 0x81, 0x58, 0x71, 0x7b, 0x45, + 0xe2, 0x89, 0x8f, 0xc2, 0xe3, 0x3e, 0xf2, 0x88, 0x66, 0xf8, 0x20, 0x28, 0x23, 0x22, 0xe3, 0x72, + 0x32, 0x4e, 0x64, 0x7a, 0x9f, 0xba, 0x55, 0xe7, 0x77, 0xce, 0x89, 0xeb, 0x89, 0x13, 0x91, 0x91, + 0xe9, 0xe8, 0x76, 0x79, 0xbe, 0x55, 0x56, 0x8c, 0xb3, 0x7a, 0xab, 0xa6, 0xd5, 0x32, 0x4b, 0x68, + 0xfb, 0x6f, 0x2c, 0x7e, 0x1e, 0xbf, 0x4f, 0x8a, 0x15, 0x5f, 0x95, 0xf4, 0x93, 0x8f, 0x0d, 0x99, + 0xb0, 0xf9, 0x9c, 0x14, 0x69, 0x2d, 0x91, 0x4f, 0x3e, 0x32, 0x12, 0xba, 0xa4, 0x05, 0x57, 0xbf, + 0x3f, 0xfb, 0xcf, 0xff, 0x1d, 0x45, 0x1f, 0xec, 0xe4, 0x19, 0x2d, 0xf8, 0x8e, 0xd2, 0x18, 0x7f, + 0x1d, 0x7d, 0x77, 0xbb, 0x2c, 0xf7, 0x29, 0x7f, 0x43, 0xab, 0x3a, 0x63, 0xc5, 0xf8, 0x5e, 0xac, + 0x1c, 0xc4, 0xa7, 0x65, 0x12, 0x6f, 0x97, 0x65, 0x6c, 0x84, 0xf1, 0x29, 0xfd, 0xe9, 0x82, 0xd6, + 0xfc, 0x93, 0xfb, 0x61, 0xa8, 0x2e, 0x59, 0x51, 0xd3, 0xf1, 0x45, 0xf4, 0x1b, 0xdb, 0x65, 0x39, + 0xa1, 0x7c, 0x97, 0x36, 0x15, 0x98, 0x70, 0xc2, 0xe9, 0x78, 0xad, 0xa3, 0xea, 0x02, 0xda, 0xc7, + 0xa3, 0x7e, 0x50, 0xf9, 0x99, 0x46, 0xdf, 0x69, 0xfc, 0x5c, 0x2e, 0x78, 0xca, 0xae, 0x8b, 0xf1, + 0xa7, 0x5d, 0x45, 0x25, 0xd2, 0xb6, 0xef, 0x86, 0x10, 0x65, 0xf5, 0x6d, 0xf4, 0xab, 0x6f, 0x49, + 0x9e, 0x53, 0xbe, 0x53, 0xd1, 0xa6, 0xe0, 0xae, 0x8e, 0x14, 0xc5, 0x52, 0xa6, 0xed, 0xde, 0x0b, + 0x32, 0xca, 0xf0, 0xd7, 0xd1, 0x77, 0xa5, 0xe4, 0x94, 0x26, 0x6c, 0x49, 0xab, 0xb1, 0x57, 0x4b, + 0x09, 0x91, 0x26, 0xef, 0x40, 0xd0, 0xf6, 0x0e, 0x2b, 0x96, 0xb4, 0xe2, 0x7e, 0xdb, 0x4a, 0x18, + 0xb6, 0x6d, 0x20, 0x65, 0xfb, 0x6f, 0x47, 0xd1, 0xf7, 0xb7, 0x93, 0x84, 0x2d, 0x0a, 0x7e, 0xc8, + 0x12, 0x92, 0x1f, 0x66, 0xc5, 0xd5, 0x31, 0xbd, 0xde, 0xb9, 0x6c, 0xf8, 0x62, 0x46, 0xc7, 0xcf, + 0xdd, 0x56, 0x95, 0x68, 0xac, 0xd9, 0xd8, 0x86, 0xb5, 0xef, 0xcf, 0x6f, 0xa6, 0xa4, 0xca, 0xf2, + 0x8f, 0xa3, 0xe8, 0x16, 0x2c, 0xcb, 0x84, 0xe5, 0x4b, 0x6a, 0x4a, 0xf3, 0xa2, 0xc7, 0xb0, 0x8b, + 0xeb, 0xf2, 0x7c, 0x71, 0x53, 0x35, 0x55, 0xa2, 0x3c, 0xfa, 0xd0, 0x1e, 0x2e, 0x13, 0x5a, 0x8b, + 0xe9, 0xf4, 0x18, 0x1f, 0x11, 0x0a, 0xd1, 0x9e, 0x9f, 0x0c, 0x41, 0x95, 0xb7, 0x2c, 0x1a, 0x2b, + 0x6f, 0x39, 0xab, 0xb5, 0xb3, 0x47, 0x5e, 0x0b, 0x16, 0xa1, 0x7d, 0x3d, 0x1e, 0x40, 0x2a, 0x57, + 0x7f, 0x14, 0xfd, 0xda, 0x5b, 0x56, 0x5d, 0xd5, 0x25, 0x49, 0xa8, 0x9a, 0x0a, 0x0f, 0x5c, 0xed, + 0x56, 0x0a, 0x67, 0xc3, 0xc3, 0x3e, 0xcc, 0x1a, 0xb4, 0xad, 0xf0, 0x75, 0x49, 0x61, 0x0c, 0x32, + 0x8a, 0x8d, 0x10, 0x1b, 0xb4, 0x10, 0x52, 0xb6, 0xaf, 0xa2, 0xb1, 0xb1, 0x7d, 0xfe, 0xc7, 0x34, + 0xe1, 0xdb, 0x69, 0x0a, 0x7b, 0xc5, 0xe8, 0x0a, 0x22, 0xde, 0x4e, 0x53, 0xac, 0x57, 0xfc, 0xa8, + 0x72, 0x76, 0x1d, 0x7d, 0x04, 0x9c, 0x1d, 0x66, 0xb5, 0x70, 0xb8, 0x19, 0xb6, 0xa2, 0x30, 0xed, + 0x34, 0x1e, 0x8a, 0x2b, 0xc7, 0x7f, 0x3e, 0x8a, 0xbe, 0xe7, 0xf1, 0x7c, 0x4a, 0xe7, 0x6c, 0x49, + 0xc7, 0x4f, 0xfb, 0xad, 0x49, 0x52, 0xfb, 0xff, 0xec, 0x06, 0x1a, 0x9e, 0x61, 0x32, 0xa1, 0x39, + 0x4d, 0x38, 0x3a, 0x4c, 0xa4, 0xb8, 0x77, 0x98, 0x68, 0xcc, 0x9a, 0x61, 0xad, 0x70, 0x9f, 0xf2, + 0x9d, 0x45, 0x55, 0xd1, 0x82, 0xa3, 0x7d, 0x69, 0x90, 0xde, 0xbe, 0x74, 0x50, 0x4f, 0x7d, 0xf6, + 0x29, 0xdf, 0xce, 0x73, 0xb4, 0x3e, 0x52, 0xdc, 0x5b, 0x1f, 0x8d, 0x29, 0x0f, 0x49, 0xf4, 0xeb, + 0x56, 0x8b, 0xf1, 0x83, 0xe2, 0x82, 0x8d, 0xf1, 0xb6, 0x10, 0x72, 0xed, 0x63, 0xad, 0x97, 0xf3, + 0x54, 0xe3, 0xd5, 0xbb, 0x92, 0x55, 0x78, 0xb7, 0x48, 0x71, 0x6f, 0x35, 0x34, 0xa6, 0x3c, 0xfc, + 0x61, 0xf4, 0x81, 0x8a, 0x92, 0xed, 0x7a, 0x76, 0xdf, 0x1b, 0x42, 0xe1, 0x82, 0xf6, 0xa0, 0x87, + 0x32, 0xc1, 0x41, 0xc9, 0x54, 0xf0, 0xb9, 0xe7, 0xd5, 0x03, 0xa1, 0xe7, 0x7e, 0x18, 0xea, 0xd8, + 0xde, 0xa5, 0x39, 0x45, 0x6d, 0x4b, 0x61, 0x8f, 0x6d, 0x0d, 0x29, 0xdb, 0x55, 0xf4, 0x5b, 0xba, + 0x59, 0x9a, 0x75, 0x54, 0xc8, 0x9b, 0x20, 0xbd, 0x8e, 0xd4, 0xdb, 0x86, 0xb4, 0xaf, 0x8d, 0x61, + 0x70, 0xa7, 0x3e, 0x6a, 0x06, 0xfa, 0xeb, 0x03, 0xe6, 0xdf, 0xfd, 0x30, 0xa4, 0x6c, 0xff, 0xdd, + 0x28, 0xfa, 0x81, 0x92, 0xbd, 0x2a, 0xc8, 0x79, 0x4e, 0xc5, 0x92, 0x78, 0x4c, 0xf9, 0x35, 0xab, + 0xae, 0x26, 0xab, 0x22, 0x41, 0x96, 0x7f, 0x3f, 0xdc, 0xb3, 0xfc, 0xa3, 0x4a, 0x56, 0xc6, 0xa7, + 0x2a, 0xca, 0x59, 0x09, 0x33, 0xbe, 0xb6, 0x06, 0x9c, 0x95, 0x58, 0xc6, 0xe7, 0x22, 0x1d, 0xab, + 0x47, 0x4d, 0xd8, 0xf4, 0x5b, 0x3d, 0xb2, 0xe3, 0xe4, 0xdd, 0x10, 0x62, 0xc2, 0x56, 0x3b, 0x80, + 0x59, 0x71, 0x91, 0xcd, 0xce, 0xca, 0xb4, 0x19, 0xc6, 0x8f, 0xfd, 0x23, 0xd4, 0x42, 0x90, 0xb0, + 0x85, 0xa0, 0xca, 0xdb, 0x3f, 0x98, 0xc4, 0x48, 0x4d, 0xa5, 0xbd, 0x8a, 0xcd, 0x0f, 0xe9, 0x8c, + 0x24, 0x2b, 0x35, 0xff, 0x3f, 0x0f, 0x4d, 0x3c, 0x48, 0xeb, 0x42, 0xbc, 0xb8, 0xa1, 0x96, 0x2a, + 0xcf, 0xbf, 0x8f, 0xa2, 0xfb, 0x6d, 0xf5, 0x2f, 0x49, 0x31, 0xa3, 0xaa, 0x3f, 0x65, 0xe9, 0xb7, + 0x8b, 0xf4, 0x94, 0xd6, 0x9c, 0x54, 0x7c, 0xfc, 0x23, 0x7f, 0x25, 0x43, 0x3a, 0xba, 0x6c, 0x3f, + 0xfe, 0xa5, 0x74, 0x4d, 0xaf, 0x4f, 0x9a, 0xc0, 0xa6, 0x42, 0x80, 0xdb, 0xeb, 0x42, 0x02, 0x03, + 0xc0, 0xdd, 0x10, 0x62, 0x7a, 0x5d, 0x08, 0x0e, 0x8a, 0x65, 0xc6, 0xe9, 0x3e, 0x2d, 0x68, 0xd5, + 0xed, 0x75, 0xa9, 0xea, 0x22, 0x48, 0xaf, 0x23, 0xa8, 0x09, 0x36, 0x8e, 0x37, 0xbd, 0x38, 0xae, + 0x07, 0x8c, 0x74, 0x96, 0xc7, 0x8d, 0x61, 0xb0, 0xd9, 0xdd, 0x59, 0x3e, 0x4f, 0xe9, 0x92, 0x5d, + 0xc1, 0xdd, 0x9d, 0x6d, 0x42, 0x02, 0xc8, 0xee, 0xce, 0x0b, 0x9a, 0x15, 0xcc, 0xf2, 0xf3, 0x26, + 0xa3, 0xd7, 0x60, 0x05, 0xb3, 0x95, 0x1b, 0x31, 0xb2, 0x82, 0x79, 0x30, 0xe5, 0xe1, 0x38, 0xfa, + 0x15, 0x21, 0xfc, 0x7d, 0x96, 0x15, 0xe3, 0xdb, 0x1e, 0xa5, 0x46, 0xa0, 0xad, 0xde, 0xc1, 0x01, + 0x50, 0xe2, 0xe6, 0xd7, 0x1d, 0x52, 0x24, 0x34, 0xf7, 0x96, 0xd8, 0x88, 0x83, 0x25, 0x76, 0x30, + 0x93, 0x3a, 0x08, 0x61, 0x13, 0xbf, 0x26, 0x97, 0xa4, 0xca, 0x8a, 0xd9, 0xd8, 0xa7, 0x6b, 0xc9, + 0x91, 0xd4, 0xc1, 0xc7, 0x81, 0x21, 0xac, 0x14, 0xb7, 0xcb, 0xb2, 0x6a, 0xc2, 0xa2, 0x6f, 0x08, + 0xbb, 0x48, 0x70, 0x08, 0x77, 0x50, 0xbf, 0xb7, 0x5d, 0x9a, 0xe4, 0x59, 0x11, 0xf4, 0xa6, 0x90, + 0x21, 0xde, 0x0c, 0x0a, 0x06, 0xef, 0x21, 0x25, 0x4b, 0xda, 0xd6, 0xcc, 0xd7, 0x32, 0x36, 0x10, + 0x1c, 0xbc, 0x00, 0x34, 0xfb, 0x34, 0x21, 0x3e, 0x22, 0x57, 0xb4, 0x69, 0x60, 0xda, 0xac, 0x6b, + 0x63, 0x9f, 0xbe, 0x43, 0x20, 0xfb, 0x34, 0x3f, 0xa9, 0x5c, 0x2d, 0xa2, 0x8f, 0x84, 0xfc, 0x84, + 0x54, 0x3c, 0x4b, 0xb2, 0x92, 0x14, 0x6d, 0xfe, 0xef, 0x9b, 0xd7, 0x1d, 0x4a, 0xbb, 0xdc, 0x1c, + 0x48, 0x2b, 0xb7, 0xff, 0x36, 0x8a, 0x3e, 0x85, 0x7e, 0x4f, 0x68, 0x35, 0xcf, 0xc4, 0x36, 0xb2, + 0x96, 0x41, 0x78, 0xfc, 0x65, 0xd8, 0x68, 0x47, 0x41, 0x97, 0xe6, 0x87, 0x37, 0x57, 0x54, 0x05, + 0xfb, 0x83, 0x28, 0x92, 0xdb, 0x15, 0xb1, 0xa5, 0x74, 0x67, 0xad, 0xda, 0xc7, 0x38, 0xfb, 0xc9, + 0x4f, 0x03, 0x84, 0x59, 0x2a, 0xe4, 0xef, 0x62, 0xa7, 0x3c, 0xf6, 0x6a, 0x08, 0x11, 0xb2, 0x54, + 0x00, 0x04, 0x16, 0x74, 0x72, 0xc9, 0xae, 0xfd, 0x05, 0x6d, 0x24, 0xe1, 0x82, 0x2a, 0xc2, 0x9c, + 0x5d, 0xa9, 0x82, 0xfa, 0xce, 0xae, 0xda, 0x62, 0x84, 0xce, 0xae, 0x20, 0xa3, 0x0c, 0xb3, 0xe8, + 0x37, 0x6d, 0xc3, 0x2f, 0x19, 0xbb, 0x9a, 0x93, 0xea, 0x6a, 0xfc, 0x04, 0x57, 0x6e, 0x19, 0xed, + 0x68, 0x7d, 0x10, 0x6b, 0xc2, 0x82, 0xed, 0xb0, 0x49, 0x34, 0xce, 0xaa, 0x1c, 0x84, 0x05, 0xc7, + 0x86, 0x42, 0x90, 0xb0, 0x80, 0xa0, 0x26, 0x72, 0xdb, 0xde, 0x26, 0x14, 0xee, 0x96, 0x1c, 0xf5, + 0x09, 0xc5, 0x76, 0x4b, 0x1e, 0x0c, 0x0e, 0xa1, 0xfd, 0x8a, 0x94, 0x97, 0xfe, 0x21, 0x24, 0x44, + 0xe1, 0x21, 0xd4, 0x22, 0xb0, 0xbf, 0x27, 0x94, 0x54, 0xc9, 0xa5, 0xbf, 0xbf, 0xa5, 0x2c, 0xdc, + 0xdf, 0x9a, 0x81, 0xfd, 0x2d, 0x05, 0x6f, 0x33, 0x7e, 0x79, 0x44, 0x39, 0xf1, 0xf7, 0xb7, 0xcb, + 0x84, 0xfb, 0xbb, 0xc3, 0x9a, 0x4c, 0xc6, 0x76, 0x38, 0x59, 0x9c, 0xd7, 0x49, 0x95, 0x9d, 0xd3, + 0x71, 0xc0, 0x8a, 0x86, 0x90, 0x4c, 0x06, 0x85, 0x95, 0xcf, 0x9f, 0x8f, 0xa2, 0xdb, 0x6d, 0xb7, + 0xb3, 0xba, 0x96, 0x2b, 0x2b, 0x70, 0xff, 0xc2, 0xdf, 0xbf, 0x08, 0x8e, 0x9c, 0x26, 0x0e, 0x50, + 0xb3, 0xa2, 0xaa, 0xbf, 0x48, 0x67, 0x45, 0xad, 0x0b, 0xf5, 0xe5, 0x10, 0xeb, 0x96, 0x02, 0x12, + 0x55, 0x07, 0x29, 0x9a, 0x05, 0x4d, 0xf5, 0x4f, 0x2b, 0x3b, 0x48, 0x6b, 0xb0, 0xa0, 0xb5, 0xed, + 0x6d, 0x11, 0xc8, 0x82, 0xe6, 0x27, 0xe1, 0x50, 0xd8, 0xaf, 0xd8, 0xa2, 0xac, 0x7b, 0x86, 0x02, + 0x80, 0xc2, 0x43, 0xa1, 0x0b, 0x2b, 0x9f, 0xef, 0xa2, 0xdf, 0xb6, 0x87, 0x9f, 0xdd, 0xd8, 0x9b, + 0xf8, 0x98, 0xf2, 0x35, 0x71, 0x3c, 0x14, 0x37, 0x29, 0x5d, 0xeb, 0x99, 0xef, 0x52, 0x4e, 0xb2, + 0xbc, 0x1e, 0x3f, 0xf4, 0xdb, 0x68, 0xe5, 0x48, 0x4a, 0xe7, 0xe3, 0x60, 0x7c, 0xdb, 0x5d, 0x94, + 0x79, 0x96, 0x74, 0xcf, 0x72, 0x95, 0xae, 0x16, 0x87, 0xe3, 0x9b, 0x8d, 0xc1, 0x78, 0x3d, 0xa1, + 0x5c, 0xfe, 0x67, 0xba, 0x2a, 0xa9, 0x3f, 0x5e, 0x3b, 0x48, 0x38, 0x5e, 0x43, 0x14, 0xd6, 0x67, + 0x42, 0xf9, 0x21, 0x59, 0xb1, 0x05, 0x12, 0xaf, 0xb5, 0x38, 0x5c, 0x1f, 0x1b, 0x33, 0x59, 0x95, + 0xf6, 0x70, 0x50, 0x70, 0x5a, 0x15, 0x24, 0xdf, 0xcb, 0xc9, 0xac, 0x1e, 0x23, 0x31, 0xc6, 0xa5, + 0x90, 0xac, 0x0a, 0xa7, 0x3d, 0xcd, 0x78, 0x50, 0xef, 0x91, 0x25, 0xab, 0x32, 0x8e, 0x37, 0xa3, + 0x41, 0x7a, 0x9b, 0xd1, 0x41, 0xbd, 0xde, 0xb6, 0xab, 0xe4, 0x32, 0x5b, 0xd2, 0x34, 0xe0, 0xad, + 0x45, 0x06, 0x78, 0xb3, 0x50, 0x4f, 0xa7, 0x4d, 0xd8, 0xa2, 0x4a, 0x28, 0xda, 0x69, 0x52, 0xdc, + 0xdb, 0x69, 0x1a, 0x53, 0x1e, 0xfe, 0x6a, 0x14, 0xfd, 0x8e, 0x94, 0xda, 0x07, 0xac, 0xbb, 0xa4, + 0xbe, 0x3c, 0x67, 0xa4, 0x4a, 0xc7, 0x9f, 0xf9, 0xec, 0x78, 0x51, 0xed, 0xfa, 0xd9, 0x4d, 0x54, + 0x60, 0xb3, 0x1e, 0x66, 0xb5, 0x35, 0xe3, 0xbc, 0xcd, 0xea, 0x20, 0xe1, 0x66, 0x85, 0x28, 0x0c, + 0x20, 0x42, 0x2e, 0x0f, 0x33, 0x1e, 0xa2, 0xfa, 0xee, 0x89, 0xc6, 0x5a, 0x2f, 0x07, 0xe3, 0x63, + 0x23, 0x74, 0x47, 0xcb, 0x26, 0x66, 0xc3, 0x3f, 0x62, 0xe2, 0xa1, 0x38, 0xea, 0x59, 0xcf, 0x8a, + 0xb0, 0xe7, 0xce, 0xcc, 0x88, 0x87, 0xe2, 0x88, 0x67, 0x2b, 0xac, 0x85, 0x3c, 0x7b, 0x42, 0x5b, + 0x3c, 0x14, 0x87, 0xd9, 0x97, 0x62, 0xda, 0x75, 0xe1, 0x49, 0xc0, 0x0e, 0x5c, 0x1b, 0xd6, 0x07, + 0xb1, 0xca, 0xe1, 0xdf, 0x8c, 0xa2, 0xef, 0x1b, 0x8f, 0x47, 0x2c, 0xcd, 0x2e, 0x56, 0x12, 0x7a, + 0x43, 0xf2, 0x05, 0xad, 0xc7, 0xcf, 0x30, 0x6b, 0x5d, 0x56, 0x97, 0xe0, 0xf9, 0x8d, 0x74, 0xe0, + 0xdc, 0xd9, 0x2e, 0xcb, 0x7c, 0x35, 0xa5, 0xf3, 0x32, 0x47, 0xe7, 0x8e, 0x83, 0x84, 0xe7, 0x0e, + 0x44, 0x61, 0x56, 0x3e, 0x65, 0x4d, 0xce, 0xef, 0xcd, 0xca, 0x85, 0x28, 0x9c, 0x95, 0xb7, 0x08, + 0xcc, 0x95, 0xa6, 0x6c, 0x87, 0xe5, 0x39, 0x4d, 0x78, 0xf7, 0x21, 0xad, 0xd6, 0x34, 0x44, 0x38, + 0x57, 0x02, 0xa4, 0x39, 0xcf, 0x68, 0xf7, 0x90, 0xa4, 0xa2, 0x2f, 0x57, 0x87, 0x59, 0x71, 0x35, + 0xf6, 0xa7, 0x05, 0x06, 0x40, 0xce, 0x33, 0xbc, 0x20, 0xdc, 0xab, 0x9e, 0x15, 0x29, 0xf3, 0xef, + 0x55, 0x1b, 0x49, 0x78, 0xaf, 0xaa, 0x08, 0x68, 0xf2, 0x94, 0x62, 0x26, 0x1b, 0x49, 0xd8, 0xa4, + 0x22, 0x7c, 0xa1, 0x50, 0x9d, 0x7a, 0xa3, 0xa1, 0x10, 0x9c, 0x73, 0xaf, 0xf5, 0x72, 0x70, 0x84, + 0xb6, 0x9b, 0xd6, 0x3d, 0xca, 0x93, 0x4b, 0xff, 0x08, 0x75, 0x90, 0xf0, 0x08, 0x85, 0x28, 0xac, + 0xd2, 0x94, 0xe9, 0x4d, 0xf7, 0x43, 0xff, 0xf8, 0xe8, 0x6c, 0xb8, 0xd7, 0x7a, 0x39, 0xb8, 0x8d, + 0x3c, 0x98, 0x8b, 0x36, 0xf3, 0x0e, 0x72, 0x29, 0x0b, 0x6f, 0x23, 0x35, 0x03, 0x4b, 0x2f, 0x05, + 0x4d, 0x73, 0xfa, 0x4b, 0x6f, 0xe4, 0xe1, 0xd2, 0x3b, 0x9c, 0x72, 0xf2, 0x2f, 0x7a, 0x1b, 0x27, + 0xa5, 0xc7, 0xac, 0x99, 0x23, 0x6f, 0x48, 0x9e, 0xa5, 0x84, 0xd3, 0x29, 0xbb, 0xa2, 0x85, 0x7f, + 0xc7, 0xa4, 0x4a, 0x2b, 0xf9, 0xd8, 0x51, 0x08, 0xef, 0x98, 0xc2, 0x8a, 0x70, 0x9c, 0x48, 0xfa, + 0xac, 0xa6, 0x3b, 0xa4, 0x46, 0x22, 0x99, 0x83, 0x84, 0xc7, 0x09, 0x44, 0x61, 0xbe, 0x2a, 0xe5, + 0xaf, 0xde, 0x95, 0xb4, 0xca, 0x68, 0x91, 0x50, 0x7f, 0xbe, 0x0a, 0xa9, 0x70, 0xbe, 0xea, 0xa1, + 0x3b, 0xc7, 0x34, 0x3a, 0x38, 0x75, 0xef, 0x59, 0x40, 0x22, 0x70, 0xcf, 0x02, 0x41, 0x61, 0x25, + 0x0d, 0xe0, 0x3d, 0xea, 0xec, 0x58, 0x09, 0x1e, 0x75, 0xe2, 0x74, 0xe7, 0xf0, 0x4b, 0x33, 0x93, + 0x66, 0x9a, 0xf4, 0x14, 0x7d, 0x62, 0x4f, 0x97, 0xf5, 0x41, 0xac, 0xff, 0xb4, 0xed, 0x94, 0xe6, + 0x44, 0x2c, 0x21, 0x81, 0x23, 0xad, 0x96, 0x19, 0x72, 0xda, 0x66, 0xb1, 0xca, 0xe1, 0x5f, 0x8c, + 0xa2, 0x4f, 0x7c, 0x1e, 0x5f, 0x97, 0xc2, 0xef, 0xd3, 0x7e, 0x5b, 0x92, 0x44, 0x2e, 0x92, 0x84, + 0x35, 0x54, 0x19, 0xfe, 0x24, 0xfa, 0xb8, 0x15, 0x99, 0x7b, 0x26, 0xaa, 0x00, 0x6e, 0x02, 0xa5, + 0xcb, 0x0f, 0x39, 0xed, 0x7e, 0x6b, 0x30, 0x6f, 0xf6, 0x26, 0x6e, 0xb9, 0x6a, 0xb0, 0x37, 0xd1, + 0x36, 0x94, 0x18, 0xd9, 0x9b, 0x78, 0x30, 0x73, 0xaa, 0x61, 0x57, 0xef, 0x6d, 0xc6, 0x2f, 0x45, + 0xee, 0x03, 0x4e, 0x35, 0x9c, 0xb2, 0x6a, 0x08, 0x39, 0xd5, 0x40, 0x61, 0x98, 0x1d, 0xb4, 0x60, + 0x33, 0x37, 0x7d, 0x71, 0x55, 0x1b, 0xb2, 0x67, 0xe6, 0xa3, 0x7e, 0x10, 0x8e, 0xd7, 0x56, 0xac, + 0xb6, 0x21, 0x4f, 0x42, 0x16, 0xc0, 0x56, 0x64, 0x7d, 0x10, 0xab, 0x1c, 0xfe, 0x59, 0xf4, 0xbd, + 0x4e, 0xc5, 0xf6, 0x28, 0xe1, 0x8b, 0x8a, 0xa6, 0xe3, 0xad, 0x9e, 0x72, 0xb7, 0xa0, 0x76, 0xfd, + 0x74, 0xb8, 0x42, 0x27, 0x5f, 0x6e, 0x39, 0x39, 0xac, 0x74, 0x19, 0x9e, 0x85, 0x4c, 0xba, 0x6c, + 0x30, 0x5f, 0xc6, 0x75, 0x3a, 0x5b, 0x5e, 0x7b, 0x74, 0x6d, 0x2f, 0x49, 0x96, 0x8b, 0x47, 0x4e, + 0x9f, 0x85, 0x8c, 0x3a, 0x68, 0x70, 0xcb, 0x8b, 0xaa, 0x74, 0x22, 0xb3, 0x98, 0xe3, 0xd6, 0x56, + 0x69, 0x03, 0x8f, 0x04, 0x9e, 0x9d, 0xd2, 0xe6, 0x40, 0x5a, 0xb9, 0xe5, 0xed, 0x51, 0x61, 0xf3, + 0xb3, 0x3d, 0xc8, 0x7d, 0x5e, 0x95, 0xaa, 0x67, 0xa4, 0x6f, 0x0e, 0xa4, 0x95, 0xd7, 0x3f, 0x8d, + 0x3e, 0xee, 0x7a, 0x55, 0x0b, 0xd1, 0x56, 0xaf, 0x29, 0xb0, 0x16, 0x3d, 0x1d, 0xae, 0x60, 0xb6, + 0x17, 0x5f, 0x65, 0x35, 0x67, 0xd5, 0x6a, 0x72, 0xc9, 0xae, 0xdb, 0xfb, 0xdb, 0xee, 0x6c, 0x55, + 0x40, 0x6c, 0x11, 0xc8, 0xf6, 0xc2, 0x4f, 0x76, 0x5c, 0x99, 0x7b, 0xde, 0x35, 0xe2, 0xca, 0x22, + 0x7a, 0x5c, 0xb9, 0xa4, 0x89, 0x55, 0x6d, 0xad, 0xcc, 0xa5, 0xf4, 0x35, 0x7f, 0x51, 0xbb, 0x17, + 0xd3, 0x1f, 0xf5, 0x83, 0x26, 0x63, 0x51, 0xe2, 0xdd, 0xec, 0xe2, 0x42, 0xd7, 0xc9, 0x5f, 0x52, + 0x1b, 0x41, 0x32, 0x16, 0x04, 0x35, 0x09, 0xf0, 0x5e, 0x96, 0x53, 0x71, 0xba, 0xfe, 0xfa, 0xe2, + 0x22, 0x67, 0x24, 0x05, 0x09, 0x70, 0x23, 0x8e, 0x6d, 0x39, 0x92, 0x00, 0xfb, 0x38, 0x73, 0xfd, + 0xab, 0x91, 0x9e, 0xd2, 0x84, 0x15, 0x49, 0x96, 0xc3, 0xeb, 0x6c, 0x42, 0x53, 0x0b, 0x91, 0xeb, + 0x5f, 0x1d, 0xc8, 0x2c, 0x8c, 0x8d, 0xa8, 0x99, 0xf6, 0x6d, 0xf9, 0x1f, 0x74, 0x15, 0x2d, 0x31, + 0xb2, 0x30, 0x7a, 0x30, 0xb3, 0x0f, 0x6c, 0x84, 0x67, 0xa5, 0x30, 0x7e, 0xa7, 0xab, 0x25, 0x25, + 0xc8, 0x3e, 0xd0, 0x25, 0xcc, 0x7e, 0xa6, 0xf9, 0x7d, 0x97, 0x5d, 0x17, 0xc2, 0xe8, 0xdd, 0xae, + 0x4a, 0x2b, 0x43, 0xf6, 0x33, 0x90, 0x51, 0x86, 0x7f, 0x12, 0xfd, 0x7f, 0x61, 0xb8, 0x62, 0xe5, + 0xf8, 0x96, 0x47, 0xa1, 0xb2, 0x6e, 0x9e, 0xdd, 0x46, 0xe5, 0xe6, 0x02, 0xa5, 0x1e, 0x1b, 0x67, + 0x35, 0x99, 0xd1, 0xf1, 0x7d, 0xa4, 0xc7, 0x85, 0x14, 0xb9, 0x40, 0xd9, 0xa5, 0xdc, 0x51, 0x71, + 0xcc, 0x52, 0x65, 0xdd, 0x53, 0x43, 0x2d, 0x0c, 0x8d, 0x0a, 0x1b, 0x32, 0xc9, 0xcc, 0x31, 0x59, + 0x66, 0x33, 0xbd, 0xe0, 0xc8, 0xb8, 0x55, 0x83, 0x64, 0xc6, 0x30, 0xb1, 0x05, 0x21, 0xc9, 0x0c, + 0x0a, 0x2b, 0x9f, 0xff, 0x3c, 0x8a, 0xee, 0x18, 0x66, 0xbf, 0x3d, 0x39, 0x3b, 0x28, 0x2e, 0x58, + 0x93, 0xfa, 0x1c, 0x66, 0xc5, 0x55, 0x3d, 0xfe, 0x02, 0x33, 0xe9, 0xe7, 0x75, 0x51, 0xbe, 0xbc, + 0xb1, 0x9e, 0xc9, 0x5a, 0xdb, 0x63, 0x25, 0xf3, 0x6c, 0x59, 0x6a, 0x80, 0xac, 0x55, 0x9f, 0x3e, + 0x41, 0x0e, 0xc9, 0x5a, 0x43, 0xbc, 0xe9, 0x62, 0xed, 0x3c, 0x67, 0x05, 0xec, 0x62, 0x63, 0xa1, + 0x11, 0x22, 0x5d, 0xdc, 0x81, 0x4c, 0x3c, 0x6e, 0x45, 0xf2, 0x04, 0x64, 0x3b, 0xcf, 0x41, 0x3c, + 0xd6, 0xaa, 0x1a, 0x40, 0xe2, 0xb1, 0x17, 0x54, 0x7e, 0x4e, 0xa3, 0xef, 0x34, 0x4d, 0x7a, 0x52, + 0xd1, 0x65, 0x46, 0xe1, 0x35, 0x08, 0x4b, 0x82, 0xcc, 0x7f, 0x97, 0x30, 0x33, 0xeb, 0xac, 0xa8, + 0xcb, 0x9c, 0xd4, 0x97, 0xea, 0xc1, 0xb8, 0x5b, 0xe7, 0x56, 0x08, 0x1f, 0x8d, 0x3f, 0xe8, 0xa1, + 0x4c, 0x50, 0x6f, 0x65, 0x3a, 0xc4, 0x3c, 0xf4, 0xab, 0x76, 0xc2, 0xcc, 0x5a, 0x2f, 0x67, 0x4e, + 0x9f, 0xf7, 0x49, 0x9e, 0xd3, 0x6a, 0xd5, 0xca, 0x8e, 0x48, 0x91, 0x5d, 0xd0, 0x9a, 0x83, 0xd3, + 0x67, 0x45, 0xc5, 0x10, 0x43, 0x4e, 0x9f, 0x03, 0xb8, 0xc9, 0xe6, 0x81, 0xe7, 0x83, 0x22, 0xa5, + 0xef, 0x40, 0x36, 0x0f, 0xed, 0x08, 0x06, 0xc9, 0xe6, 0x31, 0xd6, 0x9c, 0xc2, 0xbe, 0xcc, 0x59, + 0x72, 0xa5, 0x96, 0x00, 0xb7, 0x83, 0x85, 0x04, 0xae, 0x01, 0x77, 0x43, 0x88, 0x59, 0x04, 0x84, + 0xe0, 0x94, 0x96, 0x39, 0x49, 0xe0, 0x5d, 0x18, 0xa9, 0xa3, 0x64, 0xc8, 0x22, 0x00, 0x19, 0x50, + 0x5c, 0x75, 0xc7, 0xc6, 0x57, 0x5c, 0x70, 0xc5, 0xe6, 0x6e, 0x08, 0x31, 0xcb, 0xa0, 0x10, 0x4c, + 0xca, 0x3c, 0xe3, 0x60, 0x1a, 0x48, 0x0d, 0x21, 0x41, 0xa6, 0x81, 0x4b, 0x00, 0x93, 0x47, 0xb4, + 0x9a, 0x51, 0xaf, 0x49, 0x21, 0x09, 0x9a, 0x6c, 0x09, 0x73, 0x65, 0x52, 0xd6, 0x9d, 0x95, 0x2b, + 0x70, 0x65, 0x52, 0x55, 0x8b, 0x95, 0x2b, 0xe4, 0xca, 0xa4, 0x03, 0x80, 0x22, 0x9e, 0x90, 0x9a, + 0xfb, 0x8b, 0x28, 0x24, 0xc1, 0x22, 0xb6, 0x84, 0x59, 0xa3, 0x65, 0x11, 0x17, 0x1c, 0xac, 0xd1, + 0xaa, 0x00, 0xd6, 0xd3, 0xe0, 0xdb, 0xa8, 0xdc, 0x44, 0x12, 0xd9, 0x2b, 0x94, 0xef, 0x65, 0x34, + 0x4f, 0x6b, 0x10, 0x49, 0x54, 0xbb, 0xb7, 0x52, 0x24, 0x92, 0x74, 0x29, 0x30, 0x94, 0xd4, 0x59, + 0xb5, 0xaf, 0x76, 0xe0, 0x98, 0xfa, 0x6e, 0x08, 0x31, 0xf1, 0xa9, 0x2d, 0xf4, 0x0e, 0xa9, 0xaa, + 0xac, 0x59, 0xfc, 0x1f, 0xfa, 0x0b, 0xd4, 0xca, 0x91, 0xf8, 0xe4, 0xe3, 0xc0, 0xf4, 0x6a, 0x03, + 0xb7, 0xaf, 0x60, 0x30, 0x74, 0xdf, 0x0b, 0x32, 0x26, 0xe3, 0x14, 0x12, 0xeb, 0x71, 0xa6, 0xaf, + 0x35, 0x3d, 0x4f, 0x33, 0x1f, 0xf6, 0x61, 0xd6, 0x2b, 0x0d, 0xda, 0xc5, 0x11, 0x5b, 0xd2, 0x29, + 0x7b, 0xf5, 0x2e, 0xab, 0x79, 0x56, 0xcc, 0xd4, 0xca, 0xfd, 0x1c, 0xb1, 0xe4, 0x83, 0x91, 0x57, + 0x1a, 0x7a, 0x95, 0x4c, 0x02, 0x01, 0xca, 0x72, 0x4c, 0xaf, 0xbd, 0x09, 0x04, 0xb4, 0xa8, 0x39, + 0x24, 0x81, 0x08, 0xf1, 0xe6, 0x1c, 0x45, 0x3b, 0x57, 0xef, 0x7d, 0x4e, 0x59, 0x9b, 0xcb, 0x61, + 0xd6, 0x20, 0x88, 0x6c, 0x65, 0x83, 0x0a, 0x66, 0x7f, 0xa9, 0xfd, 0x9b, 0x29, 0xf6, 0x08, 0xb1, + 0xd3, 0x9d, 0x66, 0x8f, 0x07, 0x90, 0x1e, 0x57, 0xe6, 0x99, 0x3c, 0xe6, 0xaa, 0xfb, 0x48, 0xfe, + 0xf1, 0x00, 0xd2, 0x3a, 0x93, 0xb1, 0xab, 0xf5, 0x92, 0x24, 0x57, 0xb3, 0x8a, 0x2d, 0x8a, 0x74, + 0x87, 0xe5, 0xac, 0x02, 0x67, 0x32, 0x4e, 0xa9, 0x01, 0x8a, 0x9c, 0xc9, 0xf4, 0xa8, 0x98, 0x0c, + 0xce, 0x2e, 0xc5, 0x76, 0x9e, 0xcd, 0xe0, 0x8e, 0xda, 0x31, 0x24, 0x00, 0x24, 0x83, 0xf3, 0x82, + 0x9e, 0x41, 0x24, 0x77, 0xdc, 0x3c, 0x4b, 0x48, 0x2e, 0xfd, 0x6d, 0xe1, 0x66, 0x1c, 0xb0, 0x77, + 0x10, 0x79, 0x14, 0x3c, 0xf5, 0x9c, 0x2e, 0xaa, 0xe2, 0xa0, 0xe0, 0x0c, 0xad, 0x67, 0x0b, 0xf4, + 0xd6, 0xd3, 0x02, 0x41, 0x58, 0x9d, 0xd2, 0x77, 0x4d, 0x69, 0x9a, 0x7f, 0x7c, 0x61, 0xb5, 0xf9, + 0x3d, 0x56, 0xf2, 0x50, 0x58, 0x05, 0x1c, 0xa8, 0x8c, 0x72, 0x22, 0x07, 0x4c, 0x40, 0xdb, 0x1d, + 0x26, 0x8f, 0xfa, 0x41, 0xbf, 0x9f, 0x09, 0x5f, 0xe5, 0x34, 0xe4, 0x47, 0x00, 0x43, 0xfc, 0xb4, + 0xa0, 0x39, 0x6e, 0x71, 0xea, 0x73, 0x49, 0x93, 0xab, 0xce, 0x15, 0x23, 0xb7, 0xa0, 0x12, 0x41, + 0x8e, 0x5b, 0x10, 0xd4, 0xdf, 0x45, 0x07, 0x09, 0x2b, 0x42, 0x5d, 0xd4, 0xc8, 0x87, 0x74, 0x91, + 0xe2, 0xcc, 0xe6, 0x57, 0x4b, 0xd5, 0xc8, 0x94, 0xdd, 0xb4, 0x8e, 0x58, 0xb0, 0x21, 0x64, 0xf3, + 0x8b, 0xc2, 0x26, 0x27, 0x87, 0x3e, 0x8f, 0xba, 0xf7, 0xaf, 0x3b, 0x56, 0x8e, 0xf0, 0xfb, 0xd7, + 0x18, 0x8b, 0x57, 0x52, 0x8e, 0x91, 0x1e, 0x2b, 0xee, 0x38, 0xd9, 0x18, 0x06, 0x9b, 0x2d, 0x8f, + 0xe3, 0x73, 0x27, 0xa7, 0xa4, 0x92, 0x5e, 0x37, 0x03, 0x86, 0x0c, 0x86, 0x6c, 0x79, 0x02, 0x38, + 0x08, 0x61, 0x8e, 0xe7, 0x1d, 0x56, 0x70, 0x5a, 0x70, 0x5f, 0x08, 0x73, 0x8d, 0x29, 0x30, 0x14, + 0xc2, 0x30, 0x05, 0x30, 0x6e, 0xc5, 0x79, 0x10, 0xe5, 0xc7, 0x64, 0xee, 0xcd, 0xd8, 0xe4, 0x59, + 0x8f, 0x94, 0x87, 0xc6, 0x2d, 0xe0, 0xac, 0x87, 0x7c, 0xb6, 0x97, 0x29, 0xa9, 0x66, 0xfa, 0x74, + 0x23, 0x1d, 0x3f, 0xc5, 0xed, 0xb8, 0x24, 0xf2, 0x90, 0x2f, 0xac, 0x01, 0xc2, 0xce, 0xc1, 0x9c, + 0xcc, 0x74, 0x4d, 0x3d, 0x35, 0x10, 0xf2, 0x4e, 0x55, 0x1f, 0xf5, 0x83, 0xc0, 0xcf, 0x9b, 0x2c, + 0xa5, 0x2c, 0xe0, 0x47, 0xc8, 0x87, 0xf8, 0x81, 0x20, 0xc8, 0xde, 0x9a, 0x7a, 0xcb, 0x1d, 0xdd, + 0x76, 0x91, 0xaa, 0x7d, 0x6c, 0x8c, 0x34, 0x0f, 0xe0, 0x42, 0xd9, 0x1b, 0xc2, 0x83, 0x39, 0xda, + 0x1e, 0xd0, 0x86, 0xe6, 0xa8, 0x3e, 0x7f, 0x1d, 0x32, 0x47, 0x7d, 0xb0, 0xf2, 0xf9, 0x33, 0x35, + 0x47, 0x77, 0x09, 0x27, 0x4d, 0xde, 0xfe, 0x26, 0xa3, 0xd7, 0x6a, 0x23, 0xec, 0xa9, 0x6f, 0x4b, + 0xc5, 0xe2, 0xc5, 0x3b, 0xb0, 0x2b, 0xde, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x1d, 0x42, 0xaf, 0x6f, + 0xb0, 0x55, 0xd8, 0x1a, 0xcc, 0x07, 0x7c, 0xab, 0x37, 0x7a, 0x7b, 0x7d, 0x83, 0xd7, 0x7a, 0xb7, + 0x06, 0xf3, 0xca, 0xf7, 0x5f, 0xb6, 0x13, 0xd7, 0x76, 0xde, 0xe4, 0x61, 0x09, 0xcf, 0x96, 0xd4, + 0x97, 0x4e, 0xba, 0xf6, 0x34, 0x1a, 0x4a, 0x27, 0x71, 0x15, 0xeb, 0x33, 0x30, 0xbe, 0x52, 0x9c, + 0xb0, 0x3a, 0x13, 0x0f, 0xe9, 0x9f, 0x0f, 0x30, 0xda, 0xc2, 0xa1, 0x4d, 0x53, 0x48, 0xc9, 0x3c, + 0x6e, 0x74, 0x50, 0x73, 0xa3, 0x78, 0x23, 0x60, 0xaf, 0x7b, 0xb1, 0x78, 0x73, 0x20, 0x6d, 0x1e, + 0xfc, 0x39, 0x8c, 0xfd, 0xc4, 0x31, 0xd4, 0xab, 0xde, 0x87, 0x8e, 0x4f, 0x87, 0x2b, 0x28, 0xf7, + 0x7f, 0xdd, 0xee, 0x2b, 0xa0, 0x7f, 0x35, 0x09, 0x9e, 0x0d, 0xb1, 0x08, 0x26, 0xc2, 0xf3, 0x1b, + 0xe9, 0xa8, 0x82, 0xfc, 0x7d, 0xbb, 0x81, 0x6e, 0x51, 0xf1, 0x5e, 0xc5, 0xeb, 0x2a, 0xa5, 0x95, + 0x9a, 0x13, 0xa1, 0x6e, 0x35, 0x30, 0x9c, 0x19, 0x2f, 0x6e, 0xa8, 0x65, 0x7d, 0x14, 0xc8, 0x81, + 0xd5, 0xfb, 0x7f, 0x56, 0x79, 0x42, 0x96, 0x2d, 0x1a, 0x16, 0xe8, 0x8b, 0x9b, 0xaa, 0x61, 0x73, + 0xc5, 0x82, 0xc5, 0x37, 0x06, 0x9e, 0x0f, 0x34, 0xec, 0x7c, 0x75, 0xe0, 0xf3, 0x9b, 0x29, 0xa9, + 0xb2, 0xfc, 0xc7, 0x28, 0x7a, 0xe0, 0xb0, 0xe6, 0x79, 0x02, 0x38, 0xf5, 0xf8, 0x71, 0xc0, 0x3e, + 0xa6, 0xa4, 0x0b, 0xf7, 0xbb, 0xbf, 0x9c, 0xb2, 0xf9, 0x82, 0x8e, 0xa3, 0xb2, 0x97, 0xe5, 0x9c, + 0x56, 0xdd, 0x2f, 0xe8, 0xb8, 0x76, 0x25, 0x15, 0xe3, 0x5f, 0xd0, 0x09, 0xe0, 0xd6, 0x17, 0x74, + 0x3c, 0x9e, 0xbd, 0x5f, 0xd0, 0xf1, 0x5a, 0x0b, 0x7e, 0x41, 0x27, 0xac, 0x81, 0x85, 0xf7, 0xb6, + 0x08, 0xf2, 0xdc, 0x7a, 0x90, 0x45, 0xf7, 0x18, 0xfb, 0xd9, 0x4d, 0x54, 0x90, 0x05, 0x4e, 0x72, + 0xe2, 0x9e, 0xdb, 0x80, 0x36, 0x75, 0xee, 0xba, 0x6d, 0x0d, 0xe6, 0x95, 0xef, 0x9f, 0xaa, 0xdd, + 0x8d, 0x0e, 0xe7, 0xac, 0x12, 0x5f, 0x4f, 0x5a, 0x0f, 0x85, 0xe7, 0xc6, 0x82, 0xdd, 0xf3, 0x1b, + 0xc3, 0x60, 0xa4, 0xba, 0x0d, 0xa1, 0x3a, 0x3d, 0xee, 0x33, 0x04, 0xba, 0x7c, 0x6b, 0x30, 0x8f, + 0x2c, 0x23, 0xd2, 0xb7, 0xec, 0xed, 0x01, 0xc6, 0xdc, 0xbe, 0x7e, 0x3a, 0x5c, 0x41, 0xb9, 0x5f, + 0xaa, 0xb4, 0xd1, 0x76, 0x2f, 0xfa, 0x79, 0xb3, 0xcf, 0xd4, 0xc4, 0xe9, 0xe6, 0x78, 0x28, 0x1e, + 0x4a, 0x20, 0xec, 0x25, 0xb4, 0x2f, 0x81, 0xf0, 0x2e, 0xa3, 0x9f, 0xdf, 0x4c, 0x49, 0x95, 0xe5, + 0x9f, 0x46, 0xd1, 0x6d, 0xb4, 0x2c, 0x6a, 0x1c, 0x7c, 0x31, 0xd4, 0x32, 0x18, 0x0f, 0x5f, 0xde, + 0x58, 0x4f, 0x15, 0xea, 0x5f, 0x47, 0xd1, 0x9d, 0x40, 0xa1, 0xe4, 0x00, 0xb9, 0x81, 0x75, 0x77, + 0xa0, 0xfc, 0xf0, 0xe6, 0x8a, 0xd8, 0x72, 0x6f, 0xe3, 0x93, 0xee, 0xa7, 0x65, 0x02, 0xb6, 0x27, + 0xf8, 0xa7, 0x65, 0xfa, 0xb5, 0xe0, 0x21, 0x0f, 0x39, 0x6f, 0x37, 0x5d, 0xde, 0x43, 0x1e, 0x71, + 0x43, 0x0d, 0xec, 0x39, 0xd6, 0x7a, 0x39, 0x9f, 0x93, 0x57, 0xef, 0x4a, 0x52, 0xa4, 0xb8, 0x13, + 0x29, 0xef, 0x77, 0xa2, 0x39, 0x78, 0x38, 0xd6, 0x48, 0x4f, 0x59, 0xbb, 0x91, 0x7a, 0x8c, 0xe9, + 0x6b, 0x24, 0x78, 0x38, 0xd6, 0x41, 0x11, 0x6f, 0x2a, 0x6b, 0x0c, 0x79, 0x03, 0xc9, 0xe2, 0x93, + 0x21, 0x28, 0x48, 0xd1, 0xb5, 0x37, 0x7d, 0xe6, 0xbe, 0x11, 0xb2, 0xd2, 0x39, 0x77, 0xdf, 0x1c, + 0x48, 0x23, 0x6e, 0x27, 0x94, 0x7f, 0x45, 0x49, 0x4a, 0xab, 0xa0, 0x5b, 0x4d, 0x0d, 0x72, 0x6b, + 0xd3, 0x3e, 0xb7, 0x3b, 0x2c, 0x5f, 0xcc, 0x0b, 0xd5, 0x99, 0xa8, 0x5b, 0x9b, 0xea, 0x77, 0x0b, + 0x68, 0x78, 0x2c, 0x68, 0xdc, 0x8a, 0xf4, 0xf2, 0x49, 0xd8, 0x8c, 0x93, 0x55, 0xae, 0x0f, 0x62, + 0xf1, 0x7a, 0xaa, 0x61, 0xd4, 0x53, 0x4f, 0x30, 0x92, 0x36, 0x07, 0xd2, 0xf0, 0x7c, 0xce, 0x72, + 0xab, 0xc7, 0xd3, 0x56, 0x8f, 0xad, 0xce, 0x90, 0x7a, 0x3a, 0x5c, 0x01, 0x9e, 0x86, 0xaa, 0x51, + 0x75, 0x98, 0xd5, 0x7c, 0x2f, 0xcb, 0xf3, 0xf1, 0x7a, 0x60, 0x98, 0xb4, 0x50, 0xf0, 0x34, 0xd4, + 0x03, 0x23, 0x23, 0xb9, 0x3d, 0x3d, 0x2c, 0xc6, 0x7d, 0x76, 0x04, 0x35, 0x68, 0x24, 0xdb, 0x34, + 0x38, 0xd1, 0xb2, 0x9a, 0x5a, 0xd7, 0x36, 0x0e, 0x37, 0x5c, 0xa7, 0xc2, 0x5b, 0x83, 0x79, 0xf0, + 0xb8, 0x5d, 0x50, 0x62, 0x65, 0xb9, 0x8f, 0x99, 0x70, 0x56, 0x92, 0x07, 0x3d, 0x14, 0x38, 0x15, + 0x94, 0xd3, 0xe8, 0x6d, 0x96, 0xce, 0x28, 0xf7, 0x3e, 0x29, 0xb2, 0x81, 0xe0, 0x93, 0x22, 0x00, + 0x82, 0xae, 0x93, 0xbf, 0xeb, 0xe3, 0xd0, 0x83, 0xd4, 0xd7, 0x75, 0x4a, 0xd9, 0xa2, 0x42, 0x5d, + 0xe7, 0xa5, 0x41, 0x34, 0xd0, 0x6e, 0xd5, 0xab, 0xf1, 0x4f, 0x42, 0x66, 0xc0, 0xfb, 0xf1, 0xeb, + 0x83, 0x58, 0xb0, 0xa2, 0x18, 0x87, 0xd9, 0x3c, 0xe3, 0xbe, 0x15, 0xc5, 0xb2, 0xd1, 0x20, 0xa1, + 0x15, 0xa5, 0x8b, 0x62, 0xd5, 0x6b, 0x72, 0x84, 0x83, 0x34, 0x5c, 0x3d, 0xc9, 0x0c, 0xab, 0x9e, + 0x66, 0x3b, 0x0f, 0x36, 0x0b, 0x3d, 0x64, 0xf8, 0xa5, 0xda, 0x2c, 0x7b, 0xc6, 0xb6, 0x78, 0x65, + 0x12, 0x82, 0xa1, 0xa8, 0x83, 0x29, 0xc0, 0x03, 0xfb, 0x86, 0x6b, 0x9f, 0xbd, 0x96, 0x25, 0x25, + 0x15, 0x29, 0x12, 0xef, 0xe6, 0x54, 0x18, 0xec, 0x90, 0xa1, 0xcd, 0x29, 0xaa, 0x01, 0x1e, 0x9b, + 0xbb, 0x2f, 0x3b, 0x7a, 0xa6, 0x82, 0x7e, 0xab, 0xd0, 0x7d, 0xd7, 0xf1, 0xf1, 0x00, 0x12, 0x3e, + 0x36, 0x6f, 0x01, 0x7d, 0xf0, 0x2d, 0x9d, 0x7e, 0x16, 0x30, 0xe5, 0xa2, 0xa1, 0x8d, 0x30, 0xae, + 0x02, 0x06, 0xb5, 0x4e, 0x70, 0x29, 0xff, 0x09, 0x5d, 0xf9, 0x06, 0xb5, 0xc9, 0x4f, 0x05, 0x12, + 0x1a, 0xd4, 0x5d, 0x14, 0xe4, 0x99, 0xf6, 0x3e, 0xe8, 0x61, 0x40, 0xdf, 0xde, 0xfa, 0xac, 0xf5, + 0x72, 0x60, 0xe6, 0xec, 0x66, 0x4b, 0xe7, 0x39, 0x81, 0xa7, 0xa0, 0xbb, 0xd9, 0xd2, 0xff, 0x98, + 0x60, 0x7d, 0x10, 0x0b, 0x1f, 0xc9, 0x13, 0x4e, 0xdf, 0xb5, 0xcf, 0xca, 0x3d, 0xc5, 0x15, 0xf2, + 0xce, 0xc3, 0xf2, 0x47, 0xfd, 0xa0, 0xb9, 0x00, 0x7b, 0x52, 0xb1, 0x84, 0xd6, 0xb5, 0xfa, 0xde, + 0x9e, 0x7b, 0xc3, 0x48, 0xc9, 0x62, 0xf0, 0xb5, 0xbd, 0xfb, 0x61, 0x48, 0xd9, 0xfe, 0x2a, 0x7a, + 0xff, 0x90, 0xcd, 0x26, 0xb4, 0x48, 0xc7, 0x3f, 0x70, 0xaf, 0x9c, 0xb2, 0x59, 0xdc, 0xfc, 0xac, + 0xed, 0xdd, 0xc2, 0xc4, 0xe6, 0xd2, 0xdc, 0x2e, 0x3d, 0x5f, 0xcc, 0x26, 0x9c, 0x70, 0x70, 0x69, + 0x4e, 0xfc, 0x1e, 0x37, 0x02, 0xe4, 0xd2, 0x9c, 0x03, 0x00, 0x7b, 0xd3, 0x8a, 0x52, 0xaf, 0xbd, + 0x46, 0x10, 0xb4, 0xa7, 0x00, 0xb3, 0xea, 0x6a, 0x7b, 0x4d, 0x62, 0x0b, 0x2f, 0xb9, 0x19, 0x1d, + 0x21, 0x45, 0x56, 0xdd, 0x2e, 0x65, 0x06, 0x83, 0xac, 0xbe, 0xf8, 0x62, 0xc6, 0x62, 0x3e, 0x27, + 0xd5, 0x0a, 0x0c, 0x06, 0x55, 0x4b, 0x0b, 0x40, 0x06, 0x83, 0x17, 0x34, 0xa3, 0xbc, 0x6d, 0xe6, + 0xe4, 0x6a, 0x9f, 0x55, 0x6c, 0xc1, 0xb3, 0x82, 0xc2, 0xaf, 0x26, 0xe8, 0x06, 0xb5, 0x19, 0x64, + 0x94, 0x63, 0xac, 0xc9, 0x0a, 0x05, 0x21, 0xef, 0xdf, 0x89, 0xaf, 0xd6, 0xd6, 0x9c, 0x55, 0xf0, + 0xf9, 0x9b, 0xb4, 0x02, 0x21, 0x24, 0x2b, 0x44, 0x61, 0xd0, 0xf7, 0x27, 0x59, 0x31, 0xf3, 0xf6, + 0xfd, 0x89, 0xfd, 0xcd, 0xc7, 0x3b, 0x38, 0x60, 0xe2, 0xbb, 0x6c, 0x34, 0xf9, 0x65, 0x22, 0xf5, + 0xee, 0xa3, 0xb7, 0xd1, 0x6d, 0x02, 0x89, 0xef, 0x7e, 0x12, 0xb8, 0x7a, 0x5d, 0xd2, 0x82, 0xa6, + 0xed, 0x2d, 0x33, 0x9f, 0x2b, 0x87, 0x08, 0xba, 0x82, 0xa4, 0x89, 0xaa, 0x42, 0x7e, 0xba, 0x28, + 0x4e, 0x2a, 0x76, 0x91, 0xe5, 0xb4, 0x02, 0x51, 0x55, 0xaa, 0x5b, 0x72, 0x24, 0xaa, 0xfa, 0x38, + 0x73, 0x5d, 0x41, 0x48, 0x9d, 0x4f, 0x2f, 0x4f, 0x2b, 0x92, 0xc0, 0xeb, 0x0a, 0xd2, 0x46, 0x17, + 0x43, 0x4e, 0xd2, 0x02, 0xb8, 0x95, 0x18, 0x48, 0xd7, 0xc5, 0x4a, 0x8c, 0x0f, 0xf5, 0xee, 0x9d, + 0xf8, 0x12, 0x62, 0x0d, 0x12, 0x03, 0x65, 0xce, 0x47, 0x22, 0x89, 0x41, 0x58, 0xc3, 0xcc, 0xb6, + 0x23, 0xca, 0xab, 0x2c, 0xa9, 0x27, 0x94, 0x9f, 0x90, 0x8a, 0xcc, 0x29, 0xa7, 0x15, 0x9c, 0x6d, + 0x0a, 0x89, 0x1d, 0x06, 0x99, 0x6d, 0x18, 0xab, 0x1c, 0xfe, 0x5e, 0xf4, 0x61, 0xb3, 0xd8, 0xd0, + 0x42, 0xfd, 0xa5, 0x82, 0x57, 0xe2, 0x4f, 0x9c, 0x8c, 0x3f, 0xd2, 0x36, 0x26, 0xbc, 0xa2, 0x64, + 0xde, 0xda, 0xfe, 0x40, 0xff, 0x2e, 0xc0, 0xa7, 0xa3, 0x66, 0x50, 0x1c, 0x33, 0x9e, 0x5d, 0x34, + 0x7b, 0x3b, 0xf5, 0xda, 0x0a, 0x18, 0x14, 0xb6, 0x38, 0x0e, 0x7c, 0x8c, 0xc0, 0xc7, 0x99, 0x60, + 0x67, 0x4b, 0x4f, 0x69, 0x99, 0xc3, 0x60, 0xe7, 0x68, 0x0b, 0x00, 0x09, 0x76, 0x5e, 0xd0, 0x8c, + 0x70, 0x5b, 0x3c, 0xa5, 0xe1, 0xca, 0x4c, 0xe9, 0xb0, 0xca, 0x4c, 0x9d, 0x37, 0x01, 0xf2, 0xe8, + 0xc3, 0x23, 0x3a, 0x3f, 0xa7, 0x55, 0x7d, 0x99, 0x95, 0xfb, 0xcd, 0x2a, 0x4f, 0xf8, 0x02, 0xbe, + 0x2b, 0x67, 0x88, 0x58, 0x23, 0x48, 0x2a, 0x84, 0xa0, 0x26, 0x9c, 0x1a, 0xe0, 0xa0, 0x3e, 0x26, + 0x73, 0x2a, 0x3e, 0xad, 0x30, 0x5e, 0xc7, 0x8c, 0x58, 0x10, 0x12, 0x4e, 0x51, 0xd8, 0x7a, 0xa9, + 0xc8, 0x30, 0xa7, 0x74, 0xd6, 0x8c, 0xb0, 0xea, 0x84, 0xac, 0xe6, 0xb4, 0xe0, 0xca, 0x24, 0x38, + 0x08, 0xb6, 0x4c, 0xfa, 0x79, 0xe4, 0x20, 0x78, 0x88, 0x9e, 0x35, 0xbf, 0x9d, 0x86, 0x3f, 0x61, + 0x15, 0x97, 0x7f, 0x87, 0xe4, 0xac, 0xca, 0xc1, 0xfc, 0x76, 0x1b, 0xd5, 0x21, 0x91, 0xf9, 0x1d, + 0xd6, 0xb0, 0x3e, 0xe0, 0xed, 0x94, 0xe1, 0x0d, 0xad, 0xf4, 0x38, 0x79, 0x35, 0x27, 0x59, 0xae, + 0x46, 0xc3, 0x8f, 0x02, 0xb6, 0x11, 0x1d, 0xe4, 0x03, 0xde, 0x43, 0x75, 0xad, 0x4f, 0x9e, 0x87, + 0x4b, 0x08, 0xce, 0xa5, 0x7b, 0xec, 0x23, 0xe7, 0xd2, 0xfd, 0x5a, 0x66, 0xbb, 0x68, 0x58, 0xc1, + 0xad, 0x04, 0xb1, 0xc3, 0x52, 0x78, 0x48, 0x65, 0xd9, 0x04, 0x20, 0xb2, 0x5d, 0x0c, 0x2a, 0x98, + 0xf5, 0xd5, 0x60, 0x7b, 0x59, 0x41, 0xf2, 0xec, 0x67, 0xf0, 0x86, 0xb3, 0x65, 0xa7, 0x25, 0x90, + 0xf5, 0xd5, 0x4f, 0xfa, 0x5c, 0xed, 0x53, 0x3e, 0xcd, 0x9a, 0xd0, 0xff, 0x28, 0xd0, 0x6e, 0x82, + 0xe8, 0x77, 0x65, 0x91, 0xd6, 0x47, 0x3a, 0x61, 0xb3, 0x6e, 0x97, 0xe5, 0xa4, 0x59, 0x9a, 0x4e, + 0x69, 0x42, 0xb3, 0x92, 0x8f, 0x5f, 0x84, 0xdb, 0x0a, 0xe0, 0xc8, 0xd3, 0xfd, 0x01, 0x6a, 0xd6, + 0x33, 0xe3, 0x26, 0x96, 0x4c, 0xe4, 0x1f, 0xe8, 0x3a, 0xab, 0x69, 0xa5, 0x56, 0xeb, 0x7d, 0xca, + 0xc1, 0xec, 0xb4, 0xb8, 0xd8, 0x02, 0x9b, 0x8a, 0x22, 0xb3, 0x33, 0xac, 0x61, 0x4e, 0x98, 0x2c, + 0xee, 0x94, 0xd6, 0x2c, 0x5f, 0x52, 0x71, 0xc9, 0x6d, 0x03, 0x35, 0x66, 0x51, 0xc8, 0x09, 0x13, + 0x4e, 0x9b, 0x94, 0xa7, 0xeb, 0x76, 0xbb, 0x58, 0x1d, 0xc0, 0xe7, 0xf4, 0x1e, 0x4b, 0x02, 0x43, + 0x52, 0x9e, 0x00, 0x6e, 0x9d, 0xc0, 0x56, 0x8c, 0xa4, 0x09, 0xa9, 0xf9, 0x09, 0x59, 0xe5, 0x8c, + 0xa4, 0x62, 0x5d, 0x87, 0x27, 0xb0, 0x2d, 0x13, 0xdb, 0x10, 0x76, 0x02, 0x8b, 0xc1, 0x66, 0x77, + 0xa9, 0xfe, 0xee, 0x98, 0xba, 0x40, 0x78, 0x0f, 0xa4, 0x49, 0xa2, 0xbc, 0xf0, 0xf2, 0xe0, 0xfd, + 0x30, 0x64, 0x5e, 0x7c, 0x92, 0x22, 0x91, 0x86, 0xdc, 0xf1, 0xe9, 0x38, 0x09, 0xc8, 0xa7, 0x01, + 0xc2, 0x7c, 0x0c, 0x41, 0xfe, 0xde, 0xfe, 0xe9, 0x0c, 0xae, 0x3e, 0x65, 0xbc, 0xe1, 0xd3, 0xb5, + 0xa1, 0xd8, 0xfe, 0xc2, 0xd9, 0xe6, 0x40, 0xda, 0x6c, 0x1e, 0x77, 0x2e, 0x09, 0xdf, 0x4e, 0xd3, + 0x23, 0x5a, 0x7b, 0xde, 0x62, 0x6e, 0x84, 0xb1, 0x91, 0x22, 0x9b, 0xc7, 0x2e, 0x65, 0x06, 0x7a, + 0x23, 0x7b, 0x95, 0x66, 0x5c, 0xc9, 0xda, 0x6b, 0xb9, 0x1b, 0x5d, 0x03, 0x5d, 0x0a, 0xa9, 0x15, + 0x4e, 0x9b, 0x58, 0xde, 0x30, 0x53, 0x36, 0x9b, 0xe5, 0x54, 0x41, 0xa7, 0x94, 0xc8, 0x2f, 0xb9, + 0x6d, 0x75, 0x6d, 0x79, 0x41, 0x24, 0x96, 0x07, 0x15, 0x4c, 0x1a, 0xd9, 0x60, 0xf2, 0x39, 0x48, + 0xdb, 0xb0, 0x6b, 0x5d, 0x33, 0x0e, 0x80, 0xa4, 0x91, 0x5e, 0xd0, 0xbc, 0x6c, 0xd5, 0x88, 0xf7, + 0x69, 0xdb, 0x12, 0xf0, 0xbb, 0x37, 0x42, 0xd9, 0x12, 0x23, 0x2f, 0x5b, 0x79, 0x30, 0xb3, 0x4f, + 0x00, 0x1e, 0x5e, 0xae, 0x0e, 0x52, 0xb8, 0x4f, 0x80, 0xfa, 0x82, 0x41, 0xf6, 0x09, 0x18, 0xeb, + 0x76, 0x9d, 0xfe, 0xc8, 0xef, 0x21, 0xa9, 0x4d, 0xe5, 0x3c, 0x5d, 0xe7, 0x05, 0x43, 0x5d, 0x87, + 0x29, 0xb8, 0x4d, 0x6a, 0x7f, 0x42, 0xd8, 0xd3, 0xa4, 0xbe, 0x4f, 0x07, 0x3f, 0xec, 0xc3, 0x4c, + 0x5c, 0xd2, 0x9b, 0x32, 0x71, 0x4f, 0xc6, 0xff, 0x09, 0x77, 0x29, 0x44, 0xe2, 0x52, 0x07, 0x92, + 0xb6, 0x5f, 0x7e, 0xfa, 0x5f, 0xdf, 0xdc, 0x1a, 0xfd, 0xe2, 0x9b, 0x5b, 0xa3, 0xff, 0xf9, 0xe6, + 0xd6, 0xe8, 0xe7, 0xdf, 0xde, 0x7a, 0xef, 0x17, 0xdf, 0xde, 0x7a, 0xef, 0xbf, 0xbf, 0xbd, 0xf5, + 0xde, 0xd7, 0xef, 0xab, 0xbf, 0x47, 0x79, 0xfe, 0xff, 0xc4, 0x5f, 0x95, 0x7c, 0xfe, 0x7f, 0x01, + 0x00, 0x00, 0xff, 0xff, 0xe5, 0xb3, 0x13, 0x72, 0xb3, 0x72, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -422,13 +426,14 @@ type ClientCommandsClient interface { ObjectCreate(ctx context.Context, in *pb.RpcObjectCreateRequest, opts ...grpc.CallOption) (*pb.RpcObjectCreateResponse, error) ObjectCreateBookmark(ctx context.Context, in *pb.RpcObjectCreateBookmarkRequest, opts ...grpc.CallOption) (*pb.RpcObjectCreateBookmarkResponse, error) ObjectCreateFromUrl(ctx context.Context, in *pb.RpcObjectCreateFromUrlRequest, opts ...grpc.CallOption) (*pb.RpcObjectCreateFromUrlResponse, error) - ObjectChatAdd(ctx context.Context, in *pb.RpcObjectChatAddRequest, opts ...grpc.CallOption) (*pb.RpcObjectChatAddResponse, error) // ObjectCreateSet just creates the new set, without adding the link to it from some other page ObjectCreateSet(ctx context.Context, in *pb.RpcObjectCreateSetRequest, opts ...grpc.CallOption) (*pb.RpcObjectCreateSetResponse, error) ObjectGraph(ctx context.Context, in *pb.RpcObjectGraphRequest, opts ...grpc.CallOption) (*pb.RpcObjectGraphResponse, error) ObjectSearch(ctx context.Context, in *pb.RpcObjectSearchRequest, opts ...grpc.CallOption) (*pb.RpcObjectSearchResponse, error) ObjectSearchWithMeta(ctx context.Context, in *pb.RpcObjectSearchWithMetaRequest, opts ...grpc.CallOption) (*pb.RpcObjectSearchWithMetaResponse, error) ObjectSearchSubscribe(ctx context.Context, in *pb.RpcObjectSearchSubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectSearchSubscribeResponse, error) + ObjectCrossSpaceSearchSubscribe(ctx context.Context, in *pb.RpcObjectCrossSpaceSearchSubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectCrossSpaceSearchSubscribeResponse, error) + ObjectCrossSpaceSearchUnsubscribe(ctx context.Context, in *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectCrossSpaceSearchUnsubscribeResponse, error) ObjectSubscribeIds(ctx context.Context, in *pb.RpcObjectSubscribeIdsRequest, opts ...grpc.CallOption) (*pb.RpcObjectSubscribeIdsResponse, error) ObjectGroupsSubscribe(ctx context.Context, in *pb.RpcObjectGroupsSubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectGroupsSubscribeResponse, error) ObjectSearchUnsubscribe(ctx context.Context, in *pb.RpcObjectSearchUnsubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectSearchUnsubscribeResponse, error) @@ -630,6 +635,7 @@ type ClientCommandsClient interface { DebugOpenedObjects(ctx context.Context, in *pb.RpcDebugOpenedObjectsRequest, opts ...grpc.CallOption) (*pb.RpcDebugOpenedObjectsResponse, error) DebugRunProfiler(ctx context.Context, in *pb.RpcDebugRunProfilerRequest, opts ...grpc.CallOption) (*pb.RpcDebugRunProfilerResponse, error) DebugAccountSelectTrace(ctx context.Context, in *pb.RpcDebugAccountSelectTraceRequest, opts ...grpc.CallOption) (*pb.RpcDebugAccountSelectTraceResponse, error) + DebugAnystoreObjectChanges(ctx context.Context, in *pb.RpcDebugAnystoreObjectChangesRequest, opts ...grpc.CallOption) (*pb.RpcDebugAnystoreObjectChangesResponse, error) MetricsSetParameters(ctx context.Context, in *pb.RpcMetricsSetParametersRequest, opts ...grpc.CallOption) (*pb.RpcMetricsSetParametersResponse, error) // used only for lib-server via grpc ListenSessionEvents(ctx context.Context, in *pb.StreamRequest, opts ...grpc.CallOption) (ClientCommands_ListenSessionEventsClient, error) @@ -672,7 +678,7 @@ type ClientCommandsClient interface { DeviceSetName(ctx context.Context, in *pb.RpcDeviceSetNameRequest, opts ...grpc.CallOption) (*pb.RpcDeviceSetNameResponse, error) DeviceList(ctx context.Context, in *pb.RpcDeviceListRequest, opts ...grpc.CallOption) (*pb.RpcDeviceListResponse, error) DeviceNetworkStateSet(ctx context.Context, in *pb.RpcDeviceNetworkStateSetRequest, opts ...grpc.CallOption) (*pb.RpcDeviceNetworkStateSetResponse, error) - // Chats dummy impl + // Chats ChatAddMessage(ctx context.Context, in *pb.RpcChatAddMessageRequest, opts ...grpc.CallOption) (*pb.RpcChatAddMessageResponse, error) ChatEditMessageContent(ctx context.Context, in *pb.RpcChatEditMessageContentRequest, opts ...grpc.CallOption) (*pb.RpcChatEditMessageContentResponse, error) ChatToggleMessageReaction(ctx context.Context, in *pb.RpcChatToggleMessageReactionRequest, opts ...grpc.CallOption) (*pb.RpcChatToggleMessageReactionResponse, error) @@ -681,6 +687,7 @@ type ClientCommandsClient interface { ChatGetMessagesByIds(ctx context.Context, in *pb.RpcChatGetMessagesByIdsRequest, opts ...grpc.CallOption) (*pb.RpcChatGetMessagesByIdsResponse, error) ChatSubscribeLastMessages(ctx context.Context, in *pb.RpcChatSubscribeLastMessagesRequest, opts ...grpc.CallOption) (*pb.RpcChatSubscribeLastMessagesResponse, error) ChatUnsubscribe(ctx context.Context, in *pb.RpcChatUnsubscribeRequest, opts ...grpc.CallOption) (*pb.RpcChatUnsubscribeResponse, error) + ObjectChatAdd(ctx context.Context, in *pb.RpcObjectChatAddRequest, opts ...grpc.CallOption) (*pb.RpcObjectChatAddResponse, error) } type clientCommandsClient struct { @@ -1150,15 +1157,6 @@ func (c *clientCommandsClient) ObjectCreateFromUrl(ctx context.Context, in *pb.R return out, nil } -func (c *clientCommandsClient) ObjectChatAdd(ctx context.Context, in *pb.RpcObjectChatAddRequest, opts ...grpc.CallOption) (*pb.RpcObjectChatAddResponse, error) { - out := new(pb.RpcObjectChatAddResponse) - err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectChatAdd", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *clientCommandsClient) ObjectCreateSet(ctx context.Context, in *pb.RpcObjectCreateSetRequest, opts ...grpc.CallOption) (*pb.RpcObjectCreateSetResponse, error) { out := new(pb.RpcObjectCreateSetResponse) err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectCreateSet", in, out, opts...) @@ -1204,6 +1202,24 @@ func (c *clientCommandsClient) ObjectSearchSubscribe(ctx context.Context, in *pb return out, nil } +func (c *clientCommandsClient) ObjectCrossSpaceSearchSubscribe(ctx context.Context, in *pb.RpcObjectCrossSpaceSearchSubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectCrossSpaceSearchSubscribeResponse, error) { + out := new(pb.RpcObjectCrossSpaceSearchSubscribeResponse) + err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectCrossSpaceSearchSubscribe", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *clientCommandsClient) ObjectCrossSpaceSearchUnsubscribe(ctx context.Context, in *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest, opts ...grpc.CallOption) (*pb.RpcObjectCrossSpaceSearchUnsubscribeResponse, error) { + out := new(pb.RpcObjectCrossSpaceSearchUnsubscribeResponse) + err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectCrossSpaceSearchUnsubscribe", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *clientCommandsClient) ObjectSubscribeIds(ctx context.Context, in *pb.RpcObjectSubscribeIdsRequest, opts ...grpc.CallOption) (*pb.RpcObjectSubscribeIdsResponse, error) { out := new(pb.RpcObjectSubscribeIdsResponse) err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectSubscribeIds", in, out, opts...) @@ -2761,6 +2777,15 @@ func (c *clientCommandsClient) DebugAccountSelectTrace(ctx context.Context, in * return out, nil } +func (c *clientCommandsClient) DebugAnystoreObjectChanges(ctx context.Context, in *pb.RpcDebugAnystoreObjectChangesRequest, opts ...grpc.CallOption) (*pb.RpcDebugAnystoreObjectChangesResponse, error) { + out := new(pb.RpcDebugAnystoreObjectChangesResponse) + err := c.cc.Invoke(ctx, "/anytype.ClientCommands/DebugAnystoreObjectChanges", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *clientCommandsClient) MetricsSetParameters(ctx context.Context, in *pb.RpcMetricsSetParametersRequest, opts ...grpc.CallOption) (*pb.RpcMetricsSetParametersResponse, error) { out := new(pb.RpcMetricsSetParametersResponse) err := c.cc.Invoke(ctx, "/anytype.ClientCommands/MetricsSetParameters", in, out, opts...) @@ -3054,6 +3079,15 @@ func (c *clientCommandsClient) ChatUnsubscribe(ctx context.Context, in *pb.RpcCh return out, nil } +func (c *clientCommandsClient) ObjectChatAdd(ctx context.Context, in *pb.RpcObjectChatAddRequest, opts ...grpc.CallOption) (*pb.RpcObjectChatAddResponse, error) { + out := new(pb.RpcObjectChatAddResponse) + err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectChatAdd", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ClientCommandsServer is the server API for ClientCommands service. type ClientCommandsServer interface { AppGetVersion(context.Context, *pb.RpcAppGetVersionRequest) *pb.RpcAppGetVersionResponse @@ -3118,13 +3152,14 @@ type ClientCommandsServer interface { ObjectCreate(context.Context, *pb.RpcObjectCreateRequest) *pb.RpcObjectCreateResponse ObjectCreateBookmark(context.Context, *pb.RpcObjectCreateBookmarkRequest) *pb.RpcObjectCreateBookmarkResponse ObjectCreateFromUrl(context.Context, *pb.RpcObjectCreateFromUrlRequest) *pb.RpcObjectCreateFromUrlResponse - ObjectChatAdd(context.Context, *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse // ObjectCreateSet just creates the new set, without adding the link to it from some other page ObjectCreateSet(context.Context, *pb.RpcObjectCreateSetRequest) *pb.RpcObjectCreateSetResponse ObjectGraph(context.Context, *pb.RpcObjectGraphRequest) *pb.RpcObjectGraphResponse ObjectSearch(context.Context, *pb.RpcObjectSearchRequest) *pb.RpcObjectSearchResponse ObjectSearchWithMeta(context.Context, *pb.RpcObjectSearchWithMetaRequest) *pb.RpcObjectSearchWithMetaResponse ObjectSearchSubscribe(context.Context, *pb.RpcObjectSearchSubscribeRequest) *pb.RpcObjectSearchSubscribeResponse + ObjectCrossSpaceSearchSubscribe(context.Context, *pb.RpcObjectCrossSpaceSearchSubscribeRequest) *pb.RpcObjectCrossSpaceSearchSubscribeResponse + ObjectCrossSpaceSearchUnsubscribe(context.Context, *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) *pb.RpcObjectCrossSpaceSearchUnsubscribeResponse ObjectSubscribeIds(context.Context, *pb.RpcObjectSubscribeIdsRequest) *pb.RpcObjectSubscribeIdsResponse ObjectGroupsSubscribe(context.Context, *pb.RpcObjectGroupsSubscribeRequest) *pb.RpcObjectGroupsSubscribeResponse ObjectSearchUnsubscribe(context.Context, *pb.RpcObjectSearchUnsubscribeRequest) *pb.RpcObjectSearchUnsubscribeResponse @@ -3326,6 +3361,7 @@ type ClientCommandsServer interface { DebugOpenedObjects(context.Context, *pb.RpcDebugOpenedObjectsRequest) *pb.RpcDebugOpenedObjectsResponse DebugRunProfiler(context.Context, *pb.RpcDebugRunProfilerRequest) *pb.RpcDebugRunProfilerResponse DebugAccountSelectTrace(context.Context, *pb.RpcDebugAccountSelectTraceRequest) *pb.RpcDebugAccountSelectTraceResponse + DebugAnystoreObjectChanges(context.Context, *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse MetricsSetParameters(context.Context, *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse // used only for lib-server via grpc ListenSessionEvents(*pb.StreamRequest, ClientCommands_ListenSessionEventsServer) @@ -3368,7 +3404,7 @@ type ClientCommandsServer interface { DeviceSetName(context.Context, *pb.RpcDeviceSetNameRequest) *pb.RpcDeviceSetNameResponse DeviceList(context.Context, *pb.RpcDeviceListRequest) *pb.RpcDeviceListResponse DeviceNetworkStateSet(context.Context, *pb.RpcDeviceNetworkStateSetRequest) *pb.RpcDeviceNetworkStateSetResponse - // Chats dummy impl + // Chats ChatAddMessage(context.Context, *pb.RpcChatAddMessageRequest) *pb.RpcChatAddMessageResponse ChatEditMessageContent(context.Context, *pb.RpcChatEditMessageContentRequest) *pb.RpcChatEditMessageContentResponse ChatToggleMessageReaction(context.Context, *pb.RpcChatToggleMessageReactionRequest) *pb.RpcChatToggleMessageReactionResponse @@ -3377,6 +3413,7 @@ type ClientCommandsServer interface { ChatGetMessagesByIds(context.Context, *pb.RpcChatGetMessagesByIdsRequest) *pb.RpcChatGetMessagesByIdsResponse ChatSubscribeLastMessages(context.Context, *pb.RpcChatSubscribeLastMessagesRequest) *pb.RpcChatSubscribeLastMessagesResponse ChatUnsubscribe(context.Context, *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse + ObjectChatAdd(context.Context, *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse } // UnimplementedClientCommandsServer can be embedded to have forward compatible implementations. @@ -3536,9 +3573,6 @@ func (*UnimplementedClientCommandsServer) ObjectCreateBookmark(ctx context.Conte func (*UnimplementedClientCommandsServer) ObjectCreateFromUrl(ctx context.Context, req *pb.RpcObjectCreateFromUrlRequest) *pb.RpcObjectCreateFromUrlResponse { return nil } -func (*UnimplementedClientCommandsServer) ObjectChatAdd(ctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse { - return nil -} func (*UnimplementedClientCommandsServer) ObjectCreateSet(ctx context.Context, req *pb.RpcObjectCreateSetRequest) *pb.RpcObjectCreateSetResponse { return nil } @@ -3554,6 +3588,12 @@ func (*UnimplementedClientCommandsServer) ObjectSearchWithMeta(ctx context.Conte func (*UnimplementedClientCommandsServer) ObjectSearchSubscribe(ctx context.Context, req *pb.RpcObjectSearchSubscribeRequest) *pb.RpcObjectSearchSubscribeResponse { return nil } +func (*UnimplementedClientCommandsServer) ObjectCrossSpaceSearchSubscribe(ctx context.Context, req *pb.RpcObjectCrossSpaceSearchSubscribeRequest) *pb.RpcObjectCrossSpaceSearchSubscribeResponse { + return nil +} +func (*UnimplementedClientCommandsServer) ObjectCrossSpaceSearchUnsubscribe(ctx context.Context, req *pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) *pb.RpcObjectCrossSpaceSearchUnsubscribeResponse { + return nil +} func (*UnimplementedClientCommandsServer) ObjectSubscribeIds(ctx context.Context, req *pb.RpcObjectSubscribeIdsRequest) *pb.RpcObjectSubscribeIdsResponse { return nil } @@ -4073,6 +4113,9 @@ func (*UnimplementedClientCommandsServer) DebugRunProfiler(ctx context.Context, func (*UnimplementedClientCommandsServer) DebugAccountSelectTrace(ctx context.Context, req *pb.RpcDebugAccountSelectTraceRequest) *pb.RpcDebugAccountSelectTraceResponse { return nil } +func (*UnimplementedClientCommandsServer) DebugAnystoreObjectChanges(ctx context.Context, req *pb.RpcDebugAnystoreObjectChangesRequest) *pb.RpcDebugAnystoreObjectChangesResponse { + return nil +} func (*UnimplementedClientCommandsServer) MetricsSetParameters(ctx context.Context, req *pb.RpcMetricsSetParametersRequest) *pb.RpcMetricsSetParametersResponse { return nil } @@ -4163,6 +4206,9 @@ func (*UnimplementedClientCommandsServer) ChatSubscribeLastMessages(ctx context. func (*UnimplementedClientCommandsServer) ChatUnsubscribe(ctx context.Context, req *pb.RpcChatUnsubscribeRequest) *pb.RpcChatUnsubscribeResponse { return nil } +func (*UnimplementedClientCommandsServer) ObjectChatAdd(ctx context.Context, req *pb.RpcObjectChatAddRequest) *pb.RpcObjectChatAddResponse { + return nil +} func RegisterClientCommandsServer(s *grpc.Server, srv ClientCommandsServer) { s.RegisterService(&_ClientCommands_serviceDesc, srv) @@ -5086,24 +5132,6 @@ func _ClientCommands_ObjectCreateFromUrl_Handler(srv interface{}, ctx context.Co return interceptor(ctx, in, info, handler) } -func _ClientCommands_ObjectChatAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(pb.RpcObjectChatAddRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ClientCommandsServer).ObjectChatAdd(ctx, in), nil - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/anytype.ClientCommands/ObjectChatAdd", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ClientCommandsServer).ObjectChatAdd(ctx, req.(*pb.RpcObjectChatAddRequest)), nil - } - return interceptor(ctx, in, info, handler) -} - func _ClientCommands_ObjectCreateSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(pb.RpcObjectCreateSetRequest) if err := dec(in); err != nil { @@ -5194,6 +5222,42 @@ func _ClientCommands_ObjectSearchSubscribe_Handler(srv interface{}, ctx context. return interceptor(ctx, in, info, handler) } +func _ClientCommands_ObjectCrossSpaceSearchSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(pb.RpcObjectCrossSpaceSearchSubscribeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientCommandsServer).ObjectCrossSpaceSearchSubscribe(ctx, in), nil + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/anytype.ClientCommands/ObjectCrossSpaceSearchSubscribe", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientCommandsServer).ObjectCrossSpaceSearchSubscribe(ctx, req.(*pb.RpcObjectCrossSpaceSearchSubscribeRequest)), nil + } + return interceptor(ctx, in, info, handler) +} + +func _ClientCommands_ObjectCrossSpaceSearchUnsubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(pb.RpcObjectCrossSpaceSearchUnsubscribeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientCommandsServer).ObjectCrossSpaceSearchUnsubscribe(ctx, in), nil + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/anytype.ClientCommands/ObjectCrossSpaceSearchUnsubscribe", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientCommandsServer).ObjectCrossSpaceSearchUnsubscribe(ctx, req.(*pb.RpcObjectCrossSpaceSearchUnsubscribeRequest)), nil + } + return interceptor(ctx, in, info, handler) +} + func _ClientCommands_ObjectSubscribeIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(pb.RpcObjectSubscribeIdsRequest) if err := dec(in); err != nil { @@ -8308,6 +8372,24 @@ func _ClientCommands_DebugAccountSelectTrace_Handler(srv interface{}, ctx contex return interceptor(ctx, in, info, handler) } +func _ClientCommands_DebugAnystoreObjectChanges_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(pb.RpcDebugAnystoreObjectChangesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientCommandsServer).DebugAnystoreObjectChanges(ctx, in), nil + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/anytype.ClientCommands/DebugAnystoreObjectChanges", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientCommandsServer).DebugAnystoreObjectChanges(ctx, req.(*pb.RpcDebugAnystoreObjectChangesRequest)), nil + } + return interceptor(ctx, in, info, handler) +} + func _ClientCommands_MetricsSetParameters_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(pb.RpcMetricsSetParametersRequest) if err := dec(in); err != nil { @@ -8852,6 +8934,24 @@ func _ClientCommands_ChatUnsubscribe_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _ClientCommands_ObjectChatAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(pb.RpcObjectChatAddRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClientCommandsServer).ObjectChatAdd(ctx, in), nil + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/anytype.ClientCommands/ObjectChatAdd", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClientCommandsServer).ObjectChatAdd(ctx, req.(*pb.RpcObjectChatAddRequest)), nil + } + return interceptor(ctx, in, info, handler) +} + var _ClientCommands_serviceDesc = grpc.ServiceDesc{ ServiceName: "anytype.ClientCommands", HandlerType: (*ClientCommandsServer)(nil), @@ -9060,10 +9160,6 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{ MethodName: "ObjectCreateFromUrl", Handler: _ClientCommands_ObjectCreateFromUrl_Handler, }, - { - MethodName: "ObjectChatAdd", - Handler: _ClientCommands_ObjectChatAdd_Handler, - }, { MethodName: "ObjectCreateSet", Handler: _ClientCommands_ObjectCreateSet_Handler, @@ -9084,6 +9180,14 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{ MethodName: "ObjectSearchSubscribe", Handler: _ClientCommands_ObjectSearchSubscribe_Handler, }, + { + MethodName: "ObjectCrossSpaceSearchSubscribe", + Handler: _ClientCommands_ObjectCrossSpaceSearchSubscribe_Handler, + }, + { + MethodName: "ObjectCrossSpaceSearchUnsubscribe", + Handler: _ClientCommands_ObjectCrossSpaceSearchUnsubscribe_Handler, + }, { MethodName: "ObjectSubscribeIds", Handler: _ClientCommands_ObjectSubscribeIds_Handler, @@ -9776,6 +9880,10 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{ MethodName: "DebugAccountSelectTrace", Handler: _ClientCommands_DebugAccountSelectTrace_Handler, }, + { + MethodName: "DebugAnystoreObjectChanges", + Handler: _ClientCommands_DebugAnystoreObjectChanges_Handler, + }, { MethodName: "MetricsSetParameters", Handler: _ClientCommands_MetricsSetParameters_Handler, @@ -9892,6 +10000,10 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{ MethodName: "ChatUnsubscribe", Handler: _ClientCommands_ChatUnsubscribe_Handler, }, + { + MethodName: "ObjectChatAdd", + Handler: _ClientCommands_ObjectChatAdd_Handler, + }, }, Streams: []grpc.StreamDesc{ { diff --git a/pkg/lib/bundle/relation.gen.go b/pkg/lib/bundle/relation.gen.go index d0b2a2c392..c17868746d 100644 --- a/pkg/lib/bundle/relation.gen.go +++ b/pkg/lib/bundle/relation.gen.go @@ -9,7 +9,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) -const RelationChecksum = "a8068f8bee7828cfa88a4cf262a8276bf2cbf1eadc9934dd52c5c06be2d02bbd" +const RelationChecksum = "414402e104d3b92fa6045649ffa60f6988979f427cf91ef678c53257a0d83fc4" const ( RelationKeyTag domain.RelationKey = "tag" RelationKeyCamera domain.RelationKey = "camera" @@ -97,7 +97,6 @@ const ( RelationKeySetOf domain.RelationKey = "setOf" RelationKeyIsArchived domain.RelationKey = "isArchived" RelationKeyFileExt domain.RelationKey = "fileExt" - RelationKeyScope domain.RelationKey = "scope" RelationKeyFeaturedRelations domain.RelationKey = "featuredRelations" RelationKeyPhone domain.RelationKey = "phone" RelationKeySmartblockTypes domain.RelationKey = "smartblockTypes" @@ -141,6 +140,8 @@ const ( RelationKeySyncStatus domain.RelationKey = "syncStatus" RelationKeySyncDate domain.RelationKey = "syncDate" RelationKeySyncError domain.RelationKey = "syncError" + RelationKeyHasChat domain.RelationKey = "hasChat" + RelationKeyChatId domain.RelationKey = "chatId" RelationKeyMentions domain.RelationKey = "mentions" ) @@ -304,6 +305,20 @@ var ( ReadOnlyRelation: true, Scope: model.Relation_type, }, + RelationKeyChatId: { + + DataSource: model.Relation_derived, + Description: "Chat id", + Format: model.RelationFormat_object, + Hidden: true, + Id: "_brchatId", + Key: "chatId", + MaxCount: 1, + Name: "Chat id", + ReadOnly: true, + ReadOnlyRelation: true, + Scope: model.Relation_type, + }, RelationKeyCollectionOf: { DataSource: model.Relation_details, @@ -641,6 +656,20 @@ var ( ReadOnlyRelation: true, Scope: model.Relation_type, }, + RelationKeyHasChat: { + + DataSource: model.Relation_details, + Description: "Object has a chat", + Format: model.RelationFormat_checkbox, + Hidden: true, + Id: "_brhasChat", + Key: "hasChat", + MaxCount: 1, + Name: "Has a chat", + ReadOnly: true, + ReadOnlyRelation: true, + Scope: model.Relation_type, + }, RelationKeyHeightInPixels: { DataSource: model.Relation_details, @@ -1421,19 +1450,6 @@ var ( ReadOnlyRelation: true, Scope: model.Relation_type, }, - RelationKeyScope: { - - DataSource: model.Relation_details, - Description: "", - Format: model.RelationFormat_longtext, - Id: "_brscope", - Key: "scope", - MaxCount: 1, - Name: "Scope", - ReadOnly: false, - ReadOnlyRelation: true, - Scope: model.Relation_type, - }, RelationKeySetOf: { DataSource: model.Relation_details, diff --git a/pkg/lib/bundle/relations.json b/pkg/lib/bundle/relations.json index 1e066dff50..7cc1d660f4 100644 --- a/pkg/lib/bundle/relations.json +++ b/pkg/lib/bundle/relations.json @@ -893,15 +893,6 @@ "readonly": true, "source": "details" }, - { - "format": "longtext", - "hidden": false, - "key": "scope", - "maxCount": 1, - "name": "Scope", - "readonly": false, - "source": "details" - }, { "description": "Important relations that always appear at the top of the object", "format": "object", @@ -1330,6 +1321,26 @@ "readonly": true, "source": "local" }, + { + "description": "Object has a chat", + "format": "checkbox", + "hidden": true, + "key": "hasChat", + "maxCount": 1, + "name": "Has a chat", + "readonly": true, + "source": "details" + }, + { + "description": "Chat id", + "format": "object", + "hidden": true, + "key": "chatId", + "maxCount": 1, + "name": "Chat id", + "readonly": true, + "source": "derived" + }, { "description": "Objects that are mentioned in blocks of this object", "format": "object", diff --git a/pkg/lib/bundle/systemRelations.gen.go b/pkg/lib/bundle/systemRelations.gen.go index ce55e7ee6d..ec838cfaa5 100644 --- a/pkg/lib/bundle/systemRelations.gen.go +++ b/pkg/lib/bundle/systemRelations.gen.go @@ -6,7 +6,7 @@ package bundle import domain "github.com/anyproto/anytype-heart/core/domain" -const SystemRelationsChecksum = "86abb054e3ab3db5feb72fee757ed9e3aaa012e3137c5f99e1baba8cfcf3c3f2" +const SystemRelationsChecksum = "dccec4608e8b4d207055a77d1e475598b6ed9ef177d0d796065ebc6b9e0466f7" // SystemRelations contains relations that have some special biz logic depends on them in some objects // in case EVERY object depend on the relation please add it to RequiredInternalRelations @@ -77,7 +77,8 @@ var SystemRelations = append(RequiredInternalRelations, []domain.RelationKey{ RelationKeyLatestAclHeadId, RelationKeyIdentity, RelationKeyGlobalName, - RelationKeyScope, RelationKeyLastUsedDate, RelationKeyMentions, + RelationKeyChatId, + RelationKeyHasChat, }...) diff --git a/pkg/lib/bundle/systemRelations.json b/pkg/lib/bundle/systemRelations.json index 0bcf37d559..a4e12bd184 100644 --- a/pkg/lib/bundle/systemRelations.json +++ b/pkg/lib/bundle/systemRelations.json @@ -86,7 +86,8 @@ "syncDate", "syncStatus", "syncError", - "scope", "lastUsedDate", - "mentions" + "mentions", + "chatId", + "hasChat" ] diff --git a/pkg/lib/bundle/systemTypes.gen.go b/pkg/lib/bundle/systemTypes.gen.go index 2c141d0bc0..1cfec0d5ee 100644 --- a/pkg/lib/bundle/systemTypes.gen.go +++ b/pkg/lib/bundle/systemTypes.gen.go @@ -6,7 +6,7 @@ package bundle import domain "github.com/anyproto/anytype-heart/core/domain" -const SystemTypesChecksum = "b94f1bd90db700fcd8e97da5fb96d7d0925d67a5bfa4f8209db71943987917b8" +const SystemTypesChecksum = "e68b37f73baf858d7101257403a3a0605e09090dbe11432919e1e7a6d4668b67" // SystemTypes contains types that have some special biz logic depends on them in some objects // they shouldn't be removed or edited in any way @@ -16,6 +16,7 @@ var SystemTypes = append(InternalTypes, []domain.TypeKey{ TypeKeyTask, TypeKeyCollection, TypeKeySet, - TypeKeyProfile, TypeKeyBookmark, + TypeKeyChat, + TypeKeyChatDerived, }...) diff --git a/pkg/lib/bundle/systemTypes.json b/pkg/lib/bundle/systemTypes.json index bbe3777a99..5cd14e0331 100644 --- a/pkg/lib/bundle/systemTypes.json +++ b/pkg/lib/bundle/systemTypes.json @@ -17,6 +17,7 @@ "task", "collection", "set", - "profile", - "bookmark" + "bookmark", + "chat", + "chatDerived" ] diff --git a/pkg/lib/bundle/types.gen.go b/pkg/lib/bundle/types.gen.go index d54f956540..72341c5761 100644 --- a/pkg/lib/bundle/types.gen.go +++ b/pkg/lib/bundle/types.gen.go @@ -9,7 +9,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) -const TypeChecksum = "a475473f827167d93b818920569ea0f2c758761ef24d6a6bcb8da6b009f01904" +const TypeChecksum = "f3ae9931142aa23ec9696ccb60fe1a68b4fdafcc345e307e0a26d4fb98a0686c" const ( TypePrefix = "_ot" ) @@ -41,6 +41,8 @@ const ( TypeKeyGoal domain.TypeKey = "goal" TypeKeyFile domain.TypeKey = "file" TypeKeyProject domain.TypeKey = "project" + TypeKeyChat domain.TypeKey = "chat" + TypeKeyChatDerived domain.TypeKey = "chatDerived" ) var ( @@ -80,6 +82,29 @@ var ( Types: []model.SmartBlockType{model.SmartBlockType_Page}, Url: TypePrefix + "bookmark", }, + TypeKeyChat: { + + Description: "A chat", + IconEmoji: "💬", + Layout: model.ObjectType_chat, + Name: "Chat", + Readonly: true, + RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyDescription)}, + Types: []model.SmartBlockType{model.SmartBlockType_ChatObject}, + Url: TypePrefix + "chat", + }, + TypeKeyChatDerived: { + + Description: "A chat derived object", + Hidden: true, + Layout: model.ObjectType_chatDerived, + Name: "Chat Derived Object", + Readonly: true, + RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyDescription)}, + Revision: 1, + Types: []model.SmartBlockType{model.SmartBlockType_ChatDerivedObject}, + Url: TypePrefix + "chatDerived", + }, TypeKeyCollection: { Description: "Collect objects in one place, use different views to organize them", diff --git a/pkg/lib/bundle/types.json b/pkg/lib/bundle/types.json index e654caf0b2..d88c80bfff 100644 --- a/pkg/lib/bundle/types.json +++ b/pkg/lib/bundle/types.json @@ -456,5 +456,36 @@ "tasks" ], "description": "An individual or collaborative enterprise that is carefully planned to achieve a particular aim" + }, + { + "id": "chat", + "name": "Chat", + "types": [ + "ChatObject" + ], + "emoji": "💬", + "hidden": false, + "layout": "chat", + "relations": [ + "tag", + "description" + ], + "description": "A chat" + }, + { + "id": "chatDerived", + "name": "Chat Derived Object", + "types": [ + "ChatDerivedObject" + ], + "emoji": "", + "hidden": true, + "layout": "chatDerived", + "relations": [ + "tag", + "description" + ], + "description": "A chat derived object", + "revision": 1 } ] diff --git a/pkg/lib/core/smartblock/smartblock.go b/pkg/lib/core/smartblock/smartblock.go index b40ddbb686..aec43f972c 100644 --- a/pkg/lib/core/smartblock/smartblock.go +++ b/pkg/lib/core/smartblock/smartblock.go @@ -27,6 +27,9 @@ const ( SmartBlockTypeAnytypeProfile = SmartBlockType(model.SmartBlockType_AnytypeProfile) SmartBlockTypeDate = SmartBlockType(model.SmartBlockType_Date) SmartBlockTypeIdentity = SmartBlockType(model.SmartBlockType_Identity) + SmartBlockTypeChatObject = SmartBlockType(model.SmartBlockType_ChatObject) // Container for any-store based chats + SmartBlockTypeChatDerivedObject = SmartBlockType(model.SmartBlockType_ChatDerivedObject) // Any-store based object for chat + SmartBlockTypeAccountObject = SmartBlockType(model.SmartBlockType_AccountObject) SmartBlockTypeWorkspace = SmartBlockType(model.SmartBlockType_Workspace) SmartBlockTypeWidget = SmartBlockType(model.SmartBlockType_Widget) diff --git a/pkg/lib/database/anystore.go b/pkg/lib/database/anystore.go index a5747766a8..facb67609f 100644 --- a/pkg/lib/database/anystore.go +++ b/pkg/lib/database/anystore.go @@ -3,9 +3,8 @@ package database import ( "time" - "github.com/anyproto/any-store/encoding" + "github.com/anyproto/any-store/anyenc" "github.com/anyproto/any-store/query" - "github.com/valyala/fastjson" "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/pkg/lib/bundle" @@ -14,7 +13,7 @@ import ( ) type dateOnlySort struct { - arena *fastjson.Arena + arena *anyenc.Arena relationKey string reverse bool nulls model.BlockContentDataviewSortEmptyType @@ -28,7 +27,7 @@ func (s dateOnlySort) Fields() []query.SortField { } } -func (s dateOnlySort) AppendKey(k []byte, v *fastjson.Value) []byte { +func (s dateOnlySort) AppendKey(tuple anyenc.Tuple, v *anyenc.Value) anyenc.Tuple { defer func() { s.arena.Reset() }() @@ -37,7 +36,7 @@ func (s dateOnlySort) AppendKey(k []byte, v *fastjson.Value) []byte { empty bool ts int64 ) - if val != nil && val.Type() == fastjson.TypeNumber { + if val != nil && val.Type() == anyenc.TypeNumber { tsFloat, _ := val.Float64() ts = time_util.CutToDay(time.Unix(int64(tsFloat), 0)).Unix() } else { @@ -46,25 +45,25 @@ func (s dateOnlySort) AppendKey(k []byte, v *fastjson.Value) []byte { if empty { if s.nulls == model.BlockContentDataviewSort_Start { - return encoding.AppendJSONValue(k, s.arena.NewNull()) + return tuple.Append(s.arena.NewNull()) } else { - return encoding.AppendInvertedJSON(k, s.arena.NewNull()) + return tuple.AppendInverted(s.arena.NewNull()) } } if s.reverse { - return encoding.AppendInvertedJSON(k, s.arena.NewNumberFloat64(float64(ts))) + return tuple.Append(s.arena.NewNumberFloat64(float64(ts))) } else { - return encoding.AppendJSONValue(k, s.arena.NewNumberFloat64(float64(ts))) + return tuple.Append(s.arena.NewNumberFloat64(float64(ts))) } } type emptyPlacementSort struct { - arena *fastjson.Arena + arena *anyenc.Arena relationKey string reverse bool nulls model.BlockContentDataviewSortEmptyType - valType fastjson.Type + valType anyenc.Type } func (s emptyPlacementSort) Fields() []query.SortField { @@ -75,7 +74,7 @@ func (s emptyPlacementSort) Fields() []query.SortField { } } -func (s emptyPlacementSort) AppendKey(k []byte, v *fastjson.Value) []byte { +func (s emptyPlacementSort) AppendKey(tuple anyenc.Tuple, v *anyenc.Value) anyenc.Tuple { defer func() { s.arena.Reset() }() @@ -83,45 +82,45 @@ func (s emptyPlacementSort) AppendKey(k []byte, v *fastjson.Value) []byte { if s.isEmpty(val) { if s.nulls == model.BlockContentDataviewSort_Start { - return encoding.AppendJSONValue(k, s.arena.NewNull()) + return tuple.Append(s.arena.NewNull()) } else { - return encoding.AppendInvertedJSON(k, s.arena.NewNull()) + return tuple.AppendInverted(s.arena.NewNull()) } } if s.reverse { - return encoding.AppendInvertedJSON(k, val) + return tuple.AppendInverted(val) } else { - return encoding.AppendJSONValue(k, val) + return tuple.Append(val) } } -func (s emptyPlacementSort) isEmpty(val *fastjson.Value) bool { +func (s emptyPlacementSort) isEmpty(val *anyenc.Value) bool { if val == nil { return true } switch s.valType { - case fastjson.TypeNull: + case anyenc.TypeNull: return true - case fastjson.TypeString: + case anyenc.TypeString: return len(val.GetStringBytes()) == 0 - case fastjson.TypeNumber: + case anyenc.TypeNumber: n, _ := val.Float64() return n == 0 - case fastjson.TypeFalse: + case anyenc.TypeFalse: return true - case fastjson.TypeTrue: + case anyenc.TypeTrue: return false - case fastjson.TypeArray: + case anyenc.TypeArray: return len(val.GetArray()) == 0 - case fastjson.TypeObject: + case anyenc.TypeObject: panic("not implemented") } return false } type textSort struct { - arena *fastjson.Arena + arena *anyenc.Arena collatorBuffer *collate.Buffer collator *collate.Collator relationKey string @@ -138,14 +137,12 @@ func (s textSort) Fields() []query.SortField { } } -func (s textSort) AppendKey(k []byte, v *fastjson.Value) []byte { +func (s textSort) AppendKey(tuple anyenc.Tuple, v *anyenc.Value) anyenc.Tuple { defer func() { s.arena.Reset() s.collatorBuffer.Reset() }() - val := v.GetStringBytes(s.relationKey) - if s.relationKey == bundle.RelationKeyName.String() && len(val) == 0 { layout := model.ObjectTypeLayout(v.GetFloat64(bundle.RelationKeyLayout.String())) if layout == model.ObjectType_note { @@ -156,21 +153,21 @@ func (s textSort) AppendKey(k []byte, v *fastjson.Value) []byte { collated := s.collator.Key(s.collatorBuffer, val) if s.reverse { if s.nulls == model.BlockContentDataviewSort_Start && len(val) == 0 { - return encoding.AppendJSONValue(k, s.arena.NewNull()) + return tuple.Append(s.arena.NewNull()) } else { - return encoding.AppendInvertedJSON(k, s.arena.NewStringBytes(collated)) + return tuple.AppendInverted(s.arena.NewStringBytes(collated)) } } else { if s.nulls == model.BlockContentDataviewSort_End && len(val) == 0 { - return encoding.AppendInvertedJSON(k, s.arena.NewNull()) + return tuple.AppendInverted(s.arena.NewNull()) } else { - return encoding.AppendJSONValue(k, s.arena.NewStringBytes(collated)) + return tuple.Append(s.arena.NewStringBytes(collated)) } } } type tagStatusSort struct { - arena *fastjson.Arena + arena *anyenc.Arena relationKey string reverse bool nulls model.BlockContentDataviewSortEmptyType @@ -185,17 +182,17 @@ func (s tagStatusSort) Fields() []query.SortField { } } -func (s tagStatusSort) AppendKey(k []byte, v *fastjson.Value) []byte { +func (s tagStatusSort) AppendKey(tuple anyenc.Tuple, v *anyenc.Value) anyenc.Tuple { defer func() { s.arena.Reset() }() val := v.Get(s.relationKey) var sortKey string - if val != nil && val.Type() == fastjson.TypeString { + if val != nil && val.Type() == anyenc.TypeString { id, _ := val.StringBytes() sortKey = s.idToName[string(id)] - } else if val != nil && val.Type() == fastjson.TypeArray { + } else if val != nil && val.Type() == anyenc.TypeArray { arr, _ := val.Array() for _, it := range arr { id, _ := it.StringBytes() @@ -205,15 +202,15 @@ func (s tagStatusSort) AppendKey(k []byte, v *fastjson.Value) []byte { if sortKey == "" { if s.nulls == model.BlockContentDataviewSort_Start { - return encoding.AppendJSONValue(k, s.arena.NewNull()) + return tuple.Append(s.arena.NewNull()) } else if s.nulls == model.BlockContentDataviewSort_End { - return encoding.AppendInvertedJSON(k, s.arena.NewNull()) + return tuple.AppendInverted(s.arena.NewNull()) } } if s.reverse { - return encoding.AppendInvertedJSON(k, s.arena.NewString(sortKey)) + return tuple.AppendInverted(s.arena.NewString(sortKey)) } else { - return encoding.AppendJSONValue(k, s.arena.NewString(sortKey)) + return tuple.Append(s.arena.NewString(sortKey)) } } diff --git a/pkg/lib/database/database.go b/pkg/lib/database/database.go index 19a9e9dc8e..459ed571d6 100644 --- a/pkg/lib/database/database.go +++ b/pkg/lib/database/database.go @@ -1,11 +1,11 @@ package database import ( + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" + "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/core/domain" - "github.com/anyproto/anytype-heart/core/relationutils" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" "github.com/anyproto/anytype-heart/pkg/lib/logging" @@ -27,6 +27,7 @@ type Record struct { type Query struct { FullText string + SpaceId string Highlighter ftsearch.HighlightFormatter // default is json Filters []*model.BlockContentDataviewFilter // filters results. apply sequentially Sorts []*model.BlockContentDataviewSort // order results. apply hierarchically @@ -124,17 +125,17 @@ func injectDefaultOrder(qry Query, sorts []*model.BlockContentDataviewSort) []*m return sorts } -func NewFilters(qry Query, store ObjectStore, arena *fastjson.Arena) (filters *Filters, err error) { +func NewFilters(qry Query, store ObjectStore, arena *anyenc.Arena, collatorBuffer *collate.Buffer) (filters *Filters, err error) { // spaceID could be empty - spaceID := getSpaceIDFromFilters(qry.Filters) qry.Filters = injectDefaultFilters(qry.Filters) qry.Sorts = injectDefaultOrder(qry, qry.Sorts) filters = new(Filters) qb := queryBuilder{ - spaceId: spaceID, - arena: arena, - objectStore: store, + spaceId: store.SpaceId(), + arena: arena, + objectStore: store, + collatorBuffer: collatorBuffer, } filterObj, err := MakeFilters(qry.Filters, store) @@ -148,9 +149,10 @@ func NewFilters(qry Query, store ObjectStore, arena *fastjson.Arena) (filters *F } type queryBuilder struct { - spaceId string - arena *fastjson.Arena - objectStore ObjectStore + spaceId string + arena *anyenc.Arena + objectStore ObjectStore + collatorBuffer *collate.Buffer } func getSpaceIDFromFilters(filters []*model.BlockContentDataviewFilter) string { @@ -180,6 +182,7 @@ func (b *queryBuilder) extractOrder(sorts []*model.BlockContentDataviewSort) Set relationFormat: format, Store: b.objectStore, arena: b.arena, + collatorBuffer: b.collatorBuffer, } order = b.appendCustomOrder(sort, order, keyOrder) } @@ -195,9 +198,9 @@ func (b *queryBuilder) appendCustomOrder(sort *model.BlockContentDataviewSort, o idsIndices := make(map[string]int, len(sort.CustomOrder)) var idx int for _, it := range sort.CustomOrder { - jsonVal := pbtypes.ProtoValueToJson(b.arena, it) + val := pbtypes.ProtoValueToAnyEnc(b.arena, it) - raw := jsonVal.String() + raw := string(val.MarshalTo(nil)) if raw != "" { idsIndices[raw] = idx idx++ @@ -243,34 +246,3 @@ type Filters struct { FilterObj Filter Order Order } - -// ListRelationOptions returns options for specific relation -func ListRelationOptions(store ObjectStore, spaceID string, relationKey string) (options []*model.RelationOption, err error) { - filters := []*model.BlockContentDataviewFilter{ - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeyRelationKey.String(), - Value: pbtypes.String(relationKey), - }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeyLayout.String(), - Value: pbtypes.Int64(int64(model.ObjectType_relationOption)), - }, - } - if spaceID != "" { - filters = append(filters, &model.BlockContentDataviewFilter{ - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }) - } - records, err := store.Query(Query{ - Filters: filters, - }) - - for _, rec := range records { - options = append(options, relationutils.OptionFromStruct(rec.Details).RelationOption) - } - return -} diff --git a/pkg/lib/database/database_test.go b/pkg/lib/database/database_test.go index a0f9bc15f6..199f899792 100644 --- a/pkg/lib/database/database_test.go +++ b/pkg/lib/database/database_test.go @@ -3,9 +3,9 @@ package database import ( "testing" + "github.com/anyproto/any-store/anyenc" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/valyala/fastjson" + "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" @@ -32,18 +32,40 @@ func TestDatabase(t *testing.T) { }) } +type stubSpaceObjectStore struct { + queryRawResult []Record +} + +func (s *stubSpaceObjectStore) SpaceId() string { + return "space1" +} + +func (s *stubSpaceObjectStore) Query(q Query) (records []Record, err error) { + return nil, nil +} + +func (s *stubSpaceObjectStore) QueryRaw(filters *Filters, limit int, offset int) ([]Record, error) { + return s.queryRawResult, nil +} + +func (s *stubSpaceObjectStore) GetRelationFormatByKey(key string) (model.RelationFormat, error) { + rel, err := bundle.GetRelation(domain.RelationKey(key)) + if err != nil { + return 0, nil + } + return rel.Format, nil +} + +func (s *stubSpaceObjectStore) ListRelationOptions(relationKey string) (options []*model.RelationOption, err error) { + return nil, nil +} + func newTestQueryBuilder(t *testing.T) queryBuilder { - objectStore := NewMockObjectStore(t) - objectStore.EXPECT().GetRelationFormatByKey(mock.Anything).RunAndReturn(func(key string) (model.RelationFormat, error) { - rel, err := bundle.GetRelation(domain.RelationKey(key)) - if err != nil { - return 0, nil - } - return rel.Format, nil - }).Maybe() + objectStore := &stubSpaceObjectStore{} + return queryBuilder{ objectStore: objectStore, - arena: &fastjson.Arena{}, + arena: &anyenc.Arena{}, } } @@ -141,10 +163,10 @@ func givenSingleIncludeTime() []*model.BlockContentDataviewSort { func Test_NewFilters(t *testing.T) { t.Run("only default filters", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} // when - filters, err := NewFilters(Query{}, mockStore, &fastjson.Arena{}) + filters, err := NewFilters(Query{}, mockStore, &anyenc.Arena{}, &collate.Buffer{}) // then assert.Nil(t, err) @@ -152,7 +174,7 @@ func Test_NewFilters(t *testing.T) { }) t.Run("and filter with 3 default", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -176,7 +198,7 @@ func Test_NewFilters(t *testing.T) { } // when - filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{}) + filters, err := NewFilters(Query{Filters: filter}, mockStore, &anyenc.Arena{}, &collate.Buffer{}) // when assert.Nil(t, err) @@ -186,7 +208,7 @@ func Test_NewFilters(t *testing.T) { }) t.Run("deleted filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -216,7 +238,7 @@ func Test_NewFilters(t *testing.T) { } // then - filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{}) + filters, err := NewFilters(Query{Filters: filter}, mockStore, &anyenc.Arena{}, &collate.Buffer{}) // when assert.Nil(t, err) @@ -226,7 +248,7 @@ func Test_NewFilters(t *testing.T) { }) t.Run("archived filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -256,7 +278,7 @@ func Test_NewFilters(t *testing.T) { } // then - filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{}) + filters, err := NewFilters(Query{Filters: filter}, mockStore, &anyenc.Arena{}, &collate.Buffer{}) // when assert.Nil(t, err) @@ -266,7 +288,7 @@ func Test_NewFilters(t *testing.T) { }) t.Run("type filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -296,7 +318,7 @@ func Test_NewFilters(t *testing.T) { } // then - filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{}) + filters, err := NewFilters(Query{Filters: filter}, mockStore, &anyenc.Arena{}, &collate.Buffer{}) // when assert.Nil(t, err) @@ -306,7 +328,7 @@ func Test_NewFilters(t *testing.T) { }) t.Run("or filter with 3 default", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_Or, @@ -330,7 +352,7 @@ func Test_NewFilters(t *testing.T) { } // then - filters, err := NewFilters(Query{Filters: filter}, mockStore, &fastjson.Arena{}) + filters, err := NewFilters(Query{Filters: filter}, mockStore, &anyenc.Arena{}, &collate.Buffer{}) // when assert.Nil(t, err) diff --git a/pkg/lib/database/filter.go b/pkg/lib/database/filter.go index fb668ba023..8f25dc01cb 100644 --- a/pkg/lib/database/filter.go +++ b/pkg/lib/database/filter.go @@ -7,11 +7,10 @@ import ( "regexp" "strings" - "github.com/anyproto/any-store/encoding" + "github.com/anyproto/any-store/anyenc" "github.com/anyproto/any-store/query" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" @@ -197,13 +196,13 @@ func makeFilterByCondition(spaceID string, rawFilter *model.BlockContentDataview if err != nil { return nil, ErrValueMustBeListSupporting } - return newFilterOptionsEqual(&fastjson.Arena{}, rawFilter.RelationKey, list, optionsToMap(spaceID, rawFilter.RelationKey, store)), nil + return newFilterOptionsEqual(&anyenc.Arena{}, rawFilter.RelationKey, list, optionsToMap(spaceID, rawFilter.RelationKey, store)), nil case model.BlockContentDataviewFilter_NotExactIn: list, err := pbtypes.ValueListWrapper(rawFilter.Value) if err != nil { return nil, ErrValueMustBeListSupporting } - return FilterNot{newFilterOptionsEqual(&fastjson.Arena{}, rawFilter.RelationKey, list, optionsToMap(spaceID, rawFilter.RelationKey, store))}, nil + return FilterNot{newFilterOptionsEqual(&anyenc.Arena{}, rawFilter.RelationKey, list, optionsToMap(spaceID, rawFilter.RelationKey, store))}, nil case model.BlockContentDataviewFilter_Exists: return FilterExists{ Key: rawFilter.RelationKey, @@ -375,23 +374,27 @@ func (e FilterEq) AnystoreFilter() query.Filter { } return query.Key{ Path: path, - Filter: query.NewComp(op, scalarPbValueToAny(e.Value)), + Filter: query.NewCompValue(op, encodeScalarPbValue(&anyenc.Arena{}, e.Value)), } } -func scalarPbValueToAny(v *types.Value) any { +func encodeScalarPbValue(a *anyenc.Arena, v *types.Value) *anyenc.Value { if v == nil || v.Kind == nil { return nil } switch v.Kind.(type) { case *types.Value_NullValue: - return nil + return a.NewNull() case *types.Value_StringValue: - return v.GetStringValue() + return a.NewString(v.GetStringValue()) case *types.Value_NumberValue: - return v.GetNumberValue() + return a.NewNumberFloat64(v.GetNumberValue()) case *types.Value_BoolValue: - return v.GetBoolValue() + if v.GetBoolValue() { + return a.NewTrue() + } else { + return a.NewFalse() + } case *types.Value_StructValue: return nil case *types.Value_ListValue: @@ -452,10 +455,11 @@ func (i FilterIn) FilterObject(g *types.Struct) bool { func (i FilterIn) AnystoreFilter() query.Filter { path := []string{i.Key} conds := make([]query.Filter, 0, len(i.Value.GetValues())) + arena := &anyenc.Arena{} for _, v := range i.Value.GetValues() { conds = append(conds, query.Key{ Path: path, - Filter: query.NewComp(query.CompOpEq, scalarPbValueToAny(v)), + Filter: query.NewCompValue(query.CompOpEq, encodeScalarPbValue(arena, v)), }) } return query.Or(conds) @@ -540,6 +544,17 @@ func (e FilterEmpty) FilterObject(g *types.Struct) bool { return false } +var ( + filterEqNil = query.NewComp(query.CompOpEq, nil) + filterEqEmptyString = query.NewComp(query.CompOpEq, "") + filterEq0 = query.NewComp(query.CompOpEq, 0) + filterEqFalse = query.NewComp(query.CompOpEq, false) + filterEqEmptyArray = &query.Comp{ + CompOp: query.CompOpEq, + EqValue: anyenc.MustParseJson(`[]`).MarshalTo(nil), + } +) + func (e FilterEmpty) AnystoreFilter() query.Filter { path := []string{e.Key} return query.Or{ @@ -549,26 +564,23 @@ func (e FilterEmpty) AnystoreFilter() query.Filter { }, query.Key{ Path: path, - Filter: query.NewComp(query.CompOpEq, nil), + Filter: filterEqNil, }, query.Key{ Path: path, - Filter: query.NewComp(query.CompOpEq, ""), + Filter: filterEqEmptyString, }, query.Key{ Path: path, - Filter: query.NewComp(query.CompOpEq, 0), + Filter: filterEq0, }, query.Key{ Path: path, - Filter: query.NewComp(query.CompOpEq, false), + Filter: filterEqFalse, }, query.Key{ - Path: path, - Filter: &query.Comp{ - CompOp: query.CompOpEq, - EqValue: encoding.AppendJSONValue(nil, fastjson.MustParse(`[]`)), - }, + Path: path, + Filter: filterEqEmptyArray, }, } } @@ -611,16 +623,17 @@ func (l FilterAllIn) FilterObject(g *types.Struct) bool { func (l FilterAllIn) AnystoreFilter() query.Filter { path := []string{l.Key} conds := make([]query.Filter, 0, len(l.Value.GetValues())) + arena := &anyenc.Arena{} for _, v := range l.Value.GetValues() { conds = append(conds, query.Key{ Path: path, - Filter: query.NewComp(query.CompOpEq, scalarPbValueToAny(v)), + Filter: query.NewCompValue(query.CompOpEq, encodeScalarPbValue(arena, v)), }) } return query.And(conds) } -func newFilterOptionsEqual(arena *fastjson.Arena, key string, value *types.ListValue, options map[string]string) *FilterOptionsEqual { +func newFilterOptionsEqual(arena *anyenc.Arena, key string, value *types.ListValue, options map[string]string) *FilterOptionsEqual { f := &FilterOptionsEqual{ arena: arena, Key: key, @@ -632,7 +645,7 @@ func newFilterOptionsEqual(arena *fastjson.Arena, key string, value *types.ListV } type FilterOptionsEqual struct { - arena *fastjson.Arena + arena *anyenc.Arena Key string Value *types.ListValue @@ -682,7 +695,7 @@ func (exIn *FilterOptionsEqual) FilterObject(g *types.Struct) bool { return true } -func (exIn *FilterOptionsEqual) Ok(v *fastjson.Value) bool { +func (exIn *FilterOptionsEqual) Ok(v *anyenc.Value) bool { defer exIn.arena.Reset() arr := v.GetArray(exIn.Key) @@ -708,8 +721,9 @@ func (exIn *FilterOptionsEqual) Ok(v *fastjson.Value) bool { func (exIn *FilterOptionsEqual) compileValueFilter() { conds := make([]query.Filter, 0, len(exIn.Value.GetValues())+1) conds = append(conds, query.Size{Size: int64(len(exIn.Value.GetValues()))}) + arena := &anyenc.Arena{} for _, v := range exIn.Value.GetValues() { - conds = append(conds, query.NewComp(query.CompOpEq, scalarPbValueToAny(v))) + conds = append(conds, query.NewCompValue(query.CompOpEq, encodeScalarPbValue(arena, v))) } exIn.valueFilter = query.And(conds) } @@ -728,7 +742,7 @@ func (exIn *FilterOptionsEqual) String() string { func optionsToMap(spaceID string, key string, store ObjectStore) map[string]string { result := make(map[string]string) - options, err := ListRelationOptions(store, spaceID, key) + options, err := store.ListRelationOptions(key) if err != nil { log.Warn("nil objectStore for getting options") return result @@ -910,11 +924,11 @@ type Anystore2ValuesComp struct { buf1, buf2 []byte } -func (e *Anystore2ValuesComp) Ok(v *fastjson.Value) bool { +func (e *Anystore2ValuesComp) Ok(v *anyenc.Value) bool { value1 := v.Get(e.RelationKey1) value2 := v.Get(e.RelationKey2) - e.buf1 = encoding.AppendJSONValue(e.buf1[:0], value1) - e.buf2 = encoding.AppendJSONValue(e.buf2[:0], value2) + e.buf1 = value1.MarshalTo(e.buf1[:0]) + e.buf2 = value2.MarshalTo(e.buf2[:0]) comp := bytes.Compare(e.buf1, e.buf2) switch e.CompOp { case query.CompOpEq: diff --git a/pkg/lib/database/filter_test.go b/pkg/lib/database/filter_test.go index e3273abfc4..9c1d04bb76 100644 --- a/pkg/lib/database/filter_test.go +++ b/pkg/lib/database/filter_test.go @@ -4,11 +4,10 @@ import ( "testing" "time" + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/valyala/fastjson" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" @@ -18,8 +17,8 @@ import ( func assertFilter(t *testing.T, f Filter, obj *types.Struct, expected bool) { assert.Equal(t, expected, f.FilterObject(obj)) anystoreFilter := f.AnystoreFilter() - arena := &fastjson.Arena{} - val := pbtypes.ProtoToJson(arena, obj) + arena := &anyenc.Arena{} + val := pbtypes.ProtoToAnyEnc(arena, obj) result := anystoreFilter.Ok(val) assert.Equal(t, expected, result) } @@ -310,7 +309,7 @@ func TestAllIn_FilterObject(t *testing.T) { } func TestMakeAndFilter(t *testing.T) { - store := NewMockObjectStore(t) + store := &stubSpaceObjectStore{} t.Run("valid", func(t *testing.T) { filters := []*model.BlockContentDataviewFilter{ { @@ -448,9 +447,9 @@ func TestMakeAndFilter(t *testing.T) { func TestNestedFilters(t *testing.T) { t.Run("equal", func(t *testing.T) { - store := NewMockObjectStore(t) + store := &stubSpaceObjectStore{} // Query will occur while nested filter resolving - store.EXPECT().QueryRaw(mock.Anything, 0, 0).Return([]Record{ + store.queryRawResult = []Record{ { Details: &types.Struct{ Fields: map[string]*types.Value{ @@ -467,7 +466,7 @@ func TestNestedFilters(t *testing.T) { }, }, }, - }, nil) + } f, err := MakeFilter("spaceId", &model.BlockContentDataviewFilter{ RelationKey: "type.typeKey", @@ -483,26 +482,27 @@ func TestNestedFilters(t *testing.T) { }) t.Run("not equal", func(t *testing.T) { - store := NewMockObjectStore(t) - // Query will occur while nested filter resolving - store.EXPECT().QueryRaw(mock.Anything, 0, 0).Return([]Record{ - { - Details: &types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyId.String(): pbtypes.String("id1"), - bundle.RelationKeyUniqueKey.String(): pbtypes.String("ot-note"), + store := &stubSpaceObjectStore{ + queryRawResult: []Record{ + { + Details: &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String("id1"), + bundle.RelationKeyUniqueKey.String(): pbtypes.String("ot-note"), + }, }, }, - }, - { - Details: &types.Struct{ - Fields: map[string]*types.Value{ - bundle.RelationKeyId.String(): pbtypes.String("id2"), - bundle.RelationKeyUniqueKey.String(): pbtypes.String("ot-note"), + { + Details: &types.Struct{ + Fields: map[string]*types.Value{ + bundle.RelationKeyId.String(): pbtypes.String("id2"), + bundle.RelationKeyUniqueKey.String(): pbtypes.String("ot-note"), + }, }, }, }, - }, nil) + } + // Query will occur while nested filter resolving f, err := MakeFilter("spaceId", &model.BlockContentDataviewFilter{ RelationKey: "type.uniqueKey", @@ -542,32 +542,32 @@ func TestFilterOptionsEqual(t *testing.T) { "optionId3": "3", } t.Run("one option, ok", func(t *testing.T) { - eq := newFilterOptionsEqual(&fastjson.Arena{}, "k", pbtypes.StringList([]string{"optionId1"}).GetListValue(), optionIdToName) + eq := newFilterOptionsEqual(&anyenc.Arena{}, "k", pbtypes.StringList([]string{"optionId1"}).GetListValue(), optionIdToName) obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1"})}} assertFilter(t, eq, obj, true) }) t.Run("two options, ok", func(t *testing.T) { - eq := newFilterOptionsEqual(&fastjson.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId3"}).GetListValue(), optionIdToName) + eq := newFilterOptionsEqual(&anyenc.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId3"}).GetListValue(), optionIdToName) obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId3"})}} assertFilter(t, eq, obj, true) }) t.Run("two options, ok, not existing options are discarded", func(t *testing.T) { - eq := newFilterOptionsEqual(&fastjson.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId3"}).GetListValue(), optionIdToName) + eq := newFilterOptionsEqual(&anyenc.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId3"}).GetListValue(), optionIdToName) obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId3", "optionId7000"})}} assertFilter(t, eq, obj, true) }) t.Run("two options, not ok", func(t *testing.T) { - eq := newFilterOptionsEqual(&fastjson.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(), optionIdToName) + eq := newFilterOptionsEqual(&anyenc.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(), optionIdToName) obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId3"})}} assertFilter(t, eq, obj, false) }) t.Run("two options, not ok, because object has 1 option", func(t *testing.T) { - eq := newFilterOptionsEqual(&fastjson.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(), optionIdToName) + eq := newFilterOptionsEqual(&anyenc.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(), optionIdToName) obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1"})}} assertFilter(t, eq, obj, false) }) t.Run("two options, not ok, because object has 3 options", func(t *testing.T) { - eq := newFilterOptionsEqual(&fastjson.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(), optionIdToName) + eq := newFilterOptionsEqual(&anyenc.Arena{}, "k", pbtypes.StringList([]string{"optionId1", "optionId2"}).GetListValue(), optionIdToName) obj := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.StringList([]string{"optionId1", "optionId2", "optionId3"})}} assertFilter(t, eq, obj, false) }) @@ -576,7 +576,7 @@ func TestFilterOptionsEqual(t *testing.T) { func TestMakeFilters(t *testing.T) { t.Run("no filters", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} // when filters, err := MakeFilters(nil, mockStore) @@ -587,7 +587,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("or filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_Or, @@ -626,7 +626,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("and filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -665,7 +665,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("none filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_No, @@ -689,7 +689,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("combined filter", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -736,7 +736,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("linear and nested filters", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { RelationKey: "key1", @@ -767,7 +767,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("linear and nested filters", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_And, @@ -821,7 +821,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("transform quick options", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_Or, @@ -853,7 +853,7 @@ func TestMakeFilters(t *testing.T) { }) t.Run("transform quick options", func(t *testing.T) { // given - mockStore := NewMockObjectStore(t) + mockStore := &stubSpaceObjectStore{} filter := []*model.BlockContentDataviewFilter{ { Operator: model.BlockContentDataviewFilter_Or, diff --git a/pkg/lib/database/mock_ObjectStore.go b/pkg/lib/database/mock_ObjectStore.go deleted file mode 100644 index fa25218e94..0000000000 --- a/pkg/lib/database/mock_ObjectStore.go +++ /dev/null @@ -1,209 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package database - -import ( - model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - mock "github.com/stretchr/testify/mock" -) - -// MockObjectStore is an autogenerated mock type for the ObjectStore type -type MockObjectStore struct { - mock.Mock -} - -type MockObjectStore_Expecter struct { - mock *mock.Mock -} - -func (_m *MockObjectStore) EXPECT() *MockObjectStore_Expecter { - return &MockObjectStore_Expecter{mock: &_m.Mock} -} - -// GetRelationFormatByKey provides a mock function with given fields: key -func (_m *MockObjectStore) GetRelationFormatByKey(key string) (model.RelationFormat, error) { - ret := _m.Called(key) - - if len(ret) == 0 { - panic("no return value specified for GetRelationFormatByKey") - } - - var r0 model.RelationFormat - var r1 error - if rf, ok := ret.Get(0).(func(string) (model.RelationFormat, error)); ok { - return rf(key) - } - if rf, ok := ret.Get(0).(func(string) model.RelationFormat); ok { - r0 = rf(key) - } else { - r0 = ret.Get(0).(model.RelationFormat) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(key) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetRelationFormatByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationFormatByKey' -type MockObjectStore_GetRelationFormatByKey_Call struct { - *mock.Call -} - -// GetRelationFormatByKey is a helper method to define mock.On call -// - key string -func (_e *MockObjectStore_Expecter) GetRelationFormatByKey(key interface{}) *MockObjectStore_GetRelationFormatByKey_Call { - return &MockObjectStore_GetRelationFormatByKey_Call{Call: _e.mock.On("GetRelationFormatByKey", key)} -} - -func (_c *MockObjectStore_GetRelationFormatByKey_Call) Run(run func(key string)) *MockObjectStore_GetRelationFormatByKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetRelationFormatByKey_Call) Return(_a0 model.RelationFormat, _a1 error) *MockObjectStore_GetRelationFormatByKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetRelationFormatByKey_Call) RunAndReturn(run func(string) (model.RelationFormat, error)) *MockObjectStore_GetRelationFormatByKey_Call { - _c.Call.Return(run) - return _c -} - -// Query provides a mock function with given fields: q -func (_m *MockObjectStore) Query(q Query) ([]Record, error) { - ret := _m.Called(q) - - if len(ret) == 0 { - panic("no return value specified for Query") - } - - var r0 []Record - var r1 error - if rf, ok := ret.Get(0).(func(Query) ([]Record, error)); ok { - return rf(q) - } - if rf, ok := ret.Get(0).(func(Query) []Record); ok { - r0 = rf(q) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Record) - } - } - - if rf, ok := ret.Get(1).(func(Query) error); ok { - r1 = rf(q) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_Query_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Query' -type MockObjectStore_Query_Call struct { - *mock.Call -} - -// Query is a helper method to define mock.On call -// - q Query -func (_e *MockObjectStore_Expecter) Query(q interface{}) *MockObjectStore_Query_Call { - return &MockObjectStore_Query_Call{Call: _e.mock.On("Query", q)} -} - -func (_c *MockObjectStore_Query_Call) Run(run func(q Query)) *MockObjectStore_Query_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(Query)) - }) - return _c -} - -func (_c *MockObjectStore_Query_Call) Return(records []Record, err error) *MockObjectStore_Query_Call { - _c.Call.Return(records, err) - return _c -} - -func (_c *MockObjectStore_Query_Call) RunAndReturn(run func(Query) ([]Record, error)) *MockObjectStore_Query_Call { - _c.Call.Return(run) - return _c -} - -// QueryRaw provides a mock function with given fields: filters, limit, offset -func (_m *MockObjectStore) QueryRaw(filters *Filters, limit int, offset int) ([]Record, error) { - ret := _m.Called(filters, limit, offset) - - if len(ret) == 0 { - panic("no return value specified for QueryRaw") - } - - var r0 []Record - var r1 error - if rf, ok := ret.Get(0).(func(*Filters, int, int) ([]Record, error)); ok { - return rf(filters, limit, offset) - } - if rf, ok := ret.Get(0).(func(*Filters, int, int) []Record); ok { - r0 = rf(filters, limit, offset) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Record) - } - } - - if rf, ok := ret.Get(1).(func(*Filters, int, int) error); ok { - r1 = rf(filters, limit, offset) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_QueryRaw_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryRaw' -type MockObjectStore_QueryRaw_Call struct { - *mock.Call -} - -// QueryRaw is a helper method to define mock.On call -// - filters *Filters -// - limit int -// - offset int -func (_e *MockObjectStore_Expecter) QueryRaw(filters interface{}, limit interface{}, offset interface{}) *MockObjectStore_QueryRaw_Call { - return &MockObjectStore_QueryRaw_Call{Call: _e.mock.On("QueryRaw", filters, limit, offset)} -} - -func (_c *MockObjectStore_QueryRaw_Call) Run(run func(filters *Filters, limit int, offset int)) *MockObjectStore_QueryRaw_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*Filters), args[1].(int), args[2].(int)) - }) - return _c -} - -func (_c *MockObjectStore_QueryRaw_Call) Return(_a0 []Record, _a1 error) *MockObjectStore_QueryRaw_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_QueryRaw_Call) RunAndReturn(run func(*Filters, int, int) ([]Record, error)) *MockObjectStore_QueryRaw_Call { - _c.Call.Return(run) - return _c -} - -// NewMockObjectStore creates a new instance of MockObjectStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockObjectStore(t interface { - mock.TestingT - Cleanup(func()) -}) *MockObjectStore { - mock := &MockObjectStore{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/lib/database/order.go b/pkg/lib/database/order.go index 301a92fae1..34f1e8c8a8 100644 --- a/pkg/lib/database/order.go +++ b/pkg/lib/database/order.go @@ -1,10 +1,9 @@ package database import ( - "github.com/anyproto/any-store/encoding" + "github.com/anyproto/any-store/anyenc" "github.com/anyproto/any-store/query" "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" "golang.org/x/text/collate" "golang.org/x/text/language" @@ -21,9 +20,11 @@ type Order interface { // ObjectStore interface is used to enrich filters type ObjectStore interface { + SpaceId() string Query(q Query) (records []Record, err error) QueryRaw(filters *Filters, limit int, offset int) ([]Record, error) GetRelationFormatByKey(key string) (model.RelationFormat, error) + ListRelationOptions(relationKey string) (options []*model.RelationOption, err error) } type SetOrder []Order @@ -57,7 +58,7 @@ type KeyOrder struct { IncludeTime bool Store ObjectStore Options map[string]string - arena *fastjson.Arena + arena *anyenc.Arena collatorBuffer *collate.Buffer collator *collate.Collator } @@ -93,25 +94,25 @@ func (ko *KeyOrder) AnystoreSort() query.Sort { case model.RelationFormat_shorttext, model.RelationFormat_longtext: return ko.textSort() case model.RelationFormat_number: - return ko.basicSort(fastjson.TypeNumber) + return ko.basicSort(anyenc.TypeNumber) case model.RelationFormat_date: if ko.IncludeTime { - return ko.basicSort(fastjson.TypeNumber) + return ko.basicSort(anyenc.TypeNumber) } else { return ko.dateOnlySort() } case model.RelationFormat_object, model.RelationFormat_file: - return ko.basicSort(fastjson.TypeString) + return ko.basicSort(anyenc.TypeString) case model.RelationFormat_url, model.RelationFormat_email, model.RelationFormat_phone, model.RelationFormat_emoji: - return ko.basicSort(fastjson.TypeString) + return ko.basicSort(anyenc.TypeString) case model.RelationFormat_tag, model.RelationFormat_status: return ko.tagStatusSort() default: - return ko.basicSort(fastjson.TypeString) + return ko.basicSort(anyenc.TypeString) } } -func (ko *KeyOrder) basicSort(valType fastjson.Type) query.Sort { +func (ko *KeyOrder) basicSort(valType anyenc.Type) query.Sort { if ko.EmptyPlacement == model.BlockContentDataviewSort_Start && ko.Type == model.BlockContentDataviewSort_Desc { return ko.emptyPlacementSort(valType) } else if ko.EmptyPlacement == model.BlockContentDataviewSort_End && ko.Type == model.BlockContentDataviewSort_Asc { @@ -141,7 +142,7 @@ func (ko *KeyOrder) tagStatusSort() query.Sort { } } -func (ko *KeyOrder) emptyPlacementSort(valType fastjson.Type) query.Sort { +func (ko *KeyOrder) emptyPlacementSort(valType anyenc.Type) query.Sort { return emptyPlacementSort{ arena: ko.arena, relationKey: ko.Key, @@ -286,7 +287,7 @@ func (ko *KeyOrder) GetOptionValue(value *types.Value) *types.Value { return pbtypes.String(res) } -func newCustomOrder(arena *fastjson.Arena, key string, idsIndices map[string]int, keyOrd *KeyOrder) customOrder { +func newCustomOrder(arena *anyenc.Arena, key string, idsIndices map[string]int, keyOrd *KeyOrder) customOrder { return customOrder{ arena: arena, Key: key, @@ -296,7 +297,7 @@ func newCustomOrder(arena *fastjson.Arena, key string, idsIndices map[string]int } type customOrder struct { - arena *fastjson.Arena + arena *anyenc.Arena Key string NeedOrderMap map[string]int KeyOrd *KeyOrder @@ -304,7 +305,7 @@ type customOrder struct { buf []byte } -func (co customOrder) AppendKey(k []byte, v *fastjson.Value) []byte { +func (co customOrder) AppendKey(k anyenc.Tuple, v *anyenc.Value) anyenc.Tuple { defer func() { co.arena.Reset() co.buf = co.buf[:0] @@ -318,11 +319,11 @@ func (co customOrder) AppendKey(k []byte, v *fastjson.Value) []byte { if !ok { anystoreSort := co.KeyOrd.AnystoreSort() // Push to the end - k = encoding.AppendJSONValue(k, co.arena.NewNumberInt(len(co.NeedOrderMap))) + k = co.arena.NewNumberInt(len(co.NeedOrderMap)).MarshalTo(k) // and add sorting return anystoreSort.AppendKey(k, v) } - return encoding.AppendJSONValue(k, co.arena.NewNumberInt(idx)) + return co.arena.NewNumberInt(idx).MarshalTo(k) } func (co customOrder) Fields() []query.SortField { @@ -344,7 +345,7 @@ func (co customOrder) getStringVal(val *types.Value) string { co.buf = co.buf[:0] }() - jsonVal := pbtypes.ProtoValueToJson(co.arena, val) + jsonVal := pbtypes.ProtoValueToAnyEnc(co.arena, val) if jsonVal == nil { return "" } diff --git a/pkg/lib/database/order_test.go b/pkg/lib/database/order_test.go index a1b68fdcd8..055a219a12 100644 --- a/pkg/lib/database/order_test.go +++ b/pkg/lib/database/order_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" - "github.com/valyala/fastjson" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" @@ -16,18 +16,18 @@ import ( func assertCompare(t *testing.T, order Order, a *types.Struct, b *types.Struct, expected int) { assert.Equal(t, expected, order.Compare(a, b)) - arena := &fastjson.Arena{} - aJson := pbtypes.ProtoToJson(arena, a) - bJson := pbtypes.ProtoToJson(arena, b) + arena := &anyenc.Arena{} + aValue := pbtypes.ProtoToAnyEnc(arena, a) + bValue := pbtypes.ProtoToAnyEnc(arena, b) s := order.AnystoreSort() - aBytes := s.AppendKey(nil, aJson) - bBytes := s.AppendKey(nil, bJson) + aBytes := s.AppendKey(nil, aValue) + bBytes := s.AppendKey(nil, bValue) got := bytes.Compare(aBytes, bBytes) assert.Equal(t, expected, got) } func TestTextSort(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("note layout, not empty name", func(t *testing.T) { a := &types.Struct{ Fields: map[string]*types.Value{ @@ -85,7 +85,7 @@ func TestTextSort(t *testing.T) { } func TestKeyOrder_Compare(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("eq", func(t *testing.T) { a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}} b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}} @@ -373,7 +373,7 @@ func TestKeyOrder_Compare(t *testing.T) { } func TestKeyUnicodeOrder_Compare(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("asc", func(t *testing.T) { a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("Єгипет")}} b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("Японія")}} @@ -390,7 +390,7 @@ func TestKeyUnicodeOrder_Compare(t *testing.T) { } func TestSetOrder_Compare(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} so := SetOrder{ &KeyOrder{arena: arena, Key: "a", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}, &KeyOrder{arena: arena, Key: "b", Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_shorttext}, @@ -414,14 +414,15 @@ func TestSetOrder_Compare(t *testing.T) { } func TestCustomOrder_Compare(t *testing.T) { + a := &anyenc.Arena{} // keys are json values idxIndices := map[string]int{ - `"b"`: 0, - `"c"`: 1, - `"d"`: 2, - `"a"`: 3, + string(a.NewString("b").MarshalTo(nil)): 0, + string(a.NewString("c").MarshalTo(nil)): 1, + string(a.NewString("d").MarshalTo(nil)): 2, + string(a.NewString("a").MarshalTo(nil)): 3, } - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} co := newCustomOrder(arena, "ID", idxIndices, &KeyOrder{arena: arena, Key: "ID", Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}) t.Run("gt", func(t *testing.T) { @@ -474,7 +475,7 @@ func TestCustomOrder_Compare(t *testing.T) { } func TestTagStatusOrder_Compare(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} for _, relation := range []model.RelationFormat{model.RelationFormat_tag, model.RelationFormat_status} { t.Run("eq", func(t *testing.T) { a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.String("a")}} @@ -507,7 +508,7 @@ func TestTagStatusOrder_Compare(t *testing.T) { func TestIncludeTime_Compare(t *testing.T) { date := time.Unix(1672012800, 0) - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("date only eq", func(t *testing.T) { a := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 5).Unix())}} b := &types.Struct{Fields: map[string]*types.Value{"k": pbtypes.Int64(date.Add(time.Second * 10).Unix())}} diff --git a/pkg/lib/datastore/clientds/process.go b/pkg/lib/datastore/clientds/process.go index c340b11780..96d7bc77f5 100644 --- a/pkg/lib/datastore/clientds/process.go +++ b/pkg/lib/datastore/clientds/process.go @@ -61,12 +61,14 @@ func processByPid(pid int) (*process.Process, error) { return nil, fmt.Errorf("process not found") } -func isMyProcess(exePath string, process *process.Process) bool { +func isSameProcessExeFilename(exePath string, process *process.Process) bool { processPath, err := process.Exe() if err != nil { return false } - return processPath == exePath + + // only check the last part of the path + return filepath.Base(processPath) == filepath.Base(exePath) } func cleanupAfterOldProcess(exePath string, lockfile string) { @@ -82,7 +84,8 @@ func cleanupAfterOldProcess(exePath string, lockfile string) { isNotCurrentRun := os.Getpid() != oldPid - if isNotCurrentRun && !isMyProcess(exePath, proc) { + if isNotCurrentRun && isSameProcessExeFilename(exePath, proc) { + // isSameProcessExeFilename is to avoid false positives, because PIDs can be reused by the OS log.Warnf("Killing the old process.") err = proc.Kill() if err != nil { diff --git a/pkg/lib/localstore/ftsearch/ftsearchbleve.go b/pkg/lib/localstore/ftsearch/ftsearchbleve.go index 24a998cc91..04518cccf7 100644 --- a/pkg/lib/localstore/ftsearch/ftsearchbleve.go +++ b/pkg/lib/localstore/ftsearch/ftsearchbleve.go @@ -28,7 +28,7 @@ import ( const ( CName = "fts" ftsDir = "fts" - ftsVer = "5" + ftsVer = "6" fieldTitle = "Title" fieldText = "Text" diff --git a/pkg/lib/localstore/ftsearch/ftsearchtantivy.go b/pkg/lib/localstore/ftsearch/ftsearchtantivy.go index 00e5c790e7..192d2f7dab 100644 --- a/pkg/lib/localstore/ftsearch/ftsearchtantivy.go +++ b/pkg/lib/localstore/ftsearch/ftsearchtantivy.go @@ -29,6 +29,7 @@ import ( "github.com/anyproto/anytype-heart/core/wallet" "github.com/anyproto/anytype-heart/metrics" + "github.com/anyproto/anytype-heart/util/text" ) func TantivyNew() FTSearch { @@ -158,8 +159,7 @@ func (f *ftSearchTantivy) Run(context.Context) error { if err != nil { return err } - - index, err := tantivy.NewTantivyContextWithSchema(f.ftsPath, schema) + index, err := f.tryToBuildSchema(schema) if err != nil { return err } @@ -180,12 +180,7 @@ func (f *ftSearchTantivy) Run(context.Context) error { return err } - err = index.RegisterTextAnalyzerEdgeNgram(tantivy.TokenizerEdgeNgram, 1, 5, 100) - if err != nil { - return err - } - - err = index.RegisterTextAnalyzerNgram(tantivy.TokenizerNgram, 1, 5, false) + err = index.RegisterTextAnalyzerNgram(tantivy.TokenizerNgram, 3, 5, false) if err != nil { return err } @@ -198,6 +193,18 @@ func (f *ftSearchTantivy) Run(context.Context) error { return nil } +func (f *ftSearchTantivy) tryToBuildSchema(schema *tantivy.Schema) (*tantivy.TantivyContext, error) { + index, err := tantivy.NewTantivyContextWithSchema(f.ftsPath, schema) + if err != nil { + log.Warnf("recovering from error: %v", err) + if strings.HasSuffix(f.rootPath, ftsDir2) { + _ = os.RemoveAll(f.rootPath) + } + return tantivy.NewTantivyContextWithSchema(f.ftsPath, schema) + } + return index, err +} + func (f *ftSearchTantivy) Index(doc SearchDoc) error { metrics.ObjectFTUpdatedCounter.Inc() tantivyDoc, err := f.convertDoc(doc) @@ -266,14 +273,16 @@ func (f *ftSearchTantivy) BatchIndex(ctx context.Context, docs []SearchDoc, dele func (f *ftSearchTantivy) Search(spaceIds []string, highlightFormatter HighlightFormatter, query string) (results search.DocumentMatchCollection, err error) { spaceIdsQuery := getSpaceIdsQuery(spaceIds) - if spaceIdsQuery == "" { - query = escapeQuery(query) - } else { - query = fmt.Sprintf("%s AND %s", spaceIdsQuery, escapeQuery(query)) + query = prepareQuery(query) + if query == "" { + return nil, nil + } + if spaceIdsQuery != "" { + query = fmt.Sprintf("%s AND %s", spaceIdsQuery, query) } result, err := f.index.Search(query, 100, true, fieldId, fieldSpace, fieldTitle, fieldText) if err != nil { - return nil, err + return nil, wrapError(err) } p := f.parserPool.Get() defer f.parserPool.Put(p) @@ -309,7 +318,16 @@ func (f *ftSearchTantivy) Search(spaceIds []string, highlightFormatter Highlight ) } +func wrapError(err error) error { + errStr := err.Error() + if strings.Contains(errStr, "Syntax Error:") { + return fmt.Errorf("invalid query") + } + return err +} + func getSpaceIdsQuery(ids []string) string { + ids = lo.Filter(ids, func(item string, index int) bool { return item != "" }) if len(ids) == 0 || lo.EveryBy(ids, func(id string) bool { return id == "" }) { return "" } @@ -338,7 +356,11 @@ func (f *ftSearchTantivy) DocCount() (uint64, error) { func (f *ftSearchTantivy) Close(ctx context.Context) error { f.schema = nil - f.index.Free() + if f.index != nil { + f.index.Free() + f.index = nil + f.schema = nil + } return nil } @@ -346,16 +368,21 @@ func (f *ftSearchTantivy) cleanupBleve() { _ = os.RemoveAll(filepath.Join(f.rootPath, ftsDir)) } -func escapeQuery(query string) string { +func prepareQuery(query string) string { + query = text.Truncate(query, 100, "") + query = strings.ToLower(query) + query = strings.TrimSpace(query) var escapedQuery strings.Builder for _, char := range query { - if _, found := specialChars[char]; found { - escapedQuery.WriteRune(' ') + if _, found := specialChars[char]; !found { + escapedQuery.WriteRune(char) } - escapedQuery.WriteRune(char) } resultQuery := escapedQuery.String() + if resultQuery == "" { + return resultQuery + } return "(\"" + resultQuery + "\" OR " + resultQuery + ")" } diff --git a/pkg/lib/localstore/ftsearch/ftsearchtantivy_test.go b/pkg/lib/localstore/ftsearch/ftsearchtantivy_test.go index 81239e2516..5aa81b7643 100644 --- a/pkg/lib/localstore/ftsearch/ftsearchtantivy_test.go +++ b/pkg/lib/localstore/ftsearch/ftsearchtantivy_test.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "os" + "strings" "testing" "github.com/anyproto/any-sync/app" @@ -387,7 +388,58 @@ func assertMultiSpace(t *testing.T, tmpDir string) { validateSearch(t, ft, "", "Advanced", 1) validateSearch(t, ft, "", "dash", 2) validateSearch(t, ft, "", "space", 4) - validateSearch(t, ft, "", "of", 5) + validateSearch(t, ft, "", "of", 0) _ = ft.Close(nil) } + +func TestEscapeQuery(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {strings.Repeat("a", 99) + " aa", `("` + strings.Repeat("a", 99) + `" OR ` + strings.Repeat("a", 99) + `)`}, + {`""`, ``}, + {"simpleQuery", `("simplequery" OR simplequery)`}, + {"with+special^chars", `("withspecialchars" OR withspecialchars)`}, + {"text`with:brackets{}", `("textwithbrackets" OR textwithbrackets)`}, + {"escaped[]symbols()", `("escapedsymbols" OR escapedsymbols)`}, + {"multiple!!special~~", `("multiplespecial" OR multiplespecial)`}, + } + + for _, test := range tests { + actual := prepareQuery(test.input) + if actual != test.expected { + t.Errorf("For input '%s', expected '%s', but got '%s'", test.input, test.expected, actual) + } + } +} + +// Tests +func TestGetSpaceIdsQuery(t *testing.T) { + // Test with empty slice of ids + assert.Equal(t, "", getSpaceIdsQuery([]string{})) + + // Test with slice containing only empty strings + assert.Equal(t, "", getSpaceIdsQuery([]string{"", "", ""})) + + // Test with a single id + assert.Equal(t, "(SpaceID:123)", getSpaceIdsQuery([]string{"123"})) + + // Test with multiple ids + assert.Equal(t, "(SpaceID:123 OR SpaceID:456 OR SpaceID:789)", getSpaceIdsQuery([]string{"123", "456", "789"})) + + // Test with some empty ids + assert.Equal(t, "(SpaceID:123 OR SpaceID:789)", getSpaceIdsQuery([]string{"123", "", "789"})) +} + +func TestFtSearch_Close(t *testing.T) { + // given + fts := new(ftSearchTantivy) + + // when + err := fts.Close(nil) + + // then + assert.NoError(t, err) +} diff --git a/pkg/lib/localstore/objectstore/account_store.go b/pkg/lib/localstore/objectstore/account_store.go index f5755fdf65..b077f32141 100644 --- a/pkg/lib/localstore/objectstore/account_store.go +++ b/pkg/lib/localstore/objectstore/account_store.go @@ -4,15 +4,15 @@ import ( "encoding/json" "fmt" + "github.com/anyproto/any-store/anyenc" "github.com/anyproto/any-sync/coordinator/coordinatorproto" - "github.com/valyala/fastjson" ) const ( accountStatusKey = "account_status" ) -func keyValueItem(arena *fastjson.Arena, key string, value any) (*fastjson.Value, error) { +func keyValueItem(arena *anyenc.Arena, key string, value any) (*anyenc.Value, error) { raw, err := json.Marshal(value) if err != nil { return nil, err @@ -35,7 +35,7 @@ func (s *dsObjectStore) SaveAccountStatus(status *coordinatorproto.SpaceStatusPa if err != nil { return fmt.Errorf("create item: %w", err) } - _, err = s.system.UpsertOne(s.componentCtx, it) + err = s.system.UpsertOne(s.componentCtx, it) return err } diff --git a/pkg/lib/localstore/objectstore/activeview_test.go b/pkg/lib/localstore/objectstore/activeview_test.go deleted file mode 100644 index 0c8edf2c93..0000000000 --- a/pkg/lib/localstore/objectstore/activeview_test.go +++ /dev/null @@ -1,2 +0,0 @@ -package objectstore - diff --git a/pkg/lib/localstore/objectstore/anystorehelper/helper.go b/pkg/lib/localstore/objectstore/anystorehelper/helper.go new file mode 100644 index 0000000000..6c5c7eba2e --- /dev/null +++ b/pkg/lib/localstore/objectstore/anystorehelper/helper.go @@ -0,0 +1,94 @@ +package anystorehelper + +import ( + "context" + "errors" + "fmt" + "os" + "time" + + anystore "github.com/anyproto/any-store" + "zombiezen.com/go/sqlite" + + "github.com/anyproto/anytype-heart/pkg/lib/logging" +) + +var log = logging.Logger("objectstore.spaceindex") + +func OpenDatabaseWithLockCheck(ctx context.Context, path string, config *anystore.Config) (store anystore.DB, lockClose func() error, err error) { + lockFilePath := path + ".LOCK" + lockClose = func() error { + return os.RemoveAll(lockFilePath) + } + lockCloseNoop := func() error { + return nil + } + var lockFileAlreadyExists, runQuickCheck bool + + // Attempt to create the lock file atomically + lockFile, err := os.OpenFile(lockFilePath, os.O_CREATE|os.O_EXCL, 0644) + if err != nil { + if os.IsExist(err) { + lockFileAlreadyExists, runQuickCheck = true, true + } else { + return + } + } else { + // todo: add pid check after a full badger deprecation + _, _ = lockFile.Write([]byte(fmt.Sprintf("%d", os.Getpid()))) + _ = lockFile.Close() + } + + store, err = anystore.Open(ctx, path, config) + if err != nil { + code := sqlite.ErrCode(err) + l := log.With("error", err).With("code", code) + if errors.Is(err, anystore.ErrIncompatibleVersion) || code == sqlite.ResultCorrupt || code == sqlite.ResultNotADB || code == sqlite.ResultCantOpen { + runQuickCheck = false + l.Errorf("failed to open anystore, reinit db") + if err = os.RemoveAll(path); err != nil { + return nil, lockCloseNoop, err + } + store, err = anystore.Open(ctx, path, config) + } else { + l.Errorf("failed to open anystore, non-recoverable error") + // some other error + return nil, lockCloseNoop, err + } + } + if lockFileAlreadyExists { + // overwrite existing lock file with the current pid + err = os.WriteFile(lockFilePath, []byte(fmt.Sprintf("%d", os.Getpid())), 0644) + if err != nil { + log.Errorf("failed to write pid to existing lock file: %v", err.Error()) + } + } + + if !runQuickCheck { + return + } + // means we have not closed properly + start := time.Now() + err = store.QuickCheck(ctx) + if err != nil { + // db is corrupted, close it and reinit + closeErr := store.Close() + log.With("closeError", closeErr).With("error", err).Error("quick check failed. reinit db") + if err = os.RemoveAll(path); err != nil { + return nil, lockCloseNoop, err + } + store, err = anystore.Open(ctx, path, config) + if err != nil { + return nil, lockCloseNoop, err + } + } else { + spentMs := time.Since(start).Milliseconds() + if spentMs < 1000 { + log.With("spent", spentMs).Infof("quick check succeed") + } else { + log.With("spent", spentMs).Warn("quick check succeed") + } + } + + return +} diff --git a/pkg/lib/localstore/objectstore/debug.go b/pkg/lib/localstore/objectstore/debug.go index 1d2854cd2c..9a0f789975 100644 --- a/pkg/lib/localstore/objectstore/debug.go +++ b/pkg/lib/localstore/objectstore/debug.go @@ -1,6 +1,7 @@ package objectstore import ( + "fmt" "net/http" "github.com/go-chi/chi/v5" @@ -14,6 +15,7 @@ func (s *dsObjectStore) DebugRouter(r chi.Router) { } func (s *dsObjectStore) debugDetails(req *http.Request) (*model.ObjectDetails, error) { - id := chi.URLParam(req, "id") - return s.GetDetails(id) + // id := chi.URLParam(req, "id") + return nil, fmt.Errorf("not implemented") + // return s.GetDetails("TODO", id) } diff --git a/pkg/lib/localstore/objectstore/fixture.go b/pkg/lib/localstore/objectstore/fixture.go index 2926088a33..032e52ed93 100644 --- a/pkg/lib/localstore/objectstore/fixture.go +++ b/pkg/lib/localstore/objectstore/fixture.go @@ -3,30 +3,45 @@ package objectstore import ( "context" "fmt" - "math/rand" "testing" + "github.com/anyproto/any-store/anyenc" "github.com/anyproto/any-sync/app" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/require" - "github.com/valyala/fastjson" - "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/wallet" "github.com/anyproto/anytype-heart/core/wallet/mock_wallet" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/datastore" "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/oldstore" - "github.com/anyproto/anytype-heart/util/pbtypes" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" ) type StoreFixture struct { *dsObjectStore + FullText ftsearch.FTSearch } -// nolint: unused -const spaceName = "space1" +func (fx *StoreFixture) TechSpaceId() string { + return fx.techSpaceIdProvider.TechSpaceId() +} + +type detailsFromId struct { +} + +func (d *detailsFromId) DetailsFromIdBasedSource(id string) (*types.Struct, error) { + return nil, fmt.Errorf("not found") +} + +type stubTechSpaceIdProvider struct{} + +func (s *stubTechSpaceIdProvider) TechSpaceId() string { + return "test-tech-space" +} + +var ctx = context.Background() func NewStoreFixture(t testing.TB) *StoreFixture { ctx, cancel := context.WithCancel(context.Background()) @@ -53,13 +68,16 @@ func NewStoreFixture(t testing.TB) *StoreFixture { require.NoError(t, err) ds := &dsObjectStore{ - componentCtx: ctx, - componentCtxCancel: cancel, - fts: fullText, - sourceService: &detailsFromId{}, - arenaPool: &fastjson.ArenaPool{}, - repoPath: walletService.RepoPath(), - oldStore: oldStore, + componentCtx: ctx, + componentCtxCancel: cancel, + fts: fullText, + sourceService: &detailsFromId{}, + arenaPool: &anyenc.ArenaPool{}, + repoPath: walletService.RepoPath(), + oldStore: oldStore, + spaceIndexes: map[string]spaceindex.Store{}, + techSpaceIdProvider: &stubTechSpaceIdProvider{}, + subManager: &spaceindex.SubscriptionManager{}, } t.Cleanup(func() { @@ -72,60 +90,30 @@ func NewStoreFixture(t testing.TB) *StoreFixture { return &StoreFixture{ dsObjectStore: ds, + FullText: fullText, } } -type detailsFromId struct { -} - -func (d *detailsFromId) DetailsFromIdBasedSource(id string) (*types.Struct, error) { - return nil, fmt.Errorf("not found") -} - func (fx *StoreFixture) Init(a *app.App) (err error) { return nil } -type TestObject map[domain.RelationKey]*types.Value +type TestObject = spaceindex.TestObject -func generateObjectWithRandomID() TestObject { - id := fmt.Sprintf("%d", rand.Int()) - return TestObject{ - bundle.RelationKeyId: pbtypes.String(id), - bundle.RelationKeyName: pbtypes.String("name" + id), - } -} - -func makeObjectWithName(id string, name string) TestObject { - return TestObject{ - bundle.RelationKeyId: pbtypes.String(id), - bundle.RelationKeyName: pbtypes.String(name), - bundle.RelationKeySpaceId: pbtypes.String(spaceName), - } -} - -func makeObjectWithNameAndDescription(id string, name string, description string) TestObject { - return TestObject{ - bundle.RelationKeyId: pbtypes.String(id), - bundle.RelationKeyName: pbtypes.String(name), - bundle.RelationKeyDescription: pbtypes.String(description), - bundle.RelationKeySpaceId: pbtypes.String(spaceName), +func (fx *StoreFixture) AddObjects(t testing.TB, spaceId string, objects []spaceindex.TestObject) { + store := fx.SpaceIndex(spaceId) + for _, obj := range objects { + id := obj[bundle.RelationKeyId].GetStringValue() + require.NotEmpty(t, id) + err := store.UpdateObjectDetails(context.Background(), id, makeDetails(obj)) + require.NoError(t, err) } } -func makeDetails(fields TestObject) *types.Struct { +func makeDetails(fields spaceindex.TestObject) *types.Struct { f := map[string]*types.Value{} for k, v := range fields { f[string(k)] = v } return &types.Struct{Fields: f} } - -func (fx *StoreFixture) AddObjects(t testing.TB, objects []TestObject) { - for _, obj := range objects { - id := obj[bundle.RelationKeyId].GetStringValue() - require.NotEmpty(t, id) - err := fx.UpdateObjectDetails(context.Background(), id, makeDetails(obj)) - require.NoError(t, err) - } -} diff --git a/pkg/lib/localstore/objectstore/indexer_store.go b/pkg/lib/localstore/objectstore/indexer_store.go index 110959a741..657037a177 100644 --- a/pkg/lib/localstore/objectstore/indexer_store.go +++ b/pkg/lib/localstore/objectstore/indexer_store.go @@ -6,29 +6,34 @@ import ( "errors" "fmt" - anystore "github.com/anyproto/any-store" - "github.com/anyproto/any-store/query" - "github.com/valyala/fastjson" - "github.com/anyproto/anytype-heart/pkg/lib/pb/model" ) -func (s *dsObjectStore) AddToIndexQueue(id string) error { +func (s *dsObjectStore) AddToIndexQueue(ctx context.Context, ids ...string) error { + txn, err := s.fulltextQueue.WriteTx(ctx) + if err != nil { + return fmt.Errorf("start write tx: %w", err) + } arena := s.arenaPool.Get() defer func() { arena.Reset() s.arenaPool.Put(arena) }() - obj := arena.NewObject() - obj.Set("id", arena.NewString(id)) - _, err := s.fulltextQueue.UpsertOne(s.componentCtx, obj) - return err + obj := arena.NewObject() + for _, id := range ids { + obj.Set("id", arena.NewString(id)) + err = s.fulltextQueue.UpsertOne(txn.Context(), obj) + if err != nil { + return errors.Join(txn.Rollback(), fmt.Errorf("upsert: %w", err)) + } + } + return txn.Commit() } func (s *dsObjectStore) BatchProcessFullTextQueue(ctx context.Context, limit int, processIds func(ids []string) error) error { for { - ids, err := s.ListIDsFromFullTextQueue(limit) + ids, err := s.ListIdsFromFullTextQueue(limit) if err != nil { return fmt.Errorf("list ids from fulltext queue: %w", err) } @@ -39,31 +44,33 @@ func (s *dsObjectStore) BatchProcessFullTextQueue(ctx context.Context, limit int if err != nil { return fmt.Errorf("process ids: %w", err) } - err = s.RemoveIDsFromFullTextQueue(ids) + err = s.RemoveIdsFromFullTextQueue(ids) if err != nil { return fmt.Errorf("remove ids from fulltext queue: %w", err) } } } -func (s *dsObjectStore) ListIDsFromFullTextQueue(limit int) ([]string, error) { +func (s *dsObjectStore) ListIdsFromFullTextQueue(limit int) ([]string, error) { iter, err := s.fulltextQueue.Find(nil).Limit(uint(limit)).Iter(s.componentCtx) if err != nil { return nil, fmt.Errorf("create iterator: %w", err) } + defer iter.Close() + var ids []string for iter.Next() { doc, err := iter.Doc() if err != nil { - return nil, errors.Join(iter.Close(), fmt.Errorf("read doc: %w", err)) + return nil, fmt.Errorf("read doc: %w", err) } id := doc.Value().GetStringBytes("id") ids = append(ids, string(id)) } - return ids, iter.Close() + return ids, nil } -func (s *dsObjectStore) RemoveIDsFromFullTextQueue(ids []string) error { +func (s *dsObjectStore) RemoveIdsFromFullTextQueue(ids []string) error { txn, err := s.fulltextQueue.WriteTx(s.componentCtx) if err != nil { return fmt.Errorf("start write tx: %w", err) @@ -100,7 +107,7 @@ func (s *dsObjectStore) SaveChecksums(spaceId string, checksums *model.ObjectSto if err != nil { return err } - _, err = s.indexerChecksums.UpsertOne(s.componentCtx, it) + err = s.indexerChecksums.UpsertOne(s.componentCtx, it) return err } @@ -110,22 +117,3 @@ func (s *dsObjectStore) GetGlobalChecksums() (checksums *model.ObjectStoreChecks // TODO What to do? return s.GetChecksums("global") } - -const headsStateField = "h" - -// GetLastIndexedHeadsHash return empty hash without error if record was not found -func (s *dsObjectStore) GetLastIndexedHeadsHash(id string) (headsHash string, err error) { - doc, err := s.headsState.FindId(s.componentCtx, id) - if errors.Is(err, anystore.ErrDocNotFound) { - return "", nil - } - return string(doc.Value().GetStringBytes(headsStateField)), nil -} - -func (s *dsObjectStore) SaveLastIndexedHeadsHash(id string, headsHash string) error { - _, err := s.headsState.UpsertId(s.componentCtx, id, query.ModifyFunc(func(arena *fastjson.Arena, val *fastjson.Value) (*fastjson.Value, bool, error) { - val.Set(headsStateField, arena.NewString(headsHash)) - return val, true, nil - })) - return err -} diff --git a/pkg/lib/localstore/objectstore/indexer_store_test.go b/pkg/lib/localstore/objectstore/indexer_store_test.go index de03907433..d4335b9ac7 100644 --- a/pkg/lib/localstore/objectstore/indexer_store_test.go +++ b/pkg/lib/localstore/objectstore/indexer_store_test.go @@ -14,19 +14,19 @@ func TestDsObjectStore_IndexQueue(t *testing.T) { s := NewStoreFixture(t) t.Run("add to queue", func(t *testing.T) { - require.NoError(t, s.AddToIndexQueue("one")) - require.NoError(t, s.AddToIndexQueue("one")) - require.NoError(t, s.AddToIndexQueue("two")) + require.NoError(t, s.AddToIndexQueue(ctx, "one")) + require.NoError(t, s.AddToIndexQueue(ctx, "one")) + require.NoError(t, s.AddToIndexQueue(ctx, "two")) - ids, err := s.ListIDsFromFullTextQueue(0) + ids, err := s.ListIdsFromFullTextQueue(0) require.NoError(t, err) assert.ElementsMatch(t, []string{"one", "two"}, ids) }) t.Run("remove from queue", func(t *testing.T) { - s.RemoveIDsFromFullTextQueue([]string{"one"}) - ids, err := s.ListIDsFromFullTextQueue(0) + s.RemoveIdsFromFullTextQueue([]string{"one"}) + ids, err := s.ListIdsFromFullTextQueue(0) require.NoError(t, err) assert.ElementsMatch(t, []string{"two"}, ids) @@ -37,9 +37,9 @@ func TestIndexerBatch(t *testing.T) { s := NewStoreFixture(t) t.Run("batch - no more than limit", func(t *testing.T) { - require.NoError(t, s.AddToIndexQueue("one")) - require.NoError(t, s.AddToIndexQueue("two")) - require.NoError(t, s.AddToIndexQueue("three")) + require.NoError(t, s.AddToIndexQueue(ctx, "one")) + require.NoError(t, s.AddToIndexQueue(ctx, "two")) + require.NoError(t, s.AddToIndexQueue(ctx, "three")) var batches [][]string err := s.BatchProcessFullTextQueue(context.Background(), 2, func(ids []string) error { @@ -84,25 +84,3 @@ func TestIndexerChecksums(t *testing.T) { assert.Equal(t, want, got) }) } - -func TestHeadsHash(t *testing.T) { - t.Run("previous hash is not found", func(t *testing.T) { - s := NewStoreFixture(t) - - got, err := s.GetLastIndexedHeadsHash("id1") - require.NoError(t, err) - assert.Empty(t, got) - }) - - t.Run("save and load hash", func(t *testing.T) { - s := NewStoreFixture(t) - - want := "hash1" - - require.NoError(t, s.SaveLastIndexedHeadsHash("id1", want)) - - got, err := s.GetLastIndexedHeadsHash("id1") - require.NoError(t, err) - assert.Equal(t, want, got) - }) -} diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_AccountStore.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_AccountStore.go deleted file mode 100644 index 616354fc6d..0000000000 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_AccountStore.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_objectstore - -import ( - coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" - mock "github.com/stretchr/testify/mock" -) - -// MockAccountStore is an autogenerated mock type for the AccountStore type -type MockAccountStore struct { - mock.Mock -} - -type MockAccountStore_Expecter struct { - mock *mock.Mock -} - -func (_m *MockAccountStore) EXPECT() *MockAccountStore_Expecter { - return &MockAccountStore_Expecter{mock: &_m.Mock} -} - -// GetAccountStatus provides a mock function with given fields: -func (_m *MockAccountStore) GetAccountStatus() (*coordinatorproto.SpaceStatusPayload, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for GetAccountStatus") - } - - var r0 *coordinatorproto.SpaceStatusPayload - var r1 error - if rf, ok := ret.Get(0).(func() (*coordinatorproto.SpaceStatusPayload, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() *coordinatorproto.SpaceStatusPayload); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coordinatorproto.SpaceStatusPayload) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockAccountStore_GetAccountStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAccountStatus' -type MockAccountStore_GetAccountStatus_Call struct { - *mock.Call -} - -// GetAccountStatus is a helper method to define mock.On call -func (_e *MockAccountStore_Expecter) GetAccountStatus() *MockAccountStore_GetAccountStatus_Call { - return &MockAccountStore_GetAccountStatus_Call{Call: _e.mock.On("GetAccountStatus")} -} - -func (_c *MockAccountStore_GetAccountStatus_Call) Run(run func()) *MockAccountStore_GetAccountStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockAccountStore_GetAccountStatus_Call) Return(status *coordinatorproto.SpaceStatusPayload, err error) *MockAccountStore_GetAccountStatus_Call { - _c.Call.Return(status, err) - return _c -} - -func (_c *MockAccountStore_GetAccountStatus_Call) RunAndReturn(run func() (*coordinatorproto.SpaceStatusPayload, error)) *MockAccountStore_GetAccountStatus_Call { - _c.Call.Return(run) - return _c -} - -// SaveAccountStatus provides a mock function with given fields: status -func (_m *MockAccountStore) SaveAccountStatus(status *coordinatorproto.SpaceStatusPayload) error { - ret := _m.Called(status) - - if len(ret) == 0 { - panic("no return value specified for SaveAccountStatus") - } - - var r0 error - if rf, ok := ret.Get(0).(func(*coordinatorproto.SpaceStatusPayload) error); ok { - r0 = rf(status) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockAccountStore_SaveAccountStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveAccountStatus' -type MockAccountStore_SaveAccountStatus_Call struct { - *mock.Call -} - -// SaveAccountStatus is a helper method to define mock.On call -// - status *coordinatorproto.SpaceStatusPayload -func (_e *MockAccountStore_Expecter) SaveAccountStatus(status interface{}) *MockAccountStore_SaveAccountStatus_Call { - return &MockAccountStore_SaveAccountStatus_Call{Call: _e.mock.On("SaveAccountStatus", status)} -} - -func (_c *MockAccountStore_SaveAccountStatus_Call) Run(run func(status *coordinatorproto.SpaceStatusPayload)) *MockAccountStore_SaveAccountStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*coordinatorproto.SpaceStatusPayload)) - }) - return _c -} - -func (_c *MockAccountStore_SaveAccountStatus_Call) Return(err error) *MockAccountStore_SaveAccountStatus_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockAccountStore_SaveAccountStatus_Call) RunAndReturn(run func(*coordinatorproto.SpaceStatusPayload) error) *MockAccountStore_SaveAccountStatus_Call { - _c.Call.Return(run) - return _c -} - -// NewMockAccountStore creates a new instance of MockAccountStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockAccountStore(t interface { - mock.TestingT - Cleanup(func()) -}) *MockAccountStore { - mock := &MockAccountStore{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_IndexerStore.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_IndexerStore.go deleted file mode 100644 index ba063721e4..0000000000 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_IndexerStore.go +++ /dev/null @@ -1,485 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_objectstore - -import ( - ftsearch "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" - mock "github.com/stretchr/testify/mock" - - model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" -) - -// MockIndexerStore is an autogenerated mock type for the IndexerStore type -type MockIndexerStore struct { - mock.Mock -} - -type MockIndexerStore_Expecter struct { - mock *mock.Mock -} - -func (_m *MockIndexerStore) EXPECT() *MockIndexerStore_Expecter { - return &MockIndexerStore_Expecter{mock: &_m.Mock} -} - -// AddToIndexQueue provides a mock function with given fields: id -func (_m *MockIndexerStore) AddToIndexQueue(id string) error { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for AddToIndexQueue") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockIndexerStore_AddToIndexQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddToIndexQueue' -type MockIndexerStore_AddToIndexQueue_Call struct { - *mock.Call -} - -// AddToIndexQueue is a helper method to define mock.On call -// - id string -func (_e *MockIndexerStore_Expecter) AddToIndexQueue(id interface{}) *MockIndexerStore_AddToIndexQueue_Call { - return &MockIndexerStore_AddToIndexQueue_Call{Call: _e.mock.On("AddToIndexQueue", id)} -} - -func (_c *MockIndexerStore_AddToIndexQueue_Call) Run(run func(id string)) *MockIndexerStore_AddToIndexQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockIndexerStore_AddToIndexQueue_Call) Return(_a0 error) *MockIndexerStore_AddToIndexQueue_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockIndexerStore_AddToIndexQueue_Call) RunAndReturn(run func(string) error) *MockIndexerStore_AddToIndexQueue_Call { - _c.Call.Return(run) - return _c -} - -// FTSearch provides a mock function with given fields: -func (_m *MockIndexerStore) FTSearch() ftsearch.FTSearch { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for FTSearch") - } - - var r0 ftsearch.FTSearch - if rf, ok := ret.Get(0).(func() ftsearch.FTSearch); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(ftsearch.FTSearch) - } - } - - return r0 -} - -// MockIndexerStore_FTSearch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FTSearch' -type MockIndexerStore_FTSearch_Call struct { - *mock.Call -} - -// FTSearch is a helper method to define mock.On call -func (_e *MockIndexerStore_Expecter) FTSearch() *MockIndexerStore_FTSearch_Call { - return &MockIndexerStore_FTSearch_Call{Call: _e.mock.On("FTSearch")} -} - -func (_c *MockIndexerStore_FTSearch_Call) Run(run func()) *MockIndexerStore_FTSearch_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockIndexerStore_FTSearch_Call) Return(_a0 ftsearch.FTSearch) *MockIndexerStore_FTSearch_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockIndexerStore_FTSearch_Call) RunAndReturn(run func() ftsearch.FTSearch) *MockIndexerStore_FTSearch_Call { - _c.Call.Return(run) - return _c -} - -// GetChecksums provides a mock function with given fields: spaceID -func (_m *MockIndexerStore) GetChecksums(spaceID string) (*model.ObjectStoreChecksums, error) { - ret := _m.Called(spaceID) - - if len(ret) == 0 { - panic("no return value specified for GetChecksums") - } - - var r0 *model.ObjectStoreChecksums - var r1 error - if rf, ok := ret.Get(0).(func(string) (*model.ObjectStoreChecksums, error)); ok { - return rf(spaceID) - } - if rf, ok := ret.Get(0).(func(string) *model.ObjectStoreChecksums); ok { - r0 = rf(spaceID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectStoreChecksums) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(spaceID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockIndexerStore_GetChecksums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetChecksums' -type MockIndexerStore_GetChecksums_Call struct { - *mock.Call -} - -// GetChecksums is a helper method to define mock.On call -// - spaceID string -func (_e *MockIndexerStore_Expecter) GetChecksums(spaceID interface{}) *MockIndexerStore_GetChecksums_Call { - return &MockIndexerStore_GetChecksums_Call{Call: _e.mock.On("GetChecksums", spaceID)} -} - -func (_c *MockIndexerStore_GetChecksums_Call) Run(run func(spaceID string)) *MockIndexerStore_GetChecksums_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockIndexerStore_GetChecksums_Call) Return(checksums *model.ObjectStoreChecksums, err error) *MockIndexerStore_GetChecksums_Call { - _c.Call.Return(checksums, err) - return _c -} - -func (_c *MockIndexerStore_GetChecksums_Call) RunAndReturn(run func(string) (*model.ObjectStoreChecksums, error)) *MockIndexerStore_GetChecksums_Call { - _c.Call.Return(run) - return _c -} - -// GetGlobalChecksums provides a mock function with given fields: -func (_m *MockIndexerStore) GetGlobalChecksums() (*model.ObjectStoreChecksums, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for GetGlobalChecksums") - } - - var r0 *model.ObjectStoreChecksums - var r1 error - if rf, ok := ret.Get(0).(func() (*model.ObjectStoreChecksums, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() *model.ObjectStoreChecksums); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectStoreChecksums) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockIndexerStore_GetGlobalChecksums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGlobalChecksums' -type MockIndexerStore_GetGlobalChecksums_Call struct { - *mock.Call -} - -// GetGlobalChecksums is a helper method to define mock.On call -func (_e *MockIndexerStore_Expecter) GetGlobalChecksums() *MockIndexerStore_GetGlobalChecksums_Call { - return &MockIndexerStore_GetGlobalChecksums_Call{Call: _e.mock.On("GetGlobalChecksums")} -} - -func (_c *MockIndexerStore_GetGlobalChecksums_Call) Run(run func()) *MockIndexerStore_GetGlobalChecksums_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockIndexerStore_GetGlobalChecksums_Call) Return(checksums *model.ObjectStoreChecksums, err error) *MockIndexerStore_GetGlobalChecksums_Call { - _c.Call.Return(checksums, err) - return _c -} - -func (_c *MockIndexerStore_GetGlobalChecksums_Call) RunAndReturn(run func() (*model.ObjectStoreChecksums, error)) *MockIndexerStore_GetGlobalChecksums_Call { - _c.Call.Return(run) - return _c -} - -// GetLastIndexedHeadsHash provides a mock function with given fields: id -func (_m *MockIndexerStore) GetLastIndexedHeadsHash(id string) (string, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetLastIndexedHeadsHash") - } - - var r0 string - var r1 error - if rf, ok := ret.Get(0).(func(string) (string, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) string); ok { - r0 = rf(id) - } else { - r0 = ret.Get(0).(string) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockIndexerStore_GetLastIndexedHeadsHash_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastIndexedHeadsHash' -type MockIndexerStore_GetLastIndexedHeadsHash_Call struct { - *mock.Call -} - -// GetLastIndexedHeadsHash is a helper method to define mock.On call -// - id string -func (_e *MockIndexerStore_Expecter) GetLastIndexedHeadsHash(id interface{}) *MockIndexerStore_GetLastIndexedHeadsHash_Call { - return &MockIndexerStore_GetLastIndexedHeadsHash_Call{Call: _e.mock.On("GetLastIndexedHeadsHash", id)} -} - -func (_c *MockIndexerStore_GetLastIndexedHeadsHash_Call) Run(run func(id string)) *MockIndexerStore_GetLastIndexedHeadsHash_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockIndexerStore_GetLastIndexedHeadsHash_Call) Return(headsHash string, err error) *MockIndexerStore_GetLastIndexedHeadsHash_Call { - _c.Call.Return(headsHash, err) - return _c -} - -func (_c *MockIndexerStore_GetLastIndexedHeadsHash_Call) RunAndReturn(run func(string) (string, error)) *MockIndexerStore_GetLastIndexedHeadsHash_Call { - _c.Call.Return(run) - return _c -} - -// ListIDsFromFullTextQueue provides a mock function with given fields: -func (_m *MockIndexerStore) ListIDsFromFullTextQueue() ([]string, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for ListIDsFromFullTextQueue") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func() ([]string, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() []string); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockIndexerStore_ListIDsFromFullTextQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListIDsFromFullTextQueue' -type MockIndexerStore_ListIDsFromFullTextQueue_Call struct { - *mock.Call -} - -// ListIDsFromFullTextQueue is a helper method to define mock.On call -func (_e *MockIndexerStore_Expecter) ListIDsFromFullTextQueue() *MockIndexerStore_ListIDsFromFullTextQueue_Call { - return &MockIndexerStore_ListIDsFromFullTextQueue_Call{Call: _e.mock.On("ListIDsFromFullTextQueue")} -} - -func (_c *MockIndexerStore_ListIDsFromFullTextQueue_Call) Run(run func()) *MockIndexerStore_ListIDsFromFullTextQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockIndexerStore_ListIDsFromFullTextQueue_Call) Return(_a0 []string, _a1 error) *MockIndexerStore_ListIDsFromFullTextQueue_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockIndexerStore_ListIDsFromFullTextQueue_Call) RunAndReturn(run func() ([]string, error)) *MockIndexerStore_ListIDsFromFullTextQueue_Call { - _c.Call.Return(run) - return _c -} - -// RemoveIDsFromFullTextQueue provides a mock function with given fields: ids -func (_m *MockIndexerStore) RemoveIDsFromFullTextQueue(ids []string) { - _m.Called(ids) -} - -// MockIndexerStore_RemoveIDsFromFullTextQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveIDsFromFullTextQueue' -type MockIndexerStore_RemoveIDsFromFullTextQueue_Call struct { - *mock.Call -} - -// RemoveIDsFromFullTextQueue is a helper method to define mock.On call -// - ids []string -func (_e *MockIndexerStore_Expecter) RemoveIDsFromFullTextQueue(ids interface{}) *MockIndexerStore_RemoveIDsFromFullTextQueue_Call { - return &MockIndexerStore_RemoveIDsFromFullTextQueue_Call{Call: _e.mock.On("RemoveIDsFromFullTextQueue", ids)} -} - -func (_c *MockIndexerStore_RemoveIDsFromFullTextQueue_Call) Run(run func(ids []string)) *MockIndexerStore_RemoveIDsFromFullTextQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].([]string)) - }) - return _c -} - -func (_c *MockIndexerStore_RemoveIDsFromFullTextQueue_Call) Return() *MockIndexerStore_RemoveIDsFromFullTextQueue_Call { - _c.Call.Return() - return _c -} - -func (_c *MockIndexerStore_RemoveIDsFromFullTextQueue_Call) RunAndReturn(run func([]string)) *MockIndexerStore_RemoveIDsFromFullTextQueue_Call { - _c.Call.Return(run) - return _c -} - -// SaveChecksums provides a mock function with given fields: spaceID, checksums -func (_m *MockIndexerStore) SaveChecksums(spaceID string, checksums *model.ObjectStoreChecksums) error { - ret := _m.Called(spaceID, checksums) - - if len(ret) == 0 { - panic("no return value specified for SaveChecksums") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, *model.ObjectStoreChecksums) error); ok { - r0 = rf(spaceID, checksums) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockIndexerStore_SaveChecksums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveChecksums' -type MockIndexerStore_SaveChecksums_Call struct { - *mock.Call -} - -// SaveChecksums is a helper method to define mock.On call -// - spaceID string -// - checksums *model.ObjectStoreChecksums -func (_e *MockIndexerStore_Expecter) SaveChecksums(spaceID interface{}, checksums interface{}) *MockIndexerStore_SaveChecksums_Call { - return &MockIndexerStore_SaveChecksums_Call{Call: _e.mock.On("SaveChecksums", spaceID, checksums)} -} - -func (_c *MockIndexerStore_SaveChecksums_Call) Run(run func(spaceID string, checksums *model.ObjectStoreChecksums)) *MockIndexerStore_SaveChecksums_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(*model.ObjectStoreChecksums)) - }) - return _c -} - -func (_c *MockIndexerStore_SaveChecksums_Call) Return(err error) *MockIndexerStore_SaveChecksums_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockIndexerStore_SaveChecksums_Call) RunAndReturn(run func(string, *model.ObjectStoreChecksums) error) *MockIndexerStore_SaveChecksums_Call { - _c.Call.Return(run) - return _c -} - -// SaveLastIndexedHeadsHash provides a mock function with given fields: id, headsHash -func (_m *MockIndexerStore) SaveLastIndexedHeadsHash(id string, headsHash string) error { - ret := _m.Called(id, headsHash) - - if len(ret) == 0 { - panic("no return value specified for SaveLastIndexedHeadsHash") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, string) error); ok { - r0 = rf(id, headsHash) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockIndexerStore_SaveLastIndexedHeadsHash_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveLastIndexedHeadsHash' -type MockIndexerStore_SaveLastIndexedHeadsHash_Call struct { - *mock.Call -} - -// SaveLastIndexedHeadsHash is a helper method to define mock.On call -// - id string -// - headsHash string -func (_e *MockIndexerStore_Expecter) SaveLastIndexedHeadsHash(id interface{}, headsHash interface{}) *MockIndexerStore_SaveLastIndexedHeadsHash_Call { - return &MockIndexerStore_SaveLastIndexedHeadsHash_Call{Call: _e.mock.On("SaveLastIndexedHeadsHash", id, headsHash)} -} - -func (_c *MockIndexerStore_SaveLastIndexedHeadsHash_Call) Run(run func(id string, headsHash string)) *MockIndexerStore_SaveLastIndexedHeadsHash_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *MockIndexerStore_SaveLastIndexedHeadsHash_Call) Return(err error) *MockIndexerStore_SaveLastIndexedHeadsHash_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockIndexerStore_SaveLastIndexedHeadsHash_Call) RunAndReturn(run func(string, string) error) *MockIndexerStore_SaveLastIndexedHeadsHash_Call { - _c.Call.Return(run) - return _c -} - -// NewMockIndexerStore creates a new instance of MockIndexerStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockIndexerStore(t interface { - mock.TestingT - Cleanup(func()) -}) *MockIndexerStore { - mock := &MockIndexerStore{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go deleted file mode 100644 index 308fbb3125..0000000000 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_ObjectStore.go +++ /dev/null @@ -1,3133 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_objectstore - -import ( - context "context" - - app "github.com/anyproto/any-sync/app" - - coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" - - database "github.com/anyproto/anytype-heart/pkg/lib/database" - - domain "github.com/anyproto/anytype-heart/core/domain" - - ftsearch "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" - - mock "github.com/stretchr/testify/mock" - - model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - - pbtypes "github.com/anyproto/anytype-heart/util/pbtypes" - - relationutils "github.com/anyproto/anytype-heart/core/relationutils" - - types "github.com/gogo/protobuf/types" -) - -// MockObjectStore is an autogenerated mock type for the ObjectStore type -type MockObjectStore struct { - mock.Mock -} - -type MockObjectStore_Expecter struct { - mock *mock.Mock -} - -func (_m *MockObjectStore) EXPECT() *MockObjectStore_Expecter { - return &MockObjectStore_Expecter{mock: &_m.Mock} -} - -// AddToIndexQueue provides a mock function with given fields: id -func (_m *MockObjectStore) AddToIndexQueue(id string) error { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for AddToIndexQueue") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_AddToIndexQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddToIndexQueue' -type MockObjectStore_AddToIndexQueue_Call struct { - *mock.Call -} - -// AddToIndexQueue is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) AddToIndexQueue(id interface{}) *MockObjectStore_AddToIndexQueue_Call { - return &MockObjectStore_AddToIndexQueue_Call{Call: _e.mock.On("AddToIndexQueue", id)} -} - -func (_c *MockObjectStore_AddToIndexQueue_Call) Run(run func(id string)) *MockObjectStore_AddToIndexQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_AddToIndexQueue_Call) Return(_a0 error) *MockObjectStore_AddToIndexQueue_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_AddToIndexQueue_Call) RunAndReturn(run func(string) error) *MockObjectStore_AddToIndexQueue_Call { - _c.Call.Return(run) - return _c -} - -// BatchProcessFullTextQueue provides a mock function with given fields: ctx, limit, processIds -func (_m *MockObjectStore) BatchProcessFullTextQueue(ctx context.Context, limit int, processIds func([]string) error) error { - ret := _m.Called(ctx, limit, processIds) - - if len(ret) == 0 { - panic("no return value specified for BatchProcessFullTextQueue") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, int, func([]string) error) error); ok { - r0 = rf(ctx, limit, processIds) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_BatchProcessFullTextQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BatchProcessFullTextQueue' -type MockObjectStore_BatchProcessFullTextQueue_Call struct { - *mock.Call -} - -// BatchProcessFullTextQueue is a helper method to define mock.On call -// - ctx context.Context -// - limit int -// - processIds func([]string) error -func (_e *MockObjectStore_Expecter) BatchProcessFullTextQueue(ctx interface{}, limit interface{}, processIds interface{}) *MockObjectStore_BatchProcessFullTextQueue_Call { - return &MockObjectStore_BatchProcessFullTextQueue_Call{Call: _e.mock.On("BatchProcessFullTextQueue", ctx, limit, processIds)} -} - -func (_c *MockObjectStore_BatchProcessFullTextQueue_Call) Run(run func(ctx context.Context, limit int, processIds func([]string) error)) *MockObjectStore_BatchProcessFullTextQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(int), args[2].(func([]string) error)) - }) - return _c -} - -func (_c *MockObjectStore_BatchProcessFullTextQueue_Call) Return(_a0 error) *MockObjectStore_BatchProcessFullTextQueue_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_BatchProcessFullTextQueue_Call) RunAndReturn(run func(context.Context, int, func([]string) error) error) *MockObjectStore_BatchProcessFullTextQueue_Call { - _c.Call.Return(run) - return _c -} - -// Close provides a mock function with given fields: ctx -func (_m *MockObjectStore) Close(ctx context.Context) error { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for Close") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' -type MockObjectStore_Close_Call struct { - *mock.Call -} - -// Close is a helper method to define mock.On call -// - ctx context.Context -func (_e *MockObjectStore_Expecter) Close(ctx interface{}) *MockObjectStore_Close_Call { - return &MockObjectStore_Close_Call{Call: _e.mock.On("Close", ctx)} -} - -func (_c *MockObjectStore_Close_Call) Run(run func(ctx context.Context)) *MockObjectStore_Close_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *MockObjectStore_Close_Call) Return(err error) *MockObjectStore_Close_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockObjectStore_Close_Call) RunAndReturn(run func(context.Context) error) *MockObjectStore_Close_Call { - _c.Call.Return(run) - return _c -} - -// DeleteDetails provides a mock function with given fields: id -func (_m *MockObjectStore) DeleteDetails(id ...string) error { - _va := make([]interface{}, len(id)) - for _i := range id { - _va[_i] = id[_i] - } - var _ca []interface{} - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for DeleteDetails") - } - - var r0 error - if rf, ok := ret.Get(0).(func(...string) error); ok { - r0 = rf(id...) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_DeleteDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteDetails' -type MockObjectStore_DeleteDetails_Call struct { - *mock.Call -} - -// DeleteDetails is a helper method to define mock.On call -// - id ...string -func (_e *MockObjectStore_Expecter) DeleteDetails(id ...interface{}) *MockObjectStore_DeleteDetails_Call { - return &MockObjectStore_DeleteDetails_Call{Call: _e.mock.On("DeleteDetails", - append([]interface{}{}, id...)...)} -} - -func (_c *MockObjectStore_DeleteDetails_Call) Run(run func(id ...string)) *MockObjectStore_DeleteDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]string, len(args)-0) - for i, a := range args[0:] { - if a != nil { - variadicArgs[i] = a.(string) - } - } - run(variadicArgs...) - }) - return _c -} - -func (_c *MockObjectStore_DeleteDetails_Call) Return(_a0 error) *MockObjectStore_DeleteDetails_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_DeleteDetails_Call) RunAndReturn(run func(...string) error) *MockObjectStore_DeleteDetails_Call { - _c.Call.Return(run) - return _c -} - -// DeleteLinks provides a mock function with given fields: id -func (_m *MockObjectStore) DeleteLinks(id ...string) error { - _va := make([]interface{}, len(id)) - for _i := range id { - _va[_i] = id[_i] - } - var _ca []interface{} - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for DeleteLinks") - } - - var r0 error - if rf, ok := ret.Get(0).(func(...string) error); ok { - r0 = rf(id...) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_DeleteLinks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteLinks' -type MockObjectStore_DeleteLinks_Call struct { - *mock.Call -} - -// DeleteLinks is a helper method to define mock.On call -// - id ...string -func (_e *MockObjectStore_Expecter) DeleteLinks(id ...interface{}) *MockObjectStore_DeleteLinks_Call { - return &MockObjectStore_DeleteLinks_Call{Call: _e.mock.On("DeleteLinks", - append([]interface{}{}, id...)...)} -} - -func (_c *MockObjectStore_DeleteLinks_Call) Run(run func(id ...string)) *MockObjectStore_DeleteLinks_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]string, len(args)-0) - for i, a := range args[0:] { - if a != nil { - variadicArgs[i] = a.(string) - } - } - run(variadicArgs...) - }) - return _c -} - -func (_c *MockObjectStore_DeleteLinks_Call) Return(_a0 error) *MockObjectStore_DeleteLinks_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_DeleteLinks_Call) RunAndReturn(run func(...string) error) *MockObjectStore_DeleteLinks_Call { - _c.Call.Return(run) - return _c -} - -// DeleteObject provides a mock function with given fields: id -func (_m *MockObjectStore) DeleteObject(id domain.FullID) error { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for DeleteObject") - } - - var r0 error - if rf, ok := ret.Get(0).(func(domain.FullID) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_DeleteObject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteObject' -type MockObjectStore_DeleteObject_Call struct { - *mock.Call -} - -// DeleteObject is a helper method to define mock.On call -// - id domain.FullID -func (_e *MockObjectStore_Expecter) DeleteObject(id interface{}) *MockObjectStore_DeleteObject_Call { - return &MockObjectStore_DeleteObject_Call{Call: _e.mock.On("DeleteObject", id)} -} - -func (_c *MockObjectStore_DeleteObject_Call) Run(run func(id domain.FullID)) *MockObjectStore_DeleteObject_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(domain.FullID)) - }) - return _c -} - -func (_c *MockObjectStore_DeleteObject_Call) Return(_a0 error) *MockObjectStore_DeleteObject_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_DeleteObject_Call) RunAndReturn(run func(domain.FullID) error) *MockObjectStore_DeleteObject_Call { - _c.Call.Return(run) - return _c -} - -// DeleteVirtualSpace provides a mock function with given fields: spaceID -func (_m *MockObjectStore) DeleteVirtualSpace(spaceID string) error { - ret := _m.Called(spaceID) - - if len(ret) == 0 { - panic("no return value specified for DeleteVirtualSpace") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(spaceID) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_DeleteVirtualSpace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteVirtualSpace' -type MockObjectStore_DeleteVirtualSpace_Call struct { - *mock.Call -} - -// DeleteVirtualSpace is a helper method to define mock.On call -// - spaceID string -func (_e *MockObjectStore_Expecter) DeleteVirtualSpace(spaceID interface{}) *MockObjectStore_DeleteVirtualSpace_Call { - return &MockObjectStore_DeleteVirtualSpace_Call{Call: _e.mock.On("DeleteVirtualSpace", spaceID)} -} - -func (_c *MockObjectStore_DeleteVirtualSpace_Call) Run(run func(spaceID string)) *MockObjectStore_DeleteVirtualSpace_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_DeleteVirtualSpace_Call) Return(_a0 error) *MockObjectStore_DeleteVirtualSpace_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_DeleteVirtualSpace_Call) RunAndReturn(run func(string) error) *MockObjectStore_DeleteVirtualSpace_Call { - _c.Call.Return(run) - return _c -} - -// FTSearch provides a mock function with given fields: -func (_m *MockObjectStore) FTSearch() ftsearch.FTSearch { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for FTSearch") - } - - var r0 ftsearch.FTSearch - if rf, ok := ret.Get(0).(func() ftsearch.FTSearch); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(ftsearch.FTSearch) - } - } - - return r0 -} - -// MockObjectStore_FTSearch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FTSearch' -type MockObjectStore_FTSearch_Call struct { - *mock.Call -} - -// FTSearch is a helper method to define mock.On call -func (_e *MockObjectStore_Expecter) FTSearch() *MockObjectStore_FTSearch_Call { - return &MockObjectStore_FTSearch_Call{Call: _e.mock.On("FTSearch")} -} - -func (_c *MockObjectStore_FTSearch_Call) Run(run func()) *MockObjectStore_FTSearch_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockObjectStore_FTSearch_Call) Return(_a0 ftsearch.FTSearch) *MockObjectStore_FTSearch_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_FTSearch_Call) RunAndReturn(run func() ftsearch.FTSearch) *MockObjectStore_FTSearch_Call { - _c.Call.Return(run) - return _c -} - -// FetchRelationByKey provides a mock function with given fields: spaceID, key -func (_m *MockObjectStore) FetchRelationByKey(spaceID string, key string) (*relationutils.Relation, error) { - ret := _m.Called(spaceID, key) - - if len(ret) == 0 { - panic("no return value specified for FetchRelationByKey") - } - - var r0 *relationutils.Relation - var r1 error - if rf, ok := ret.Get(0).(func(string, string) (*relationutils.Relation, error)); ok { - return rf(spaceID, key) - } - if rf, ok := ret.Get(0).(func(string, string) *relationutils.Relation); ok { - r0 = rf(spaceID, key) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*relationutils.Relation) - } - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(spaceID, key) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_FetchRelationByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FetchRelationByKey' -type MockObjectStore_FetchRelationByKey_Call struct { - *mock.Call -} - -// FetchRelationByKey is a helper method to define mock.On call -// - spaceID string -// - key string -func (_e *MockObjectStore_Expecter) FetchRelationByKey(spaceID interface{}, key interface{}) *MockObjectStore_FetchRelationByKey_Call { - return &MockObjectStore_FetchRelationByKey_Call{Call: _e.mock.On("FetchRelationByKey", spaceID, key)} -} - -func (_c *MockObjectStore_FetchRelationByKey_Call) Run(run func(spaceID string, key string)) *MockObjectStore_FetchRelationByKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *MockObjectStore_FetchRelationByKey_Call) Return(relation *relationutils.Relation, err error) *MockObjectStore_FetchRelationByKey_Call { - _c.Call.Return(relation, err) - return _c -} - -func (_c *MockObjectStore_FetchRelationByKey_Call) RunAndReturn(run func(string, string) (*relationutils.Relation, error)) *MockObjectStore_FetchRelationByKey_Call { - _c.Call.Return(run) - return _c -} - -// FetchRelationByKeys provides a mock function with given fields: spaceId, keys -func (_m *MockObjectStore) FetchRelationByKeys(spaceId string, keys ...string) (relationutils.Relations, error) { - _va := make([]interface{}, len(keys)) - for _i := range keys { - _va[_i] = keys[_i] - } - var _ca []interface{} - _ca = append(_ca, spaceId) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for FetchRelationByKeys") - } - - var r0 relationutils.Relations - var r1 error - if rf, ok := ret.Get(0).(func(string, ...string) (relationutils.Relations, error)); ok { - return rf(spaceId, keys...) - } - if rf, ok := ret.Get(0).(func(string, ...string) relationutils.Relations); ok { - r0 = rf(spaceId, keys...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(relationutils.Relations) - } - } - - if rf, ok := ret.Get(1).(func(string, ...string) error); ok { - r1 = rf(spaceId, keys...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_FetchRelationByKeys_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FetchRelationByKeys' -type MockObjectStore_FetchRelationByKeys_Call struct { - *mock.Call -} - -// FetchRelationByKeys is a helper method to define mock.On call -// - spaceId string -// - keys ...string -func (_e *MockObjectStore_Expecter) FetchRelationByKeys(spaceId interface{}, keys ...interface{}) *MockObjectStore_FetchRelationByKeys_Call { - return &MockObjectStore_FetchRelationByKeys_Call{Call: _e.mock.On("FetchRelationByKeys", - append([]interface{}{spaceId}, keys...)...)} -} - -func (_c *MockObjectStore_FetchRelationByKeys_Call) Run(run func(spaceId string, keys ...string)) *MockObjectStore_FetchRelationByKeys_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]string, len(args)-1) - for i, a := range args[1:] { - if a != nil { - variadicArgs[i] = a.(string) - } - } - run(args[0].(string), variadicArgs...) - }) - return _c -} - -func (_c *MockObjectStore_FetchRelationByKeys_Call) Return(relations relationutils.Relations, err error) *MockObjectStore_FetchRelationByKeys_Call { - _c.Call.Return(relations, err) - return _c -} - -func (_c *MockObjectStore_FetchRelationByKeys_Call) RunAndReturn(run func(string, ...string) (relationutils.Relations, error)) *MockObjectStore_FetchRelationByKeys_Call { - _c.Call.Return(run) - return _c -} - -// FetchRelationByLinks provides a mock function with given fields: spaceId, links -func (_m *MockObjectStore) FetchRelationByLinks(spaceId string, links pbtypes.RelationLinks) (relationutils.Relations, error) { - ret := _m.Called(spaceId, links) - - if len(ret) == 0 { - panic("no return value specified for FetchRelationByLinks") - } - - var r0 relationutils.Relations - var r1 error - if rf, ok := ret.Get(0).(func(string, pbtypes.RelationLinks) (relationutils.Relations, error)); ok { - return rf(spaceId, links) - } - if rf, ok := ret.Get(0).(func(string, pbtypes.RelationLinks) relationutils.Relations); ok { - r0 = rf(spaceId, links) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(relationutils.Relations) - } - } - - if rf, ok := ret.Get(1).(func(string, pbtypes.RelationLinks) error); ok { - r1 = rf(spaceId, links) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_FetchRelationByLinks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FetchRelationByLinks' -type MockObjectStore_FetchRelationByLinks_Call struct { - *mock.Call -} - -// FetchRelationByLinks is a helper method to define mock.On call -// - spaceId string -// - links pbtypes.RelationLinks -func (_e *MockObjectStore_Expecter) FetchRelationByLinks(spaceId interface{}, links interface{}) *MockObjectStore_FetchRelationByLinks_Call { - return &MockObjectStore_FetchRelationByLinks_Call{Call: _e.mock.On("FetchRelationByLinks", spaceId, links)} -} - -func (_c *MockObjectStore_FetchRelationByLinks_Call) Run(run func(spaceId string, links pbtypes.RelationLinks)) *MockObjectStore_FetchRelationByLinks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(pbtypes.RelationLinks)) - }) - return _c -} - -func (_c *MockObjectStore_FetchRelationByLinks_Call) Return(relations relationutils.Relations, err error) *MockObjectStore_FetchRelationByLinks_Call { - _c.Call.Return(relations, err) - return _c -} - -func (_c *MockObjectStore_FetchRelationByLinks_Call) RunAndReturn(run func(string, pbtypes.RelationLinks) (relationutils.Relations, error)) *MockObjectStore_FetchRelationByLinks_Call { - _c.Call.Return(run) - return _c -} - -// GetAccountStatus provides a mock function with given fields: -func (_m *MockObjectStore) GetAccountStatus() (*coordinatorproto.SpaceStatusPayload, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for GetAccountStatus") - } - - var r0 *coordinatorproto.SpaceStatusPayload - var r1 error - if rf, ok := ret.Get(0).(func() (*coordinatorproto.SpaceStatusPayload, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() *coordinatorproto.SpaceStatusPayload); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*coordinatorproto.SpaceStatusPayload) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetAccountStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAccountStatus' -type MockObjectStore_GetAccountStatus_Call struct { - *mock.Call -} - -// GetAccountStatus is a helper method to define mock.On call -func (_e *MockObjectStore_Expecter) GetAccountStatus() *MockObjectStore_GetAccountStatus_Call { - return &MockObjectStore_GetAccountStatus_Call{Call: _e.mock.On("GetAccountStatus")} -} - -func (_c *MockObjectStore_GetAccountStatus_Call) Run(run func()) *MockObjectStore_GetAccountStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockObjectStore_GetAccountStatus_Call) Return(status *coordinatorproto.SpaceStatusPayload, err error) *MockObjectStore_GetAccountStatus_Call { - _c.Call.Return(status, err) - return _c -} - -func (_c *MockObjectStore_GetAccountStatus_Call) RunAndReturn(run func() (*coordinatorproto.SpaceStatusPayload, error)) *MockObjectStore_GetAccountStatus_Call { - _c.Call.Return(run) - return _c -} - -// GetActiveViews provides a mock function with given fields: objectId -func (_m *MockObjectStore) GetActiveViews(objectId string) (map[string]string, error) { - ret := _m.Called(objectId) - - if len(ret) == 0 { - panic("no return value specified for GetActiveViews") - } - - var r0 map[string]string - var r1 error - if rf, ok := ret.Get(0).(func(string) (map[string]string, error)); ok { - return rf(objectId) - } - if rf, ok := ret.Get(0).(func(string) map[string]string); ok { - r0 = rf(objectId) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]string) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(objectId) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetActiveViews_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetActiveViews' -type MockObjectStore_GetActiveViews_Call struct { - *mock.Call -} - -// GetActiveViews is a helper method to define mock.On call -// - objectId string -func (_e *MockObjectStore_Expecter) GetActiveViews(objectId interface{}) *MockObjectStore_GetActiveViews_Call { - return &MockObjectStore_GetActiveViews_Call{Call: _e.mock.On("GetActiveViews", objectId)} -} - -func (_c *MockObjectStore_GetActiveViews_Call) Run(run func(objectId string)) *MockObjectStore_GetActiveViews_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetActiveViews_Call) Return(_a0 map[string]string, _a1 error) *MockObjectStore_GetActiveViews_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetActiveViews_Call) RunAndReturn(run func(string) (map[string]string, error)) *MockObjectStore_GetActiveViews_Call { - _c.Call.Return(run) - return _c -} - -// GetByIDs provides a mock function with given fields: spaceID, ids -func (_m *MockObjectStore) GetByIDs(spaceID string, ids []string) ([]*model.ObjectInfo, error) { - ret := _m.Called(spaceID, ids) - - if len(ret) == 0 { - panic("no return value specified for GetByIDs") - } - - var r0 []*model.ObjectInfo - var r1 error - if rf, ok := ret.Get(0).(func(string, []string) ([]*model.ObjectInfo, error)); ok { - return rf(spaceID, ids) - } - if rf, ok := ret.Get(0).(func(string, []string) []*model.ObjectInfo); ok { - r0 = rf(spaceID, ids) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*model.ObjectInfo) - } - } - - if rf, ok := ret.Get(1).(func(string, []string) error); ok { - r1 = rf(spaceID, ids) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetByIDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetByIDs' -type MockObjectStore_GetByIDs_Call struct { - *mock.Call -} - -// GetByIDs is a helper method to define mock.On call -// - spaceID string -// - ids []string -func (_e *MockObjectStore_Expecter) GetByIDs(spaceID interface{}, ids interface{}) *MockObjectStore_GetByIDs_Call { - return &MockObjectStore_GetByIDs_Call{Call: _e.mock.On("GetByIDs", spaceID, ids)} -} - -func (_c *MockObjectStore_GetByIDs_Call) Run(run func(spaceID string, ids []string)) *MockObjectStore_GetByIDs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]string)) - }) - return _c -} - -func (_c *MockObjectStore_GetByIDs_Call) Return(_a0 []*model.ObjectInfo, _a1 error) *MockObjectStore_GetByIDs_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetByIDs_Call) RunAndReturn(run func(string, []string) ([]*model.ObjectInfo, error)) *MockObjectStore_GetByIDs_Call { - _c.Call.Return(run) - return _c -} - -// GetChecksums provides a mock function with given fields: spaceID -func (_m *MockObjectStore) GetChecksums(spaceID string) (*model.ObjectStoreChecksums, error) { - ret := _m.Called(spaceID) - - if len(ret) == 0 { - panic("no return value specified for GetChecksums") - } - - var r0 *model.ObjectStoreChecksums - var r1 error - if rf, ok := ret.Get(0).(func(string) (*model.ObjectStoreChecksums, error)); ok { - return rf(spaceID) - } - if rf, ok := ret.Get(0).(func(string) *model.ObjectStoreChecksums); ok { - r0 = rf(spaceID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectStoreChecksums) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(spaceID) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetChecksums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetChecksums' -type MockObjectStore_GetChecksums_Call struct { - *mock.Call -} - -// GetChecksums is a helper method to define mock.On call -// - spaceID string -func (_e *MockObjectStore_Expecter) GetChecksums(spaceID interface{}) *MockObjectStore_GetChecksums_Call { - return &MockObjectStore_GetChecksums_Call{Call: _e.mock.On("GetChecksums", spaceID)} -} - -func (_c *MockObjectStore_GetChecksums_Call) Run(run func(spaceID string)) *MockObjectStore_GetChecksums_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetChecksums_Call) Return(checksums *model.ObjectStoreChecksums, err error) *MockObjectStore_GetChecksums_Call { - _c.Call.Return(checksums, err) - return _c -} - -func (_c *MockObjectStore_GetChecksums_Call) RunAndReturn(run func(string) (*model.ObjectStoreChecksums, error)) *MockObjectStore_GetChecksums_Call { - _c.Call.Return(run) - return _c -} - -// GetDetails provides a mock function with given fields: id -func (_m *MockObjectStore) GetDetails(id string) (*model.ObjectDetails, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetDetails") - } - - var r0 *model.ObjectDetails - var r1 error - if rf, ok := ret.Get(0).(func(string) (*model.ObjectDetails, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) *model.ObjectDetails); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectDetails) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDetails' -type MockObjectStore_GetDetails_Call struct { - *mock.Call -} - -// GetDetails is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) GetDetails(id interface{}) *MockObjectStore_GetDetails_Call { - return &MockObjectStore_GetDetails_Call{Call: _e.mock.On("GetDetails", id)} -} - -func (_c *MockObjectStore_GetDetails_Call) Run(run func(id string)) *MockObjectStore_GetDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetDetails_Call) Return(_a0 *model.ObjectDetails, _a1 error) *MockObjectStore_GetDetails_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetDetails_Call) RunAndReturn(run func(string) (*model.ObjectDetails, error)) *MockObjectStore_GetDetails_Call { - _c.Call.Return(run) - return _c -} - -// GetGlobalChecksums provides a mock function with given fields: -func (_m *MockObjectStore) GetGlobalChecksums() (*model.ObjectStoreChecksums, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for GetGlobalChecksums") - } - - var r0 *model.ObjectStoreChecksums - var r1 error - if rf, ok := ret.Get(0).(func() (*model.ObjectStoreChecksums, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() *model.ObjectStoreChecksums); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectStoreChecksums) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetGlobalChecksums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGlobalChecksums' -type MockObjectStore_GetGlobalChecksums_Call struct { - *mock.Call -} - -// GetGlobalChecksums is a helper method to define mock.On call -func (_e *MockObjectStore_Expecter) GetGlobalChecksums() *MockObjectStore_GetGlobalChecksums_Call { - return &MockObjectStore_GetGlobalChecksums_Call{Call: _e.mock.On("GetGlobalChecksums")} -} - -func (_c *MockObjectStore_GetGlobalChecksums_Call) Run(run func()) *MockObjectStore_GetGlobalChecksums_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockObjectStore_GetGlobalChecksums_Call) Return(checksums *model.ObjectStoreChecksums, err error) *MockObjectStore_GetGlobalChecksums_Call { - _c.Call.Return(checksums, err) - return _c -} - -func (_c *MockObjectStore_GetGlobalChecksums_Call) RunAndReturn(run func() (*model.ObjectStoreChecksums, error)) *MockObjectStore_GetGlobalChecksums_Call { - _c.Call.Return(run) - return _c -} - -// GetInboundLinksByID provides a mock function with given fields: id -func (_m *MockObjectStore) GetInboundLinksByID(id string) ([]string, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetInboundLinksByID") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) []string); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetInboundLinksByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetInboundLinksByID' -type MockObjectStore_GetInboundLinksByID_Call struct { - *mock.Call -} - -// GetInboundLinksByID is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) GetInboundLinksByID(id interface{}) *MockObjectStore_GetInboundLinksByID_Call { - return &MockObjectStore_GetInboundLinksByID_Call{Call: _e.mock.On("GetInboundLinksByID", id)} -} - -func (_c *MockObjectStore_GetInboundLinksByID_Call) Run(run func(id string)) *MockObjectStore_GetInboundLinksByID_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetInboundLinksByID_Call) Return(_a0 []string, _a1 error) *MockObjectStore_GetInboundLinksByID_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetInboundLinksByID_Call) RunAndReturn(run func(string) ([]string, error)) *MockObjectStore_GetInboundLinksByID_Call { - _c.Call.Return(run) - return _c -} - -// GetLastIndexedHeadsHash provides a mock function with given fields: id -func (_m *MockObjectStore) GetLastIndexedHeadsHash(id string) (string, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetLastIndexedHeadsHash") - } - - var r0 string - var r1 error - if rf, ok := ret.Get(0).(func(string) (string, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) string); ok { - r0 = rf(id) - } else { - r0 = ret.Get(0).(string) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetLastIndexedHeadsHash_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastIndexedHeadsHash' -type MockObjectStore_GetLastIndexedHeadsHash_Call struct { - *mock.Call -} - -// GetLastIndexedHeadsHash is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) GetLastIndexedHeadsHash(id interface{}) *MockObjectStore_GetLastIndexedHeadsHash_Call { - return &MockObjectStore_GetLastIndexedHeadsHash_Call{Call: _e.mock.On("GetLastIndexedHeadsHash", id)} -} - -func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) Run(run func(id string)) *MockObjectStore_GetLastIndexedHeadsHash_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) Return(headsHash string, err error) *MockObjectStore_GetLastIndexedHeadsHash_Call { - _c.Call.Return(headsHash, err) - return _c -} - -func (_c *MockObjectStore_GetLastIndexedHeadsHash_Call) RunAndReturn(run func(string) (string, error)) *MockObjectStore_GetLastIndexedHeadsHash_Call { - _c.Call.Return(run) - return _c -} - -// GetObjectByUniqueKey provides a mock function with given fields: spaceId, uniqueKey -func (_m *MockObjectStore) GetObjectByUniqueKey(spaceId string, uniqueKey domain.UniqueKey) (*model.ObjectDetails, error) { - ret := _m.Called(spaceId, uniqueKey) - - if len(ret) == 0 { - panic("no return value specified for GetObjectByUniqueKey") - } - - var r0 *model.ObjectDetails - var r1 error - if rf, ok := ret.Get(0).(func(string, domain.UniqueKey) (*model.ObjectDetails, error)); ok { - return rf(spaceId, uniqueKey) - } - if rf, ok := ret.Get(0).(func(string, domain.UniqueKey) *model.ObjectDetails); ok { - r0 = rf(spaceId, uniqueKey) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectDetails) - } - } - - if rf, ok := ret.Get(1).(func(string, domain.UniqueKey) error); ok { - r1 = rf(spaceId, uniqueKey) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetObjectByUniqueKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetObjectByUniqueKey' -type MockObjectStore_GetObjectByUniqueKey_Call struct { - *mock.Call -} - -// GetObjectByUniqueKey is a helper method to define mock.On call -// - spaceId string -// - uniqueKey domain.UniqueKey -func (_e *MockObjectStore_Expecter) GetObjectByUniqueKey(spaceId interface{}, uniqueKey interface{}) *MockObjectStore_GetObjectByUniqueKey_Call { - return &MockObjectStore_GetObjectByUniqueKey_Call{Call: _e.mock.On("GetObjectByUniqueKey", spaceId, uniqueKey)} -} - -func (_c *MockObjectStore_GetObjectByUniqueKey_Call) Run(run func(spaceId string, uniqueKey domain.UniqueKey)) *MockObjectStore_GetObjectByUniqueKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(domain.UniqueKey)) - }) - return _c -} - -func (_c *MockObjectStore_GetObjectByUniqueKey_Call) Return(_a0 *model.ObjectDetails, _a1 error) *MockObjectStore_GetObjectByUniqueKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetObjectByUniqueKey_Call) RunAndReturn(run func(string, domain.UniqueKey) (*model.ObjectDetails, error)) *MockObjectStore_GetObjectByUniqueKey_Call { - _c.Call.Return(run) - return _c -} - -// GetObjectType provides a mock function with given fields: url -func (_m *MockObjectStore) GetObjectType(url string) (*model.ObjectType, error) { - ret := _m.Called(url) - - if len(ret) == 0 { - panic("no return value specified for GetObjectType") - } - - var r0 *model.ObjectType - var r1 error - if rf, ok := ret.Get(0).(func(string) (*model.ObjectType, error)); ok { - return rf(url) - } - if rf, ok := ret.Get(0).(func(string) *model.ObjectType); ok { - r0 = rf(url) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectType) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(url) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetObjectType_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetObjectType' -type MockObjectStore_GetObjectType_Call struct { - *mock.Call -} - -// GetObjectType is a helper method to define mock.On call -// - url string -func (_e *MockObjectStore_Expecter) GetObjectType(url interface{}) *MockObjectStore_GetObjectType_Call { - return &MockObjectStore_GetObjectType_Call{Call: _e.mock.On("GetObjectType", url)} -} - -func (_c *MockObjectStore_GetObjectType_Call) Run(run func(url string)) *MockObjectStore_GetObjectType_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetObjectType_Call) Return(_a0 *model.ObjectType, _a1 error) *MockObjectStore_GetObjectType_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetObjectType_Call) RunAndReturn(run func(string) (*model.ObjectType, error)) *MockObjectStore_GetObjectType_Call { - _c.Call.Return(run) - return _c -} - -// GetOutboundLinksByID provides a mock function with given fields: id -func (_m *MockObjectStore) GetOutboundLinksByID(id string) ([]string, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetOutboundLinksByID") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) []string); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetOutboundLinksByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOutboundLinksByID' -type MockObjectStore_GetOutboundLinksByID_Call struct { - *mock.Call -} - -// GetOutboundLinksByID is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) GetOutboundLinksByID(id interface{}) *MockObjectStore_GetOutboundLinksByID_Call { - return &MockObjectStore_GetOutboundLinksByID_Call{Call: _e.mock.On("GetOutboundLinksByID", id)} -} - -func (_c *MockObjectStore_GetOutboundLinksByID_Call) Run(run func(id string)) *MockObjectStore_GetOutboundLinksByID_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetOutboundLinksByID_Call) Return(_a0 []string, _a1 error) *MockObjectStore_GetOutboundLinksByID_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetOutboundLinksByID_Call) RunAndReturn(run func(string) ([]string, error)) *MockObjectStore_GetOutboundLinksByID_Call { - _c.Call.Return(run) - return _c -} - -// GetRelationByID provides a mock function with given fields: id -func (_m *MockObjectStore) GetRelationByID(id string) (*model.Relation, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetRelationByID") - } - - var r0 *model.Relation - var r1 error - if rf, ok := ret.Get(0).(func(string) (*model.Relation, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) *model.Relation); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.Relation) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetRelationByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationByID' -type MockObjectStore_GetRelationByID_Call struct { - *mock.Call -} - -// GetRelationByID is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) GetRelationByID(id interface{}) *MockObjectStore_GetRelationByID_Call { - return &MockObjectStore_GetRelationByID_Call{Call: _e.mock.On("GetRelationByID", id)} -} - -func (_c *MockObjectStore_GetRelationByID_Call) Run(run func(id string)) *MockObjectStore_GetRelationByID_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetRelationByID_Call) Return(relation *model.Relation, err error) *MockObjectStore_GetRelationByID_Call { - _c.Call.Return(relation, err) - return _c -} - -func (_c *MockObjectStore_GetRelationByID_Call) RunAndReturn(run func(string) (*model.Relation, error)) *MockObjectStore_GetRelationByID_Call { - _c.Call.Return(run) - return _c -} - -// GetRelationByKey provides a mock function with given fields: spaceId, key -func (_m *MockObjectStore) GetRelationByKey(spaceId string, key string) (*model.Relation, error) { - ret := _m.Called(spaceId, key) - - if len(ret) == 0 { - panic("no return value specified for GetRelationByKey") - } - - var r0 *model.Relation - var r1 error - if rf, ok := ret.Get(0).(func(string, string) (*model.Relation, error)); ok { - return rf(spaceId, key) - } - if rf, ok := ret.Get(0).(func(string, string) *model.Relation); ok { - r0 = rf(spaceId, key) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.Relation) - } - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(spaceId, key) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetRelationByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationByKey' -type MockObjectStore_GetRelationByKey_Call struct { - *mock.Call -} - -// GetRelationByKey is a helper method to define mock.On call -// - spaceId string -// - key string -func (_e *MockObjectStore_Expecter) GetRelationByKey(spaceId interface{}, key interface{}) *MockObjectStore_GetRelationByKey_Call { - return &MockObjectStore_GetRelationByKey_Call{Call: _e.mock.On("GetRelationByKey", spaceId, key)} -} - -func (_c *MockObjectStore_GetRelationByKey_Call) Run(run func(spaceId string, key string)) *MockObjectStore_GetRelationByKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetRelationByKey_Call) Return(_a0 *model.Relation, _a1 error) *MockObjectStore_GetRelationByKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetRelationByKey_Call) RunAndReturn(run func(string, string) (*model.Relation, error)) *MockObjectStore_GetRelationByKey_Call { - _c.Call.Return(run) - return _c -} - -// GetRelationFormatByKey provides a mock function with given fields: key -func (_m *MockObjectStore) GetRelationFormatByKey(key string) (model.RelationFormat, error) { - ret := _m.Called(key) - - if len(ret) == 0 { - panic("no return value specified for GetRelationFormatByKey") - } - - var r0 model.RelationFormat - var r1 error - if rf, ok := ret.Get(0).(func(string) (model.RelationFormat, error)); ok { - return rf(key) - } - if rf, ok := ret.Get(0).(func(string) model.RelationFormat); ok { - r0 = rf(key) - } else { - r0 = ret.Get(0).(model.RelationFormat) - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(key) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetRelationFormatByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationFormatByKey' -type MockObjectStore_GetRelationFormatByKey_Call struct { - *mock.Call -} - -// GetRelationFormatByKey is a helper method to define mock.On call -// - key string -func (_e *MockObjectStore_Expecter) GetRelationFormatByKey(key interface{}) *MockObjectStore_GetRelationFormatByKey_Call { - return &MockObjectStore_GetRelationFormatByKey_Call{Call: _e.mock.On("GetRelationFormatByKey", key)} -} - -func (_c *MockObjectStore_GetRelationFormatByKey_Call) Run(run func(key string)) *MockObjectStore_GetRelationFormatByKey_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetRelationFormatByKey_Call) Return(_a0 model.RelationFormat, _a1 error) *MockObjectStore_GetRelationFormatByKey_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetRelationFormatByKey_Call) RunAndReturn(run func(string) (model.RelationFormat, error)) *MockObjectStore_GetRelationFormatByKey_Call { - _c.Call.Return(run) - return _c -} - -// GetRelationLink provides a mock function with given fields: spaceID, key -func (_m *MockObjectStore) GetRelationLink(spaceID string, key string) (*model.RelationLink, error) { - ret := _m.Called(spaceID, key) - - if len(ret) == 0 { - panic("no return value specified for GetRelationLink") - } - - var r0 *model.RelationLink - var r1 error - if rf, ok := ret.Get(0).(func(string, string) (*model.RelationLink, error)); ok { - return rf(spaceID, key) - } - if rf, ok := ret.Get(0).(func(string, string) *model.RelationLink); ok { - r0 = rf(spaceID, key) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.RelationLink) - } - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(spaceID, key) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetRelationLink_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationLink' -type MockObjectStore_GetRelationLink_Call struct { - *mock.Call -} - -// GetRelationLink is a helper method to define mock.On call -// - spaceID string -// - key string -func (_e *MockObjectStore_Expecter) GetRelationLink(spaceID interface{}, key interface{}) *MockObjectStore_GetRelationLink_Call { - return &MockObjectStore_GetRelationLink_Call{Call: _e.mock.On("GetRelationLink", spaceID, key)} -} - -func (_c *MockObjectStore_GetRelationLink_Call) Run(run func(spaceID string, key string)) *MockObjectStore_GetRelationLink_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetRelationLink_Call) Return(_a0 *model.RelationLink, _a1 error) *MockObjectStore_GetRelationLink_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetRelationLink_Call) RunAndReturn(run func(string, string) (*model.RelationLink, error)) *MockObjectStore_GetRelationLink_Call { - _c.Call.Return(run) - return _c -} - -// GetSpaceName provides a mock function with given fields: spaceId -func (_m *MockObjectStore) GetSpaceName(spaceId string) string { - ret := _m.Called(spaceId) - - if len(ret) == 0 { - panic("no return value specified for GetSpaceName") - } - - var r0 string - if rf, ok := ret.Get(0).(func(string) string); ok { - r0 = rf(spaceId) - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// MockObjectStore_GetSpaceName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSpaceName' -type MockObjectStore_GetSpaceName_Call struct { - *mock.Call -} - -// GetSpaceName is a helper method to define mock.On call -// - spaceId string -func (_e *MockObjectStore_Expecter) GetSpaceName(spaceId interface{}) *MockObjectStore_GetSpaceName_Call { - return &MockObjectStore_GetSpaceName_Call{Call: _e.mock.On("GetSpaceName", spaceId)} -} - -func (_c *MockObjectStore_GetSpaceName_Call) Run(run func(spaceId string)) *MockObjectStore_GetSpaceName_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetSpaceName_Call) Return(_a0 string) *MockObjectStore_GetSpaceName_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_GetSpaceName_Call) RunAndReturn(run func(string) string) *MockObjectStore_GetSpaceName_Call { - _c.Call.Return(run) - return _c -} - -// GetUniqueKeyById provides a mock function with given fields: id -func (_m *MockObjectStore) GetUniqueKeyById(id string) (domain.UniqueKey, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for GetUniqueKeyById") - } - - var r0 domain.UniqueKey - var r1 error - if rf, ok := ret.Get(0).(func(string) (domain.UniqueKey, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) domain.UniqueKey); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(domain.UniqueKey) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetUniqueKeyById_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUniqueKeyById' -type MockObjectStore_GetUniqueKeyById_Call struct { - *mock.Call -} - -// GetUniqueKeyById is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) GetUniqueKeyById(id interface{}) *MockObjectStore_GetUniqueKeyById_Call { - return &MockObjectStore_GetUniqueKeyById_Call{Call: _e.mock.On("GetUniqueKeyById", id)} -} - -func (_c *MockObjectStore_GetUniqueKeyById_Call) Run(run func(id string)) *MockObjectStore_GetUniqueKeyById_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetUniqueKeyById_Call) Return(key domain.UniqueKey, err error) *MockObjectStore_GetUniqueKeyById_Call { - _c.Call.Return(key, err) - return _c -} - -func (_c *MockObjectStore_GetUniqueKeyById_Call) RunAndReturn(run func(string) (domain.UniqueKey, error)) *MockObjectStore_GetUniqueKeyById_Call { - _c.Call.Return(run) - return _c -} - -// GetWithLinksInfoByID provides a mock function with given fields: spaceID, id -func (_m *MockObjectStore) GetWithLinksInfoByID(spaceID string, id string) (*model.ObjectInfoWithLinks, error) { - ret := _m.Called(spaceID, id) - - if len(ret) == 0 { - panic("no return value specified for GetWithLinksInfoByID") - } - - var r0 *model.ObjectInfoWithLinks - var r1 error - if rf, ok := ret.Get(0).(func(string, string) (*model.ObjectInfoWithLinks, error)); ok { - return rf(spaceID, id) - } - if rf, ok := ret.Get(0).(func(string, string) *model.ObjectInfoWithLinks); ok { - r0 = rf(spaceID, id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ObjectInfoWithLinks) - } - } - - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(spaceID, id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_GetWithLinksInfoByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWithLinksInfoByID' -type MockObjectStore_GetWithLinksInfoByID_Call struct { - *mock.Call -} - -// GetWithLinksInfoByID is a helper method to define mock.On call -// - spaceID string -// - id string -func (_e *MockObjectStore_Expecter) GetWithLinksInfoByID(spaceID interface{}, id interface{}) *MockObjectStore_GetWithLinksInfoByID_Call { - return &MockObjectStore_GetWithLinksInfoByID_Call{Call: _e.mock.On("GetWithLinksInfoByID", spaceID, id)} -} - -func (_c *MockObjectStore_GetWithLinksInfoByID_Call) Run(run func(spaceID string, id string)) *MockObjectStore_GetWithLinksInfoByID_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *MockObjectStore_GetWithLinksInfoByID_Call) Return(_a0 *model.ObjectInfoWithLinks, _a1 error) *MockObjectStore_GetWithLinksInfoByID_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_GetWithLinksInfoByID_Call) RunAndReturn(run func(string, string) (*model.ObjectInfoWithLinks, error)) *MockObjectStore_GetWithLinksInfoByID_Call { - _c.Call.Return(run) - return _c -} - -// HasIDs provides a mock function with given fields: ids -func (_m *MockObjectStore) HasIDs(ids ...string) ([]string, error) { - _va := make([]interface{}, len(ids)) - for _i := range ids { - _va[_i] = ids[_i] - } - var _ca []interface{} - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for HasIDs") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(...string) ([]string, error)); ok { - return rf(ids...) - } - if rf, ok := ret.Get(0).(func(...string) []string); ok { - r0 = rf(ids...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(...string) error); ok { - r1 = rf(ids...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_HasIDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HasIDs' -type MockObjectStore_HasIDs_Call struct { - *mock.Call -} - -// HasIDs is a helper method to define mock.On call -// - ids ...string -func (_e *MockObjectStore_Expecter) HasIDs(ids ...interface{}) *MockObjectStore_HasIDs_Call { - return &MockObjectStore_HasIDs_Call{Call: _e.mock.On("HasIDs", - append([]interface{}{}, ids...)...)} -} - -func (_c *MockObjectStore_HasIDs_Call) Run(run func(ids ...string)) *MockObjectStore_HasIDs_Call { - _c.Call.Run(func(args mock.Arguments) { - variadicArgs := make([]string, len(args)-0) - for i, a := range args[0:] { - if a != nil { - variadicArgs[i] = a.(string) - } - } - run(variadicArgs...) - }) - return _c -} - -func (_c *MockObjectStore_HasIDs_Call) Return(exists []string, err error) *MockObjectStore_HasIDs_Call { - _c.Call.Return(exists, err) - return _c -} - -func (_c *MockObjectStore_HasIDs_Call) RunAndReturn(run func(...string) ([]string, error)) *MockObjectStore_HasIDs_Call { - _c.Call.Return(run) - return _c -} - -// Init provides a mock function with given fields: a -func (_m *MockObjectStore) Init(a *app.App) error { - ret := _m.Called(a) - - if len(ret) == 0 { - panic("no return value specified for Init") - } - - var r0 error - if rf, ok := ret.Get(0).(func(*app.App) error); ok { - r0 = rf(a) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' -type MockObjectStore_Init_Call struct { - *mock.Call -} - -// Init is a helper method to define mock.On call -// - a *app.App -func (_e *MockObjectStore_Expecter) Init(a interface{}) *MockObjectStore_Init_Call { - return &MockObjectStore_Init_Call{Call: _e.mock.On("Init", a)} -} - -func (_c *MockObjectStore_Init_Call) Run(run func(a *app.App)) *MockObjectStore_Init_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*app.App)) - }) - return _c -} - -func (_c *MockObjectStore_Init_Call) Return(err error) *MockObjectStore_Init_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockObjectStore_Init_Call) RunAndReturn(run func(*app.App) error) *MockObjectStore_Init_Call { - _c.Call.Return(run) - return _c -} - -// List provides a mock function with given fields: spaceID, includeArchived -func (_m *MockObjectStore) List(spaceID string, includeArchived bool) ([]*model.ObjectInfo, error) { - ret := _m.Called(spaceID, includeArchived) - - if len(ret) == 0 { - panic("no return value specified for List") - } - - var r0 []*model.ObjectInfo - var r1 error - if rf, ok := ret.Get(0).(func(string, bool) ([]*model.ObjectInfo, error)); ok { - return rf(spaceID, includeArchived) - } - if rf, ok := ret.Get(0).(func(string, bool) []*model.ObjectInfo); ok { - r0 = rf(spaceID, includeArchived) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*model.ObjectInfo) - } - } - - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(spaceID, includeArchived) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' -type MockObjectStore_List_Call struct { - *mock.Call -} - -// List is a helper method to define mock.On call -// - spaceID string -// - includeArchived bool -func (_e *MockObjectStore_Expecter) List(spaceID interface{}, includeArchived interface{}) *MockObjectStore_List_Call { - return &MockObjectStore_List_Call{Call: _e.mock.On("List", spaceID, includeArchived)} -} - -func (_c *MockObjectStore_List_Call) Run(run func(spaceID string, includeArchived bool)) *MockObjectStore_List_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(bool)) - }) - return _c -} - -func (_c *MockObjectStore_List_Call) Return(_a0 []*model.ObjectInfo, _a1 error) *MockObjectStore_List_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_List_Call) RunAndReturn(run func(string, bool) ([]*model.ObjectInfo, error)) *MockObjectStore_List_Call { - _c.Call.Return(run) - return _c -} - -// ListAllRelations provides a mock function with given fields: spaceId -func (_m *MockObjectStore) ListAllRelations(spaceId string) (relationutils.Relations, error) { - ret := _m.Called(spaceId) - - if len(ret) == 0 { - panic("no return value specified for ListAllRelations") - } - - var r0 relationutils.Relations - var r1 error - if rf, ok := ret.Get(0).(func(string) (relationutils.Relations, error)); ok { - return rf(spaceId) - } - if rf, ok := ret.Get(0).(func(string) relationutils.Relations); ok { - r0 = rf(spaceId) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(relationutils.Relations) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(spaceId) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_ListAllRelations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListAllRelations' -type MockObjectStore_ListAllRelations_Call struct { - *mock.Call -} - -// ListAllRelations is a helper method to define mock.On call -// - spaceId string -func (_e *MockObjectStore_Expecter) ListAllRelations(spaceId interface{}) *MockObjectStore_ListAllRelations_Call { - return &MockObjectStore_ListAllRelations_Call{Call: _e.mock.On("ListAllRelations", spaceId)} -} - -func (_c *MockObjectStore_ListAllRelations_Call) Run(run func(spaceId string)) *MockObjectStore_ListAllRelations_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_ListAllRelations_Call) Return(relations relationutils.Relations, err error) *MockObjectStore_ListAllRelations_Call { - _c.Call.Return(relations, err) - return _c -} - -func (_c *MockObjectStore_ListAllRelations_Call) RunAndReturn(run func(string) (relationutils.Relations, error)) *MockObjectStore_ListAllRelations_Call { - _c.Call.Return(run) - return _c -} - -// ListIDsFromFullTextQueue provides a mock function with given fields: limit -func (_m *MockObjectStore) ListIDsFromFullTextQueue(limit int) ([]string, error) { - ret := _m.Called(limit) - - if len(ret) == 0 { - panic("no return value specified for ListIDsFromFullTextQueue") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(int) ([]string, error)); ok { - return rf(limit) - } - if rf, ok := ret.Get(0).(func(int) []string); ok { - r0 = rf(limit) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(int) error); ok { - r1 = rf(limit) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_ListIDsFromFullTextQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListIDsFromFullTextQueue' -type MockObjectStore_ListIDsFromFullTextQueue_Call struct { - *mock.Call -} - -// ListIDsFromFullTextQueue is a helper method to define mock.On call -// - limit int -func (_e *MockObjectStore_Expecter) ListIDsFromFullTextQueue(limit interface{}) *MockObjectStore_ListIDsFromFullTextQueue_Call { - return &MockObjectStore_ListIDsFromFullTextQueue_Call{Call: _e.mock.On("ListIDsFromFullTextQueue", limit)} -} - -func (_c *MockObjectStore_ListIDsFromFullTextQueue_Call) Run(run func(limit int)) *MockObjectStore_ListIDsFromFullTextQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(int)) - }) - return _c -} - -func (_c *MockObjectStore_ListIDsFromFullTextQueue_Call) Return(_a0 []string, _a1 error) *MockObjectStore_ListIDsFromFullTextQueue_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_ListIDsFromFullTextQueue_Call) RunAndReturn(run func(int) ([]string, error)) *MockObjectStore_ListIDsFromFullTextQueue_Call { - _c.Call.Return(run) - return _c -} - -// ListIds provides a mock function with given fields: -func (_m *MockObjectStore) ListIds() ([]string, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for ListIds") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func() ([]string, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() []string); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_ListIds_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListIds' -type MockObjectStore_ListIds_Call struct { - *mock.Call -} - -// ListIds is a helper method to define mock.On call -func (_e *MockObjectStore_Expecter) ListIds() *MockObjectStore_ListIds_Call { - return &MockObjectStore_ListIds_Call{Call: _e.mock.On("ListIds")} -} - -func (_c *MockObjectStore_ListIds_Call) Run(run func()) *MockObjectStore_ListIds_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockObjectStore_ListIds_Call) Return(_a0 []string, _a1 error) *MockObjectStore_ListIds_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_ListIds_Call) RunAndReturn(run func() ([]string, error)) *MockObjectStore_ListIds_Call { - _c.Call.Return(run) - return _c -} - -// ListIdsBySpace provides a mock function with given fields: spaceId -func (_m *MockObjectStore) ListIdsBySpace(spaceId string) ([]string, error) { - ret := _m.Called(spaceId) - - if len(ret) == 0 { - panic("no return value specified for ListIdsBySpace") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func(string) ([]string, error)); ok { - return rf(spaceId) - } - if rf, ok := ret.Get(0).(func(string) []string); ok { - r0 = rf(spaceId) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(spaceId) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_ListIdsBySpace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListIdsBySpace' -type MockObjectStore_ListIdsBySpace_Call struct { - *mock.Call -} - -// ListIdsBySpace is a helper method to define mock.On call -// - spaceId string -func (_e *MockObjectStore_Expecter) ListIdsBySpace(spaceId interface{}) *MockObjectStore_ListIdsBySpace_Call { - return &MockObjectStore_ListIdsBySpace_Call{Call: _e.mock.On("ListIdsBySpace", spaceId)} -} - -func (_c *MockObjectStore_ListIdsBySpace_Call) Run(run func(spaceId string)) *MockObjectStore_ListIdsBySpace_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_ListIdsBySpace_Call) Return(_a0 []string, _a1 error) *MockObjectStore_ListIdsBySpace_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_ListIdsBySpace_Call) RunAndReturn(run func(string) ([]string, error)) *MockObjectStore_ListIdsBySpace_Call { - _c.Call.Return(run) - return _c -} - -// ListVirtualSpaces provides a mock function with given fields: -func (_m *MockObjectStore) ListVirtualSpaces() ([]string, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for ListVirtualSpaces") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func() ([]string, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() []string); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_ListVirtualSpaces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListVirtualSpaces' -type MockObjectStore_ListVirtualSpaces_Call struct { - *mock.Call -} - -// ListVirtualSpaces is a helper method to define mock.On call -func (_e *MockObjectStore_Expecter) ListVirtualSpaces() *MockObjectStore_ListVirtualSpaces_Call { - return &MockObjectStore_ListVirtualSpaces_Call{Call: _e.mock.On("ListVirtualSpaces")} -} - -func (_c *MockObjectStore_ListVirtualSpaces_Call) Run(run func()) *MockObjectStore_ListVirtualSpaces_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockObjectStore_ListVirtualSpaces_Call) Return(_a0 []string, _a1 error) *MockObjectStore_ListVirtualSpaces_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockObjectStore_ListVirtualSpaces_Call) RunAndReturn(run func() ([]string, error)) *MockObjectStore_ListVirtualSpaces_Call { - _c.Call.Return(run) - return _c -} - -// ModifyObjectDetails provides a mock function with given fields: id, proc -func (_m *MockObjectStore) ModifyObjectDetails(id string, proc func(*types.Struct) (*types.Struct, bool, error)) error { - ret := _m.Called(id, proc) - - if len(ret) == 0 { - panic("no return value specified for ModifyObjectDetails") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, func(*types.Struct) (*types.Struct, bool, error)) error); ok { - r0 = rf(id, proc) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_ModifyObjectDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ModifyObjectDetails' -type MockObjectStore_ModifyObjectDetails_Call struct { - *mock.Call -} - -// ModifyObjectDetails is a helper method to define mock.On call -// - id string -// - proc func(*types.Struct)(*types.Struct , bool , error) -func (_e *MockObjectStore_Expecter) ModifyObjectDetails(id interface{}, proc interface{}) *MockObjectStore_ModifyObjectDetails_Call { - return &MockObjectStore_ModifyObjectDetails_Call{Call: _e.mock.On("ModifyObjectDetails", id, proc)} -} - -func (_c *MockObjectStore_ModifyObjectDetails_Call) Run(run func(id string, proc func(*types.Struct) (*types.Struct, bool, error))) *MockObjectStore_ModifyObjectDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(func(*types.Struct) (*types.Struct, bool, error))) - }) - return _c -} - -func (_c *MockObjectStore_ModifyObjectDetails_Call) Return(_a0 error) *MockObjectStore_ModifyObjectDetails_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_ModifyObjectDetails_Call) RunAndReturn(run func(string, func(*types.Struct) (*types.Struct, bool, error)) error) *MockObjectStore_ModifyObjectDetails_Call { - _c.Call.Return(run) - return _c -} - -// Name provides a mock function with given fields: -func (_m *MockObjectStore) Name() string { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Name") - } - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// MockObjectStore_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' -type MockObjectStore_Name_Call struct { - *mock.Call -} - -// Name is a helper method to define mock.On call -func (_e *MockObjectStore_Expecter) Name() *MockObjectStore_Name_Call { - return &MockObjectStore_Name_Call{Call: _e.mock.On("Name")} -} - -func (_c *MockObjectStore_Name_Call) Run(run func()) *MockObjectStore_Name_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockObjectStore_Name_Call) Return(name string) *MockObjectStore_Name_Call { - _c.Call.Return(name) - return _c -} - -func (_c *MockObjectStore_Name_Call) RunAndReturn(run func() string) *MockObjectStore_Name_Call { - _c.Call.Return(run) - return _c -} - -// Query provides a mock function with given fields: q -func (_m *MockObjectStore) Query(q database.Query) ([]database.Record, error) { - ret := _m.Called(q) - - if len(ret) == 0 { - panic("no return value specified for Query") - } - - var r0 []database.Record - var r1 error - if rf, ok := ret.Get(0).(func(database.Query) ([]database.Record, error)); ok { - return rf(q) - } - if rf, ok := ret.Get(0).(func(database.Query) []database.Record); ok { - r0 = rf(q) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]database.Record) - } - } - - if rf, ok := ret.Get(1).(func(database.Query) error); ok { - r1 = rf(q) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_Query_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Query' -type MockObjectStore_Query_Call struct { - *mock.Call -} - -// Query is a helper method to define mock.On call -// - q database.Query -func (_e *MockObjectStore_Expecter) Query(q interface{}) *MockObjectStore_Query_Call { - return &MockObjectStore_Query_Call{Call: _e.mock.On("Query", q)} -} - -func (_c *MockObjectStore_Query_Call) Run(run func(q database.Query)) *MockObjectStore_Query_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(database.Query)) - }) - return _c -} - -func (_c *MockObjectStore_Query_Call) Return(records []database.Record, err error) *MockObjectStore_Query_Call { - _c.Call.Return(records, err) - return _c -} - -func (_c *MockObjectStore_Query_Call) RunAndReturn(run func(database.Query) ([]database.Record, error)) *MockObjectStore_Query_Call { - _c.Call.Return(run) - return _c -} - -// QueryByID provides a mock function with given fields: ids -func (_m *MockObjectStore) QueryByID(ids []string) ([]database.Record, error) { - ret := _m.Called(ids) - - if len(ret) == 0 { - panic("no return value specified for QueryByID") - } - - var r0 []database.Record - var r1 error - if rf, ok := ret.Get(0).(func([]string) ([]database.Record, error)); ok { - return rf(ids) - } - if rf, ok := ret.Get(0).(func([]string) []database.Record); ok { - r0 = rf(ids) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]database.Record) - } - } - - if rf, ok := ret.Get(1).(func([]string) error); ok { - r1 = rf(ids) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_QueryByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryByID' -type MockObjectStore_QueryByID_Call struct { - *mock.Call -} - -// QueryByID is a helper method to define mock.On call -// - ids []string -func (_e *MockObjectStore_Expecter) QueryByID(ids interface{}) *MockObjectStore_QueryByID_Call { - return &MockObjectStore_QueryByID_Call{Call: _e.mock.On("QueryByID", ids)} -} - -func (_c *MockObjectStore_QueryByID_Call) Run(run func(ids []string)) *MockObjectStore_QueryByID_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].([]string)) - }) - return _c -} - -func (_c *MockObjectStore_QueryByID_Call) Return(records []database.Record, err error) *MockObjectStore_QueryByID_Call { - _c.Call.Return(records, err) - return _c -} - -func (_c *MockObjectStore_QueryByID_Call) RunAndReturn(run func([]string) ([]database.Record, error)) *MockObjectStore_QueryByID_Call { - _c.Call.Return(run) - return _c -} - -// QueryByIDAndSubscribeForChanges provides a mock function with given fields: ids, subscription -func (_m *MockObjectStore) QueryByIDAndSubscribeForChanges(ids []string, subscription database.Subscription) ([]database.Record, func(), error) { - ret := _m.Called(ids, subscription) - - if len(ret) == 0 { - panic("no return value specified for QueryByIDAndSubscribeForChanges") - } - - var r0 []database.Record - var r1 func() - var r2 error - if rf, ok := ret.Get(0).(func([]string, database.Subscription) ([]database.Record, func(), error)); ok { - return rf(ids, subscription) - } - if rf, ok := ret.Get(0).(func([]string, database.Subscription) []database.Record); ok { - r0 = rf(ids, subscription) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]database.Record) - } - } - - if rf, ok := ret.Get(1).(func([]string, database.Subscription) func()); ok { - r1 = rf(ids, subscription) - } else { - if ret.Get(1) != nil { - r1 = ret.Get(1).(func()) - } - } - - if rf, ok := ret.Get(2).(func([]string, database.Subscription) error); ok { - r2 = rf(ids, subscription) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - -// MockObjectStore_QueryByIDAndSubscribeForChanges_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryByIDAndSubscribeForChanges' -type MockObjectStore_QueryByIDAndSubscribeForChanges_Call struct { - *mock.Call -} - -// QueryByIDAndSubscribeForChanges is a helper method to define mock.On call -// - ids []string -// - subscription database.Subscription -func (_e *MockObjectStore_Expecter) QueryByIDAndSubscribeForChanges(ids interface{}, subscription interface{}) *MockObjectStore_QueryByIDAndSubscribeForChanges_Call { - return &MockObjectStore_QueryByIDAndSubscribeForChanges_Call{Call: _e.mock.On("QueryByIDAndSubscribeForChanges", ids, subscription)} -} - -func (_c *MockObjectStore_QueryByIDAndSubscribeForChanges_Call) Run(run func(ids []string, subscription database.Subscription)) *MockObjectStore_QueryByIDAndSubscribeForChanges_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].([]string), args[1].(database.Subscription)) - }) - return _c -} - -func (_c *MockObjectStore_QueryByIDAndSubscribeForChanges_Call) Return(records []database.Record, close func(), err error) *MockObjectStore_QueryByIDAndSubscribeForChanges_Call { - _c.Call.Return(records, close, err) - return _c -} - -func (_c *MockObjectStore_QueryByIDAndSubscribeForChanges_Call) RunAndReturn(run func([]string, database.Subscription) ([]database.Record, func(), error)) *MockObjectStore_QueryByIDAndSubscribeForChanges_Call { - _c.Call.Return(run) - return _c -} - -// QueryIterate provides a mock function with given fields: q, proc -func (_m *MockObjectStore) QueryIterate(q database.Query, proc func(*types.Struct)) error { - ret := _m.Called(q, proc) - - if len(ret) == 0 { - panic("no return value specified for QueryIterate") - } - - var r0 error - if rf, ok := ret.Get(0).(func(database.Query, func(*types.Struct)) error); ok { - r0 = rf(q, proc) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_QueryIterate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryIterate' -type MockObjectStore_QueryIterate_Call struct { - *mock.Call -} - -// QueryIterate is a helper method to define mock.On call -// - q database.Query -// - proc func(*types.Struct) -func (_e *MockObjectStore_Expecter) QueryIterate(q interface{}, proc interface{}) *MockObjectStore_QueryIterate_Call { - return &MockObjectStore_QueryIterate_Call{Call: _e.mock.On("QueryIterate", q, proc)} -} - -func (_c *MockObjectStore_QueryIterate_Call) Run(run func(q database.Query, proc func(*types.Struct))) *MockObjectStore_QueryIterate_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(database.Query), args[1].(func(*types.Struct))) - }) - return _c -} - -func (_c *MockObjectStore_QueryIterate_Call) Return(_a0 error) *MockObjectStore_QueryIterate_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_QueryIterate_Call) RunAndReturn(run func(database.Query, func(*types.Struct)) error) *MockObjectStore_QueryIterate_Call { - _c.Call.Return(run) - return _c -} - -// QueryObjectIDs provides a mock function with given fields: q -func (_m *MockObjectStore) QueryObjectIDs(q database.Query) ([]string, int, error) { - ret := _m.Called(q) - - if len(ret) == 0 { - panic("no return value specified for QueryObjectIDs") - } - - var r0 []string - var r1 int - var r2 error - if rf, ok := ret.Get(0).(func(database.Query) ([]string, int, error)); ok { - return rf(q) - } - if rf, ok := ret.Get(0).(func(database.Query) []string); ok { - r0 = rf(q) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func(database.Query) int); ok { - r1 = rf(q) - } else { - r1 = ret.Get(1).(int) - } - - if rf, ok := ret.Get(2).(func(database.Query) error); ok { - r2 = rf(q) - } else { - r2 = ret.Error(2) - } - - return r0, r1, r2 -} - -// MockObjectStore_QueryObjectIDs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryObjectIDs' -type MockObjectStore_QueryObjectIDs_Call struct { - *mock.Call -} - -// QueryObjectIDs is a helper method to define mock.On call -// - q database.Query -func (_e *MockObjectStore_Expecter) QueryObjectIDs(q interface{}) *MockObjectStore_QueryObjectIDs_Call { - return &MockObjectStore_QueryObjectIDs_Call{Call: _e.mock.On("QueryObjectIDs", q)} -} - -func (_c *MockObjectStore_QueryObjectIDs_Call) Run(run func(q database.Query)) *MockObjectStore_QueryObjectIDs_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(database.Query)) - }) - return _c -} - -func (_c *MockObjectStore_QueryObjectIDs_Call) Return(ids []string, total int, err error) *MockObjectStore_QueryObjectIDs_Call { - _c.Call.Return(ids, total, err) - return _c -} - -func (_c *MockObjectStore_QueryObjectIDs_Call) RunAndReturn(run func(database.Query) ([]string, int, error)) *MockObjectStore_QueryObjectIDs_Call { - _c.Call.Return(run) - return _c -} - -// QueryRaw provides a mock function with given fields: f, limit, offset -func (_m *MockObjectStore) QueryRaw(f *database.Filters, limit int, offset int) ([]database.Record, error) { - ret := _m.Called(f, limit, offset) - - if len(ret) == 0 { - panic("no return value specified for QueryRaw") - } - - var r0 []database.Record - var r1 error - if rf, ok := ret.Get(0).(func(*database.Filters, int, int) ([]database.Record, error)); ok { - return rf(f, limit, offset) - } - if rf, ok := ret.Get(0).(func(*database.Filters, int, int) []database.Record); ok { - r0 = rf(f, limit, offset) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]database.Record) - } - } - - if rf, ok := ret.Get(1).(func(*database.Filters, int, int) error); ok { - r1 = rf(f, limit, offset) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockObjectStore_QueryRaw_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'QueryRaw' -type MockObjectStore_QueryRaw_Call struct { - *mock.Call -} - -// QueryRaw is a helper method to define mock.On call -// - f *database.Filters -// - limit int -// - offset int -func (_e *MockObjectStore_Expecter) QueryRaw(f interface{}, limit interface{}, offset interface{}) *MockObjectStore_QueryRaw_Call { - return &MockObjectStore_QueryRaw_Call{Call: _e.mock.On("QueryRaw", f, limit, offset)} -} - -func (_c *MockObjectStore_QueryRaw_Call) Run(run func(f *database.Filters, limit int, offset int)) *MockObjectStore_QueryRaw_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*database.Filters), args[1].(int), args[2].(int)) - }) - return _c -} - -func (_c *MockObjectStore_QueryRaw_Call) Return(records []database.Record, err error) *MockObjectStore_QueryRaw_Call { - _c.Call.Return(records, err) - return _c -} - -func (_c *MockObjectStore_QueryRaw_Call) RunAndReturn(run func(*database.Filters, int, int) ([]database.Record, error)) *MockObjectStore_QueryRaw_Call { - _c.Call.Return(run) - return _c -} - -// RemoveIDsFromFullTextQueue provides a mock function with given fields: ids -func (_m *MockObjectStore) RemoveIDsFromFullTextQueue(ids []string) error { - ret := _m.Called(ids) - - if len(ret) == 0 { - panic("no return value specified for RemoveIDsFromFullTextQueue") - } - - var r0 error - if rf, ok := ret.Get(0).(func([]string) error); ok { - r0 = rf(ids) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_RemoveIDsFromFullTextQueue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveIDsFromFullTextQueue' -type MockObjectStore_RemoveIDsFromFullTextQueue_Call struct { - *mock.Call -} - -// RemoveIDsFromFullTextQueue is a helper method to define mock.On call -// - ids []string -func (_e *MockObjectStore_Expecter) RemoveIDsFromFullTextQueue(ids interface{}) *MockObjectStore_RemoveIDsFromFullTextQueue_Call { - return &MockObjectStore_RemoveIDsFromFullTextQueue_Call{Call: _e.mock.On("RemoveIDsFromFullTextQueue", ids)} -} - -func (_c *MockObjectStore_RemoveIDsFromFullTextQueue_Call) Run(run func(ids []string)) *MockObjectStore_RemoveIDsFromFullTextQueue_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].([]string)) - }) - return _c -} - -func (_c *MockObjectStore_RemoveIDsFromFullTextQueue_Call) Return(_a0 error) *MockObjectStore_RemoveIDsFromFullTextQueue_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_RemoveIDsFromFullTextQueue_Call) RunAndReturn(run func([]string) error) *MockObjectStore_RemoveIDsFromFullTextQueue_Call { - _c.Call.Return(run) - return _c -} - -// Run provides a mock function with given fields: ctx -func (_m *MockObjectStore) Run(ctx context.Context) error { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for Run") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_Run_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Run' -type MockObjectStore_Run_Call struct { - *mock.Call -} - -// Run is a helper method to define mock.On call -// - ctx context.Context -func (_e *MockObjectStore_Expecter) Run(ctx interface{}) *MockObjectStore_Run_Call { - return &MockObjectStore_Run_Call{Call: _e.mock.On("Run", ctx)} -} - -func (_c *MockObjectStore_Run_Call) Run(run func(ctx context.Context)) *MockObjectStore_Run_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) - }) - return _c -} - -func (_c *MockObjectStore_Run_Call) Return(err error) *MockObjectStore_Run_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockObjectStore_Run_Call) RunAndReturn(run func(context.Context) error) *MockObjectStore_Run_Call { - _c.Call.Return(run) - return _c -} - -// SaveAccountStatus provides a mock function with given fields: status -func (_m *MockObjectStore) SaveAccountStatus(status *coordinatorproto.SpaceStatusPayload) error { - ret := _m.Called(status) - - if len(ret) == 0 { - panic("no return value specified for SaveAccountStatus") - } - - var r0 error - if rf, ok := ret.Get(0).(func(*coordinatorproto.SpaceStatusPayload) error); ok { - r0 = rf(status) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_SaveAccountStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveAccountStatus' -type MockObjectStore_SaveAccountStatus_Call struct { - *mock.Call -} - -// SaveAccountStatus is a helper method to define mock.On call -// - status *coordinatorproto.SpaceStatusPayload -func (_e *MockObjectStore_Expecter) SaveAccountStatus(status interface{}) *MockObjectStore_SaveAccountStatus_Call { - return &MockObjectStore_SaveAccountStatus_Call{Call: _e.mock.On("SaveAccountStatus", status)} -} - -func (_c *MockObjectStore_SaveAccountStatus_Call) Run(run func(status *coordinatorproto.SpaceStatusPayload)) *MockObjectStore_SaveAccountStatus_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*coordinatorproto.SpaceStatusPayload)) - }) - return _c -} - -func (_c *MockObjectStore_SaveAccountStatus_Call) Return(err error) *MockObjectStore_SaveAccountStatus_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockObjectStore_SaveAccountStatus_Call) RunAndReturn(run func(*coordinatorproto.SpaceStatusPayload) error) *MockObjectStore_SaveAccountStatus_Call { - _c.Call.Return(run) - return _c -} - -// SaveChecksums provides a mock function with given fields: spaceID, checksums -func (_m *MockObjectStore) SaveChecksums(spaceID string, checksums *model.ObjectStoreChecksums) error { - ret := _m.Called(spaceID, checksums) - - if len(ret) == 0 { - panic("no return value specified for SaveChecksums") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, *model.ObjectStoreChecksums) error); ok { - r0 = rf(spaceID, checksums) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_SaveChecksums_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveChecksums' -type MockObjectStore_SaveChecksums_Call struct { - *mock.Call -} - -// SaveChecksums is a helper method to define mock.On call -// - spaceID string -// - checksums *model.ObjectStoreChecksums -func (_e *MockObjectStore_Expecter) SaveChecksums(spaceID interface{}, checksums interface{}) *MockObjectStore_SaveChecksums_Call { - return &MockObjectStore_SaveChecksums_Call{Call: _e.mock.On("SaveChecksums", spaceID, checksums)} -} - -func (_c *MockObjectStore_SaveChecksums_Call) Run(run func(spaceID string, checksums *model.ObjectStoreChecksums)) *MockObjectStore_SaveChecksums_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(*model.ObjectStoreChecksums)) - }) - return _c -} - -func (_c *MockObjectStore_SaveChecksums_Call) Return(err error) *MockObjectStore_SaveChecksums_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockObjectStore_SaveChecksums_Call) RunAndReturn(run func(string, *model.ObjectStoreChecksums) error) *MockObjectStore_SaveChecksums_Call { - _c.Call.Return(run) - return _c -} - -// SaveLastIndexedHeadsHash provides a mock function with given fields: id, headsHash -func (_m *MockObjectStore) SaveLastIndexedHeadsHash(id string, headsHash string) error { - ret := _m.Called(id, headsHash) - - if len(ret) == 0 { - panic("no return value specified for SaveLastIndexedHeadsHash") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, string) error); ok { - r0 = rf(id, headsHash) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_SaveLastIndexedHeadsHash_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveLastIndexedHeadsHash' -type MockObjectStore_SaveLastIndexedHeadsHash_Call struct { - *mock.Call -} - -// SaveLastIndexedHeadsHash is a helper method to define mock.On call -// - id string -// - headsHash string -func (_e *MockObjectStore_Expecter) SaveLastIndexedHeadsHash(id interface{}, headsHash interface{}) *MockObjectStore_SaveLastIndexedHeadsHash_Call { - return &MockObjectStore_SaveLastIndexedHeadsHash_Call{Call: _e.mock.On("SaveLastIndexedHeadsHash", id, headsHash)} -} - -func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) Run(run func(id string, headsHash string)) *MockObjectStore_SaveLastIndexedHeadsHash_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string)) - }) - return _c -} - -func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) Return(err error) *MockObjectStore_SaveLastIndexedHeadsHash_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockObjectStore_SaveLastIndexedHeadsHash_Call) RunAndReturn(run func(string, string) error) *MockObjectStore_SaveLastIndexedHeadsHash_Call { - _c.Call.Return(run) - return _c -} - -// SaveVirtualSpace provides a mock function with given fields: id -func (_m *MockObjectStore) SaveVirtualSpace(id string) error { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for SaveVirtualSpace") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_SaveVirtualSpace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveVirtualSpace' -type MockObjectStore_SaveVirtualSpace_Call struct { - *mock.Call -} - -// SaveVirtualSpace is a helper method to define mock.On call -// - id string -func (_e *MockObjectStore_Expecter) SaveVirtualSpace(id interface{}) *MockObjectStore_SaveVirtualSpace_Call { - return &MockObjectStore_SaveVirtualSpace_Call{Call: _e.mock.On("SaveVirtualSpace", id)} -} - -func (_c *MockObjectStore_SaveVirtualSpace_Call) Run(run func(id string)) *MockObjectStore_SaveVirtualSpace_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockObjectStore_SaveVirtualSpace_Call) Return(_a0 error) *MockObjectStore_SaveVirtualSpace_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_SaveVirtualSpace_Call) RunAndReturn(run func(string) error) *MockObjectStore_SaveVirtualSpace_Call { - _c.Call.Return(run) - return _c -} - -// SetActiveView provides a mock function with given fields: objectId, blockId, viewId -func (_m *MockObjectStore) SetActiveView(objectId string, blockId string, viewId string) error { - ret := _m.Called(objectId, blockId, viewId) - - if len(ret) == 0 { - panic("no return value specified for SetActiveView") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, string, string) error); ok { - r0 = rf(objectId, blockId, viewId) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_SetActiveView_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetActiveView' -type MockObjectStore_SetActiveView_Call struct { - *mock.Call -} - -// SetActiveView is a helper method to define mock.On call -// - objectId string -// - blockId string -// - viewId string -func (_e *MockObjectStore_Expecter) SetActiveView(objectId interface{}, blockId interface{}, viewId interface{}) *MockObjectStore_SetActiveView_Call { - return &MockObjectStore_SetActiveView_Call{Call: _e.mock.On("SetActiveView", objectId, blockId, viewId)} -} - -func (_c *MockObjectStore_SetActiveView_Call) Run(run func(objectId string, blockId string, viewId string)) *MockObjectStore_SetActiveView_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(string), args[2].(string)) - }) - return _c -} - -func (_c *MockObjectStore_SetActiveView_Call) Return(_a0 error) *MockObjectStore_SetActiveView_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_SetActiveView_Call) RunAndReturn(run func(string, string, string) error) *MockObjectStore_SetActiveView_Call { - _c.Call.Return(run) - return _c -} - -// SetActiveViews provides a mock function with given fields: objectId, views -func (_m *MockObjectStore) SetActiveViews(objectId string, views map[string]string) error { - ret := _m.Called(objectId, views) - - if len(ret) == 0 { - panic("no return value specified for SetActiveViews") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, map[string]string) error); ok { - r0 = rf(objectId, views) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_SetActiveViews_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetActiveViews' -type MockObjectStore_SetActiveViews_Call struct { - *mock.Call -} - -// SetActiveViews is a helper method to define mock.On call -// - objectId string -// - views map[string]string -func (_e *MockObjectStore_Expecter) SetActiveViews(objectId interface{}, views interface{}) *MockObjectStore_SetActiveViews_Call { - return &MockObjectStore_SetActiveViews_Call{Call: _e.mock.On("SetActiveViews", objectId, views)} -} - -func (_c *MockObjectStore_SetActiveViews_Call) Run(run func(objectId string, views map[string]string)) *MockObjectStore_SetActiveViews_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(map[string]string)) - }) - return _c -} - -func (_c *MockObjectStore_SetActiveViews_Call) Return(_a0 error) *MockObjectStore_SetActiveViews_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_SetActiveViews_Call) RunAndReturn(run func(string, map[string]string) error) *MockObjectStore_SetActiveViews_Call { - _c.Call.Return(run) - return _c -} - -// SubscribeForAll provides a mock function with given fields: callback -func (_m *MockObjectStore) SubscribeForAll(callback func(database.Record)) { - _m.Called(callback) -} - -// MockObjectStore_SubscribeForAll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SubscribeForAll' -type MockObjectStore_SubscribeForAll_Call struct { - *mock.Call -} - -// SubscribeForAll is a helper method to define mock.On call -// - callback func(database.Record) -func (_e *MockObjectStore_Expecter) SubscribeForAll(callback interface{}) *MockObjectStore_SubscribeForAll_Call { - return &MockObjectStore_SubscribeForAll_Call{Call: _e.mock.On("SubscribeForAll", callback)} -} - -func (_c *MockObjectStore_SubscribeForAll_Call) Run(run func(callback func(database.Record))) *MockObjectStore_SubscribeForAll_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(func(database.Record))) - }) - return _c -} - -func (_c *MockObjectStore_SubscribeForAll_Call) Return() *MockObjectStore_SubscribeForAll_Call { - _c.Call.Return() - return _c -} - -func (_c *MockObjectStore_SubscribeForAll_Call) RunAndReturn(run func(func(database.Record))) *MockObjectStore_SubscribeForAll_Call { - _c.Call.Return(run) - return _c -} - -// UpdateObjectDetails provides a mock function with given fields: ctx, id, details -func (_m *MockObjectStore) UpdateObjectDetails(ctx context.Context, id string, details *types.Struct) error { - ret := _m.Called(ctx, id, details) - - if len(ret) == 0 { - panic("no return value specified for UpdateObjectDetails") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string, *types.Struct) error); ok { - r0 = rf(ctx, id, details) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_UpdateObjectDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateObjectDetails' -type MockObjectStore_UpdateObjectDetails_Call struct { - *mock.Call -} - -// UpdateObjectDetails is a helper method to define mock.On call -// - ctx context.Context -// - id string -// - details *types.Struct -func (_e *MockObjectStore_Expecter) UpdateObjectDetails(ctx interface{}, id interface{}, details interface{}) *MockObjectStore_UpdateObjectDetails_Call { - return &MockObjectStore_UpdateObjectDetails_Call{Call: _e.mock.On("UpdateObjectDetails", ctx, id, details)} -} - -func (_c *MockObjectStore_UpdateObjectDetails_Call) Run(run func(ctx context.Context, id string, details *types.Struct)) *MockObjectStore_UpdateObjectDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(*types.Struct)) - }) - return _c -} - -func (_c *MockObjectStore_UpdateObjectDetails_Call) Return(_a0 error) *MockObjectStore_UpdateObjectDetails_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_UpdateObjectDetails_Call) RunAndReturn(run func(context.Context, string, *types.Struct) error) *MockObjectStore_UpdateObjectDetails_Call { - _c.Call.Return(run) - return _c -} - -// UpdateObjectLinks provides a mock function with given fields: id, links -func (_m *MockObjectStore) UpdateObjectLinks(id string, links []string) error { - ret := _m.Called(id, links) - - if len(ret) == 0 { - panic("no return value specified for UpdateObjectLinks") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, []string) error); ok { - r0 = rf(id, links) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_UpdateObjectLinks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateObjectLinks' -type MockObjectStore_UpdateObjectLinks_Call struct { - *mock.Call -} - -// UpdateObjectLinks is a helper method to define mock.On call -// - id string -// - links []string -func (_e *MockObjectStore_Expecter) UpdateObjectLinks(id interface{}, links interface{}) *MockObjectStore_UpdateObjectLinks_Call { - return &MockObjectStore_UpdateObjectLinks_Call{Call: _e.mock.On("UpdateObjectLinks", id, links)} -} - -func (_c *MockObjectStore_UpdateObjectLinks_Call) Run(run func(id string, links []string)) *MockObjectStore_UpdateObjectLinks_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].([]string)) - }) - return _c -} - -func (_c *MockObjectStore_UpdateObjectLinks_Call) Return(_a0 error) *MockObjectStore_UpdateObjectLinks_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_UpdateObjectLinks_Call) RunAndReturn(run func(string, []string) error) *MockObjectStore_UpdateObjectLinks_Call { - _c.Call.Return(run) - return _c -} - -// UpdatePendingLocalDetails provides a mock function with given fields: id, proc -func (_m *MockObjectStore) UpdatePendingLocalDetails(id string, proc func(*types.Struct) (*types.Struct, error)) error { - ret := _m.Called(id, proc) - - if len(ret) == 0 { - panic("no return value specified for UpdatePendingLocalDetails") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string, func(*types.Struct) (*types.Struct, error)) error); ok { - r0 = rf(id, proc) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockObjectStore_UpdatePendingLocalDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdatePendingLocalDetails' -type MockObjectStore_UpdatePendingLocalDetails_Call struct { - *mock.Call -} - -// UpdatePendingLocalDetails is a helper method to define mock.On call -// - id string -// - proc func(*types.Struct)(*types.Struct , error) -func (_e *MockObjectStore_Expecter) UpdatePendingLocalDetails(id interface{}, proc interface{}) *MockObjectStore_UpdatePendingLocalDetails_Call { - return &MockObjectStore_UpdatePendingLocalDetails_Call{Call: _e.mock.On("UpdatePendingLocalDetails", id, proc)} -} - -func (_c *MockObjectStore_UpdatePendingLocalDetails_Call) Run(run func(id string, proc func(*types.Struct) (*types.Struct, error))) *MockObjectStore_UpdatePendingLocalDetails_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string), args[1].(func(*types.Struct) (*types.Struct, error))) - }) - return _c -} - -func (_c *MockObjectStore_UpdatePendingLocalDetails_Call) Return(_a0 error) *MockObjectStore_UpdatePendingLocalDetails_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockObjectStore_UpdatePendingLocalDetails_Call) RunAndReturn(run func(string, func(*types.Struct) (*types.Struct, error)) error) *MockObjectStore_UpdatePendingLocalDetails_Call { - _c.Call.Return(run) - return _c -} - -// NewMockObjectStore creates a new instance of MockObjectStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockObjectStore(t interface { - mock.TestingT - Cleanup(func()) -}) *MockObjectStore { - mock := &MockObjectStore{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_SourceDetailsFromID.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_SourceDetailsFromID.go deleted file mode 100644 index e1ffd2f256..0000000000 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_SourceDetailsFromID.go +++ /dev/null @@ -1,94 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_objectstore - -import ( - mock "github.com/stretchr/testify/mock" - - types "github.com/gogo/protobuf/types" -) - -// MockSourceDetailsFromID is an autogenerated mock type for the SourceDetailsFromID type -type MockSourceDetailsFromID struct { - mock.Mock -} - -type MockSourceDetailsFromID_Expecter struct { - mock *mock.Mock -} - -func (_m *MockSourceDetailsFromID) EXPECT() *MockSourceDetailsFromID_Expecter { - return &MockSourceDetailsFromID_Expecter{mock: &_m.Mock} -} - -// DetailsFromIdBasedSource provides a mock function with given fields: id -func (_m *MockSourceDetailsFromID) DetailsFromIdBasedSource(id string) (*types.Struct, error) { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for DetailsFromIdBasedSource") - } - - var r0 *types.Struct - var r1 error - if rf, ok := ret.Get(0).(func(string) (*types.Struct, error)); ok { - return rf(id) - } - if rf, ok := ret.Get(0).(func(string) *types.Struct); ok { - r0 = rf(id) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*types.Struct) - } - } - - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockSourceDetailsFromID_DetailsFromIdBasedSource_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DetailsFromIdBasedSource' -type MockSourceDetailsFromID_DetailsFromIdBasedSource_Call struct { - *mock.Call -} - -// DetailsFromIdBasedSource is a helper method to define mock.On call -// - id string -func (_e *MockSourceDetailsFromID_Expecter) DetailsFromIdBasedSource(id interface{}) *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call { - return &MockSourceDetailsFromID_DetailsFromIdBasedSource_Call{Call: _e.mock.On("DetailsFromIdBasedSource", id)} -} - -func (_c *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call) Run(run func(id string)) *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call) Return(_a0 *types.Struct, _a1 error) *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call) RunAndReturn(run func(string) (*types.Struct, error)) *MockSourceDetailsFromID_DetailsFromIdBasedSource_Call { - _c.Call.Return(run) - return _c -} - -// NewMockSourceDetailsFromID creates a new instance of MockSourceDetailsFromID. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockSourceDetailsFromID(t interface { - mock.TestingT - Cleanup(func()) -}) *MockSourceDetailsFromID { - mock := &MockSourceDetailsFromID{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/lib/localstore/objectstore/mock_objectstore/mock_VirtualSpacesStore.go b/pkg/lib/localstore/objectstore/mock_objectstore/mock_VirtualSpacesStore.go deleted file mode 100644 index 827a4389a3..0000000000 --- a/pkg/lib/localstore/objectstore/mock_objectstore/mock_VirtualSpacesStore.go +++ /dev/null @@ -1,181 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_objectstore - -import mock "github.com/stretchr/testify/mock" - -// MockVirtualSpacesStore is an autogenerated mock type for the VirtualSpacesStore type -type MockVirtualSpacesStore struct { - mock.Mock -} - -type MockVirtualSpacesStore_Expecter struct { - mock *mock.Mock -} - -func (_m *MockVirtualSpacesStore) EXPECT() *MockVirtualSpacesStore_Expecter { - return &MockVirtualSpacesStore_Expecter{mock: &_m.Mock} -} - -// DeleteVirtualSpace provides a mock function with given fields: spaceID -func (_m *MockVirtualSpacesStore) DeleteVirtualSpace(spaceID string) error { - ret := _m.Called(spaceID) - - if len(ret) == 0 { - panic("no return value specified for DeleteVirtualSpace") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(spaceID) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockVirtualSpacesStore_DeleteVirtualSpace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteVirtualSpace' -type MockVirtualSpacesStore_DeleteVirtualSpace_Call struct { - *mock.Call -} - -// DeleteVirtualSpace is a helper method to define mock.On call -// - spaceID string -func (_e *MockVirtualSpacesStore_Expecter) DeleteVirtualSpace(spaceID interface{}) *MockVirtualSpacesStore_DeleteVirtualSpace_Call { - return &MockVirtualSpacesStore_DeleteVirtualSpace_Call{Call: _e.mock.On("DeleteVirtualSpace", spaceID)} -} - -func (_c *MockVirtualSpacesStore_DeleteVirtualSpace_Call) Run(run func(spaceID string)) *MockVirtualSpacesStore_DeleteVirtualSpace_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockVirtualSpacesStore_DeleteVirtualSpace_Call) Return(_a0 error) *MockVirtualSpacesStore_DeleteVirtualSpace_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockVirtualSpacesStore_DeleteVirtualSpace_Call) RunAndReturn(run func(string) error) *MockVirtualSpacesStore_DeleteVirtualSpace_Call { - _c.Call.Return(run) - return _c -} - -// ListVirtualSpaces provides a mock function with given fields: -func (_m *MockVirtualSpacesStore) ListVirtualSpaces() ([]string, error) { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for ListVirtualSpaces") - } - - var r0 []string - var r1 error - if rf, ok := ret.Get(0).(func() ([]string, error)); ok { - return rf() - } - if rf, ok := ret.Get(0).(func() []string); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// MockVirtualSpacesStore_ListVirtualSpaces_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListVirtualSpaces' -type MockVirtualSpacesStore_ListVirtualSpaces_Call struct { - *mock.Call -} - -// ListVirtualSpaces is a helper method to define mock.On call -func (_e *MockVirtualSpacesStore_Expecter) ListVirtualSpaces() *MockVirtualSpacesStore_ListVirtualSpaces_Call { - return &MockVirtualSpacesStore_ListVirtualSpaces_Call{Call: _e.mock.On("ListVirtualSpaces")} -} - -func (_c *MockVirtualSpacesStore_ListVirtualSpaces_Call) Run(run func()) *MockVirtualSpacesStore_ListVirtualSpaces_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockVirtualSpacesStore_ListVirtualSpaces_Call) Return(_a0 []string, _a1 error) *MockVirtualSpacesStore_ListVirtualSpaces_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *MockVirtualSpacesStore_ListVirtualSpaces_Call) RunAndReturn(run func() ([]string, error)) *MockVirtualSpacesStore_ListVirtualSpaces_Call { - _c.Call.Return(run) - return _c -} - -// SaveVirtualSpace provides a mock function with given fields: id -func (_m *MockVirtualSpacesStore) SaveVirtualSpace(id string) error { - ret := _m.Called(id) - - if len(ret) == 0 { - panic("no return value specified for SaveVirtualSpace") - } - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(id) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockVirtualSpacesStore_SaveVirtualSpace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveVirtualSpace' -type MockVirtualSpacesStore_SaveVirtualSpace_Call struct { - *mock.Call -} - -// SaveVirtualSpace is a helper method to define mock.On call -// - id string -func (_e *MockVirtualSpacesStore_Expecter) SaveVirtualSpace(id interface{}) *MockVirtualSpacesStore_SaveVirtualSpace_Call { - return &MockVirtualSpacesStore_SaveVirtualSpace_Call{Call: _e.mock.On("SaveVirtualSpace", id)} -} - -func (_c *MockVirtualSpacesStore_SaveVirtualSpace_Call) Run(run func(id string)) *MockVirtualSpacesStore_SaveVirtualSpace_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(string)) - }) - return _c -} - -func (_c *MockVirtualSpacesStore_SaveVirtualSpace_Call) Return(_a0 error) *MockVirtualSpacesStore_SaveVirtualSpace_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockVirtualSpacesStore_SaveVirtualSpace_Call) RunAndReturn(run func(string) error) *MockVirtualSpacesStore_SaveVirtualSpace_Call { - _c.Call.Return(run) - return _c -} - -// NewMockVirtualSpacesStore creates a new instance of MockVirtualSpacesStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockVirtualSpacesStore(t interface { - mock.TestingT - Cleanup(func()) -}) *MockVirtualSpacesStore { - mock := &MockVirtualSpacesStore{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/pkg/lib/localstore/objectstore/objects.go b/pkg/lib/localstore/objectstore/objects.go deleted file mode 100644 index ab0c56fde0..0000000000 --- a/pkg/lib/localstore/objectstore/objects.go +++ /dev/null @@ -1,600 +0,0 @@ -package objectstore - -import ( - "context" - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "sync" - - anystore "github.com/anyproto/any-store" - "github.com/anyproto/any-sync/app" - "github.com/anyproto/any-sync/coordinator/coordinatorproto" - "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" - "golang.org/x/exp/slices" - - "github.com/anyproto/anytype-heart/core/domain" - "github.com/anyproto/anytype-heart/core/relationutils" - "github.com/anyproto/anytype-heart/core/wallet" - "github.com/anyproto/anytype-heart/pkg/lib/bundle" - "github.com/anyproto/anytype-heart/pkg/lib/database" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/oldstore" - "github.com/anyproto/anytype-heart/pkg/lib/logging" - "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - "github.com/anyproto/anytype-heart/util/pbtypes" -) - -var log = logging.Logger("anytype-localstore") - -const CName = "objectstore" - -var ( - ErrObjectNotFound = errors.New("object not found") - ErrNotAnObject = fmt.Errorf("not an object") - - _ ObjectStore = (*dsObjectStore)(nil) -) - -// nolint: interfacebloat -type ObjectStore interface { - app.ComponentRunnable - IndexerStore - AccountStore - VirtualSpacesStore - SpaceNameGetter - - SubscribeForAll(callback func(rec database.Record)) - - // Query adds implicit filters on isArchived, isDeleted and objectType relations! To avoid them use QueryRaw - Query(q database.Query) (records []database.Record, err error) - - QueryRaw(f *database.Filters, limit int, offset int) (records []database.Record, err error) - QueryByID(ids []string) (records []database.Record, err error) - QueryByIDAndSubscribeForChanges(ids []string, subscription database.Subscription) (records []database.Record, close func(), err error) - QueryObjectIDs(q database.Query) (ids []string, total int, err error) - QueryIterate(q database.Query, proc func(details *types.Struct)) error - - HasIDs(ids ...string) (exists []string, err error) - GetByIDs(spaceID string, ids []string) ([]*model.ObjectInfo, error) - List(spaceID string, includeArchived bool) ([]*model.ObjectInfo, error) - ListIds() ([]string, error) - ListIdsBySpace(spaceId string) ([]string, error) - - // UpdateObjectDetails updates existing object or create if not missing. Should be used in order to amend existing indexes based on prev/new value - // set discardLocalDetailsChanges to true in case the caller doesn't have local details in the State - UpdateObjectDetails(ctx context.Context, id string, details *types.Struct) error - UpdateObjectLinks(id string, links []string) error - UpdatePendingLocalDetails(id string, proc func(details *types.Struct) (*types.Struct, error)) error - ModifyObjectDetails(id string, proc func(details *types.Struct) (*types.Struct, bool, error)) error - - DeleteObject(id domain.FullID) error - DeleteDetails(id ...string) error - DeleteLinks(id ...string) error - - GetDetails(id string) (*model.ObjectDetails, error) - GetObjectByUniqueKey(spaceId string, uniqueKey domain.UniqueKey) (*model.ObjectDetails, error) - GetUniqueKeyById(id string) (key domain.UniqueKey, err error) - - GetInboundLinksByID(id string) ([]string, error) - GetOutboundLinksByID(id string) ([]string, error) - GetWithLinksInfoByID(spaceID string, id string) (*model.ObjectInfoWithLinks, error) - - SetActiveView(objectId, blockId, viewId string) error - SetActiveViews(objectId string, views map[string]string) error - GetActiveViews(objectId string) (map[string]string, error) - - GetRelationLink(spaceID string, key string) (*model.RelationLink, error) - FetchRelationByKey(spaceID string, key string) (relation *relationutils.Relation, err error) - FetchRelationByKeys(spaceId string, keys ...string) (relations relationutils.Relations, err error) - FetchRelationByLinks(spaceId string, links pbtypes.RelationLinks) (relations relationutils.Relations, err error) - ListAllRelations(spaceId string) (relations relationutils.Relations, err error) - GetRelationByID(id string) (relation *model.Relation, err error) - GetRelationByKey(spaceId string, key string) (*model.Relation, error) - GetRelationFormatByKey(key string) (model.RelationFormat, error) - - GetObjectType(url string) (*model.ObjectType, error) - BatchProcessFullTextQueue(ctx context.Context, limit int, processIds func(processIds []string) error) error -} - -type IndexerStore interface { - AddToIndexQueue(id string) error - ListIDsFromFullTextQueue(limit int) ([]string, error) - RemoveIDsFromFullTextQueue(ids []string) error - FTSearch() ftsearch.FTSearch - GetGlobalChecksums() (checksums *model.ObjectStoreChecksums, err error) - - // GetChecksums Used to get information about localstore state and decide do we need to reindex some objects - GetChecksums(spaceID string) (checksums *model.ObjectStoreChecksums, err error) - // SaveChecksums Used to save checksums and force reindex counter - SaveChecksums(spaceID string, checksums *model.ObjectStoreChecksums) (err error) - - GetLastIndexedHeadsHash(id string) (headsHash string, err error) - SaveLastIndexedHeadsHash(id string, headsHash string) (err error) -} - -type AccountStore interface { - GetAccountStatus() (status *coordinatorproto.SpaceStatusPayload, err error) - SaveAccountStatus(status *coordinatorproto.SpaceStatusPayload) (err error) -} - -type VirtualSpacesStore interface { - SaveVirtualSpace(id string) error - ListVirtualSpaces() ([]string, error) - DeleteVirtualSpace(spaceID string) error -} - -type configProvider interface { - GetAnyStoreConfig() *anystore.Config -} - -type dsObjectStore struct { - oldStore oldstore.Service - - repoPath string - anyStoreConfig *anystore.Config - sourceService SourceDetailsFromID - anyStore anystore.DB - objects anystore.Collection - fulltextQueue anystore.Collection - links anystore.Collection - headsState anystore.Collection - system anystore.Collection - activeViews anystore.Collection - indexerChecksums anystore.Collection - virtualSpaces anystore.Collection - pendingDetails anystore.Collection - - arenaPool *fastjson.ArenaPool - - fts ftsearch.FTSearch - - sync.RWMutex - onChangeCallback func(record database.Record) - subscriptions []database.Subscription - onLinksUpdateCallback func(info LinksUpdateInfo) - - componentCtx context.Context - componentCtxCancel context.CancelFunc -} - -func New() ObjectStore { - ctx, cancel := context.WithCancel(context.Background()) - return &dsObjectStore{ - componentCtx: ctx, - componentCtxCancel: cancel, - } -} - -type SourceDetailsFromID interface { - DetailsFromIdBasedSource(id string) (*types.Struct, error) -} - -func (s *dsObjectStore) Init(a *app.App) (err error) { - src := a.Component("source") - if src != nil { - s.sourceService = a.MustComponent("source").(SourceDetailsFromID) - } - fts := a.Component(ftsearch.CName) - if fts == nil { - log.Warnf("init objectstore without fulltext") - } else { - s.fts = fts.(ftsearch.FTSearch) - } - s.arenaPool = &fastjson.ArenaPool{} - s.repoPath = app.MustComponent[wallet.Wallet](a).RepoPath() - s.anyStoreConfig = app.MustComponent[configProvider](a).GetAnyStoreConfig() - s.oldStore = app.MustComponent[oldstore.Service](a) - - return nil -} - -func (s *dsObjectStore) Name() (name string) { - return CName -} - -func (s *dsObjectStore) Run(ctx context.Context) error { - dbDir := filepath.Join(s.repoPath, "objectstore") - _, err := os.Stat(dbDir) - if errors.Is(err, os.ErrNotExist) { - err = os.MkdirAll(dbDir, 0700) - if err != nil { - return fmt.Errorf("create db dir: %w", err) - } - } - return s.runDatabase(ctx, filepath.Join(dbDir, "objects.db")) -} - -func (s *dsObjectStore) runDatabase(ctx context.Context, path string) error { - store, err := anystore.Open(ctx, path, s.anyStoreConfig) - if err != nil { - return fmt.Errorf("open database: %w", err) - } - objects, err := store.Collection(ctx, "objects") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open objects collection: %w", err)) - } - fulltextQueue, err := store.Collection(ctx, "fulltext_queue") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open fulltextQueue collection: %w", err)) - } - links, err := store.Collection(ctx, "links") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open links collection: %w", err)) - } - headsState, err := store.Collection(ctx, "headsState") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open headsState collection: %w", err)) - } - system, err := store.Collection(ctx, "system") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open system collection: %w", err)) - } - activeViews, err := store.Collection(ctx, "activeViews") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open activeViews collection: %w", err)) - } - indexerChecksums, err := store.Collection(ctx, "indexerChecksums") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open indexerChecksums collection: %w", err)) - } - virtualSpaces, err := store.Collection(ctx, "virtualSpaces") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open virtualSpaces collection: %w", err)) - } - pendingDetails, err := store.Collection(ctx, "pendingDetails") - if err != nil { - return errors.Join(store.Close(), fmt.Errorf("open pendingDetails collection: %w", err)) - } - s.anyStore = store - - objectIndexes := []anystore.IndexInfo{ - { - Name: "uniqueKey", - Fields: []string{bundle.RelationKeyUniqueKey.String()}, - }, - { - Name: "source", - Fields: []string{bundle.RelationKeySource.String()}, - }, - { - Name: "layout", - Fields: []string{bundle.RelationKeyLayout.String()}, - }, - { - Name: "type", - Fields: []string{bundle.RelationKeyType.String()}, - }, - { - Name: "relationKey", - Fields: []string{bundle.RelationKeyRelationKey.String()}, - }, - { - Name: "lastModifiedDate", - Fields: []string{bundle.RelationKeyLastModifiedDate.String()}, - }, - { - Name: "fileId", - Fields: []string{bundle.RelationKeyFileId.String()}, - Sparse: true, - }, - { - Name: "oldAnytypeID", - Fields: []string{bundle.RelationKeyOldAnytypeID.String()}, - Sparse: true, - }, - } - err = s.addIndexes(ctx, objects, objectIndexes) - if err != nil { - log.Errorf("ensure object indexes: %s", err) - } - - linksIndexes := []anystore.IndexInfo{ - { - Name: linkOutboundField, - Fields: []string{linkOutboundField}, - }, - } - err = s.addIndexes(ctx, links, linksIndexes) - if err != nil { - log.Errorf("ensure links indexes: %s", err) - } - - s.objects = objects - s.fulltextQueue = fulltextQueue - s.links = links - s.headsState = headsState - s.system = system - s.activeViews = activeViews - s.indexerChecksums = indexerChecksums - s.virtualSpaces = virtualSpaces - s.pendingDetails = pendingDetails - - return nil -} - -func (s *dsObjectStore) addIndexes(ctx context.Context, coll anystore.Collection, indexes []anystore.IndexInfo) error { - gotIndexes := coll.GetIndexes() - toCreate := indexes[:0] - var toDrop []string - for _, idx := range indexes { - if !slices.ContainsFunc(gotIndexes, func(i anystore.Index) bool { - return i.Info().Name == idx.Name - }) { - toCreate = append(toCreate, idx) - } - } - for _, idx := range gotIndexes { - if !slices.ContainsFunc(indexes, func(i anystore.IndexInfo) bool { - return i.Name == idx.Info().Name - }) { - toDrop = append(toDrop, idx.Info().Name) - } - } - if len(toDrop) > 0 { - for _, indexName := range toDrop { - if err := coll.DropIndex(ctx, indexName); err != nil { - return err - } - } - } - return coll.EnsureIndex(ctx, toCreate...) -} - -func (s *dsObjectStore) WriteTx(ctx context.Context) (anystore.WriteTx, error) { - return s.anyStore.WriteTx(ctx) -} - -func (s *dsObjectStore) Close(_ context.Context) (err error) { - s.componentCtxCancel() - if s.objects != nil { - err = errors.Join(err, s.objects.Close()) - } - // TODO Close collections - if s.anyStore != nil { - err = errors.Join(err, s.anyStore.Close()) - } - return err -} - -// unsafe, use under mutex -func (s *dsObjectStore) addSubscriptionIfNotExists(sub database.Subscription) (existed bool) { - for _, s := range s.subscriptions { - if s == sub { - return true - } - } - - s.subscriptions = append(s.subscriptions, sub) - return false -} - -func (s *dsObjectStore) closeAndRemoveSubscription(subscription database.Subscription) { - s.Lock() - defer s.Unlock() - subscription.Close() - - for i, sub := range s.subscriptions { - if sub == subscription { - s.subscriptions = append(s.subscriptions[:i], s.subscriptions[i+1:]...) - break - } - } -} - -func (s *dsObjectStore) SubscribeForAll(callback func(rec database.Record)) { - s.Lock() - s.onChangeCallback = callback - s.Unlock() -} - -// GetDetails returns empty struct without errors in case details are not found -// todo: get rid of this or change the name method! -func (s *dsObjectStore) GetDetails(id string) (*model.ObjectDetails, error) { - doc, err := s.objects.FindId(s.componentCtx, id) - if errors.Is(err, anystore.ErrDocNotFound) { - return &model.ObjectDetails{ - Details: &types.Struct{Fields: map[string]*types.Value{}}, - }, nil - } - if err != nil { - return nil, fmt.Errorf("find by id: %w", err) - } - details, err := pbtypes.JsonToProto(doc.Value()) - if err != nil { - return nil, fmt.Errorf("unmarshal details: %w", err) - } - return &model.ObjectDetails{ - Details: details, - }, nil -} - -func (s *dsObjectStore) GetUniqueKeyById(id string) (domain.UniqueKey, error) { - details, err := s.GetDetails(id) - if err != nil { - return nil, err - } - rawUniqueKey := pbtypes.GetString(details.Details, bundle.RelationKeyUniqueKey.String()) - if rawUniqueKey == "" { - return nil, fmt.Errorf("object does not have unique key in details") - } - return domain.UnmarshalUniqueKey(rawUniqueKey) -} - -func (s *dsObjectStore) List(spaceID string, includeArchived bool) ([]*model.ObjectInfo, error) { - var filters []*model.BlockContentDataviewFilter - if spaceID != "" { - filters = append(filters, &model.BlockContentDataviewFilter{ - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceID), - }) - } - if includeArchived { - filters = append(filters, &model.BlockContentDataviewFilter{ - RelationKey: bundle.RelationKeyIsArchived.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.Bool(true), - }) - } - ids, _, err := s.QueryObjectIDs(database.Query{ - Filters: filters, - }) - if err != nil { - return nil, fmt.Errorf("query object ids: %w", err) - } - return s.GetByIDs(spaceID, ids) -} - -func (s *dsObjectStore) HasIDs(ids ...string) (exists []string, err error) { - for _, id := range ids { - _, err := s.objects.FindId(s.componentCtx, id) - if err != nil && !errors.Is(err, anystore.ErrDocNotFound) { - return nil, fmt.Errorf("get %s: %w", id, err) - } - if err == nil { - exists = append(exists, id) - } - } - return exists, err -} - -func (s *dsObjectStore) GetByIDs(spaceID string, ids []string) ([]*model.ObjectInfo, error) { - return s.getObjectsInfo(s.componentCtx, spaceID, ids) -} - -func (s *dsObjectStore) ListIdsBySpace(spaceId string) ([]string, error) { - ids, _, err := s.QueryObjectIDs(database.Query{ - Filters: []*model.BlockContentDataviewFilter{ - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, - }, - }) - return ids, err -} - -func (s *dsObjectStore) ListIds() ([]string, error) { - var ids []string - iter, err := s.objects.Find(nil).Iter(s.componentCtx) - if err != nil { - return nil, fmt.Errorf("find all: %w", err) - } - for iter.Next() { - doc, err := iter.Doc() - if err != nil { - return nil, errors.Join(fmt.Errorf("get doc: %w", err), iter.Close()) - } - id := doc.Value().GetStringBytes("id") - ids = append(ids, string(id)) - } - err = iter.Err() - if err != nil { - return nil, errors.Join(fmt.Errorf("iterate: %w", err), iter.Close()) - } - return ids, iter.Close() -} - -// TODO objstore: Just use dependency injection -func (s *dsObjectStore) FTSearch() ftsearch.FTSearch { - return s.fts -} - -func (s *dsObjectStore) getObjectInfo(ctx context.Context, spaceID string, id string) (*model.ObjectInfo, error) { - details, err := s.sourceService.DetailsFromIdBasedSource(id) - if err == nil { - details.Fields[database.RecordIDField] = pbtypes.ToValue(id) - return &model.ObjectInfo{ - Id: id, - Details: details, - }, nil - } - - doc, err := s.objects.FindId(ctx, id) - if err != nil { - return nil, fmt.Errorf("find by id: %w", err) - } - details, err = pbtypes.JsonToProto(doc.Value()) - if err != nil { - return nil, fmt.Errorf("unmarshal details: %w", err) - } - snippet := pbtypes.GetString(details, bundle.RelationKeySnippet.String()) - - return &model.ObjectInfo{ - Id: id, - Details: details, - Snippet: snippet, - }, nil -} - -func (s *dsObjectStore) getObjectsInfo(ctx context.Context, spaceID string, ids []string) ([]*model.ObjectInfo, error) { - objects := make([]*model.ObjectInfo, 0, len(ids)) - for _, id := range ids { - info, err := s.getObjectInfo(ctx, spaceID, id) - if err != nil { - if errors.Is(err, anystore.ErrDocNotFound) || errors.Is(err, ErrObjectNotFound) || errors.Is(err, ErrNotAnObject) { - continue - } - return nil, err - } - if f := info.GetDetails().GetFields(); f != nil { - // skip deleted objects - if v := f[bundle.RelationKeyIsDeleted.String()]; v != nil && v.GetBoolValue() { - continue - } - } - objects = append(objects, info) - } - - return objects, nil -} - -func (s *dsObjectStore) GetObjectByUniqueKey(spaceId string, uniqueKey domain.UniqueKey) (*model.ObjectDetails, error) { - records, err := s.Query(database.Query{ - Filters: []*model.BlockContentDataviewFilter{ - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeyUniqueKey.String(), - Value: pbtypes.String(uniqueKey.Marshal()), - }, - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceId), - }, - }, - Limit: 2, - }) - if err != nil { - return nil, err - } - - if len(records) == 0 { - return nil, ErrObjectNotFound - } - - if len(records) > 1 { - // should never happen - return nil, fmt.Errorf("multiple objects with unique key %s", uniqueKey) - } - - return &model.ObjectDetails{Details: records[0].Details}, nil -} - -func extractIdFromKey(key string) (id string) { - i := strings.LastIndexByte(key, '/') - if i == -1 || len(key)-1 == i { - return - } - return key[i+1:] -} - -// bytesToString unmarshalls bytes to string -func bytesToString(b []byte) (string, error) { - return string(b), nil -} diff --git a/pkg/lib/localstore/objectstore/service.go b/pkg/lib/localstore/objectstore/service.go new file mode 100644 index 0000000000..7a6f0b8e79 --- /dev/null +++ b/pkg/lib/localstore/objectstore/service.go @@ -0,0 +1,386 @@ +package objectstore + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "sync" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/coordinator/coordinatorproto" + + "github.com/anyproto/anytype-heart/core/wallet" + "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/anystorehelper" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/oldstore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/spaceindex" + "github.com/anyproto/anytype-heart/pkg/lib/logging" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +var log = logging.Logger("anytype-localstore") + +const CName = "objectstore" + +var ( + _ ObjectStore = (*dsObjectStore)(nil) +) + +type CrossSpace interface { + QueryCrossSpace(q database.Query) (records []database.Record, err error) + QueryRawCrossSpace(f *database.Filters, limit int, offset int) (records []database.Record, err error) + QueryByIdCrossSpace(ids []string) (records []database.Record, err error) + + ListIdsCrossSpace() ([]string, error) + BatchProcessFullTextQueue(ctx context.Context, limit int, processIds func(processIds []string) error) error + + AccountStore + VirtualSpacesStore + IndexerStore +} + +type ObjectStore interface { + app.ComponentRunnable + + SpaceIndex(spaceId string) spaceindex.Store + GetCrdtDb(spaceId string) anystore.DB + + SpaceNameGetter + CrossSpace +} + +type IndexerStore interface { + AddToIndexQueue(ctx context.Context, id ...string) error + ListIdsFromFullTextQueue(limit int) ([]string, error) + RemoveIdsFromFullTextQueue(ids []string) error + GetGlobalChecksums() (checksums *model.ObjectStoreChecksums, err error) + + // GetChecksums Used to get information about localstore state and decide do we need to reindex some objects + GetChecksums(spaceID string) (checksums *model.ObjectStoreChecksums, err error) + // SaveChecksums Used to save checksums and force reindex counter + SaveChecksums(spaceID string, checksums *model.ObjectStoreChecksums) (err error) +} + +type AccountStore interface { + GetAccountStatus() (status *coordinatorproto.SpaceStatusPayload, err error) + SaveAccountStatus(status *coordinatorproto.SpaceStatusPayload) (err error) +} + +type VirtualSpacesStore interface { + SaveVirtualSpace(id string) error + ListVirtualSpaces() ([]string, error) + DeleteVirtualSpace(spaceID string) error +} + +type configProvider interface { + GetAnyStoreConfig() *anystore.Config +} + +type TechSpaceIdProvider interface { + TechSpaceId() string +} + +type dsObjectStore struct { + repoPath string + techSpaceId string + anyStoreConfig anystore.Config + + anyStore anystore.DB + anyStoreLockRemove func() error + + indexerChecksums anystore.Collection + virtualSpaces anystore.Collection + system anystore.Collection + fulltextQueue anystore.Collection + + arenaPool *anyenc.ArenaPool + + fts ftsearch.FTSearch + subManager *spaceindex.SubscriptionManager + sourceService spaceindex.SourceDetailsFromID + oldStore oldstore.Service + techSpaceIdProvider TechSpaceIdProvider + + sync.Mutex + spaceIndexes map[string]spaceindex.Store + spaceStoreDirsCheck sync.Once + + crtdStoreLock sync.Mutex + crdtDbs map[string]anystore.DB + + componentCtx context.Context + componentCtxCancel context.CancelFunc +} + +func New() ObjectStore { + ctx, cancel := context.WithCancel(context.Background()) + return &dsObjectStore{ + componentCtx: ctx, + componentCtxCancel: cancel, + subManager: &spaceindex.SubscriptionManager{}, + spaceIndexes: map[string]spaceindex.Store{}, + crdtDbs: map[string]anystore.DB{}, + } +} + +func (s *dsObjectStore) Init(a *app.App) (err error) { + s.sourceService = app.MustComponent[spaceindex.SourceDetailsFromID](a) + fts := a.Component(ftsearch.CName) + if fts == nil { + log.Warnf("init objectstore without fulltext") + } else { + s.fts = fts.(ftsearch.FTSearch) + } + s.arenaPool = &anyenc.ArenaPool{} + s.repoPath = app.MustComponent[wallet.Wallet](a).RepoPath() + s.anyStoreConfig = *app.MustComponent[configProvider](a).GetAnyStoreConfig() + s.setDefaultConfig() + s.oldStore = app.MustComponent[oldstore.Service](a) + s.techSpaceIdProvider = app.MustComponent[TechSpaceIdProvider](a) + + return nil +} + +func (s *dsObjectStore) Name() (name string) { + return CName +} + +func (s *dsObjectStore) Run(ctx context.Context) error { + s.techSpaceId = s.techSpaceIdProvider.TechSpaceId() + + dbDir := s.storeRootDir() + err := ensureDirExists(dbDir) + if err != nil { + return err + } + return s.openDatabase(ctx, filepath.Join(dbDir, "objects.db")) +} + +func (s *dsObjectStore) setDefaultConfig() { + if s.anyStoreConfig.SQLiteConnectionOptions == nil { + s.anyStoreConfig.SQLiteConnectionOptions = map[string]string{} + } + + s.anyStoreConfig.SQLiteConnectionOptions["synchronous"] = "off" +} + +func (s *dsObjectStore) storeRootDir() string { + return filepath.Join(s.repoPath, "objectstore") +} + +func ensureDirExists(dir string) error { + _, err := os.Stat(dir) + if errors.Is(err, os.ErrNotExist) { + err = os.MkdirAll(dir, 0700) + if err != nil { + return fmt.Errorf("create db dir: %w", err) + } + } + return nil +} + +func (s *dsObjectStore) openDatabase(ctx context.Context, path string) error { + store, lockRemove, err := anystorehelper.OpenDatabaseWithLockCheck(ctx, path, &s.anyStoreConfig) + if err != nil { + return fmt.Errorf("open database: %w", err) + } + fulltextQueue, err := store.Collection(ctx, "fulltext_queue") + if err != nil { + return errors.Join(store.Close(), fmt.Errorf("open fulltextQueue collection: %w", err)) + } + system, err := store.Collection(ctx, "system") + if err != nil { + return errors.Join(store.Close(), fmt.Errorf("open system collection: %w", err)) + } + indexerChecksums, err := store.Collection(ctx, "indexerChecksums") + if err != nil { + return errors.Join(store.Close(), fmt.Errorf("open indexerChecksums collection: %w", err)) + } + virtualSpaces, err := store.Collection(ctx, "virtualSpaces") + if err != nil { + return errors.Join(store.Close(), fmt.Errorf("open virtualSpaces collection: %w", err)) + } + + s.anyStore = store + s.anyStoreLockRemove = lockRemove + + s.fulltextQueue = fulltextQueue + s.system = system + s.indexerChecksums = indexerChecksums + s.virtualSpaces = virtualSpaces + + return nil +} + +// preloadExistingObjectStores loads all existing object stores from the filesystem +// this makes sense to do because spaces register themselves in the object store asynchronously and we may want to know the list before that +func (s *dsObjectStore) preloadExistingObjectStores() error { + var err error + s.spaceStoreDirsCheck.Do(func() { + var entries []os.DirEntry + entries, err = os.ReadDir(s.storeRootDir()) + s.Lock() + defer s.Unlock() + for _, entry := range entries { + if entry.IsDir() { + spaceId := entry.Name() + _ = s.getOrInitSpaceIndex(spaceId) + } + } + }) + return err +} + +func (s *dsObjectStore) Close(_ context.Context) (err error) { + s.componentCtxCancel() + if s.anyStore != nil { + err = errors.Join(err, s.anyStore.Close(), s.anyStoreLockRemove()) + } + + s.Lock() + // close in parallel + closeChan := make(chan error, len(s.spaceIndexes)) + for spaceId, store := range s.spaceIndexes { + go func(spaceId string, store spaceindex.Store) { + closeChan <- store.Close() + }(spaceId, store) + } + for i := 0; i < len(s.spaceIndexes); i++ { + err = errors.Join(err, <-closeChan) + } + s.spaceIndexes = map[string]spaceindex.Store{} + s.Unlock() + + s.crtdStoreLock.Lock() + closeChan = make(chan error, len(s.crdtDbs)) + for spaceId, store := range s.crdtDbs { + go func(spaceId string, store anystore.DB) { + closeChan <- store.Close() + }(spaceId, store) + } + for i := 0; i < len(s.crdtDbs); i++ { + err = errors.Join(err, <-closeChan) + } + s.crdtDbs = map[string]anystore.DB{} + s.crtdStoreLock.Unlock() + + return err +} + +func (s *dsObjectStore) SpaceIndex(spaceId string) spaceindex.Store { + if spaceId == "" { + return spaceindex.NewInvalidStore(errors.New("empty spaceId")) + } + s.Lock() + defer s.Unlock() + + return s.getOrInitSpaceIndex(spaceId) +} + +func (s *dsObjectStore) getOrInitSpaceIndex(spaceId string) spaceindex.Store { + store, ok := s.spaceIndexes[spaceId] + if !ok { + dir := filepath.Join(s.storeRootDir(), spaceId) + err := ensureDirExists(dir) + if err != nil { + return spaceindex.NewInvalidStore(err) + } + store = spaceindex.New(s.componentCtx, spaceId, spaceindex.Deps{ + AnyStoreConfig: &s.anyStoreConfig, + SourceService: s.sourceService, + OldStore: s.oldStore, + Fts: s.fts, + SubManager: s.subManager, + DbPath: filepath.Join(dir, "objects.db"), + FulltextQueue: s, + }) + s.spaceIndexes[spaceId] = store + } + return store +} + +func (s *dsObjectStore) GetCrdtDb(spaceId string) anystore.DB { + s.crtdStoreLock.Lock() + defer s.crtdStoreLock.Unlock() + + db, ok := s.crdtDbs[spaceId] + if !ok { + dir := filepath.Join(s.storeRootDir(), spaceId) + err := ensureDirExists(dir) + if err != nil { + return nil + } + path := filepath.Join(dir, "crdt.db") + db, err = anystore.Open(s.componentCtx, path, &s.anyStoreConfig) + if errors.Is(err, anystore.ErrIncompatibleVersion) { + _ = os.RemoveAll(path) + db, err = anystore.Open(s.componentCtx, path, &s.anyStoreConfig) + } + if err != nil { + return nil + } + s.crdtDbs[spaceId] = db + } + return db +} + +func (s *dsObjectStore) listStores() []spaceindex.Store { + err := s.preloadExistingObjectStores() + if err != nil { + log.Errorf("preloadExistingObjectStores: %v", err) + } + s.Lock() + stores := make([]spaceindex.Store, 0, len(s.spaceIndexes)) + for _, store := range s.spaceIndexes { + stores = append(stores, store) + } + s.Unlock() + return stores +} + +func collectCrossSpace[T any](s *dsObjectStore, proc func(store spaceindex.Store) ([]T, error)) ([]T, error) { + stores := s.listStores() + + var result []T + for _, store := range stores { + items, err := proc(store) + if err != nil { + return nil, err + } + result = append(result, items...) + } + return result, nil +} + +func (s *dsObjectStore) ListIdsCrossSpace() ([]string, error) { + return collectCrossSpace(s, func(store spaceindex.Store) ([]string, error) { + return store.ListIds() + }) +} + +func (s *dsObjectStore) QueryByIdCrossSpace(ids []string) ([]database.Record, error) { + return collectCrossSpace(s, func(store spaceindex.Store) ([]database.Record, error) { + return store.QueryByIds(ids) + }) +} + +func (s *dsObjectStore) QueryCrossSpace(q database.Query) ([]database.Record, error) { + return collectCrossSpace(s, func(store spaceindex.Store) ([]database.Record, error) { + return store.Query(q) + }) +} + +func (s *dsObjectStore) QueryRawCrossSpace(filters *database.Filters, limit int, offset int) ([]database.Record, error) { + return collectCrossSpace(s, func(store spaceindex.Store) ([]database.Record, error) { + return store.QueryRaw(filters, limit, offset) + }) +} + +func (s *dsObjectStore) SubscribeLinksUpdate(callback func(info spaceindex.LinksUpdateInfo)) { + s.subManager.SubscribeLinksUpdate(callback) +} diff --git a/pkg/lib/localstore/objectstore/space.go b/pkg/lib/localstore/objectstore/space.go index 23659c9ccc..f48cecdc21 100644 --- a/pkg/lib/localstore/objectstore/space.go +++ b/pkg/lib/localstore/objectstore/space.go @@ -12,7 +12,7 @@ type SpaceNameGetter interface { } func (d *dsObjectStore) GetSpaceName(spaceId string) string { - records, err := d.Query(database.Query{ + records, err := d.SpaceIndex(d.techSpaceId).Query(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyTargetSpaceId.String(), diff --git a/pkg/lib/localstore/objectstore/space_test.go b/pkg/lib/localstore/objectstore/space_test.go index 15a684601f..baec18b81d 100644 --- a/pkg/lib/localstore/objectstore/space_test.go +++ b/pkg/lib/localstore/objectstore/space_test.go @@ -32,7 +32,7 @@ func TestGetSpaceName(t *testing.T) { // given s := NewStoreFixture(t) - err := s.UpdateObjectDetails(context.Background(), spaceViewId, &types.Struct{Fields: map[string]*types.Value{ + err := s.SpaceIndex(s.techSpaceId).UpdateObjectDetails(context.Background(), spaceViewId, &types.Struct{Fields: map[string]*types.Value{ bundle.RelationKeyId.String(): pbtypes.String(spaceViewId), bundle.RelationKeyLayout.String(): pbtypes.Int64(int64(model.ObjectType_spaceView)), bundle.RelationKeyTargetSpaceId.String(): pbtypes.String(spaceId), @@ -51,7 +51,7 @@ func TestGetSpaceName(t *testing.T) { // given s := NewStoreFixture(t) - err := s.UpdateObjectDetails(context.Background(), spaceViewId, &types.Struct{Fields: map[string]*types.Value{ + err := s.SpaceIndex(s.techSpaceId).UpdateObjectDetails(context.Background(), spaceViewId, &types.Struct{Fields: map[string]*types.Value{ bundle.RelationKeyId.String(): pbtypes.String(spaceViewId), bundle.RelationKeyLayout.String(): pbtypes.Int64(int64(model.ObjectType_spaceView)), bundle.RelationKeyTargetSpaceId.String(): pbtypes.String(spaceId), diff --git a/pkg/lib/localstore/objectstore/activeview.go b/pkg/lib/localstore/objectstore/spaceindex/activeview.go similarity index 77% rename from pkg/lib/localstore/objectstore/activeview.go rename to pkg/lib/localstore/objectstore/spaceindex/activeview.go index ed6a142b3d..ada9506b11 100644 --- a/pkg/lib/localstore/objectstore/activeview.go +++ b/pkg/lib/localstore/objectstore/spaceindex/activeview.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "encoding/json" @@ -6,6 +6,7 @@ import ( "fmt" anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" ) // SetActiveViews accepts map of active views by blocks, as objects can handle multiple dataview blocks @@ -20,7 +21,7 @@ func (s *dsObjectStore) SetActiveViews(objectId string, views map[string]string) if err != nil { return err } - _, err = s.activeViews.UpsertOne(s.componentCtx, it) + err = s.activeViews.UpsertOne(s.componentCtx, it) return err } @@ -51,3 +52,15 @@ func (s *dsObjectStore) GetActiveViews(objectId string) (map[string]string, erro err = json.Unmarshal(val, &views) return views, err } + +func keyValueItem(arena *anyenc.Arena, key string, value any) (*anyenc.Value, error) { + raw, err := json.Marshal(value) + if err != nil { + return nil, err + } + + obj := arena.NewObject() + obj.Set("id", arena.NewString(key)) + obj.Set("value", arena.NewStringBytes(raw)) + return obj, nil +} diff --git a/pkg/lib/localstore/objectstore/spaceindex/activeview_test.go b/pkg/lib/localstore/objectstore/spaceindex/activeview_test.go new file mode 100644 index 0000000000..2d41d91ba7 --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/activeview_test.go @@ -0,0 +1 @@ +package spaceindex diff --git a/pkg/lib/localstore/objectstore/delete.go b/pkg/lib/localstore/objectstore/spaceindex/delete.go similarity index 66% rename from pkg/lib/localstore/objectstore/delete.go rename to pkg/lib/localstore/objectstore/spaceindex/delete.go index 321d25c52c..711e60caa7 100644 --- a/pkg/lib/localstore/objectstore/delete.go +++ b/pkg/lib/localstore/objectstore/spaceindex/delete.go @@ -1,7 +1,6 @@ -package objectstore +package spaceindex import ( - "bytes" "context" "errors" "fmt" @@ -9,13 +8,12 @@ import ( anystore "github.com/anyproto/any-store" "github.com/gogo/protobuf/types" - "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/util/pbtypes" ) -func (s *dsObjectStore) DeleteDetails(ids ...string) error { - txn, err := s.anyStore.WriteTx(s.componentCtx) +func (s *dsObjectStore) DeleteDetails(ctx context.Context, ids []string) error { + txn, err := s.db.WriteTx(ctx) if err != nil { return fmt.Errorf("write txn: %w", err) } @@ -34,8 +32,8 @@ func (s *dsObjectStore) DeleteDetails(ids ...string) error { } // DeleteObject removes all details, leaving only id and isDeleted -func (s *dsObjectStore) DeleteObject(id domain.FullID) error { - txn, err := s.anyStore.WriteTx(s.componentCtx) +func (s *dsObjectStore) DeleteObject(id string) error { + txn, err := s.db.WriteTx(s.componentCtx) if err != nil { return fmt.Errorf("write txn: %w", err) } @@ -43,26 +41,26 @@ func (s *dsObjectStore) DeleteObject(id domain.FullID) error { return errors.Join(txn.Rollback(), err) } // do not completely remove object details, so we can distinguish links to deleted and not-yet-loaded objects - err = s.UpdateObjectDetails(txn.Context(), id.ObjectID, &types.Struct{ + err = s.UpdateObjectDetails(txn.Context(), id, &types.Struct{ Fields: map[string]*types.Value{ - bundle.RelationKeyId.String(): pbtypes.String(id.ObjectID), - bundle.RelationKeySpaceId.String(): pbtypes.String(id.SpaceID), + bundle.RelationKeyId.String(): pbtypes.String(id), + bundle.RelationKeySpaceId.String(): pbtypes.String(s.spaceId), bundle.RelationKeyIsDeleted.String(): pbtypes.Bool(true), // maybe we can store the date instead? }, }) if err != nil { return rollback(fmt.Errorf("failed to overwrite details and relations: %w", err)) } - err = s.fulltextQueue.DeleteId(txn.Context(), id.ObjectID) - if err != nil && !errors.Is(err, anystore.ErrDocNotFound) { + err = s.fulltextQueue.RemoveIdsFromFullTextQueue([]string{id}) + if err != nil { return rollback(fmt.Errorf("delete: fulltext queue: %w", err)) } - err = s.headsState.DeleteId(txn.Context(), id.ObjectID) + err = s.headsState.DeleteId(txn.Context(), id) if err != nil && !errors.Is(err, anystore.ErrDocNotFound) { return rollback(fmt.Errorf("delete: heads state: %w", err)) } - err = s.eraseLinksForObject(txn.Context(), id.ObjectID) + err = s.eraseLinksForObject(txn.Context(), id) if err != nil { return rollback(err) } @@ -71,15 +69,13 @@ func (s *dsObjectStore) DeleteObject(id domain.FullID) error { return fmt.Errorf("delete object info: %w", err) } - if s.fts != nil { - if err := s.fts.DeleteObject(id.ObjectID); err != nil { - return err - } + if err := s.fts.DeleteObject(id); err != nil { + return err } return nil } -func (s *dsObjectStore) DeleteLinks(ids ...string) error { +func (s *dsObjectStore) DeleteLinks(ids []string) error { txn, err := s.links.WriteTx(s.componentCtx) if err != nil { return fmt.Errorf("read txn: %w", err) @@ -93,14 +89,6 @@ func (s *dsObjectStore) DeleteLinks(ids ...string) error { return txn.Commit() } -func getLastPartOfKey(key []byte) string { - lastSlashIdx := bytes.LastIndexByte(key, '/') - if lastSlashIdx == -1 { - return string(key) - } - return string(key[lastSlashIdx+1:]) -} - func (s *dsObjectStore) eraseLinksForObject(ctx context.Context, from string) error { err := s.links.DeleteId(ctx, from) if err != nil && !errors.Is(err, anystore.ErrDocNotFound) { diff --git a/pkg/lib/localstore/objectstore/spaceindex/fixture.go b/pkg/lib/localstore/objectstore/spaceindex/fixture.go new file mode 100644 index 0000000000..b3acb6bb7f --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/fixture.go @@ -0,0 +1,160 @@ +package spaceindex + +import ( + "context" + "fmt" + "math/rand" + "path/filepath" + "sync" + "testing" + + "github.com/anyproto/any-sync/app" + "github.com/gogo/protobuf/types" + "github.com/samber/lo" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/wallet" + "github.com/anyproto/anytype-heart/core/wallet/mock_wallet" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/datastore" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/oldstore" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +var ctx = context.Background() + +type StoreFixture struct { + *dsObjectStore +} + +const spaceName = "space1" + +type detailsFromId struct { +} + +func (d *detailsFromId) DetailsFromIdBasedSource(id string) (*types.Struct, error) { + return nil, fmt.Errorf("not found") +} + +type dummyFulltextQueue struct { + lock sync.Mutex + ids []string +} + +func (q *dummyFulltextQueue) RemoveIdsFromFullTextQueue(ids []string) error { + q.lock.Lock() + defer q.lock.Unlock() + q.ids = lo.Without(q.ids, ids...) + return nil +} + +func (q *dummyFulltextQueue) AddToIndexQueue(ctx context.Context, ids ...string) error { + q.lock.Lock() + defer q.lock.Unlock() + for _, id := range ids { + if !lo.Contains(q.ids, id) { + q.ids = append(q.ids, id) + } + } + return nil +} + +func (q *dummyFulltextQueue) ListIdsFromFullTextQueue(limit int) ([]string, error) { + q.lock.Lock() + defer q.lock.Unlock() + + if limit > len(q.ids) { + limit = len(q.ids) + } + return q.ids[:limit], nil +} + +func NewStoreFixture(t testing.TB) *StoreFixture { + walletService := mock_wallet.NewMockWallet(t) + walletService.EXPECT().Name().Return(wallet.CName).Maybe() + walletService.EXPECT().RepoPath().Return(t.TempDir()) + + fullText := ftsearch.TantivyNew() + testApp := &app.App{} + + dataStore, err := datastore.NewInMemory() + require.NoError(t, err) + + testApp.Register(dataStore) + testApp.Register(walletService) + err = fullText.Init(testApp) + require.NoError(t, err) + err = fullText.Run(context.Background()) + require.NoError(t, err) + + oldStore := oldstore.New() + err = oldStore.Init(testApp) + require.NoError(t, err) + + s := New(context.Background(), "test", Deps{ + DbPath: filepath.Join(t.TempDir(), "test.db"), + Fts: fullText, + OldStore: oldStore, + SourceService: &detailsFromId{}, + SubManager: &SubscriptionManager{}, + AnyStoreConfig: nil, + FulltextQueue: &dummyFulltextQueue{}, + }) + return &StoreFixture{ + dsObjectStore: s.(*dsObjectStore), + } +} + +type TestObject map[domain.RelationKey]*types.Value + +func (o TestObject) Id() string { + return o[bundle.RelationKeyId].GetStringValue() +} + +func (o TestObject) Details() *types.Struct { + return makeDetails(o) +} + +func generateObjectWithRandomID() TestObject { + id := fmt.Sprintf("%d", rand.Int()) + return TestObject{ + bundle.RelationKeyId: pbtypes.String(id), + bundle.RelationKeyName: pbtypes.String("name" + id), + } +} + +func makeObjectWithName(id string, name string) TestObject { + return TestObject{ + bundle.RelationKeyId: pbtypes.String(id), + bundle.RelationKeyName: pbtypes.String(name), + bundle.RelationKeySpaceId: pbtypes.String(spaceName), + } +} + +func makeObjectWithNameAndDescription(id string, name string, description string) TestObject { + return TestObject{ + bundle.RelationKeyId: pbtypes.String(id), + bundle.RelationKeyName: pbtypes.String(name), + bundle.RelationKeyDescription: pbtypes.String(description), + bundle.RelationKeySpaceId: pbtypes.String(spaceName), + } +} + +func makeDetails(fields TestObject) *types.Struct { + f := map[string]*types.Value{} + for k, v := range fields { + f[string(k)] = v + } + return &types.Struct{Fields: f} +} + +func (fx *StoreFixture) AddObjects(t testing.TB, objects []TestObject) { + for _, obj := range objects { + id := obj[bundle.RelationKeyId].GetStringValue() + require.NotEmpty(t, id) + err := fx.UpdateObjectDetails(context.Background(), id, makeDetails(obj)) + require.NoError(t, err) + } +} diff --git a/pkg/lib/localstore/objectstore/spaceindex/indexer.go b/pkg/lib/localstore/objectstore/spaceindex/indexer.go new file mode 100644 index 0000000000..8f8d9e627a --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/indexer.go @@ -0,0 +1,32 @@ +package spaceindex + +import ( + "context" + "errors" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/query" +) + +const headsStateField = "h" + +// GetLastIndexedHeadsHash return empty hash without error if record was not found +func (s *dsObjectStore) GetLastIndexedHeadsHash(ctx context.Context, id string) (headsHash string, err error) { + doc, err := s.headsState.FindId(ctx, id) + if errors.Is(err, anystore.ErrDocNotFound) { + return "", nil + } + if err != nil { + return "", err + } + return string(doc.Value().GetStringBytes(headsStateField)), nil +} + +func (s *dsObjectStore) SaveLastIndexedHeadsHash(ctx context.Context, id string, headsHash string) error { + _, err := s.headsState.UpsertId(ctx, id, query.ModifyFunc(func(arena *anyenc.Arena, val *anyenc.Value) (*anyenc.Value, bool, error) { + val.Set(headsStateField, arena.NewString(headsHash)) + return val, true, nil + })) + return err +} diff --git a/pkg/lib/localstore/objectstore/spaceindex/indexer_test.go b/pkg/lib/localstore/objectstore/spaceindex/indexer_test.go new file mode 100644 index 0000000000..524237e3d4 --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/indexer_test.go @@ -0,0 +1,33 @@ +package spaceindex + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestHeadsHash(t *testing.T) { + ctx := context.Background() + + t.Run("previous hash is not found", func(t *testing.T) { + s := NewStoreFixture(t) + + got, err := s.GetLastIndexedHeadsHash(ctx, "id1") + require.NoError(t, err) + assert.Empty(t, got) + }) + + t.Run("save and load hash", func(t *testing.T) { + s := NewStoreFixture(t) + + want := "hash1" + + require.NoError(t, s.SaveLastIndexedHeadsHash(ctx, "id1", want)) + + got, err := s.GetLastIndexedHeadsHash(ctx, "id1") + require.NoError(t, err) + assert.Equal(t, want, got) + }) +} diff --git a/pkg/lib/localstore/objectstore/spaceindex/invalid.go b/pkg/lib/localstore/objectstore/spaceindex/invalid.go new file mode 100644 index 0000000000..7d892aad92 --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/invalid.go @@ -0,0 +1,192 @@ +package spaceindex + +import ( + "context" + + anystore "github.com/anyproto/any-store" + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/relationutils" + "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +type invalidStore struct { + err error +} + +var _ Store = (*invalidStore)(nil) + +func NewInvalidStore(err error) Store { + return &invalidStore{err: err} +} + +func (s *invalidStore) SpaceId() string { + return "" +} + +func (s *invalidStore) Close() error { + return s.err +} + +func (s *invalidStore) Query(q database.Query) (records []database.Record, err error) { + return nil, s.err +} + +func (s *invalidStore) QueryRaw(f *database.Filters, limit int, offset int) (records []database.Record, err error) { + return nil, s.err +} + +func (s *invalidStore) QueryByIds(ids []string) (records []database.Record, err error) { + return nil, s.err +} + +func (s *invalidStore) QueryByIdsAndSubscribeForChanges(ids []string, subscription database.Subscription) (records []database.Record, close func(), err error) { + return nil, nil, s.err +} + +func (s *invalidStore) QueryObjectIds(q database.Query) (ids []string, total int, err error) { + return nil, 0, s.err +} + +func (s *invalidStore) QueryIterate(q database.Query, proc func(details *types.Struct)) error { + return s.err +} + +func (s *invalidStore) HasIds(ids []string) (exists []string, err error) { + return nil, s.err +} + +func (s *invalidStore) GetInfosByIds(ids []string) ([]*model.ObjectInfo, error) { + return nil, s.err +} + +func (s *invalidStore) List(includeArchived bool) ([]*model.ObjectInfo, error) { + return nil, s.err +} + +func (s *invalidStore) ListIds() ([]string, error) { + return nil, s.err +} + +func (s *invalidStore) UpdateObjectDetails(ctx context.Context, id string, details *types.Struct) error { + return s.err +} + +func (s *invalidStore) UpdateObjectLinks(ctx context.Context, id string, links []string) error { + return s.err +} + +func (s *invalidStore) UpdatePendingLocalDetails(id string, proc func(details *types.Struct) (*types.Struct, error)) error { + return s.err +} + +func (s *invalidStore) ModifyObjectDetails(id string, proc func(details *types.Struct) (*types.Struct, bool, error)) error { + return s.err +} + +func (s *invalidStore) DeleteObject(id string) error { + return s.err +} + +func (s *invalidStore) DeleteDetails(ctx context.Context, ids []string) error { + return s.err +} + +func (s *invalidStore) DeleteLinks(ids []string) error { + return s.err +} + +func (s *invalidStore) GetDetails(id string) (*model.ObjectDetails, error) { + return nil, s.err +} + +func (s *invalidStore) GetObjectByUniqueKey(uniqueKey domain.UniqueKey) (*model.ObjectDetails, error) { + return nil, s.err +} + +func (s *invalidStore) GetUniqueKeyById(id string) (key domain.UniqueKey, err error) { + return nil, s.err +} + +func (s *invalidStore) GetInboundLinksById(id string) ([]string, error) { + return nil, s.err +} + +func (s *invalidStore) GetOutboundLinksById(id string) ([]string, error) { + return nil, s.err +} + +func (s *invalidStore) GetWithLinksInfoById(id string) (*model.ObjectInfoWithLinks, error) { + return nil, s.err +} + +func (s *invalidStore) SetActiveView(objectId, blockId, viewId string) error { + return s.err +} + +func (s *invalidStore) SetActiveViews(objectId string, views map[string]string) error { + return s.err +} + +func (s *invalidStore) GetActiveViews(objectId string) (map[string]string, error) { + return nil, s.err +} + +func (s *invalidStore) GetRelationLink(key string) (*model.RelationLink, error) { + return nil, s.err +} + +func (s *invalidStore) FetchRelationByKey(key string) (relation *relationutils.Relation, err error) { + return nil, s.err +} + +func (s *invalidStore) FetchRelationByKeys(keys ...string) (relations relationutils.Relations, err error) { + return nil, s.err +} + +func (s *invalidStore) FetchRelationByLinks(links pbtypes.RelationLinks) (relations relationutils.Relations, err error) { + return nil, s.err +} + +func (s *invalidStore) ListAllRelations() (relations relationutils.Relations, err error) { + return nil, s.err +} + +func (s *invalidStore) GetRelationById(id string) (relation *model.Relation, err error) { + return nil, s.err +} + +func (s *invalidStore) GetRelationByKey(key string) (*model.Relation, error) { + return nil, s.err +} + +func (s *invalidStore) GetRelationFormatByKey(key string) (model.RelationFormat, error) { + return 0, s.err +} + +func (s *invalidStore) ListRelationOptions(relationKey string) (options []*model.RelationOption, err error) { + return nil, s.err +} + +func (s *invalidStore) GetObjectType(id string) (*model.ObjectType, error) { + return nil, s.err +} + +func (s *invalidStore) GetLastIndexedHeadsHash(ctx context.Context, id string) (headsHash string, err error) { + return "", s.err +} + +func (s *invalidStore) SaveLastIndexedHeadsHash(ctx context.Context, id string, headsHash string) (err error) { + return s.err +} + +func (s *invalidStore) WriteTx(ctx context.Context) (anystore.WriteTx, error) { + return nil, s.err +} + +func (s *invalidStore) SubscribeForAll(callback func(rec database.Record)) { + +} diff --git a/pkg/lib/localstore/objectstore/links.go b/pkg/lib/localstore/objectstore/spaceindex/links.go similarity index 72% rename from pkg/lib/localstore/objectstore/links.go rename to pkg/lib/localstore/objectstore/spaceindex/links.go index 8742c5c69d..38bcdc787a 100644 --- a/pkg/lib/localstore/objectstore/links.go +++ b/pkg/lib/localstore/objectstore/spaceindex/links.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "context" @@ -12,14 +12,9 @@ import ( "github.com/anyproto/anytype-heart/util/pbtypes" ) -type LinksUpdateInfo struct { - LinksFromId string - Added, Removed []string -} - const linkOutboundField = "o" -func (s *dsObjectStore) GetWithLinksInfoByID(spaceId string, id string) (*model.ObjectInfoWithLinks, error) { +func (s *dsObjectStore) GetWithLinksInfoById(id string) (*model.ObjectInfoWithLinks, error) { txn, err := s.links.ReadTx(s.componentCtx) if err != nil { return nil, fmt.Errorf("read txn: %w", err) @@ -27,7 +22,7 @@ func (s *dsObjectStore) GetWithLinksInfoByID(spaceId string, id string) (*model. commit := func(err error) error { return errors.Join(txn.Commit(), err) } - pages, err := s.getObjectsInfo(txn.Context(), spaceId, []string{id}) + pages, err := s.getObjectsInfo(txn.Context(), []string{id}) if err != nil { return nil, commit(err) } @@ -46,12 +41,12 @@ func (s *dsObjectStore) GetWithLinksInfoByID(spaceId string, id string) (*model. return nil, commit(fmt.Errorf("find outbound links: %w", err)) } - inbound, err := s.getObjectsInfo(s.componentCtx, spaceId, inboundIds) + inbound, err := s.getObjectsInfo(s.componentCtx, inboundIds) if err != nil { return nil, commit(err) } - outbound, err := s.getObjectsInfo(s.componentCtx, spaceId, outboundsIds) + outbound, err := s.getObjectsInfo(s.componentCtx, outboundsIds) if err != nil { return nil, commit(err) } @@ -70,20 +65,14 @@ func (s *dsObjectStore) GetWithLinksInfoByID(spaceId string, id string) (*model. }, nil } -func (s *dsObjectStore) GetOutboundLinksByID(id string) ([]string, error) { +func (s *dsObjectStore) GetOutboundLinksById(id string) ([]string, error) { return s.findOutboundLinks(s.componentCtx, id) } -func (s *dsObjectStore) GetInboundLinksByID(id string) ([]string, error) { +func (s *dsObjectStore) GetInboundLinksById(id string) ([]string, error) { return s.findInboundLinks(s.componentCtx, id) } -func (s *dsObjectStore) SubscribeLinksUpdate(callback func(info LinksUpdateInfo)) { - s.Lock() - s.onLinksUpdateCallback = callback - s.Unlock() -} - // Find to which IDs specified one has outbound links. func (s *dsObjectStore) findOutboundLinks(ctx context.Context, id string) ([]string, error) { doc, err := s.links.FindId(ctx, id) @@ -94,7 +83,7 @@ func (s *dsObjectStore) findOutboundLinks(ctx context.Context, id string) ([]str return nil, err } arr := doc.Value().GetArray(linkOutboundField) - return pbtypes.JsonArrayToStrings(arr), nil + return pbtypes.AnyEncArrayToStrings(arr), nil } // Find from which IDs specified one has inbound links. @@ -106,13 +95,15 @@ func (s *dsObjectStore) findInboundLinks(ctx context.Context, id string) ([]stri if err != nil { return nil, err } + defer iter.Close() + var links []string for iter.Next() { doc, err := iter.Doc() if err != nil { - return nil, errors.Join(iter.Close(), fmt.Errorf("get doc: %w", err)) + return nil, fmt.Errorf("get doc: %w", err) } links = append(links, string(doc.Value().GetStringBytes("id"))) } - return links, iter.Close() + return links, nil } diff --git a/pkg/lib/localstore/objectstore/object_type.go b/pkg/lib/localstore/objectstore/spaceindex/object_type.go similarity index 97% rename from pkg/lib/localstore/objectstore/object_type.go rename to pkg/lib/localstore/objectstore/spaceindex/object_type.go index c2bb0e5ead..c097be6ae0 100644 --- a/pkg/lib/localstore/objectstore/object_type.go +++ b/pkg/lib/localstore/objectstore/spaceindex/object_type.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "fmt" @@ -59,7 +59,7 @@ func (s *dsObjectStore) getRelationLinksForRecommendedRelations(details *types.S recommendedRelationIDs := pbtypes.GetStringList(details, bundle.RelationKeyRecommendedRelations.String()) relationLinks := make([]*model.RelationLink, 0, len(recommendedRelationIDs)) for _, relationID := range recommendedRelationIDs { - relation, err := s.GetRelationByID(relationID) + relation, err := s.GetRelationById(relationID) if err != nil { log.Errorf("failed to get relation %s: %s", relationID, err) } else { diff --git a/pkg/lib/localstore/objectstore/object_type_test.go b/pkg/lib/localstore/objectstore/spaceindex/object_type_test.go similarity index 99% rename from pkg/lib/localstore/objectstore/object_type_test.go rename to pkg/lib/localstore/objectstore/spaceindex/object_type_test.go index 627028fca3..043540c696 100644 --- a/pkg/lib/localstore/objectstore/object_type_test.go +++ b/pkg/lib/localstore/objectstore/spaceindex/object_type_test.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "testing" diff --git a/pkg/lib/localstore/objectstore/spaceindex/objects.go b/pkg/lib/localstore/objectstore/spaceindex/objects.go new file mode 100644 index 0000000000..4e98160267 --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/objects.go @@ -0,0 +1,160 @@ +package spaceindex + +import ( + "context" + "errors" + "fmt" + + anystore "github.com/anyproto/any-store" + "github.com/gogo/protobuf/types" + + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +// GetDetails returns empty struct without errors in case details are not found +// todo: get rid of this or change the name method! +func (s *dsObjectStore) GetDetails(id string) (*model.ObjectDetails, error) { + doc, err := s.objects.FindId(s.componentCtx, id) + if errors.Is(err, anystore.ErrDocNotFound) { + return &model.ObjectDetails{ + Details: &types.Struct{Fields: map[string]*types.Value{}}, + }, nil + } + if err != nil { + return nil, fmt.Errorf("find by id: %w", err) + } + details, err := pbtypes.AnyEncToProto(doc.Value()) + if err != nil { + return nil, fmt.Errorf("unmarshal details: %w", err) + } + return &model.ObjectDetails{ + Details: details, + }, nil +} + +func (s *dsObjectStore) GetUniqueKeyById(id string) (domain.UniqueKey, error) { + details, err := s.GetDetails(id) + if err != nil { + return nil, err + } + rawUniqueKey := pbtypes.GetString(details.Details, bundle.RelationKeyUniqueKey.String()) + if rawUniqueKey == "" { + return nil, fmt.Errorf("object does not have unique key in details") + } + return domain.UnmarshalUniqueKey(rawUniqueKey) +} + +func (s *dsObjectStore) List(includeArchived bool) ([]*model.ObjectInfo, error) { + var filters []*model.BlockContentDataviewFilter + if includeArchived { + filters = append(filters, &model.BlockContentDataviewFilter{ + RelationKey: bundle.RelationKeyIsArchived.String(), + Condition: model.BlockContentDataviewFilter_Equal, + Value: pbtypes.Bool(true), + }) + } + ids, _, err := s.QueryObjectIds(database.Query{ + Filters: filters, + }) + if err != nil { + return nil, fmt.Errorf("query object ids: %w", err) + } + return s.GetInfosByIds(ids) +} + +func (s *dsObjectStore) HasIds(ids []string) (exists []string, err error) { + for _, id := range ids { + _, err := s.objects.FindId(s.componentCtx, id) + if err != nil && !errors.Is(err, anystore.ErrDocNotFound) { + return nil, fmt.Errorf("get %s: %w", id, err) + } + if err == nil { + exists = append(exists, id) + } + } + return exists, err +} + +func (s *dsObjectStore) GetInfosByIds(ids []string) ([]*model.ObjectInfo, error) { + return s.getObjectsInfo(s.componentCtx, ids) +} + +func (s *dsObjectStore) getObjectInfo(ctx context.Context, id string) (*model.ObjectInfo, error) { + details, err := s.sourceService.DetailsFromIdBasedSource(id) + if err == nil { + details.Fields[database.RecordIDField] = pbtypes.ToValue(id) + return &model.ObjectInfo{ + Id: id, + Details: details, + }, nil + } + + doc, err := s.objects.FindId(ctx, id) + if err != nil { + return nil, fmt.Errorf("find by id: %w", err) + } + details, err = pbtypes.AnyEncToProto(doc.Value()) + if err != nil { + return nil, fmt.Errorf("unmarshal details: %w", err) + } + snippet := pbtypes.GetString(details, bundle.RelationKeySnippet.String()) + + return &model.ObjectInfo{ + Id: id, + Details: details, + Snippet: snippet, + }, nil +} + +func (s *dsObjectStore) getObjectsInfo(ctx context.Context, ids []string) ([]*model.ObjectInfo, error) { + objects := make([]*model.ObjectInfo, 0, len(ids)) + for _, id := range ids { + info, err := s.getObjectInfo(ctx, id) + if err != nil { + if errors.Is(err, anystore.ErrDocNotFound) || errors.Is(err, ErrObjectNotFound) || errors.Is(err, ErrNotAnObject) { + continue + } + return nil, err + } + if f := info.GetDetails().GetFields(); f != nil { + // skip deleted objects + if v := f[bundle.RelationKeyIsDeleted.String()]; v != nil && v.GetBoolValue() { + continue + } + } + objects = append(objects, info) + } + + return objects, nil +} + +func (s *dsObjectStore) GetObjectByUniqueKey(uniqueKey domain.UniqueKey) (*model.ObjectDetails, error) { + records, err := s.Query(database.Query{ + Filters: []*model.BlockContentDataviewFilter{ + { + Condition: model.BlockContentDataviewFilter_Equal, + RelationKey: bundle.RelationKeyUniqueKey.String(), + Value: pbtypes.String(uniqueKey.Marshal()), + }, + }, + Limit: 2, + }) + if err != nil { + return nil, err + } + + if len(records) == 0 { + return nil, ErrObjectNotFound + } + + if len(records) > 1 { + // should never happen + return nil, fmt.Errorf("multiple objects with unique key %s", uniqueKey) + } + + return &model.ObjectDetails{Details: records[0].Details}, nil +} diff --git a/pkg/lib/localstore/objectstore/objects_test.go b/pkg/lib/localstore/objectstore/spaceindex/objects_test.go similarity index 82% rename from pkg/lib/localstore/objectstore/objects_test.go rename to pkg/lib/localstore/objectstore/spaceindex/objects_test.go index 201f03bce4..9a8af0d2be 100644 --- a/pkg/lib/localstore/objectstore/objects_test.go +++ b/pkg/lib/localstore/objectstore/spaceindex/objects_test.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( context2 "context" @@ -12,7 +12,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" @@ -67,19 +66,19 @@ func Test_removeByPrefix(t *testing.T) { bundle.RelationKeySpaceId: pbtypes.String(spaceId), }) require.NoError(t, s.UpdateObjectDetails(context2.Background(), objId, details)) - require.NoError(t, s.UpdateObjectLinks(objId, links)) + require.NoError(t, s.UpdateObjectLinks(ctx, objId, links)) } // Test huge transaction - err := s.DeleteLinks(objectIds...) + err := s.DeleteLinks(objectIds) require.NoError(t, err) for _, id := range objectIds { - links, err := s.GetInboundLinksByID(id) + links, err := s.GetInboundLinksById(id) require.NoError(t, err) require.Empty(t, links) - links, err = s.GetOutboundLinksByID(id) + links, err = s.GetOutboundLinksById(id) require.NoError(t, err) require.Empty(t, links) } @@ -98,7 +97,7 @@ func TestList(t *testing.T) { s.AddObjects(t, []TestObject{obj1, obj2, obj3}) - got, err := s.List("space1", false) + got, err := s.List(false) require.NoError(t, err) want := []*model.ObjectInfo{ @@ -147,22 +146,22 @@ func TestHasIDs(t *testing.T) { }) t.Run("none found", func(t *testing.T) { - got, err := s.HasIDs("id4", "id5") + got, err := s.HasIds([]string{"id4", "id5"}) require.NoError(t, err) assert.Empty(t, got) }) t.Run("some found", func(t *testing.T) { - got, err := s.HasIDs("id2", "id3", "id4") + got, err := s.HasIds([]string{"id2", "id3", "id4"}) require.NoError(t, err) assert.Equal(t, []string{"id2", "id3"}, got) }) t.Run("all found", func(t *testing.T) { - got, err := s.HasIDs("id1", "id3") + got, err := s.HasIds([]string{"id1", "id3"}) require.NoError(t, err) assert.Equal(t, []string{"id1", "id3"}, got) }) t.Run("all found, check that input and output orders are equal by reversing arguments", func(t *testing.T) { - got, err := s.HasIDs("id3", "id1") + got, err := s.HasIds([]string{"id3", "id1"}) require.NoError(t, err) assert.Equal(t, []string{"id3", "id1"}, got) }) @@ -175,11 +174,11 @@ func TestGetWithLinksInfoByID(t *testing.T) { obj3 := makeObjectWithName("id3", "name3") s.AddObjects(t, []TestObject{obj1, obj2, obj3}) - err := s.UpdateObjectLinks("id1", []string{"id2", "id3"}) + err := s.UpdateObjectLinks(ctx, "id1", []string{"id2", "id3"}) require.NoError(t, err) t.Run("links of first object", func(t *testing.T) { - got, err := s.GetWithLinksInfoByID("space1", "id1") + got, err := s.GetWithLinksInfoById("id1") require.NoError(t, err) assert.Equal(t, makeDetails(obj1), got.Info.Details) @@ -189,7 +188,7 @@ func TestGetWithLinksInfoByID(t *testing.T) { }) t.Run("links of second object", func(t *testing.T) { - got, err := s.GetWithLinksInfoByID("space1", "id2") + got, err := s.GetWithLinksInfoById("id2") require.NoError(t, err) assert.Equal(t, makeDetails(obj2), got.Info.Details) @@ -198,7 +197,7 @@ func TestGetWithLinksInfoByID(t *testing.T) { }) t.Run("links of third object", func(t *testing.T) { - got, err := s.GetWithLinksInfoByID("space1", "id3") + got, err := s.GetWithLinksInfoById("id3") require.NoError(t, err) assert.Equal(t, makeDetails(obj3), got.Info.Details) @@ -211,7 +210,7 @@ func TestDeleteObject(t *testing.T) { t.Run("on deleting object: details of deleted object are updated, but object is still in store", func(t *testing.T) { s := NewStoreFixture(t) - err := s.DeleteObject(domain.FullID{SpaceID: "space1", ObjectID: "id1"}) + err := s.DeleteObject("id1") require.NoError(t, err) got, err := s.GetDetails("id1") @@ -219,7 +218,7 @@ func TestDeleteObject(t *testing.T) { assert.Equal(t, &model.ObjectDetails{ Details: makeDetails(TestObject{ bundle.RelationKeyId: pbtypes.String("id1"), - bundle.RelationKeySpaceId: pbtypes.String("space1"), + bundle.RelationKeySpaceId: pbtypes.String("test"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), }), }, got) @@ -227,10 +226,10 @@ func TestDeleteObject(t *testing.T) { t.Run("object is already deleted", func(t *testing.T) { s := NewStoreFixture(t) - err := s.DeleteObject(domain.FullID{SpaceID: "space1", ObjectID: "id1"}) + err := s.DeleteObject("id1") require.NoError(t, err) - err = s.DeleteObject(domain.FullID{SpaceID: "space1", ObjectID: "id1"}) + err = s.DeleteObject("id1") require.NoError(t, err) got, err := s.GetDetails("id1") @@ -238,7 +237,7 @@ func TestDeleteObject(t *testing.T) { assert.Equal(t, &model.ObjectDetails{ Details: makeDetails(TestObject{ bundle.RelationKeyId: pbtypes.String("id1"), - bundle.RelationKeySpaceId: pbtypes.String("space1"), + bundle.RelationKeySpaceId: pbtypes.String("test"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), }), }, got) @@ -250,17 +249,17 @@ func TestDeleteObject(t *testing.T) { obj := makeObjectWithName("id1", "name1") s.AddObjects(t, []TestObject{obj}) - err := s.UpdateObjectLinks("id2", []string{"id1"}) + err := s.UpdateObjectLinks(ctx, "id2", []string{"id1"}) require.NoError(t, err) - err = s.SaveLastIndexedHeadsHash("id1", "hash1") + err = s.SaveLastIndexedHeadsHash(ctx, "id1", "hash1") require.NoError(t, err) - err = s.AddToIndexQueue("id1") + err = s.fulltextQueue.AddToIndexQueue(ctx, "id1") require.NoError(t, err) // Act - err = s.DeleteObject(domain.FullID{SpaceID: "space1", ObjectID: "id1"}) + err = s.DeleteObject("id1") require.NoError(t, err) // Assert @@ -269,28 +268,28 @@ func TestDeleteObject(t *testing.T) { assert.Equal(t, &model.ObjectDetails{ Details: makeDetails(TestObject{ bundle.RelationKeyId: pbtypes.String("id1"), - bundle.RelationKeySpaceId: pbtypes.String("space1"), + bundle.RelationKeySpaceId: pbtypes.String("test"), bundle.RelationKeyIsDeleted: pbtypes.Bool(true), }), }, got) - objects, err := s.GetByIDs("space1", []string{"id1"}) + objects, err := s.GetInfosByIds([]string{"id1"}) require.NoError(t, err) assert.Empty(t, objects) - outbound, err := s.GetOutboundLinksByID("id1") + outbound, err := s.GetOutboundLinksById("id1") require.NoError(t, err) assert.Empty(t, outbound) - inbound, err := s.GetInboundLinksByID("id2") + inbound, err := s.GetInboundLinksById("id2") require.NoError(t, err) assert.Empty(t, inbound) - hash, err := s.GetLastIndexedHeadsHash("id1") + hash, err := s.GetLastIndexedHeadsHash(ctx, "id1") require.NoError(t, err) assert.Empty(t, hash) - ids, err := s.ListIDsFromFullTextQueue(0) + ids, err := s.fulltextQueue.ListIdsFromFullTextQueue(0) require.NoError(t, err) assert.Empty(t, ids) }) @@ -300,7 +299,7 @@ func TestDeleteDetails(t *testing.T) { s := NewStoreFixture(t) s.AddObjects(t, []TestObject{makeObjectWithName("id1", "name1")}) - err := s.DeleteDetails("id1") + err := s.DeleteDetails(ctx, []string{"id1"}) require.NoError(t, err) got, err := s.GetDetails("id1") diff --git a/pkg/lib/localstore/objectstore/performance_test.go b/pkg/lib/localstore/objectstore/spaceindex/performance_test.go similarity index 95% rename from pkg/lib/localstore/objectstore/performance_test.go rename to pkg/lib/localstore/objectstore/spaceindex/performance_test.go index d69084e315..d776a18814 100644 --- a/pkg/lib/localstore/objectstore/performance_test.go +++ b/pkg/lib/localstore/objectstore/spaceindex/performance_test.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "testing" diff --git a/pkg/lib/localstore/objectstore/queries.go b/pkg/lib/localstore/objectstore/spaceindex/queries.go similarity index 86% rename from pkg/lib/localstore/objectstore/queries.go rename to pkg/lib/localstore/objectstore/spaceindex/queries.go index a2089ba4be..2430aa35c2 100644 --- a/pkg/lib/localstore/objectstore/queries.go +++ b/pkg/lib/localstore/objectstore/spaceindex/queries.go @@ -1,11 +1,11 @@ -package objectstore +package spaceindex import ( - "errors" "fmt" "math" "sort" "strings" + "sync" "time" anystore "github.com/anyproto/any-store" @@ -13,6 +13,7 @@ import ( "github.com/gogo/protobuf/types" "github.com/samber/lo" "golang.org/x/exp/slices" + "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" @@ -115,7 +116,7 @@ func (s *dsObjectStore) queryAnyStore(filter database.Filter, order database.Ord // Debug slow queries if false { dur := time.Since(now) - if dur.Milliseconds() > 10 { + if dur.Milliseconds() > 100 { explain := "" if exp, expErr := query.Explain(s.componentCtx); expErr == nil { for _, idx := range exp.Indexes { @@ -135,24 +136,22 @@ func (s *dsObjectStore) queryAnyStore(filter database.Filter, order database.Ord if err != nil { return nil, fmt.Errorf("find: %w", err) } + defer iter.Close() + for iter.Next() { doc, err := iter.Doc() if err != nil { - return nil, errors.Join(fmt.Errorf("get doc: %w", err), iter.Close()) + return nil, fmt.Errorf("get doc: %w", err) } - details, err := pbtypes.JsonToProto(doc.Value()) + details, err := pbtypes.AnyEncToProto(doc.Value()) if err != nil { - return nil, errors.Join(fmt.Errorf("json to proto: %w", err), iter.Close()) + return nil, fmt.Errorf("json to proto: %w", err) } records = append(records, database.Record{Details: details}) } err = iter.Err() if err != nil { - return nil, errors.Join(fmt.Errorf("iterate: %w", err), iter.Close()) - } - err = iter.Close() - if err != nil { - return nil, fmt.Errorf("close iterator: %w", err) + return nil, fmt.Errorf("iterate: %w", err) } return records, nil } @@ -193,7 +192,7 @@ func (s *dsObjectStore) QueryFromFulltext(results []database.FulltextResult, par log.Errorf("QueryByIds failed to find id: %s", res.Path.ObjectId) continue } - details, err := pbtypes.JsonToProto(doc.Value()) + details, err := pbtypes.AnyEncToProto(doc.Value()) if err != nil { log.Errorf("QueryByIds failed to extract details: %s", res.Path.ObjectId) continue @@ -262,8 +261,11 @@ func (s *dsObjectStore) performQuery(q database.Query) (records []database.Recor arena := s.arenaPool.Get() defer s.arenaPool.Put(arena) + collatorBuffer := s.collatorBufferPool.get() + defer s.collatorBufferPool.put(collatorBuffer) + q.FullText = strings.TrimSpace(q.FullText) - filters, err := database.NewFilters(q, s, arena) + filters, err := database.NewFilters(q, s, arena, collatorBuffer) if err != nil { return nil, fmt.Errorf("new filters: %w", err) } @@ -273,7 +275,7 @@ func (s *dsObjectStore) performQuery(q database.Query) (records []database.Recor highlighter = ftsearch.DefaultHighlightFormatter } - fulltextResults, err := s.performFulltextSearch(q.FullText, highlighter, filters) + fulltextResults, err := s.performFulltextSearch(q.FullText, highlighter, q.SpaceId) if err != nil { return nil, fmt.Errorf("perform fulltext search: %w", err) } @@ -333,9 +335,8 @@ func jsonHighlightToRanges(s string) (text string, ranges []*model.Range) { return string(fragment.Text), ranges } -func (s *dsObjectStore) performFulltextSearch(text string, highlightFormatter ftsearch.HighlightFormatter, filters *database.Filters) ([]database.FulltextResult, error) { - spaceIds := getSpaceIdsFromFilter(filters.FilterObj) - bleveResults, err := s.fts.Search(spaceIds, highlightFormatter, text) +func (s *dsObjectStore) performFulltextSearch(text string, highlightFormatter ftsearch.HighlightFormatter, spaceId string) ([]database.FulltextResult, error) { + bleveResults, err := s.fts.Search([]string{spaceId}, highlightFormatter, text) if err != nil { return nil, fmt.Errorf("fullText search: %w", err) } @@ -415,32 +416,8 @@ func (s *dsObjectStore) performFulltextSearch(text string, highlightFormatter ft return results, nil } -func getSpaceIdsFromFilter(fltr database.Filter) []string { - switch f := fltr.(type) { - case database.FilterEq: - if f.Key == bundle.RelationKeySpaceId.String() { - return []string{f.Value.GetStringValue()} - } - case database.FilterIn: - if f.Key == bundle.RelationKeySpaceId.String() { - return pbtypes.ListValueToStrings(f.Value) - } - case database.FiltersAnd: - return iterateOverAndFilters(f) - } - return nil -} - -func iterateOverAndFilters(fs []database.Filter) []string { - var spaceIds []string - for _, f := range fs { - spaceIds = append(spaceIds, getSpaceIdsFromFilter(f)...) - } - return spaceIds -} - // TODO: objstore: no one uses total -func (s *dsObjectStore) QueryObjectIDs(q database.Query) (ids []string, total int, err error) { +func (s *dsObjectStore) QueryObjectIds(q database.Query) (ids []string, total int, err error) { recs, err := s.performQuery(q) if err != nil { return nil, 0, fmt.Errorf("build query: %w", err) @@ -452,7 +429,7 @@ func (s *dsObjectStore) QueryObjectIDs(q database.Query) (ids []string, total in return ids, len(recs), nil } -func (s *dsObjectStore) QueryByID(ids []string) (records []database.Record, err error) { +func (s *dsObjectStore) QueryByIds(ids []string) (records []database.Record, err error) { for _, id := range ids { // Don't use spaceID because expected objects are virtual if sbt, err := typeprovider.SmartblockTypeFromID(id); err == nil { @@ -472,7 +449,7 @@ func (s *dsObjectStore) QueryByID(ids []string) (records []database.Record, err log.Infof("QueryByIds failed to find id: %s", id) continue } - details, err := pbtypes.JsonToProto(doc.Value()) + details, err := pbtypes.AnyEncToProto(doc.Value()) if err != nil { log.Errorf("QueryByIds failed to extract details: %s", id) continue @@ -482,19 +459,19 @@ func (s *dsObjectStore) QueryByID(ids []string) (records []database.Record, err return } -func (s *dsObjectStore) QueryByIDAndSubscribeForChanges(ids []string, sub database.Subscription) (records []database.Record, closeFunc func(), err error) { - s.Lock() - defer s.Unlock() +func (s *dsObjectStore) QueryByIdsAndSubscribeForChanges(ids []string, sub database.Subscription) (records []database.Record, closeFunc func(), err error) { + s.lock.Lock() + defer s.lock.Unlock() if sub == nil { err = fmt.Errorf("subscription func is nil") return } sub.Subscribe(ids) - records, err = s.QueryByID(ids) + records, err = s.QueryByIds(ids) if err != nil { // can mean only the datastore is already closed, so we can resign and return - log.Errorf("QueryByIDAndSubscribeForChanges failed to query ids: %v", err) + log.Errorf("QueryByIdsAndSubscribeForChanges failed to query ids: %v", err) return nil, nil, err } @@ -506,11 +483,37 @@ func (s *dsObjectStore) QueryByIDAndSubscribeForChanges(ids []string, sub databa return } +type collatorBufferPool struct { + pool *sync.Pool +} + +func newCollatorBufferPool() *collatorBufferPool { + return &collatorBufferPool{ + pool: &sync.Pool{ + New: func() interface{} { + return &collate.Buffer{} + }, + }, + } +} + +func (p *collatorBufferPool) get() *collate.Buffer { + return p.pool.Get().(*collate.Buffer) +} + +func (p *collatorBufferPool) put(b *collate.Buffer) { + b.Reset() + p.pool.Put(b) +} + func (s *dsObjectStore) QueryIterate(q database.Query, proc func(details *types.Struct)) (err error) { arena := s.arenaPool.Get() defer s.arenaPool.Put(arena) - filters, err := database.NewFilters(q, s, arena) + collatorBuffer := s.collatorBufferPool.get() + defer s.collatorBufferPool.put(collatorBuffer) + + filters, err := database.NewFilters(q, s, arena, collatorBuffer) if err != nil { return fmt.Errorf("new filters: %w", err) } @@ -522,12 +525,7 @@ func (s *dsObjectStore) QueryIterate(q database.Query, proc func(details *types. if err != nil { return fmt.Errorf("find: %w", err) } - - defer func() { - if iterCloseErr := iter.Close(); iterCloseErr != nil { - err = errors.Join(iterCloseErr, err) - } - }() + defer iter.Close() for iter.Next() { var doc anystore.Doc @@ -538,7 +536,7 @@ func (s *dsObjectStore) QueryIterate(q database.Query, proc func(details *types. } var details *types.Struct - details, err = pbtypes.JsonToProto(doc.Value()) + details, err = pbtypes.AnyEncToProto(doc.Value()) if err != nil { err = fmt.Errorf("json to proto: %w", err) return @@ -552,3 +550,26 @@ func (s *dsObjectStore) QueryIterate(q database.Query, proc func(details *types. } return } + +func (s *dsObjectStore) ListIds() ([]string, error) { + var ids []string + iter, err := s.objects.Find(nil).Iter(s.componentCtx) + if err != nil { + return nil, fmt.Errorf("find all: %w", err) + } + defer iter.Close() + + for iter.Next() { + doc, err := iter.Doc() + if err != nil { + return nil, fmt.Errorf("get doc: %w", err) + } + id := doc.Value().GetStringBytes("id") + ids = append(ids, string(id)) + } + err = iter.Err() + if err != nil { + return nil, fmt.Errorf("iterate: %w", err) + } + return ids, nil +} diff --git a/pkg/lib/localstore/objectstore/queries_test.go b/pkg/lib/localstore/objectstore/spaceindex/queries_test.go similarity index 91% rename from pkg/lib/localstore/objectstore/queries_test.go rename to pkg/lib/localstore/objectstore/spaceindex/queries_test.go index 08c1482d00..6373af48ff 100644 --- a/pkg/lib/localstore/objectstore/queries_test.go +++ b/pkg/lib/localstore/objectstore/spaceindex/queries_test.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "context" @@ -8,11 +8,12 @@ import ( "testing" "time" + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/valyala/fastjson" "golang.org/x/exp/slices" + "golang.org/x/text/collate" "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/pkg/lib/bundle" @@ -863,7 +864,7 @@ func TestQueryObjectIds(t *testing.T) { obj3 := makeObjectWithName("id3", "name3") s.AddObjects(t, []TestObject{obj1, obj2, obj3}) - ids, _, err := s.QueryObjectIDs(database.Query{}) + ids, _, err := s.QueryObjectIds(database.Query{}) require.NoError(t, err) assert.Equal(t, []string{"id1", "id2", "id3"}, ids) }) @@ -879,7 +880,7 @@ func TestQueryObjectIds(t *testing.T) { s.AddObjects(t, []TestObject{obj1, obj2, obj3}) // When - ids, _, err := s.QueryObjectIDs(database.Query{ + ids, _, err := s.QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyDescription.String(), @@ -896,7 +897,7 @@ func TestQueryObjectIds(t *testing.T) { } func TestQueryRaw(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("with nil filter expect error", func(t *testing.T) { s := NewStoreFixture(t) @@ -921,7 +922,7 @@ func TestQueryRaw(t *testing.T) { obj3 := makeObjectWithName("id3", "name3") s.AddObjects(t, []TestObject{obj1, obj2, obj3}) - flt, err := database.NewFilters(database.Query{}, s, arena) + flt, err := database.NewFilters(database.Query{}, s, arena, &collate.Buffer{}) require.NoError(t, err) recs, err := s.QueryRaw(flt, 0, 0) @@ -944,7 +945,7 @@ func TestQueryRaw(t *testing.T) { Value: pbtypes.String("foo"), }, }, - }, s, arena) + }, s, arena, &collate.Buffer{}) require.NoError(t, err) recs, err := s.QueryRaw(flt, 0, 0) @@ -975,7 +976,7 @@ func TestQueryRaw(t *testing.T) { Value: pbtypes.String("ot-note"), }, }, - }, s, arena) + }, s, arena, &collate.Buffer{}) require.NoError(t, err) recs, err := s.QueryRaw(flt, 0, 0) @@ -1022,7 +1023,7 @@ func TestQueryRaw(t *testing.T) { Value: pbtypes.Int64(int64(model.ObjectType_basic)), }, }, - }, s, arena) + }, s, arena, &collate.Buffer{}) require.NoError(t, err) recs, err := s.QueryRaw(flt, 0, 0) @@ -1045,7 +1046,7 @@ func TestQueryById(t *testing.T) { t.Run("no ids", func(t *testing.T) { s := NewStoreFixture(t) - recs, err := s.QueryByID(nil) + recs, err := s.QueryByIds(nil) require.NoError(t, err) assert.Empty(t, recs) }) @@ -1057,12 +1058,12 @@ func TestQueryById(t *testing.T) { obj3 := makeObjectWithName("id3", "name3") s.AddObjects(t, []TestObject{obj1, obj2, obj3}) - recs, err := s.QueryByID([]string{"id1", "id3"}) + recs, err := s.QueryByIds([]string{"id1", "id3"}) require.NoError(t, err) assertRecordsEqual(t, []TestObject{obj1, obj3}, recs) t.Run("reverse order", func(t *testing.T) { - recs, err := s.QueryByID([]string{"id3", "id1"}) + recs, err := s.QueryByIds([]string{"id3", "id1"}) require.NoError(t, err) assertRecordsEqual(t, []TestObject{obj3, obj1}, recs) }) @@ -1081,7 +1082,7 @@ func TestQueryById(t *testing.T) { s.sourceService = dummySourceService{objectToReturn: obj2} - recs, err := s.QueryByID([]string{"id1", dateID}) + recs, err := s.QueryByIds([]string{"id1", dateID}) require.NoError(t, err) assertRecordsEqual(t, []TestObject{obj1, obj2}, recs) }) @@ -1097,7 +1098,7 @@ func TestQueryByIdAndSubscribeForChanges(t *testing.T) { recordsCh := make(chan *types.Struct) sub := database.NewSubscription(nil, recordsCh) - recs, closeSub, err := s.QueryByIDAndSubscribeForChanges([]string{"id1", "id3"}, sub) + recs, closeSub, err := s.QueryByIdsAndSubscribeForChanges([]string{"id1", "id3"}, sub) require.NoError(t, err) defer closeSub() @@ -1139,100 +1140,6 @@ func TestQueryByIdAndSubscribeForChanges(t *testing.T) { }) } -func TestGetSpaceIDFromFilters(t *testing.T) { - t.Run("spaceID provided", func(t *testing.T) { - spaceId := "myspace" - f := database.FiltersAnd{ - database.FilterEq{ - Key: bundle.RelationKeyCreator.String(), - Value: pbtypes.String("anytype"), - }, - database.FilterEq{ - Key: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceId), - }, - database.FilterNot{ - Filter: database.FilterEq{ - Key: bundle.RelationKeyName.String(), - Value: pbtypes.String("hidden obj"), - }, - }, - } - assert.Equal(t, []string{spaceId}, getSpaceIdsFromFilter(f)) - }) - - t.Run("no spaceID provided", func(t *testing.T) { - f := database.FiltersAnd{ - database.FilterEq{ - Key: bundle.RelationKeyId.String(), - Value: pbtypes.String("some id"), - }, - database.FilterEmpty{ - Key: bundle.RelationKeyType.String(), - }, - } - assert.Equal(t, 0, len(getSpaceIdsFromFilter(f))) - }) - - t.Run("filters is filter.FilterEq with spaceID", func(t *testing.T) { - spaceId := "open space" - f := database.FilterEq{ - Key: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceId), - } - assert.Equal(t, []string{spaceId}, getSpaceIdsFromFilter(f)) - }) - - t.Run("filters is filter.FilterEq without spaceID", func(t *testing.T) { - f := database.FilterEq{ - Key: bundle.RelationKeySetOf.String(), - Value: pbtypes.String("ot-note"), - } - assert.Equal(t, 0, len(getSpaceIdsFromFilter(f))) - }) - - t.Run("filters is filter.FilterIn with spaceId", func(t *testing.T) { - list, err := pbtypes.ValueListWrapper(pbtypes.StringList([]string{"space1"})) - assert.NoError(t, err) - - f := database.FilterIn{ - Key: bundle.RelationKeySpaceId.String(), - Value: list, - } - assert.Equal(t, []string{"space1"}, getSpaceIdsFromFilter(f)) - }) - - t.Run("filters is filter.FilterIn with many spaceId", func(t *testing.T) { - list, err := pbtypes.ValueListWrapper(pbtypes.StringList([]string{"space1", "space2"})) - assert.NoError(t, err) - - f := database.FilterIn{ - Key: bundle.RelationKeySpaceId.String(), - Value: list, - } - assert.Equal(t, []string{"space1", "space2"}, getSpaceIdsFromFilter(f)) - }) - - t.Run("spaceID is nested in and filters", func(t *testing.T) { - spaceId := "secret_space" - f := database.FiltersAnd{ - database.FiltersAnd{ - database.FilterEmpty{Key: "somekey"}, - database.FilterEq{Key: "key", Value: pbtypes.String("value")}, - database.FiltersAnd{ - database.FilterEq{Key: "amount", Value: pbtypes.Float64(15)}, - database.FilterEq{Key: "type", Value: pbtypes.String("ot-note")}, - database.FilterEq{ - Key: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceId), - }, - }, - }, - } - assert.Equal(t, []string{spaceId}, getSpaceIdsFromFilter(f)) - }) -} - func TestIndex(t *testing.T) { s := NewStoreFixture(t) obj1 := TestObject{ diff --git a/pkg/lib/localstore/objectstore/relations.go b/pkg/lib/localstore/objectstore/spaceindex/relations.go similarity index 71% rename from pkg/lib/localstore/objectstore/relations.go rename to pkg/lib/localstore/objectstore/spaceindex/relations.go index 39244f550c..3bb1d6d2ae 100644 --- a/pkg/lib/localstore/objectstore/relations.go +++ b/pkg/lib/localstore/objectstore/spaceindex/relations.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "fmt" @@ -14,7 +14,7 @@ import ( "github.com/anyproto/anytype-heart/util/pbtypes" ) -func (s *dsObjectStore) GetRelationLink(spaceID string, key string) (*model.RelationLink, error) { +func (s *dsObjectStore) GetRelationLink(key string) (*model.RelationLink, error) { bundledRel, err := bundle.GetRelation(domain.RelationKey(key)) if err == nil { return &model.RelationLink{ @@ -23,14 +23,14 @@ func (s *dsObjectStore) GetRelationLink(spaceID string, key string) (*model.Rela }, nil } - rel, err := s.FetchRelationByKey(spaceID, key) + rel, err := s.FetchRelationByKey(key) if err != nil { return nil, fmt.Errorf("get relation: %w", err) } return rel.RelationLink(), nil } -func (s *dsObjectStore) FetchRelationByKey(spaceID string, key string) (relation *relationutils.Relation, err error) { +func (s *dsObjectStore) FetchRelationByKey(key string) (relation *relationutils.Relation, err error) { bundledRel, err := bundle.GetRelation(domain.RelationKey(key)) if err == nil { return &relationutils.Relation{Relation: bundledRel}, nil @@ -49,11 +49,6 @@ func (s *dsObjectStore) FetchRelationByKey(spaceID string, key string) (relation }, }, } - q.Filters = append(q.Filters, &model.BlockContentDataviewFilter{ - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }) records, err := s.Query(q) if err != nil { @@ -65,10 +60,16 @@ func (s *dsObjectStore) FetchRelationByKey(spaceID string, key string) (relation return nil, ErrObjectNotFound } -func (s *dsObjectStore) FetchRelationByKeys(spaceId string, keys ...string) (relations relationutils.Relations, err error) { +func (s *dsObjectStore) FetchRelationByKeys(keys ...string) (relations relationutils.Relations, err error) { uks := make([]string, 0, len(keys)) - for _, key := range keys { + // we should be able to get system relations even when not indexed + bundledRel, err := bundle.GetRelation(domain.RelationKey(key)) + if err == nil { + relations = append(relations, &relationutils.Relation{Relation: bundledRel}) + continue + } + uk, err := domain.NewUniqueKey(smartblock.SmartBlockTypeRelation, key) if err != nil { return nil, err @@ -82,11 +83,6 @@ func (s *dsObjectStore) FetchRelationByKeys(spaceId string, keys ...string) (rel Condition: model.BlockContentDataviewFilter_In, Value: pbtypes.StringList(uks), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, }, }) if err != nil { @@ -99,15 +95,15 @@ func (s *dsObjectStore) FetchRelationByKeys(spaceId string, keys ...string) (rel return } -func (s *dsObjectStore) FetchRelationByLinks(spaceId string, links pbtypes.RelationLinks) (relations relationutils.Relations, err error) { +func (s *dsObjectStore) FetchRelationByLinks(links pbtypes.RelationLinks) (relations relationutils.Relations, err error) { keys := make([]string, 0, len(links)) for _, l := range links { keys = append(keys, l.Key) } - return s.FetchRelationByKeys(spaceId, keys...) + return s.FetchRelationByKeys(keys...) } -func (s *dsObjectStore) GetRelationByID(id string) (*model.Relation, error) { +func (s *dsObjectStore) GetRelationById(id string) (*model.Relation, error) { det, err := s.GetDetails(id) if err != nil { return nil, err @@ -121,7 +117,7 @@ func (s *dsObjectStore) GetRelationByID(id string) (*model.Relation, error) { return rel.Relation, nil } -func (s *dsObjectStore) ListAllRelations(spaceId string) (relations relationutils.Relations, err error) { +func (s *dsObjectStore) ListAllRelations() (relations relationutils.Relations, err error) { filters := []*model.BlockContentDataviewFilter{ { RelationKey: bundle.RelationKeyLayout.String(), @@ -129,11 +125,6 @@ func (s *dsObjectStore) ListAllRelations(spaceId string) (relations relationutil Value: pbtypes.Float64(float64(model.ObjectType_relation)), }, } - filters = append(filters, &model.BlockContentDataviewFilter{ - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }) relations2, err := s.Query(database.Query{ Filters: filters, @@ -148,7 +139,7 @@ func (s *dsObjectStore) ListAllRelations(spaceId string) (relations relationutil return } -func (s *dsObjectStore) GetRelationByKey(spaceId string, key string) (*model.Relation, error) { +func (s *dsObjectStore) GetRelationByKey(key string) (*model.Relation, error) { q := database.Query{ Filters: []*model.BlockContentDataviewFilter{ { @@ -161,11 +152,6 @@ func (s *dsObjectStore) GetRelationByKey(spaceId string, key string) (*model.Rel Condition: model.BlockContentDataviewFilter_Equal, Value: pbtypes.Int64(int64(model.ObjectType_relation)), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, }, } @@ -216,3 +202,27 @@ func (s *dsObjectStore) GetRelationFormatByKey(key string) (model.RelationFormat details := records[0].Details return model.RelationFormat(pbtypes.GetInt64(details, bundle.RelationKeyRelationFormat.String())), nil } + +// ListRelationOptions returns options for specific relation +func (s *dsObjectStore) ListRelationOptions(relationKey string) (options []*model.RelationOption, err error) { + filters := []*model.BlockContentDataviewFilter{ + { + Condition: model.BlockContentDataviewFilter_Equal, + RelationKey: bundle.RelationKeyRelationKey.String(), + Value: pbtypes.String(relationKey), + }, + { + Condition: model.BlockContentDataviewFilter_Equal, + RelationKey: bundle.RelationKeyLayout.String(), + Value: pbtypes.Int64(int64(model.ObjectType_relationOption)), + }, + } + records, err := s.Query(database.Query{ + Filters: filters, + }) + + for _, rec := range records { + options = append(options, relationutils.OptionFromStruct(rec.Details).RelationOption) + } + return +} diff --git a/pkg/lib/localstore/objectstore/relations_test.go b/pkg/lib/localstore/objectstore/spaceindex/relations_test.go similarity index 94% rename from pkg/lib/localstore/objectstore/relations_test.go rename to pkg/lib/localstore/objectstore/spaceindex/relations_test.go index 7ad7554d83..d21a03c709 100644 --- a/pkg/lib/localstore/objectstore/relations_test.go +++ b/pkg/lib/localstore/objectstore/spaceindex/relations_test.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( context2 "context" @@ -53,7 +53,7 @@ func TestGetRelationById(t *testing.T) { t.Run("relation is not found", func(t *testing.T) { s := NewStoreFixture(t) - _, err := s.GetRelationByID("relationID") + _, err := s.GetRelationById("relationID") require.Error(t, err) }) @@ -67,7 +67,7 @@ func TestGetRelationById(t *testing.T) { } s.AddObjects(t, []TestObject{obj}) - _, err := s.GetRelationByID("id1") + _, err := s.GetRelationById("id1") require.Error(t, err) }) @@ -81,7 +81,7 @@ func TestGetRelationById(t *testing.T) { err := s.UpdateObjectDetails(context2.Background(), relation.Id, relObject) require.NoError(t, err) - got, err := s.GetRelationByID(relationID) + got, err := s.GetRelationById(relationID) require.NoError(t, err) assert.Equal(t, relationutils.RelationFromStruct(relObject).Relation, got) }) diff --git a/pkg/lib/localstore/objectstore/spaceindex/store.go b/pkg/lib/localstore/objectstore/spaceindex/store.go new file mode 100644 index 0000000000..992e3f7231 --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/store.go @@ -0,0 +1,327 @@ +package spaceindex + +import ( + "context" + "errors" + "fmt" + "sync" + + anystore "github.com/anyproto/any-store" + "github.com/anyproto/any-store/anyenc" + "github.com/gogo/protobuf/types" + "golang.org/x/exp/slices" + + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/relationutils" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/database" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/anystorehelper" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/oldstore" + "github.com/anyproto/anytype-heart/pkg/lib/logging" + "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +var log = logging.Logger("objectstore.spaceindex") + +var ( + ErrObjectNotFound = fmt.Errorf("object not found") + ErrNotAnObject = fmt.Errorf("not an object") +) + +type Store interface { + SpaceId() string + Close() error + + // Query adds implicit filters on isArchived, isDeleted and objectType relations! To avoid them use QueryRaw + Query(q database.Query) (records []database.Record, err error) + QueryRaw(f *database.Filters, limit int, offset int) (records []database.Record, err error) + QueryByIds(ids []string) (records []database.Record, err error) + QueryByIdsAndSubscribeForChanges(ids []string, subscription database.Subscription) (records []database.Record, close func(), err error) + QueryObjectIds(q database.Query) (ids []string, total int, err error) + QueryIterate(q database.Query, proc func(details *types.Struct)) error + + HasIds(ids []string) (exists []string, err error) + GetInfosByIds(ids []string) ([]*model.ObjectInfo, error) + List(includeArchived bool) ([]*model.ObjectInfo, error) + + ListIds() ([]string, error) + + // UpdateObjectDetails updates existing object or create if not missing. Should be used in order to amend existing indexes based on prev/new value + // set discardLocalDetailsChanges to true in case the caller doesn't have local details in the State + UpdateObjectDetails(ctx context.Context, id string, details *types.Struct) error + SubscribeForAll(callback func(rec database.Record)) + + UpdateObjectLinks(ctx context.Context, id string, links []string) error + UpdatePendingLocalDetails(id string, proc func(details *types.Struct) (*types.Struct, error)) error + ModifyObjectDetails(id string, proc func(details *types.Struct) (*types.Struct, bool, error)) error + + DeleteObject(id string) error + DeleteDetails(ctx context.Context, ids []string) error + DeleteLinks(ids []string) error + + GetDetails(id string) (*model.ObjectDetails, error) + GetObjectByUniqueKey(uniqueKey domain.UniqueKey) (*model.ObjectDetails, error) + GetUniqueKeyById(id string) (key domain.UniqueKey, err error) + + GetInboundLinksById(id string) ([]string, error) + GetOutboundLinksById(id string) ([]string, error) + GetWithLinksInfoById(id string) (*model.ObjectInfoWithLinks, error) + + SetActiveView(objectId, blockId, viewId string) error + SetActiveViews(objectId string, views map[string]string) error + GetActiveViews(objectId string) (map[string]string, error) + + GetRelationLink(key string) (*model.RelationLink, error) + FetchRelationByKey(key string) (relation *relationutils.Relation, err error) + FetchRelationByKeys(keys ...string) (relations relationutils.Relations, err error) + FetchRelationByLinks(links pbtypes.RelationLinks) (relations relationutils.Relations, err error) + ListAllRelations() (relations relationutils.Relations, err error) + GetRelationById(id string) (relation *model.Relation, err error) + GetRelationByKey(key string) (*model.Relation, error) + GetRelationFormatByKey(key string) (model.RelationFormat, error) + ListRelationOptions(relationKey string) (options []*model.RelationOption, err error) + + GetObjectType(id string) (*model.ObjectType, error) + + GetLastIndexedHeadsHash(ctx context.Context, id string) (headsHash string, err error) + SaveLastIndexedHeadsHash(ctx context.Context, id string, headsHash string) (err error) + + WriteTx(ctx context.Context) (anystore.WriteTx, error) +} + +type SourceDetailsFromID interface { + DetailsFromIdBasedSource(id string) (*types.Struct, error) +} + +type FulltextQueue interface { + RemoveIdsFromFullTextQueue(ids []string) error + AddToIndexQueue(ctx context.Context, ids ...string) error + ListIdsFromFullTextQueue(limit int) ([]string, error) +} + +type dsObjectStore struct { + initErr error + + spaceId string + db anystore.DB + objects anystore.Collection + links anystore.Collection + headsState anystore.Collection + activeViews anystore.Collection + pendingDetails anystore.Collection + collections []anystore.Collection + + // Deps + anyStoreConfig *anystore.Config + fts ftsearch.FTSearch + sourceService SourceDetailsFromID + oldStore oldstore.Service + subManager *SubscriptionManager + fulltextQueue FulltextQueue + + componentCtx context.Context + arenaPool *anyenc.ArenaPool + collatorBufferPool *collatorBufferPool + + // State + lock sync.RWMutex + subscriptions []database.Subscription + onChangeCallback func(rec database.Record) + dbLockRemove func() error +} + +type Deps struct { + AnyStoreConfig *anystore.Config + Fts ftsearch.FTSearch + SourceService SourceDetailsFromID + OldStore oldstore.Service + SubManager *SubscriptionManager + DbPath string + FulltextQueue FulltextQueue +} + +func New(componentCtx context.Context, spaceId string, deps Deps) Store { + s := &dsObjectStore{ + spaceId: spaceId, + componentCtx: componentCtx, + arenaPool: &anyenc.ArenaPool{}, + collatorBufferPool: newCollatorBufferPool(), + anyStoreConfig: deps.AnyStoreConfig, + sourceService: deps.SourceService, + oldStore: deps.OldStore, + fts: deps.Fts, + subManager: deps.SubManager, + fulltextQueue: deps.FulltextQueue, + } + + var err error + err = s.openDatabase(componentCtx, deps.DbPath) + if err != nil { + s.initErr = err + return s + } + + return s +} + +type LinksUpdateInfo struct { + LinksFromId string + Added, Removed []string +} + +var _ Store = (*dsObjectStore)(nil) + +func (s *dsObjectStore) WriteTx(ctx context.Context) (anystore.WriteTx, error) { + return s.db.WriteTx(ctx) +} + +func (s *dsObjectStore) openDatabase(ctx context.Context, path string) error { + var err error + s.db, s.dbLockRemove, err = anystorehelper.OpenDatabaseWithLockCheck(s.componentCtx, path, s.anyStoreConfig) + if err != nil { + return err + } + + objects, err := s.newCollection(ctx, "objects") + if err != nil { + return errors.Join(s.db.Close(), fmt.Errorf("open objects collection: %w", err)) + } + links, err := s.newCollection(ctx, "links") + if err != nil { + return errors.Join(s.db.Close(), fmt.Errorf("open links collection: %w", err)) + } + headsState, err := s.newCollection(ctx, "headsState") + if err != nil { + return errors.Join(s.db.Close(), fmt.Errorf("open headsState collection: %w", err)) + } + activeViews, err := s.newCollection(ctx, "activeViews") + if err != nil { + return errors.Join(s.db.Close(), fmt.Errorf("open activeViews collection: %w", err)) + } + pendingDetails, err := s.newCollection(ctx, "pendingDetails") + if err != nil { + return errors.Join(s.db.Close(), fmt.Errorf("open pendingDetails collection: %w", err)) + } + + objectIndexes := []anystore.IndexInfo{ + { + Name: "uniqueKey", + Fields: []string{bundle.RelationKeyUniqueKey.String()}, + }, + { + Name: "source", + Fields: []string{bundle.RelationKeySource.String()}, + }, + { + Name: "layout", + Fields: []string{bundle.RelationKeyLayout.String()}, + }, + { + Name: "type", + Fields: []string{bundle.RelationKeyType.String()}, + }, + { + Name: "relationKey", + Fields: []string{bundle.RelationKeyRelationKey.String()}, + }, + { + Name: "lastModifiedDate", + Fields: []string{bundle.RelationKeyLastModifiedDate.String()}, + }, + { + Name: "fileId", + Fields: []string{bundle.RelationKeyFileId.String()}, + Sparse: true, + }, + { + Name: "oldAnytypeID", + Fields: []string{bundle.RelationKeyOldAnytypeID.String()}, + Sparse: true, + }, + } + err = s.addIndexes(ctx, objects, objectIndexes) + if err != nil { + log.Errorf("ensure object indexes: %s", err) + } + + linksIndexes := []anystore.IndexInfo{ + { + Name: linkOutboundField, + Fields: []string{linkOutboundField}, + }, + } + err = s.addIndexes(ctx, links, linksIndexes) + if err != nil { + log.Errorf("ensure links indexes: %s", err) + } + + s.objects = objects + s.links = links + s.headsState = headsState + s.activeViews = activeViews + s.pendingDetails = pendingDetails + + return nil +} + +func (s *dsObjectStore) newCollection(ctx context.Context, name string) (anystore.Collection, error) { + coll, err := s.db.Collection(ctx, name) + if err != nil { + return nil, fmt.Errorf("open collection %s: %w", name, err) + } + s.collections = append(s.collections, coll) + return coll, nil +} + +func (s *dsObjectStore) Close() error { + var err error + for _, col := range s.collections { + err = errors.Join(err, col.Close()) + } + + s.lock.Lock() + err = errors.Join(err, s.db.Checkpoint(context.Background(), true)) + s.lock.Unlock() + + err = errors.Join(err, s.db.Close()) + // remove lock file only after successful close + err = errors.Join(err, s.dbLockRemove()) + return err +} + +func (s *dsObjectStore) addIndexes(ctx context.Context, coll anystore.Collection, indexes []anystore.IndexInfo) error { + gotIndexes := coll.GetIndexes() + toCreate := indexes[:0] + var toDrop []string + for _, idx := range indexes { + if !slices.ContainsFunc(gotIndexes, func(i anystore.Index) bool { + return i.Info().Name == idx.Name + }) { + toCreate = append(toCreate, idx) + } + } + for _, idx := range gotIndexes { + if !slices.ContainsFunc(indexes, func(i anystore.IndexInfo) bool { + return i.Name == idx.Info().Name + }) { + toDrop = append(toDrop, idx.Info().Name) + } + } + if len(toDrop) > 0 { + for _, indexName := range toDrop { + if err := coll.DropIndex(ctx, indexName); err != nil { + return err + } + } + } + if len(toCreate) > 0 { + return coll.EnsureIndex(ctx, toCreate...) + } + return nil +} + +func (s *dsObjectStore) SpaceId() string { + return s.spaceId +} diff --git a/pkg/lib/localstore/objectstore/spaceindex/submanager.go b/pkg/lib/localstore/objectstore/spaceindex/submanager.go new file mode 100644 index 0000000000..38442d8e75 --- /dev/null +++ b/pkg/lib/localstore/objectstore/spaceindex/submanager.go @@ -0,0 +1,28 @@ +package spaceindex + +import ( + "sync" +) + +type SubscriptionManager struct { + lock sync.RWMutex + onLinksUpdateCallback func(info LinksUpdateInfo) +} + +func (s *SubscriptionManager) SubscribeLinksUpdate(callback func(info LinksUpdateInfo)) { + s.lock.Lock() + s.onLinksUpdateCallback = callback + s.lock.Unlock() +} + +func (s *SubscriptionManager) updateObjectLinks(fromId string, added []string, removed []string) { + s.lock.RLock() + defer s.lock.RUnlock() + if s.onLinksUpdateCallback != nil && len(added)+len(removed) > 0 { + s.onLinksUpdateCallback(LinksUpdateInfo{ + LinksFromId: fromId, + Added: added, + Removed: removed, + }) + } +} diff --git a/pkg/lib/localstore/objectstore/update.go b/pkg/lib/localstore/objectstore/spaceindex/update.go similarity index 74% rename from pkg/lib/localstore/objectstore/update.go rename to pkg/lib/localstore/objectstore/spaceindex/update.go index 62569bf81b..0aa13b5d8b 100644 --- a/pkg/lib/localstore/objectstore/update.go +++ b/pkg/lib/localstore/objectstore/spaceindex/update.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "context" @@ -6,12 +6,12 @@ import ( "fmt" anystore "github.com/anyproto/any-store" - "github.com/anyproto/any-store/jsonutil" + "github.com/anyproto/any-store/anyenc" + "github.com/anyproto/any-store/anyenc/anyencutil" "github.com/anyproto/any-store/query" "github.com/dgraph-io/badger/v4" "github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/database" @@ -34,19 +34,23 @@ func (s *dsObjectStore) UpdateObjectDetails(ctx context.Context, id string, deta // Ensure ID is set details.Fields[bundle.RelationKeyId.String()] = pbtypes.String(id) + // Only id is set + if len(details.Fields) == 1 { + return fmt.Errorf("should be more than just id") + } + arena := s.arenaPool.Get() defer func() { - arena.Reset() s.arenaPool.Put(arena) }() - jsonVal := pbtypes.ProtoToJson(arena, details) + newVal := pbtypes.ProtoToAnyEnc(arena, details) var isModified bool - _, err := s.objects.UpsertId(ctx, id, query.ModifyFunc(func(arena *fastjson.Arena, val *fastjson.Value) (*fastjson.Value, bool, error) { - if jsonutil.Equal(val, jsonVal) { + _, err := s.objects.UpsertId(ctx, id, query.ModifyFunc(func(arena *anyenc.Arena, val *anyenc.Value) (*anyenc.Value, bool, error) { + if anyencutil.Equal(val, newVal) { return nil, false, nil } isModified = true - return jsonVal, true, nil + return newVal, true, nil })) if isModified { s.sendUpdatesToSubscriptions(id, details) @@ -59,6 +63,52 @@ func (s *dsObjectStore) UpdateObjectDetails(ctx context.Context, id string, deta return nil } +func (s *dsObjectStore) SubscribeForAll(callback func(rec database.Record)) { + s.lock.Lock() + s.onChangeCallback = callback + s.lock.Unlock() +} + +func (s *dsObjectStore) sendUpdatesToSubscriptions(id string, details *types.Struct) { + detCopy := pbtypes.CopyStruct(details, false) + detCopy.Fields[database.RecordIDField] = pbtypes.ToValue(id) + s.lock.RLock() + defer s.lock.RUnlock() + if s.onChangeCallback != nil { + s.onChangeCallback(database.Record{ + Details: detCopy, + }) + } + for _, sub := range s.subscriptions { + _ = sub.PublishAsync(id, detCopy) + } +} + +// unsafe, use under mutex +func (s *dsObjectStore) addSubscriptionIfNotExists(sub database.Subscription) (existed bool) { + for _, s := range s.subscriptions { + if s == sub { + return true + } + } + + s.subscriptions = append(s.subscriptions, sub) + return false +} + +func (s *dsObjectStore) closeAndRemoveSubscription(subscription database.Subscription) { + s.lock.Lock() + defer s.lock.Unlock() + subscription.Close() + + for i, sub := range s.subscriptions { + if sub == subscription { + s.subscriptions = append(s.subscriptions[:i], s.subscriptions[i+1:]...) + break + } + } +} + func (s *dsObjectStore) migrateLocalDetails(objectId string, details *types.Struct) bool { existingLocalDetails, err := s.oldStore.GetLocalDetails(objectId) if err != nil || existingLocalDetails == nil { @@ -72,20 +122,14 @@ func (s *dsObjectStore) migrateLocalDetails(objectId string, details *types.Stru return true } -func (s *dsObjectStore) UpdateObjectLinks(id string, links []string) error { - added, removed, err := s.updateObjectLinks(s.componentCtx, id, links) +func (s *dsObjectStore) UpdateObjectLinks(ctx context.Context, id string, links []string) error { + added, removed, err := s.updateObjectLinks(ctx, id, links) if err != nil { return err } - s.RLock() - defer s.RUnlock() - if s.onLinksUpdateCallback != nil && len(added)+len(removed) > 0 { - s.onLinksUpdateCallback(LinksUpdateInfo{ - LinksFromId: id, - Added: added, - Removed: removed, - }) - } + + s.subManager.updateObjectLinks(id, added, removed) + return nil } @@ -114,7 +158,7 @@ func (s *dsObjectStore) UpdatePendingLocalDetails(id string, proc func(details * } else if err != nil { return rollback(fmt.Errorf("find details: %w", err)) } else { - inputDetails, err = pbtypes.JsonToProto(doc.Value()) + inputDetails, err = pbtypes.AnyEncToProto(doc.Value()) if err != nil { return rollback(fmt.Errorf("json to proto: %w", err)) } @@ -135,8 +179,8 @@ func (s *dsObjectStore) UpdatePendingLocalDetails(id string, proc func(details * return txn.Commit() } newDetails.Fields[bundle.RelationKeyId.String()] = pbtypes.String(id) - jsonVal := pbtypes.ProtoToJson(arena, newDetails) - _, err = s.pendingDetails.UpsertOne(txn.Context(), jsonVal) + jsonVal := pbtypes.ProtoToAnyEnc(arena, newDetails) + err = s.pendingDetails.UpsertOne(txn.Context(), jsonVal) if err != nil { return rollback(fmt.Errorf("upsert details: %w", err)) } @@ -166,8 +210,8 @@ func (s *dsObjectStore) ModifyObjectDetails(id string, proc func(details *types. arena.Reset() s.arenaPool.Put(arena) }() - _, err := s.objects.UpsertId(s.componentCtx, id, query.ModifyFunc(func(arena *fastjson.Arena, val *fastjson.Value) (*fastjson.Value, bool, error) { - inputDetails, err := pbtypes.JsonToProto(val) + _, err := s.objects.UpsertId(s.componentCtx, id, query.ModifyFunc(func(arena *anyenc.Arena, val *anyenc.Value) (*anyenc.Value, bool, error) { + inputDetails, err := pbtypes.AnyEncToProto(val) if err != nil { return nil, false, fmt.Errorf("get old details: json to proto: %w", err) } @@ -183,8 +227,8 @@ func (s *dsObjectStore) ModifyObjectDetails(id string, proc func(details *types. // Ensure ID is set newDetails.Fields[bundle.RelationKeyId.String()] = pbtypes.String(id) - jsonVal := pbtypes.ProtoToJson(arena, newDetails) - diff, err := pbtypes.DiffJson(val, jsonVal) + jsonVal := pbtypes.ProtoToAnyEnc(arena, newDetails) + diff, err := pbtypes.AnyEncJson(val, jsonVal) if err != nil { return nil, false, fmt.Errorf("diff json: %w", err) } @@ -210,26 +254,11 @@ func (s *dsObjectStore) getPendingLocalDetails(txn *badger.Txn, key []byte) (*mo } func (s *dsObjectStore) updateObjectLinks(ctx context.Context, id string, links []string) (added []string, removed []string, err error) { - _, err = s.links.UpsertId(ctx, id, query.ModifyFunc(func(arena *fastjson.Arena, val *fastjson.Value) (*fastjson.Value, bool, error) { - prev := pbtypes.JsonArrayToStrings(val.GetArray(linkOutboundField)) + _, err = s.links.UpsertId(ctx, id, query.ModifyFunc(func(arena *anyenc.Arena, val *anyenc.Value) (*anyenc.Value, bool, error) { + prev := pbtypes.AnyEncArrayToStrings(val.GetArray(linkOutboundField)) added, removed = slice.DifferenceRemovedAdded(prev, links) - val.Set(linkOutboundField, pbtypes.StringsToJsonArray(arena, links)) + val.Set(linkOutboundField, pbtypes.StringsToAnyEnc(arena, links)) return val, len(added)+len(removed) > 0, nil })) return } - -func (s *dsObjectStore) sendUpdatesToSubscriptions(id string, details *types.Struct) { - detCopy := pbtypes.CopyStruct(details, false) - detCopy.Fields[database.RecordIDField] = pbtypes.ToValue(id) - s.RLock() - defer s.RUnlock() - if s.onChangeCallback != nil { - s.onChangeCallback(database.Record{ - Details: detCopy, - }) - } - for _, sub := range s.subscriptions { - _ = sub.PublishAsync(id, detCopy) - } -} diff --git a/pkg/lib/localstore/objectstore/update_test.go b/pkg/lib/localstore/objectstore/spaceindex/update_test.go similarity index 96% rename from pkg/lib/localstore/objectstore/update_test.go rename to pkg/lib/localstore/objectstore/spaceindex/update_test.go index f5a1927260..19a0d62b7b 100644 --- a/pkg/lib/localstore/objectstore/update_test.go +++ b/pkg/lib/localstore/objectstore/spaceindex/update_test.go @@ -1,4 +1,4 @@ -package objectstore +package spaceindex import ( "context" @@ -277,10 +277,10 @@ func TestUpdateObjectLinks(t *testing.T) { t.Run("with no links added", func(t *testing.T) { s := NewStoreFixture(t) - err := s.UpdateObjectLinks("id1", []string{}) + err := s.UpdateObjectLinks(ctx, "id1", []string{}) require.NoError(t, err) - out, err := s.GetOutboundLinksByID("id1") + out, err := s.GetOutboundLinksById("id1") require.NoError(t, err) assert.Empty(t, out) }) @@ -288,7 +288,7 @@ func TestUpdateObjectLinks(t *testing.T) { t.Run("with some links added", func(t *testing.T) { s := NewStoreFixture(t) - err := s.UpdateObjectLinks("id1", []string{"id2", "id3"}) + err := s.UpdateObjectLinks(ctx, "id1", []string{"id2", "id3"}) require.NoError(t, err) s.assertOutboundLinks(t, "id1", []string{"id2", "id3"}) @@ -301,7 +301,7 @@ func TestUpdateObjectLinks(t *testing.T) { s.givenExistingLinks(t) - err := s.UpdateObjectLinks("id1", []string{"id2", "id3"}) + err := s.UpdateObjectLinks(ctx, "id1", []string{"id2", "id3"}) require.NoError(t, err) s.assertOutboundLinks(t, "id1", []string{"id2", "id3"}) @@ -314,7 +314,7 @@ func TestUpdateObjectLinks(t *testing.T) { s.givenExistingLinks(t) - err := s.UpdateObjectLinks("id1", []string{}) + err := s.UpdateObjectLinks(ctx, "id1", []string{}) require.NoError(t, err) s.assertOutboundLinks(t, "id1", nil) @@ -324,7 +324,7 @@ func TestUpdateObjectLinks(t *testing.T) { } func (fx *StoreFixture) assertInboundLinks(t *testing.T, id string, links []string) { - in, err := fx.GetInboundLinksByID(id) + in, err := fx.GetInboundLinksById(id) assert.NoError(t, err) if len(links) == 0 { assert.Empty(t, in) @@ -334,7 +334,7 @@ func (fx *StoreFixture) assertInboundLinks(t *testing.T, id string, links []stri } func (fx *StoreFixture) assertOutboundLinks(t *testing.T, id string, links []string) { - out, err := fx.GetOutboundLinksByID(id) + out, err := fx.GetOutboundLinksById(id) assert.NoError(t, err) if len(links) == 0 { assert.Empty(t, out) @@ -344,7 +344,7 @@ func (fx *StoreFixture) assertOutboundLinks(t *testing.T, id string, links []str } func (fx *StoreFixture) givenExistingLinks(t *testing.T) { - err := fx.UpdateObjectLinks("id1", []string{"id2"}) + err := fx.UpdateObjectLinks(ctx, "id1", []string{"id2"}) require.NoError(t, err) fx.assertOutboundLinks(t, "id1", []string{"id2"}) diff --git a/pkg/lib/localstore/objectstore/virtual_space_store.go b/pkg/lib/localstore/objectstore/virtual_space_store.go index cee623f8db..7dc303620a 100644 --- a/pkg/lib/localstore/objectstore/virtual_space_store.go +++ b/pkg/lib/localstore/objectstore/virtual_space_store.go @@ -2,6 +2,7 @@ package objectstore import ( "errors" + "fmt" anystore "github.com/anyproto/any-store" @@ -23,7 +24,7 @@ func (s *dsObjectStore) SaveVirtualSpace(id string) (err error) { if err != nil { return err } - _, err = s.virtualSpaces.UpsertOne(s.componentCtx, it) + err = s.virtualSpaces.UpsertOne(s.componentCtx, it) return err } @@ -32,26 +33,23 @@ func (s *dsObjectStore) ListVirtualSpaces() ([]string, error) { if err != nil { return nil, err } + defer iter.Close() + var spaceIds []string for iter.Next() { doc, err := iter.Doc() if err != nil { - return nil, errors.Join(iter.Close(), err) + return nil, fmt.Errorf("get doc: %w", err) } id := doc.Value().GetStringBytes("id") spaceIds = append(spaceIds, string(id)) } - return spaceIds, iter.Close() + return spaceIds, nil } func (s *dsObjectStore) DeleteVirtualSpace(spaceID string) error { - ids, _, err := s.QueryObjectIDs(database.Query{ + ids, _, err := s.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ - { - Condition: model.BlockContentDataviewFilter_Equal, - RelationKey: bundle.RelationKeySpaceId.String(), - Value: pbtypes.String(spaceID), - }, { Condition: model.BlockContentDataviewFilter_NotLike, RelationKey: bundle.RelationKeyId.String(), @@ -77,7 +75,7 @@ func (s *dsObjectStore) DeleteVirtualSpace(spaceID string) error { if err != nil { return err } - err = s.DeleteDetails(ids...) + err = s.SpaceIndex(spaceID).DeleteDetails(s.componentCtx, ids) if err != nil { return err } diff --git a/pkg/lib/pb/model/models.pb.go b/pkg/lib/pb/model/models.pb.go index 3a0ae9d641..71d3fd4966 100644 --- a/pkg/lib/pb/model/models.pb.go +++ b/pkg/lib/pb/model/models.pb.go @@ -53,6 +53,7 @@ const ( SmartBlockType_DevicesObject SmartBlockType = 536 SmartBlockType_ChatObject SmartBlockType = 537 SmartBlockType_ChatDerivedObject SmartBlockType = 544 + SmartBlockType_AccountObject SmartBlockType = 545 ) var SmartBlockType_name = map[int32]string{ @@ -83,6 +84,7 @@ var SmartBlockType_name = map[int32]string{ 536: "DevicesObject", 537: "ChatObject", 544: "ChatDerivedObject", + 545: "AccountObject", } var SmartBlockType_value = map[string]int32{ @@ -113,6 +115,7 @@ var SmartBlockType_value = map[string]int32{ "DevicesObject": 536, "ChatObject": 537, "ChatDerivedObject": 544, + "AccountObject": 545, } func (x SmartBlockType) String() string { @@ -9397,547 +9400,547 @@ func init() { } var fileDescriptor_98a910b73321e591 = []byte{ - // 8626 bytes of a gzipped FileDescriptorProto + // 8632 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x7d, 0x4b, 0x90, 0x24, 0x49, - 0x76, 0x50, 0xe5, 0x3f, 0xf3, 0x65, 0x7d, 0xbc, 0xbc, 0x7f, 0xb9, 0x39, 0xad, 0x56, 0x6f, 0xee, - 0xec, 0x4c, 0x6f, 0xef, 0x6c, 0xf5, 0x4c, 0xcf, 0x77, 0x47, 0x3b, 0x33, 0x5b, 0x9f, 0xac, 0xae, - 0x9c, 0xae, 0xdf, 0x44, 0x66, 0x77, 0xef, 0x8e, 0x49, 0x34, 0x5e, 0x19, 0x5e, 0x99, 0x31, 0x15, - 0x19, 0x91, 0x1b, 0xe1, 0x59, 0x5d, 0x35, 0x06, 0x98, 0x00, 0x21, 0xa1, 0xdb, 0x22, 0x43, 0x7c, - 0x0e, 0x98, 0x56, 0x37, 0x0c, 0xad, 0x81, 0x71, 0x58, 0x63, 0xc1, 0x90, 0x19, 0xe8, 0x82, 0xcc, - 0xb8, 0x2c, 0x70, 0x00, 0x0e, 0x18, 0xd8, 0xce, 0x11, 0x13, 0x32, 0x38, 0xc9, 0x30, 0x0e, 0xd8, - 0x7b, 0xee, 0xf1, 0xc9, 0x4f, 0x55, 0x67, 0x8f, 0x24, 0x8c, 0x53, 0x85, 0xbf, 0x78, 0xef, 0x85, - 0x7f, 0x9e, 0x3f, 0x7f, 0x3f, 0xcf, 0x82, 0x97, 0x87, 0x27, 0xbd, 0x7b, 0xae, 0x73, 0x74, 0x6f, - 0x78, 0x74, 0x6f, 0xe0, 0xdb, 0xd2, 0xbd, 0x37, 0x0c, 0x7c, 0xe5, 0x87, 0xba, 0x11, 0xae, 0x51, - 0x8b, 0x2f, 0x09, 0xef, 0x5c, 0x9d, 0x0f, 0xe5, 0x1a, 0x41, 0xeb, 0x37, 0x7b, 0xbe, 0xdf, 0x73, - 0xa5, 0x46, 0x3d, 0x1a, 0x1d, 0xdf, 0x0b, 0x55, 0x30, 0xea, 0x2a, 0x8d, 0xdc, 0xf8, 0x59, 0x1e, - 0xae, 0xb7, 0x07, 0x22, 0x50, 0x1b, 0xae, 0xdf, 0x3d, 0x69, 0x7b, 0x62, 0x18, 0xf6, 0x7d, 0xb5, - 0x21, 0x42, 0xc9, 0x5f, 0x83, 0xe2, 0x11, 0x02, 0xc3, 0x5a, 0xe6, 0x76, 0xee, 0x4e, 0xf5, 0xfe, - 0xd5, 0xb5, 0x31, 0xc6, 0x6b, 0x44, 0x61, 0x19, 0x1c, 0xfe, 0x06, 0x94, 0x6c, 0xa9, 0x84, 0xe3, - 0x86, 0xb5, 0xec, 0xed, 0xcc, 0x9d, 0xea, 0xfd, 0x1b, 0x6b, 0xfa, 0xc3, 0x6b, 0xd1, 0x87, 0xd7, - 0xda, 0xf4, 0x61, 0x2b, 0xc2, 0xe3, 0xef, 0x42, 0xf9, 0xd8, 0x71, 0xe5, 0x43, 0x79, 0x1e, 0xd6, - 0x72, 0x97, 0xd2, 0x6c, 0x64, 0x6b, 0x19, 0x2b, 0x46, 0xe6, 0x9b, 0xb0, 0x2c, 0xcf, 0x54, 0x20, - 0x2c, 0xe9, 0x0a, 0xe5, 0xf8, 0x5e, 0x58, 0xcb, 0x53, 0x0f, 0x6f, 0x4c, 0xf4, 0x30, 0x7a, 0x4f, - 0xe4, 0x13, 0x24, 0xfc, 0x36, 0x54, 0xfd, 0xa3, 0xcf, 0x64, 0x57, 0x75, 0xce, 0x87, 0x32, 0xac, - 0x15, 0x6e, 0xe7, 0xee, 0x54, 0xac, 0x34, 0x88, 0x7f, 0x1b, 0xaa, 0x5d, 0xdf, 0x75, 0x65, 0x57, - 0x7f, 0xa3, 0x78, 0xf9, 0xb0, 0xd2, 0xb8, 0xfc, 0x2d, 0xb8, 0x16, 0xc8, 0x81, 0x7f, 0x2a, 0xed, - 0xcd, 0x18, 0x4a, 0xe3, 0x2c, 0xd3, 0x67, 0x66, 0xbf, 0xe4, 0xeb, 0xb0, 0x14, 0x98, 0xfe, 0xed, - 0x3a, 0xde, 0x49, 0x58, 0x2b, 0xd1, 0xb0, 0x5e, 0xba, 0x60, 0x58, 0x88, 0x63, 0x8d, 0x53, 0x70, - 0x06, 0xb9, 0x13, 0x79, 0x5e, 0xab, 0xdc, 0xce, 0xdc, 0xa9, 0x58, 0xf8, 0xc8, 0xdf, 0x87, 0x9a, - 0x1f, 0x38, 0x3d, 0xc7, 0x13, 0xee, 0x66, 0x20, 0x85, 0x92, 0x76, 0xc7, 0x19, 0xc8, 0x50, 0x89, - 0xc1, 0xb0, 0x06, 0xb7, 0x33, 0x77, 0x72, 0xd6, 0x85, 0xef, 0xf9, 0x9b, 0x7a, 0x85, 0x5a, 0xde, - 0xb1, 0x5f, 0xab, 0x9a, 0xe1, 0x8f, 0xf7, 0x65, 0xdb, 0xbc, 0xb6, 0x62, 0xc4, 0xc6, 0x9f, 0x64, - 0xa1, 0xd8, 0x96, 0x22, 0xe8, 0xf6, 0xeb, 0xbf, 0x91, 0x81, 0xa2, 0x25, 0xc3, 0x91, 0xab, 0x78, - 0x1d, 0xca, 0x7a, 0x6e, 0x5b, 0x76, 0x2d, 0x43, 0xbd, 0x8b, 0xdb, 0x5f, 0x46, 0x76, 0xd6, 0x20, - 0x3f, 0x90, 0x4a, 0xd4, 0x72, 0x34, 0x43, 0xf5, 0x89, 0x5e, 0xe9, 0xcf, 0xaf, 0xed, 0x49, 0x25, - 0x2c, 0xc2, 0xab, 0x7f, 0x91, 0x81, 0x3c, 0x36, 0xf9, 0x4d, 0xa8, 0xf4, 0x9d, 0x5e, 0xdf, 0x75, - 0x7a, 0x7d, 0x65, 0x3a, 0x92, 0x00, 0xf8, 0x87, 0xb0, 0x12, 0x37, 0x2c, 0xe1, 0xf5, 0x24, 0xf6, - 0x68, 0x96, 0xf0, 0xd3, 0x4b, 0x6b, 0x12, 0x99, 0xd7, 0xa0, 0x44, 0xfb, 0xa1, 0x65, 0x93, 0x44, - 0x57, 0xac, 0xa8, 0x89, 0xe2, 0x16, 0xad, 0xd4, 0x43, 0x79, 0x5e, 0xcb, 0xd3, 0xdb, 0x34, 0x88, - 0xaf, 0xc3, 0x4a, 0xd4, 0xdc, 0x32, 0xb3, 0x51, 0xb8, 0x7c, 0x36, 0x26, 0xf1, 0x1b, 0xff, 0xb1, - 0x05, 0x05, 0xda, 0x96, 0x7c, 0x19, 0xb2, 0x4e, 0x34, 0xd1, 0x59, 0xc7, 0xe6, 0xf7, 0xa0, 0x78, - 0xec, 0x48, 0xd7, 0x7e, 0xee, 0x0c, 0x1b, 0x34, 0xde, 0x84, 0xc5, 0x40, 0x86, 0x2a, 0x70, 0x8c, - 0xf4, 0xeb, 0x0d, 0xfa, 0xd5, 0x59, 0x3a, 0x60, 0xcd, 0x4a, 0x21, 0x5a, 0x63, 0x64, 0x38, 0xec, - 0x6e, 0xdf, 0x71, 0xed, 0x40, 0x7a, 0x2d, 0x5b, 0xef, 0xd3, 0x8a, 0x95, 0x06, 0xf1, 0x3b, 0xb0, - 0x72, 0x24, 0xba, 0x27, 0xbd, 0xc0, 0x1f, 0x79, 0xb8, 0x21, 0xfc, 0x80, 0x86, 0x5d, 0xb1, 0x26, - 0xc1, 0xfc, 0x75, 0x28, 0x08, 0xd7, 0xe9, 0x79, 0xb4, 0x13, 0x97, 0xa7, 0x16, 0x5d, 0xf7, 0x65, - 0x1d, 0x31, 0x2c, 0x8d, 0xc8, 0x77, 0x60, 0xe9, 0x54, 0x06, 0xca, 0xe9, 0x0a, 0x97, 0xe0, 0xb5, - 0x12, 0x51, 0x36, 0x66, 0x52, 0x3e, 0x4e, 0x63, 0x5a, 0xe3, 0x84, 0xbc, 0x05, 0x10, 0xa2, 0x9a, - 0xa4, 0xe5, 0x34, 0x7b, 0xe1, 0xd5, 0x99, 0x6c, 0x36, 0x7d, 0x4f, 0x49, 0x4f, 0xad, 0xb5, 0x63, - 0xf4, 0x9d, 0x05, 0x2b, 0x45, 0xcc, 0xdf, 0x85, 0xbc, 0x92, 0x67, 0xaa, 0xb6, 0x7c, 0xc9, 0x8c, - 0x46, 0x4c, 0x3a, 0xf2, 0x4c, 0xed, 0x2c, 0x58, 0x44, 0x80, 0x84, 0xb8, 0xc9, 0x6a, 0x2b, 0x73, - 0x10, 0xe2, 0xbe, 0x44, 0x42, 0x24, 0xe0, 0x1f, 0x40, 0xd1, 0x15, 0xe7, 0xfe, 0x48, 0xd5, 0x18, - 0x91, 0x7e, 0xed, 0x52, 0xd2, 0x5d, 0x42, 0xdd, 0x59, 0xb0, 0x0c, 0x11, 0x7f, 0x0b, 0x72, 0xb6, - 0x73, 0x5a, 0x5b, 0x25, 0xda, 0xdb, 0x97, 0xd2, 0x6e, 0x39, 0xa7, 0x3b, 0x0b, 0x16, 0xa2, 0xf3, - 0x4d, 0x28, 0x1f, 0xf9, 0xfe, 0xc9, 0x40, 0x04, 0x27, 0x35, 0x4e, 0xa4, 0x5f, 0xbf, 0x94, 0x74, - 0xc3, 0x20, 0xef, 0x2c, 0x58, 0x31, 0x21, 0x0e, 0xd9, 0xe9, 0xfa, 0x5e, 0xed, 0xca, 0x1c, 0x43, - 0x6e, 0x75, 0x7d, 0x0f, 0x87, 0x8c, 0x04, 0x48, 0xe8, 0x3a, 0xde, 0x49, 0xed, 0xea, 0x1c, 0x84, - 0xa8, 0x39, 0x91, 0x10, 0x09, 0xb0, 0xdb, 0xb6, 0x50, 0xe2, 0xd4, 0x91, 0xcf, 0x6a, 0xd7, 0xe6, - 0xe8, 0xf6, 0x96, 0x41, 0xc6, 0x6e, 0x47, 0x84, 0xc8, 0x24, 0xda, 0x9a, 0xb5, 0xeb, 0x73, 0x30, - 0x89, 0x34, 0x3a, 0x32, 0x89, 0x08, 0xf9, 0x5f, 0x80, 0xd5, 0x63, 0x29, 0xd4, 0x28, 0x90, 0x76, - 0x72, 0xd0, 0xdd, 0x20, 0x6e, 0x6b, 0x97, 0xaf, 0xfd, 0x24, 0xd5, 0xce, 0x82, 0x35, 0xcd, 0x8a, - 0xbf, 0x0f, 0x05, 0x57, 0x28, 0x79, 0x56, 0xab, 0x11, 0xcf, 0xc6, 0x73, 0x84, 0x42, 0xc9, 0xb3, - 0x9d, 0x05, 0x4b, 0x93, 0xf0, 0xef, 0xc1, 0x8a, 0x12, 0x47, 0xae, 0x3c, 0x38, 0x36, 0x08, 0x61, - 0xed, 0x2b, 0xc4, 0xe5, 0xb5, 0xcb, 0xc5, 0x79, 0x9c, 0x66, 0x67, 0xc1, 0x9a, 0x64, 0x83, 0xbd, - 0x22, 0x50, 0xad, 0x3e, 0x47, 0xaf, 0x88, 0x1f, 0xf6, 0x8a, 0x48, 0xf8, 0x2e, 0x54, 0xe9, 0x61, - 0xd3, 0x77, 0x47, 0x03, 0xaf, 0xf6, 0x12, 0x71, 0xb8, 0xf3, 0x7c, 0x0e, 0x1a, 0x7f, 0x67, 0xc1, - 0x4a, 0x93, 0xe3, 0x22, 0x52, 0xd3, 0xf2, 0x9f, 0xd5, 0x6e, 0xce, 0xb1, 0x88, 0x1d, 0x83, 0x8c, - 0x8b, 0x18, 0x11, 0xe2, 0xd6, 0x7b, 0xe6, 0xd8, 0x3d, 0xa9, 0x6a, 0xbf, 0x30, 0xc7, 0xd6, 0x7b, - 0x42, 0xa8, 0xb8, 0xf5, 0x34, 0x11, 0x8a, 0x71, 0xb7, 0x2f, 0x54, 0xed, 0xd6, 0x1c, 0x62, 0xbc, - 0xd9, 0x17, 0xa4, 0x2b, 0x90, 0xa0, 0xfe, 0x39, 0x2c, 0xa6, 0xb5, 0x32, 0xe7, 0x90, 0x0f, 0xa4, - 0xd0, 0x27, 0x42, 0xd9, 0xa2, 0x67, 0x84, 0x49, 0xdb, 0x51, 0x74, 0x22, 0x94, 0x2d, 0x7a, 0xe6, - 0xd7, 0xa1, 0xa8, 0x6d, 0x13, 0x52, 0xf8, 0x65, 0xcb, 0xb4, 0x10, 0xd7, 0x0e, 0x44, 0x8f, 0xce, - 0xad, 0xb2, 0x45, 0xcf, 0x88, 0x6b, 0x07, 0xfe, 0xf0, 0xc0, 0x23, 0x85, 0x5d, 0xb6, 0x4c, 0xab, - 0xfe, 0x2f, 0xde, 0x87, 0x92, 0xe9, 0x54, 0xfd, 0x1f, 0x64, 0xa0, 0xa8, 0x15, 0x0a, 0xff, 0x08, - 0x0a, 0xa1, 0x3a, 0x77, 0x25, 0xf5, 0x61, 0xf9, 0xfe, 0x37, 0xe6, 0x50, 0x42, 0x6b, 0x6d, 0x24, - 0xb0, 0x34, 0x5d, 0xc3, 0x82, 0x02, 0xb5, 0x79, 0x09, 0x72, 0x96, 0xff, 0x8c, 0x2d, 0x70, 0x80, - 0xa2, 0x5e, 0x2c, 0x96, 0x41, 0xe0, 0x96, 0x73, 0xca, 0xb2, 0x08, 0xdc, 0x91, 0xc2, 0x96, 0x01, - 0xcb, 0xf1, 0x25, 0xa8, 0x44, 0xcb, 0x12, 0xb2, 0x3c, 0x67, 0xb0, 0x98, 0x5a, 0xf0, 0x90, 0x15, - 0xea, 0xff, 0x2b, 0x0f, 0x79, 0xdc, 0xff, 0xfc, 0x65, 0x58, 0x52, 0x22, 0xe8, 0x49, 0x6d, 0x08, - 0xc7, 0x46, 0xca, 0x38, 0x90, 0x7f, 0x10, 0x8d, 0x21, 0x4b, 0x63, 0x78, 0xf5, 0xb9, 0x7a, 0x65, - 0x6c, 0x04, 0xa9, 0x53, 0x38, 0x37, 0xdf, 0x29, 0xbc, 0x0d, 0x65, 0x54, 0x67, 0x6d, 0xe7, 0x73, - 0x49, 0x53, 0xbf, 0x7c, 0xff, 0xee, 0xf3, 0x3f, 0xd9, 0x32, 0x14, 0x56, 0x4c, 0xcb, 0x5b, 0x50, - 0xe9, 0x8a, 0xc0, 0xa6, 0xce, 0xd0, 0x6a, 0x2d, 0xdf, 0xff, 0xe6, 0xf3, 0x19, 0x6d, 0x46, 0x24, - 0x56, 0x42, 0xcd, 0x0f, 0xa0, 0x6a, 0xcb, 0xb0, 0x1b, 0x38, 0x43, 0x52, 0x6f, 0xfa, 0x2c, 0xfe, - 0xd6, 0xf3, 0x99, 0x6d, 0x25, 0x44, 0x56, 0x9a, 0x03, 0x5a, 0x64, 0x41, 0xac, 0xdf, 0x4a, 0x64, - 0x20, 0x24, 0x80, 0xc6, 0xbb, 0x50, 0x8e, 0xc6, 0xc3, 0x17, 0xa1, 0x8c, 0x7f, 0xf7, 0x7d, 0x4f, - 0xb2, 0x05, 0x5c, 0x5b, 0x6c, 0xb5, 0x07, 0xc2, 0x75, 0x59, 0x86, 0x2f, 0x03, 0x60, 0x73, 0x4f, - 0xda, 0xce, 0x68, 0xc0, 0xb2, 0x8d, 0x5f, 0x8a, 0xa4, 0xa5, 0x0c, 0xf9, 0x43, 0xd1, 0x43, 0x8a, - 0x45, 0x28, 0x47, 0xea, 0x9a, 0x65, 0x90, 0x7e, 0x4b, 0x84, 0xfd, 0x23, 0x5f, 0x04, 0x36, 0xcb, - 0xf2, 0x2a, 0x94, 0xd6, 0x83, 0x6e, 0xdf, 0x39, 0x95, 0x2c, 0xd7, 0xb8, 0x07, 0xd5, 0x54, 0x7f, - 0x91, 0x85, 0xf9, 0x68, 0x05, 0x0a, 0xeb, 0xb6, 0x2d, 0x6d, 0x96, 0x41, 0x02, 0x33, 0x40, 0x96, - 0x6d, 0x7c, 0x13, 0x2a, 0xf1, 0x6c, 0x21, 0x3a, 0x1e, 0xdc, 0x6c, 0x01, 0x9f, 0x10, 0xcc, 0x32, - 0x28, 0x95, 0x2d, 0xcf, 0x75, 0x3c, 0xc9, 0xb2, 0xf5, 0xbf, 0x48, 0xa2, 0xca, 0xbf, 0x33, 0xbe, - 0x21, 0x5e, 0x79, 0xde, 0xc9, 0x3a, 0xbe, 0x1b, 0x5e, 0x4a, 0x8d, 0x6f, 0xd7, 0xa1, 0xce, 0x95, - 0x21, 0xbf, 0xe5, 0xab, 0x90, 0x65, 0xea, 0xff, 0x3d, 0x0b, 0xe5, 0xe8, 0x40, 0x45, 0x9f, 0x60, - 0x14, 0xb8, 0x46, 0xa0, 0xf1, 0x91, 0x5f, 0x85, 0x82, 0x72, 0x94, 0x11, 0xe3, 0x8a, 0xa5, 0x1b, - 0x68, 0xab, 0xa5, 0x57, 0x56, 0x1b, 0xb0, 0x93, 0x4b, 0xe5, 0x0c, 0x44, 0x4f, 0xee, 0x88, 0xb0, - 0x6f, 0x4c, 0xd8, 0x04, 0x80, 0xf4, 0xc7, 0xe2, 0x14, 0x65, 0x8e, 0xde, 0x6b, 0x2b, 0x2e, 0x0d, - 0xe2, 0x6f, 0x42, 0x1e, 0x07, 0x68, 0x84, 0xe6, 0x17, 0x27, 0x06, 0x8c, 0x62, 0x72, 0x18, 0x48, - 0x5c, 0x9e, 0x35, 0xf4, 0xc0, 0x2c, 0x42, 0xe6, 0xaf, 0xc0, 0xb2, 0xde, 0x84, 0x07, 0x91, 0xff, - 0x50, 0x22, 0xce, 0x13, 0x50, 0xbe, 0x8e, 0xd3, 0x29, 0x94, 0xac, 0x95, 0xe7, 0x90, 0xef, 0x68, - 0x72, 0xd6, 0xda, 0x48, 0x62, 0x69, 0xca, 0xc6, 0xdb, 0x38, 0xa7, 0x42, 0x49, 0x5c, 0xe6, 0xe6, - 0x60, 0xa8, 0xce, 0xb5, 0xd0, 0x6c, 0x4b, 0xd5, 0xed, 0x3b, 0x5e, 0x8f, 0x65, 0xf4, 0x14, 0xe3, - 0x22, 0x12, 0x4a, 0x10, 0xf8, 0x01, 0xcb, 0xd5, 0xeb, 0x90, 0x47, 0x19, 0x45, 0x25, 0xe9, 0x89, - 0x81, 0x34, 0x33, 0x4d, 0xcf, 0xf5, 0x2b, 0xb0, 0x3a, 0x75, 0x1e, 0xd7, 0xff, 0x79, 0x51, 0x4b, - 0x08, 0x52, 0x90, 0x2d, 0x68, 0x28, 0xc8, 0xcc, 0x7b, 0x21, 0x1d, 0x83, 0x5c, 0xc6, 0x75, 0xcc, - 0x07, 0x50, 0xc0, 0x81, 0x45, 0x2a, 0x66, 0x0e, 0xf2, 0x3d, 0x44, 0xb7, 0x34, 0x15, 0x7a, 0x30, - 0xdd, 0xbe, 0xec, 0x9e, 0x48, 0xdb, 0xe8, 0xfa, 0xa8, 0x89, 0x42, 0xd3, 0x4d, 0x99, 0xe7, 0xba, - 0x41, 0x22, 0xd1, 0xf5, 0xbd, 0xe6, 0xc0, 0xff, 0xcc, 0xa1, 0x75, 0x45, 0x91, 0x88, 0x00, 0xd1, - 0xdb, 0x16, 0xca, 0x88, 0x59, 0xb6, 0x04, 0x50, 0x6f, 0x42, 0x81, 0xbe, 0x8d, 0x3b, 0x41, 0xf7, - 0x59, 0x47, 0x1a, 0x5e, 0x99, 0xaf, 0xcf, 0xa6, 0xcb, 0xf5, 0x1f, 0x67, 0x21, 0x8f, 0x6d, 0x7e, - 0x17, 0x0a, 0x01, 0xfa, 0x61, 0x34, 0x9d, 0x17, 0xf9, 0x6c, 0x1a, 0x85, 0x7f, 0x64, 0x44, 0x31, - 0x3b, 0x87, 0xb0, 0xc4, 0x5f, 0x4c, 0x8b, 0xe5, 0x55, 0x28, 0x0c, 0x45, 0x20, 0x06, 0x66, 0x9f, - 0xe8, 0x46, 0xe3, 0x47, 0x19, 0xc8, 0x23, 0x12, 0x5f, 0x85, 0xa5, 0xb6, 0x0a, 0x9c, 0x13, 0xa9, - 0xfa, 0x81, 0x3f, 0xea, 0xf5, 0xb5, 0x24, 0x3d, 0x94, 0xe7, 0x5a, 0xdf, 0x68, 0x85, 0xa0, 0x84, - 0xeb, 0x74, 0x59, 0x16, 0xa5, 0x6a, 0xc3, 0x77, 0x6d, 0x96, 0xe3, 0x2b, 0x50, 0x7d, 0xe4, 0xd9, - 0x32, 0x08, 0xbb, 0x7e, 0x20, 0x6d, 0x96, 0x37, 0xbb, 0xfb, 0x84, 0x15, 0xe8, 0x2c, 0x93, 0x67, - 0x8a, 0x7c, 0x21, 0x56, 0xe4, 0x57, 0x60, 0x65, 0x63, 0xdc, 0x41, 0x62, 0x25, 0xd4, 0x49, 0x7b, - 0xd2, 0x43, 0x21, 0x63, 0x65, 0x2d, 0xc4, 0xfe, 0x67, 0x0e, 0xab, 0xe0, 0xc7, 0xf4, 0x3e, 0x61, - 0xd0, 0xf8, 0x97, 0x99, 0x48, 0x73, 0x2c, 0x41, 0xe5, 0x50, 0x04, 0xa2, 0x17, 0x88, 0x21, 0xf6, - 0xaf, 0x0a, 0x25, 0x7d, 0x70, 0xbe, 0xa1, 0xb5, 0x9b, 0x6e, 0xdc, 0xd7, 0xba, 0x51, 0x37, 0xde, - 0x64, 0xb9, 0xa4, 0xf1, 0x16, 0xcb, 0xe3, 0x37, 0x3e, 0x19, 0xf9, 0x4a, 0xb2, 0x02, 0xe9, 0x3a, - 0xdf, 0x96, 0xac, 0x88, 0xc0, 0x0e, 0x6a, 0x14, 0x56, 0xc2, 0x31, 0x6f, 0xa2, 0xfc, 0x1c, 0xf9, - 0x67, 0xac, 0x8c, 0xdd, 0xc0, 0x69, 0x94, 0x36, 0xab, 0xe0, 0x9b, 0xfd, 0xd1, 0xe0, 0x48, 0xe2, - 0x30, 0x01, 0xdf, 0x74, 0xfc, 0x5e, 0xcf, 0x95, 0xac, 0x8a, 0x73, 0x90, 0x52, 0xbe, 0x6c, 0x91, - 0x34, 0xad, 0x70, 0x5d, 0x7f, 0xa4, 0xd8, 0x52, 0xfd, 0x4f, 0x72, 0x90, 0x47, 0xef, 0x06, 0xf7, - 0x4e, 0x1f, 0xf5, 0x8c, 0xd9, 0x3b, 0xf8, 0x1c, 0xef, 0xc0, 0x6c, 0xb2, 0x03, 0xf9, 0xfb, 0x66, - 0xa5, 0x73, 0x73, 0x68, 0x59, 0x64, 0x9c, 0x5e, 0x64, 0x0e, 0xf9, 0x81, 0x33, 0x90, 0x46, 0xd7, - 0xd1, 0x33, 0xc2, 0x42, 0x3c, 0x8f, 0x0b, 0x14, 0x3c, 0xa1, 0x67, 0xdc, 0x35, 0x02, 0x8f, 0x85, - 0x75, 0x45, 0x7b, 0x20, 0x67, 0x45, 0xcd, 0x19, 0xda, 0xab, 0x32, 0x53, 0x7b, 0x7d, 0x10, 0x69, - 0xaf, 0xd2, 0x1c, 0xbb, 0x9e, 0xba, 0x99, 0xd6, 0x5c, 0x89, 0xd2, 0x28, 0xcf, 0x4f, 0x9e, 0x3a, - 0x4c, 0xb6, 0x8c, 0xd4, 0x26, 0x07, 0x5d, 0x59, 0xcf, 0x32, 0xcb, 0xe0, 0x6a, 0xd2, 0x76, 0xd5, - 0x3a, 0xef, 0xb1, 0x63, 0x4b, 0x9f, 0xe5, 0xe8, 0x20, 0x1c, 0xd9, 0x8e, 0xcf, 0xf2, 0x68, 0x79, - 0x1d, 0x6e, 0x6d, 0xb3, 0x42, 0xe3, 0x95, 0xd4, 0x91, 0xb4, 0x3e, 0x52, 0xbe, 0x66, 0x43, 0xe2, - 0x9b, 0xd1, 0xd2, 0x78, 0x24, 0x6d, 0x96, 0x6d, 0xbc, 0x33, 0x43, 0xcd, 0x2e, 0x41, 0xe5, 0xd1, - 0xd0, 0xf5, 0x85, 0x7d, 0x89, 0x9e, 0x5d, 0x04, 0x48, 0xbc, 0xea, 0xfa, 0x1f, 0xfd, 0x62, 0x72, - 0x9c, 0xa3, 0x2d, 0x1a, 0xfa, 0xa3, 0xa0, 0x2b, 0x49, 0x85, 0x54, 0x2c, 0xd3, 0xe2, 0xdf, 0x85, - 0x02, 0xbe, 0x8f, 0xc2, 0x38, 0x77, 0xe7, 0xf2, 0xe5, 0xd6, 0x1e, 0x3b, 0xf2, 0x99, 0xa5, 0x09, - 0xf9, 0x2d, 0x00, 0xd1, 0x55, 0xce, 0xa9, 0x44, 0xa0, 0xd9, 0xec, 0x29, 0x08, 0x7f, 0x3b, 0x6d, - 0xbe, 0x5c, 0x1e, 0x87, 0x4c, 0xd9, 0x35, 0xdc, 0x82, 0x2a, 0x6e, 0xdd, 0xe1, 0x41, 0x80, 0xbb, - 0xbd, 0xb6, 0x48, 0x84, 0xaf, 0xcf, 0xd7, 0xbd, 0x07, 0x31, 0xa1, 0x95, 0x66, 0xc2, 0x1f, 0xc1, - 0xa2, 0x8e, 0xa9, 0x19, 0xa6, 0x4b, 0xc4, 0xf4, 0x8d, 0xf9, 0x98, 0x1e, 0x24, 0x94, 0xd6, 0x18, - 0x9b, 0xe9, 0xb0, 0x64, 0xe1, 0x85, 0xc3, 0x92, 0xaf, 0xc0, 0x72, 0x67, 0x7c, 0x17, 0xe8, 0xa3, - 0x62, 0x02, 0xca, 0x1b, 0xb0, 0xe8, 0x84, 0x49, 0x54, 0x94, 0x62, 0x24, 0x65, 0x6b, 0x0c, 0x56, - 0xff, 0x77, 0x45, 0xc8, 0xd3, 0xcc, 0x4f, 0xc6, 0xb8, 0x36, 0xc7, 0x54, 0xfa, 0xbd, 0xf9, 0x97, - 0x7a, 0x62, 0xc7, 0x93, 0x06, 0xc9, 0xa5, 0x34, 0xc8, 0x77, 0xa1, 0x10, 0xfa, 0x81, 0x8a, 0x96, - 0x77, 0x4e, 0x21, 0x6a, 0xfb, 0x81, 0xb2, 0x34, 0x21, 0xdf, 0x86, 0xd2, 0xb1, 0xe3, 0x2a, 0x5c, - 0x14, 0x3d, 0x79, 0xaf, 0xcd, 0xc7, 0x63, 0x9b, 0x88, 0xac, 0x88, 0x98, 0xef, 0xa6, 0x85, 0xad, - 0x48, 0x9c, 0xd6, 0xe6, 0xe3, 0x34, 0x4b, 0x06, 0xef, 0x02, 0xeb, 0xfa, 0xa7, 0x32, 0xb0, 0x52, - 0x81, 0x49, 0x7d, 0x48, 0x4f, 0xc1, 0x79, 0x1d, 0xca, 0x7d, 0xc7, 0x96, 0x68, 0xe7, 0x90, 0x8e, - 0x29, 0x5b, 0x71, 0x9b, 0x3f, 0x84, 0x32, 0xf9, 0x07, 0xa8, 0x15, 0x2b, 0x2f, 0x3c, 0xf9, 0xda, - 0x55, 0x89, 0x18, 0xe0, 0x87, 0xe8, 0xe3, 0xdb, 0x8e, 0xa2, 0xf8, 0x74, 0xd9, 0x8a, 0xdb, 0xd8, - 0x61, 0x92, 0xf7, 0x74, 0x87, 0xab, 0xba, 0xc3, 0x93, 0x70, 0xfe, 0x16, 0x5c, 0x23, 0xd8, 0xc4, - 0x21, 0x89, 0x5b, 0x0d, 0x99, 0xce, 0x7e, 0x89, 0x06, 0xcb, 0x50, 0xf4, 0xe4, 0xae, 0x33, 0x70, - 0x54, 0x6d, 0xe9, 0x76, 0xe6, 0x4e, 0xc1, 0x4a, 0x00, 0xfc, 0x35, 0x58, 0xb5, 0xe5, 0xb1, 0x18, - 0xb9, 0xaa, 0x23, 0x07, 0x43, 0x57, 0x28, 0xd9, 0xb2, 0x49, 0x46, 0x2b, 0xd6, 0xf4, 0x0b, 0xfe, - 0x3a, 0x5c, 0x31, 0xc0, 0x83, 0x38, 0xab, 0xd0, 0xb2, 0x29, 0x7c, 0x57, 0xb1, 0x66, 0xbd, 0x6a, - 0xec, 0x19, 0x35, 0x8c, 0x07, 0x28, 0xfa, 0xa9, 0x91, 0x02, 0x0d, 0x95, 0x3e, 0x91, 0x1f, 0x08, - 0xd7, 0x95, 0xc1, 0xb9, 0x76, 0x72, 0x1f, 0x0a, 0xef, 0x48, 0x78, 0x2c, 0x47, 0x67, 0xac, 0x70, - 0xa5, 0x67, 0x8b, 0x40, 0x9f, 0xc8, 0x0f, 0xe8, 0x40, 0x2f, 0x34, 0xee, 0x40, 0x9e, 0xa6, 0xb4, - 0x02, 0x05, 0xed, 0x25, 0x91, 0xc7, 0x6c, 0x3c, 0x24, 0xd2, 0xc8, 0xbb, 0xb8, 0xfd, 0x58, 0xb6, - 0xfe, 0xd3, 0x1c, 0x94, 0xa3, 0xc9, 0x8b, 0x72, 0x08, 0x99, 0x24, 0x87, 0x80, 0x66, 0x5c, 0xf8, - 0xd8, 0x09, 0x9d, 0x23, 0x63, 0x96, 0x96, 0xad, 0x04, 0x80, 0x96, 0xd0, 0x33, 0xc7, 0x56, 0x7d, - 0xda, 0x33, 0x05, 0x4b, 0x37, 0xf8, 0x1d, 0x58, 0xb1, 0x71, 0x1e, 0xbc, 0xae, 0x3b, 0xb2, 0x65, - 0x07, 0x4f, 0x51, 0x1d, 0x26, 0x98, 0x04, 0xf3, 0xef, 0x03, 0x28, 0x67, 0x20, 0xb7, 0xfd, 0x60, - 0x20, 0x94, 0xf1, 0x0d, 0xbe, 0xfd, 0x62, 0x52, 0xbd, 0xd6, 0x89, 0x19, 0x58, 0x29, 0x66, 0xc8, - 0x1a, 0xbf, 0x66, 0x58, 0x97, 0xbe, 0x14, 0xeb, 0xad, 0x98, 0x81, 0x95, 0x62, 0xd6, 0xf8, 0x65, - 0x80, 0xe4, 0x0d, 0xbf, 0x0e, 0x7c, 0xcf, 0xf7, 0x54, 0x7f, 0xfd, 0xe8, 0x28, 0xd8, 0x90, 0xc7, - 0x7e, 0x20, 0xb7, 0x04, 0x1e, 0x6b, 0xd7, 0x60, 0x35, 0x86, 0xaf, 0x1f, 0x2b, 0x19, 0x20, 0x98, - 0xa6, 0xbe, 0xdd, 0xf7, 0x03, 0xa5, 0x6d, 0x2b, 0x7a, 0x7c, 0xd4, 0x66, 0x39, 0x3c, 0x4a, 0x5b, - 0xed, 0x03, 0x96, 0x6f, 0xdc, 0x01, 0x48, 0x86, 0x44, 0x3e, 0x08, 0x3d, 0xbd, 0x71, 0xdf, 0x78, - 0x24, 0xd4, 0xba, 0xff, 0x16, 0xcb, 0xd4, 0xff, 0x30, 0x07, 0x79, 0x54, 0x35, 0xe8, 0x7e, 0xa5, - 0xf7, 0x85, 0x5e, 0xbe, 0x34, 0xe8, 0xcb, 0x29, 0x48, 0xe4, 0x9d, 0x56, 0x90, 0xef, 0x41, 0xb5, - 0x3b, 0x0a, 0x95, 0x3f, 0xa0, 0xd3, 0xc1, 0x24, 0x60, 0xae, 0x4f, 0x05, 0x32, 0x1e, 0x0b, 0x77, - 0x24, 0xad, 0x34, 0x2a, 0x7f, 0x1b, 0x8a, 0xc7, 0x7a, 0x21, 0x74, 0x28, 0xe3, 0x17, 0x2e, 0x38, - 0x40, 0xcc, 0x64, 0x1b, 0x64, 0x1c, 0x97, 0x33, 0x25, 0x44, 0x69, 0x90, 0x39, 0x08, 0x8a, 0xf1, - 0x41, 0xf0, 0xcb, 0xb0, 0x2c, 0xd1, 0xac, 0x38, 0x74, 0x45, 0x57, 0x0e, 0xa4, 0x17, 0xad, 0xfc, - 0x5b, 0x2f, 0x30, 0x62, 0xb2, 0x4b, 0x68, 0xd8, 0x13, 0xbc, 0x1a, 0x5f, 0x37, 0x9b, 0xb4, 0x04, - 0xb9, 0xf5, 0xb0, 0x6b, 0xdc, 0x6e, 0x19, 0x76, 0xb5, 0x4d, 0xbf, 0x49, 0x03, 0x66, 0xd9, 0xc6, - 0x1b, 0x50, 0x89, 0x79, 0x70, 0x06, 0x8b, 0xfb, 0xbe, 0x6a, 0x0f, 0x65, 0xd7, 0x39, 0x76, 0xa4, - 0xad, 0x03, 0x09, 0x6d, 0x25, 0x02, 0xa5, 0x23, 0x57, 0x4d, 0xcf, 0x66, 0xd9, 0xfa, 0xef, 0x95, - 0xa1, 0xa8, 0x35, 0xbe, 0x19, 0x52, 0x25, 0x1e, 0xd2, 0x27, 0x50, 0xf6, 0x87, 0x32, 0x10, 0xca, - 0x0f, 0x4c, 0xb8, 0xe0, 0xed, 0x17, 0x39, 0x41, 0xd6, 0x0e, 0x0c, 0xb1, 0x15, 0xb3, 0x99, 0x94, - 0x97, 0xec, 0xb4, 0xbc, 0xdc, 0x05, 0x16, 0x1d, 0x16, 0x87, 0x01, 0xd2, 0xa9, 0x73, 0xe3, 0xfc, - 0x4d, 0xc1, 0x79, 0x07, 0x2a, 0x5d, 0xdf, 0xb3, 0x9d, 0x38, 0x74, 0xb0, 0x7c, 0xff, 0x9d, 0x17, - 0xea, 0xe1, 0x66, 0x44, 0x6d, 0x25, 0x8c, 0xf8, 0x6b, 0x50, 0x38, 0x45, 0x41, 0x22, 0x89, 0xb9, - 0x58, 0xcc, 0x34, 0x12, 0xff, 0x14, 0xaa, 0x3f, 0x18, 0x39, 0xdd, 0x93, 0x83, 0x74, 0x68, 0xea, - 0xbd, 0x17, 0xea, 0xc5, 0x27, 0x09, 0xbd, 0x95, 0x66, 0x96, 0x12, 0xde, 0xd2, 0x9f, 0x42, 0x78, - 0xcb, 0xd3, 0xc2, 0x6b, 0xc1, 0x92, 0x27, 0x43, 0x25, 0xed, 0x6d, 0x63, 0x20, 0xc0, 0x97, 0x30, - 0x10, 0xc6, 0x59, 0x34, 0xbe, 0x06, 0xe5, 0x68, 0xc1, 0x79, 0x11, 0xb2, 0xfb, 0x68, 0x89, 0x17, - 0x21, 0x7b, 0x10, 0x68, 0x69, 0x5b, 0x47, 0x69, 0x6b, 0xfc, 0x71, 0x06, 0x2a, 0xf1, 0xa4, 0x8f, - 0x87, 0xb8, 0x9a, 0x3f, 0x18, 0x09, 0x97, 0x65, 0xc8, 0x47, 0xf3, 0x95, 0x6e, 0x91, 0xa6, 0x7a, - 0x40, 0x19, 0xe2, 0x80, 0xe5, 0xe8, 0x5c, 0x92, 0x61, 0xc8, 0xf2, 0x9c, 0xc3, 0xb2, 0x01, 0x1f, - 0x04, 0x1a, 0xb5, 0x80, 0x2e, 0x1c, 0xbe, 0x8d, 0x00, 0x45, 0x7d, 0x8c, 0x9d, 0x48, 0xed, 0xa2, - 0xee, 0xfb, 0x8a, 0x1a, 0x65, 0xec, 0x54, 0xcb, 0x63, 0x15, 0xfc, 0xe6, 0xbe, 0xaf, 0x5a, 0x1e, - 0x83, 0xc4, 0x27, 0xa8, 0x46, 0x9f, 0xa7, 0xd6, 0x22, 0x79, 0x1c, 0xae, 0xdb, 0xf2, 0xd8, 0x92, - 0x79, 0xa1, 0x5b, 0xcb, 0xc8, 0xb1, 0x79, 0x26, 0xba, 0x48, 0xbe, 0xc2, 0x97, 0x01, 0x90, 0xc6, - 0xb4, 0x19, 0x6e, 0xc9, 0xe6, 0x99, 0x13, 0xaa, 0x90, 0xad, 0x36, 0xfe, 0x6d, 0x06, 0xaa, 0xa9, - 0x05, 0x46, 0x9f, 0x83, 0x10, 0x51, 0x8f, 0x6b, 0x17, 0xe4, 0xfb, 0x38, 0x8d, 0x81, 0x1d, 0xe9, - 0xe8, 0x8e, 0x8f, 0x8f, 0x59, 0xfc, 0x5e, 0xc7, 0x1f, 0xf8, 0x41, 0xe0, 0x3f, 0xd3, 0xe7, 0xed, - 0xae, 0x08, 0xd5, 0x13, 0x29, 0x4f, 0x58, 0x1e, 0x87, 0xba, 0x39, 0x0a, 0x02, 0xe9, 0x69, 0x40, - 0x81, 0x3a, 0x27, 0xcf, 0x74, 0xab, 0x88, 0x4c, 0x11, 0x99, 0x0e, 0x01, 0x56, 0x42, 0x45, 0x60, - 0xb0, 0x35, 0xa4, 0x8c, 0x08, 0x88, 0xae, 0x9b, 0x15, 0x74, 0xeb, 0xb5, 0x5b, 0x7c, 0x70, 0xbc, - 0x25, 0xce, 0xc3, 0xf5, 0x9e, 0xcf, 0x60, 0x12, 0xb8, 0xef, 0x3f, 0x63, 0xd5, 0xfa, 0x08, 0x20, - 0x71, 0x04, 0xd0, 0x01, 0x42, 0x81, 0x88, 0x03, 0xd7, 0xa6, 0xc5, 0x0f, 0x00, 0xf0, 0x89, 0x30, - 0x23, 0x2f, 0xe8, 0x05, 0xac, 0x33, 0xa2, 0xb3, 0x52, 0x2c, 0xea, 0x7f, 0x19, 0x2a, 0xf1, 0x0b, - 0xf4, 0x7b, 0xc9, 0x8e, 0x8a, 0x3f, 0x1b, 0x35, 0xd1, 0x28, 0x70, 0x3c, 0x5b, 0x9e, 0x91, 0x5e, - 0x29, 0x58, 0xba, 0x81, 0xbd, 0xec, 0x3b, 0xb6, 0x2d, 0xbd, 0x28, 0xbd, 0xa0, 0x5b, 0xb3, 0x92, - 0xc0, 0xf9, 0x99, 0x49, 0xe0, 0xfa, 0xaf, 0x40, 0x35, 0xe5, 0xa9, 0x5c, 0x38, 0xec, 0x54, 0xc7, - 0xb2, 0xe3, 0x1d, 0xbb, 0x09, 0x95, 0xa8, 0xf0, 0x20, 0xa4, 0xd3, 0xab, 0x62, 0x25, 0x80, 0xfa, - 0x3f, 0xcb, 0xa2, 0xf9, 0x84, 0x43, 0x9b, 0xf4, 0x2e, 0xb6, 0xa1, 0x88, 0xae, 0xf6, 0x28, 0xca, - 0xa0, 0xcf, 0xb9, 0x41, 0xdb, 0x44, 0xb3, 0xb3, 0x60, 0x19, 0x6a, 0xfe, 0x01, 0xe4, 0x94, 0xe8, - 0x99, 0xe8, 0xdc, 0x37, 0xe6, 0x63, 0xd2, 0x11, 0xbd, 0x9d, 0x05, 0x0b, 0xe9, 0xf8, 0x2e, 0x94, - 0xbb, 0x26, 0xa0, 0x62, 0x94, 0xe2, 0x9c, 0x0e, 0x40, 0x14, 0x86, 0xd9, 0x59, 0xb0, 0x62, 0x0e, - 0xfc, 0xbb, 0x90, 0x47, 0x93, 0xc6, 0x14, 0x1a, 0xcc, 0xe9, 0xd8, 0xe0, 0x76, 0xd9, 0x59, 0xb0, - 0x88, 0x72, 0xa3, 0x04, 0x05, 0xd2, 0xc1, 0xf5, 0x1a, 0x14, 0xf5, 0x58, 0x27, 0x67, 0xae, 0x7e, - 0x03, 0x72, 0x1d, 0xd1, 0x43, 0xb3, 0xd2, 0xb1, 0x43, 0xe3, 0x9f, 0xe3, 0x63, 0xfd, 0xe5, 0x24, - 0x38, 0x94, 0x8e, 0x3b, 0x66, 0xc6, 0xe2, 0x8e, 0xf5, 0x22, 0xe4, 0xf1, 0x8b, 0xf5, 0x9b, 0x97, - 0x99, 0xa8, 0xf5, 0x7f, 0x94, 0x43, 0x6b, 0x56, 0xc9, 0xb3, 0x99, 0x31, 0xd5, 0x8f, 0xa1, 0x32, - 0x0c, 0xfc, 0xae, 0x0c, 0x43, 0x3f, 0x30, 0xe6, 0xcf, 0x6b, 0xcf, 0xcf, 0x77, 0xae, 0x1d, 0x46, - 0x34, 0x56, 0x42, 0xde, 0xf8, 0x57, 0x59, 0xa8, 0xc4, 0x2f, 0xb4, 0x11, 0xad, 0xe4, 0x99, 0x8e, - 0x9f, 0xed, 0xc9, 0x60, 0x20, 0x1c, 0x5b, 0x6b, 0x8f, 0xcd, 0xbe, 0x88, 0x2c, 0xbc, 0xef, 0xfb, - 0x23, 0x35, 0x3a, 0x92, 0x3a, 0x6e, 0xf2, 0xd8, 0x19, 0x48, 0x9f, 0xe5, 0x29, 0x63, 0x81, 0x82, - 0xdd, 0x75, 0xfd, 0x91, 0xcd, 0x0a, 0xd8, 0x7e, 0x40, 0xc7, 0xdb, 0x9e, 0x18, 0x86, 0x5a, 0x67, - 0xee, 0x39, 0x81, 0xcf, 0x4a, 0x48, 0xb4, 0xed, 0xf4, 0x06, 0x82, 0x95, 0x91, 0x59, 0xe7, 0x99, - 0xa3, 0x50, 0x09, 0x57, 0xf8, 0x2a, 0x2c, 0x1d, 0x0c, 0xa5, 0xd7, 0x56, 0x81, 0x94, 0x6a, 0x4f, - 0x0c, 0x75, 0x20, 0xcd, 0x92, 0xb6, 0xed, 0x28, 0xad, 0x3f, 0xb7, 0x45, 0x57, 0x1e, 0xf9, 0xfe, - 0x09, 0x5b, 0x44, 0x45, 0xd3, 0xf2, 0x42, 0x25, 0x7a, 0x81, 0x18, 0x68, 0x1d, 0xda, 0x91, 0xae, - 0xa4, 0xd6, 0x32, 0x7d, 0xdb, 0x51, 0xfd, 0xd1, 0xd1, 0x03, 0x74, 0x36, 0x56, 0x74, 0x72, 0xc3, - 0x96, 0x43, 0x89, 0x3a, 0x74, 0x11, 0xca, 0x1b, 0x8e, 0xeb, 0x1c, 0x39, 0xae, 0xc3, 0x56, 0x11, - 0xb5, 0x79, 0xd6, 0x15, 0xae, 0x63, 0x07, 0xe2, 0x19, 0xe3, 0xd8, 0xb9, 0x87, 0x81, 0x7f, 0xe2, - 0xb0, 0x2b, 0x88, 0x48, 0xbe, 0xc7, 0xa9, 0xf3, 0x39, 0xbb, 0x4a, 0x09, 0x9a, 0x13, 0xa9, 0xba, - 0xfd, 0x63, 0x71, 0xc4, 0xae, 0x25, 0x71, 0xa4, 0xeb, 0xf5, 0x55, 0x58, 0x99, 0x48, 0x05, 0xd7, - 0x4b, 0xc6, 0xe5, 0xa9, 0x2f, 0x41, 0x35, 0x95, 0xa3, 0xab, 0xbf, 0x02, 0xe5, 0x28, 0x83, 0x87, - 0xae, 0xa1, 0x13, 0xea, 0xd8, 0xa3, 0x11, 0x92, 0xb8, 0x5d, 0xff, 0xfd, 0x0c, 0x14, 0x75, 0xfa, - 0x94, 0x6f, 0xc4, 0xe5, 0x0e, 0x99, 0x39, 0x52, 0x66, 0x9a, 0xc8, 0x24, 0x1c, 0xe3, 0x9a, 0x87, - 0xab, 0x50, 0x70, 0xc9, 0x07, 0x34, 0xea, 0x8b, 0x1a, 0x29, 0x6d, 0x93, 0x4b, 0x6b, 0x9b, 0xc6, - 0x7a, 0x9c, 0xe4, 0x8c, 0xe2, 0x5d, 0x64, 0x15, 0x76, 0x02, 0x29, 0x75, 0x2c, 0x8b, 0x5c, 0xb8, - 0x2c, 0x9d, 0x15, 0xfe, 0x60, 0x28, 0xba, 0x8a, 0x00, 0x74, 0x8a, 0xa2, 0x32, 0x65, 0x79, 0x94, - 0xf2, 0xcd, 0xbe, 0x50, 0x8d, 0x63, 0x28, 0x1f, 0xfa, 0xe1, 0xe4, 0x99, 0x5c, 0x82, 0x5c, 0xc7, - 0x1f, 0x6a, 0x0b, 0x73, 0xc3, 0x57, 0x64, 0x61, 0xea, 0x23, 0xf8, 0x58, 0x69, 0xa1, 0xb2, 0x9c, - 0x5e, 0x5f, 0x69, 0xf7, 0xaf, 0xe5, 0x79, 0x32, 0x60, 0x05, 0x5c, 0x43, 0x4b, 0x0e, 0xd1, 0x6e, - 0x65, 0x45, 0x5c, 0x35, 0x82, 0x6f, 0x3b, 0x41, 0xa8, 0x58, 0xa9, 0xd1, 0xc2, 0xd3, 0xd4, 0xe9, - 0xd1, 0x21, 0x48, 0x0f, 0xc4, 0x6a, 0x01, 0xbb, 0x48, 0xcd, 0x4d, 0xe9, 0xa1, 0x8c, 0x51, 0x5e, - 0x4d, 0x57, 0xc4, 0xd0, 0x07, 0xb2, 0x78, 0x82, 0x51, 0xfb, 0xe3, 0x51, 0xa8, 0x9c, 0xe3, 0x73, - 0x96, 0x6b, 0x3c, 0x81, 0xa5, 0xb1, 0xda, 0x19, 0x7e, 0x15, 0xd8, 0x18, 0x00, 0xbb, 0xbe, 0xc0, - 0x6f, 0xc0, 0x95, 0x31, 0xe8, 0x9e, 0x63, 0xdb, 0x14, 0x60, 0x9c, 0x7c, 0x11, 0x0d, 0x70, 0xa3, - 0x02, 0xa5, 0xae, 0x5e, 0xa5, 0xc6, 0x21, 0x2c, 0xd1, 0xb2, 0xed, 0x49, 0x25, 0x0e, 0x3c, 0xf7, - 0xfc, 0x4f, 0x5d, 0xe0, 0xd4, 0xf8, 0x26, 0x14, 0x28, 0x21, 0x80, 0xfa, 0xe2, 0x38, 0xf0, 0x07, - 0xc4, 0xab, 0x60, 0xd1, 0x33, 0x72, 0x57, 0xbe, 0x59, 0xfb, 0xac, 0xf2, 0x1b, 0x5f, 0x94, 0xa1, - 0xb4, 0xde, 0xed, 0xfa, 0x23, 0x4f, 0x4d, 0x7d, 0xf9, 0x6d, 0x28, 0x76, 0x7d, 0xef, 0xd8, 0xe9, - 0x19, 0x7d, 0x3c, 0x69, 0x19, 0x1a, 0x3a, 0x14, 0xb8, 0x63, 0xa7, 0x67, 0x19, 0x64, 0x24, 0x33, - 0xe7, 0x49, 0xe1, 0x52, 0x32, 0xad, 0x54, 0xe3, 0xe3, 0xe3, 0x1e, 0xe4, 0x1d, 0xef, 0xd8, 0x37, - 0xd5, 0x88, 0x2f, 0x5d, 0x40, 0x44, 0x25, 0x79, 0x84, 0x58, 0xff, 0xaf, 0x19, 0x28, 0xea, 0x4f, - 0xf3, 0x57, 0x60, 0x59, 0x7a, 0xb8, 0x99, 0x22, 0x55, 0x6e, 0x76, 0xd1, 0x04, 0x14, 0x8d, 0x56, - 0x03, 0x91, 0x47, 0xa3, 0x9e, 0x71, 0xf8, 0xd3, 0x20, 0xfe, 0x1e, 0xdc, 0xd0, 0xcd, 0xc3, 0x40, - 0x06, 0xd2, 0x95, 0x22, 0x94, 0x9b, 0x7d, 0xe1, 0x79, 0xd2, 0x35, 0x07, 0xfb, 0x45, 0xaf, 0x79, - 0x03, 0x16, 0xf5, 0xab, 0xf6, 0x50, 0x74, 0x65, 0x68, 0x92, 0x4c, 0x63, 0x30, 0xfe, 0x2d, 0x28, - 0x50, 0xb1, 0x66, 0xcd, 0xbe, 0x7c, 0x29, 0x35, 0x56, 0xdd, 0x8f, 0x4f, 0x9e, 0x75, 0x00, 0x3d, - 0x4d, 0xe8, 0x74, 0x99, 0xdd, 0xff, 0xd5, 0x4b, 0xe7, 0x95, 0x3c, 0xbc, 0x14, 0x11, 0xf6, 0xcf, - 0x96, 0xae, 0xa4, 0xaa, 0x3a, 0x3c, 0x19, 0xb3, 0x14, 0xce, 0x1f, 0x83, 0xd5, 0x7f, 0x2d, 0x0f, - 0x79, 0x9c, 0x61, 0x44, 0xee, 0xfb, 0x03, 0x19, 0x07, 0x35, 0xb5, 0xa9, 0x31, 0x06, 0x43, 0xd3, - 0x46, 0xe8, 0xbc, 0x72, 0x8c, 0xa6, 0x95, 0xc7, 0x24, 0x18, 0x31, 0x87, 0x81, 0x7f, 0xec, 0xb8, - 0x09, 0xa6, 0x31, 0x82, 0x26, 0xc0, 0xfc, 0x1d, 0xb8, 0x3e, 0x10, 0xc1, 0x89, 0x54, 0xb4, 0xbb, - 0x9f, 0xf8, 0xc1, 0x49, 0x88, 0x33, 0xd7, 0xb2, 0x4d, 0x34, 0xec, 0x82, 0xb7, 0xa8, 0x40, 0x6d, - 0x79, 0xea, 0x10, 0x66, 0x59, 0x17, 0x61, 0x46, 0x6d, 0x14, 0x0e, 0xa1, 0xa7, 0xa6, 0x6d, 0x78, - 0x99, 0x44, 0xc5, 0x38, 0x14, 0xed, 0x27, 0x5d, 0x9c, 0x12, 0xb6, 0x6c, 0x0a, 0xd0, 0x55, 0xac, - 0x04, 0x80, 0xa2, 0x43, 0x1f, 0x7b, 0xac, 0xd5, 0xe4, 0x92, 0x76, 0x2a, 0x53, 0x20, 0xc4, 0x50, - 0xb2, 0xdb, 0x8f, 0x3e, 0xa2, 0xa3, 0x67, 0x69, 0x10, 0xbf, 0x05, 0xd0, 0x13, 0x4a, 0x3e, 0x13, - 0xe7, 0x8f, 0x02, 0xb7, 0x26, 0x75, 0xc4, 0x3d, 0x81, 0xa0, 0x5b, 0xea, 0xfa, 0x5d, 0xe1, 0xb6, - 0x95, 0x1f, 0x88, 0x9e, 0x3c, 0x14, 0xaa, 0x5f, 0xeb, 0x69, 0xb7, 0x74, 0x12, 0x8e, 0x23, 0x56, - 0xce, 0x40, 0x7e, 0xea, 0x7b, 0xb2, 0xd6, 0xd7, 0x23, 0x8e, 0xda, 0xd8, 0x13, 0xe1, 0x09, 0xf7, - 0x5c, 0x39, 0x5d, 0x1c, 0x8b, 0xa3, 0x7b, 0x92, 0x02, 0xe1, 0x58, 0x3d, 0xa9, 0x9e, 0xf9, 0xc1, - 0x49, 0xcb, 0xae, 0x7d, 0xa6, 0xc7, 0x1a, 0x03, 0x1a, 0x07, 0x00, 0x89, 0x10, 0xa1, 0x66, 0x5e, - 0xa7, 0xac, 0x00, 0x5b, 0x40, 0x7b, 0xfd, 0x50, 0x7a, 0xb6, 0xe3, 0xf5, 0xb6, 0x8c, 0xdc, 0xb0, - 0x0c, 0x02, 0xc9, 0xe3, 0x97, 0x76, 0x0c, 0x24, 0xdb, 0x80, 0x5a, 0xd2, 0x66, 0xb9, 0xc6, 0xff, - 0xc9, 0x40, 0x35, 0x95, 0x04, 0xff, 0x33, 0x4c, 0xdc, 0xe3, 0xc9, 0x89, 0x67, 0x2f, 0x4e, 0xa8, - 0x96, 0xa9, 0xb8, 0x8d, 0xd3, 0x6d, 0x72, 0xf4, 0xf8, 0x56, 0xfb, 0xf7, 0x29, 0xc8, 0x97, 0x4a, - 0xda, 0x37, 0xee, 0x9b, 0x20, 0x49, 0x15, 0x4a, 0x8f, 0xbc, 0x13, 0xcf, 0x7f, 0xe6, 0xe9, 0x23, - 0x91, 0x2a, 0x31, 0xc6, 0x72, 0x4a, 0x51, 0xb1, 0x44, 0xae, 0xf1, 0x8f, 0xf3, 0x13, 0x45, 0x4b, - 0x4d, 0x28, 0x6a, 0xcb, 0x9c, 0x8c, 0xc6, 0xe9, 0x2a, 0x93, 0x34, 0xb2, 0xc9, 0x5f, 0xa4, 0x40, - 0x96, 0x21, 0x46, 0x93, 0x39, 0x2e, 0xe9, 0xcb, 0xce, 0xcc, 0xb3, 0x8c, 0x31, 0x8a, 0xd4, 0xe0, - 0x58, 0x55, 0x6b, 0xcc, 0xa1, 0xfe, 0x37, 0x32, 0x70, 0x75, 0x16, 0x4a, 0xba, 0xf6, 0x37, 0x33, - 0x5e, 0xfb, 0xdb, 0x9e, 0xa8, 0xa5, 0xcd, 0xd2, 0x68, 0xee, 0xbd, 0x60, 0x27, 0xc6, 0x2b, 0x6b, - 0x1b, 0x3f, 0xce, 0xc0, 0xea, 0xd4, 0x98, 0x53, 0x26, 0x03, 0x40, 0x51, 0x4b, 0x96, 0x2e, 0x75, - 0x89, 0x8b, 0x0f, 0x74, 0xf0, 0x98, 0x0e, 0xd3, 0x50, 0x67, 0x73, 0x4d, 0xf5, 0xb0, 0xb6, 0x48, - 0x71, 0xd5, 0x50, 0x57, 0xf7, 0x24, 0x2b, 0xe0, 0x59, 0xaf, 0xed, 0x1a, 0x03, 0x29, 0x6a, 0xab, - 0x51, 0x47, 0xb8, 0x59, 0x89, 0x4a, 0x68, 0x46, 0x43, 0xd7, 0xe9, 0x62, 0xb3, 0xcc, 0xeb, 0x70, - 0x5d, 0x97, 0x90, 0x1b, 0x0f, 0xed, 0xb8, 0xd3, 0x77, 0x68, 0x73, 0xb0, 0x4a, 0xc3, 0x82, 0x2b, - 0x33, 0xc6, 0x44, 0xbd, 0x7c, 0x6c, 0x7a, 0xbc, 0x0c, 0xb0, 0xf5, 0x38, 0xea, 0x27, 0xcb, 0x70, - 0x0e, 0xcb, 0x5b, 0x8f, 0xd3, 0x0c, 0xcd, 0x7e, 0x79, 0x8c, 0x9a, 0x24, 0x64, 0xb9, 0xc6, 0xaf, - 0x67, 0xa2, 0xb4, 0x76, 0xfd, 0x2f, 0xc1, 0x92, 0xee, 0xe3, 0xa1, 0x38, 0x77, 0x7d, 0x61, 0xf3, - 0x26, 0x2c, 0x87, 0xf1, 0xbd, 0x86, 0xd4, 0x71, 0x30, 0x79, 0xcc, 0xb6, 0xc7, 0x90, 0xac, 0x09, - 0xa2, 0xc8, 0xd1, 0xc8, 0x26, 0xb1, 0x70, 0x4e, 0x2e, 0x93, 0xa0, 0x5d, 0xb6, 0x48, 0x4e, 0x90, - 0x68, 0x7c, 0x0b, 0x56, 0x49, 0x79, 0xe9, 0xce, 0x68, 0x8b, 0x14, 0xe5, 0x41, 0xeb, 0xdd, 0xad, - 0x48, 0x1e, 0x4c, 0xb3, 0xf1, 0x1f, 0x8a, 0x00, 0x49, 0xdc, 0x7f, 0xc6, 0x36, 0x9f, 0x95, 0xc6, - 0x9e, 0xca, 0xc2, 0xe5, 0x5e, 0x38, 0x0b, 0xf7, 0x5e, 0x6c, 0x18, 0xeb, 0x00, 0xec, 0x64, 0x2d, - 0x6f, 0xd2, 0xa7, 0x49, 0x73, 0x78, 0xac, 0xca, 0xa3, 0x30, 0x59, 0xe5, 0x71, 0x7b, 0xba, 0x24, - 0x6c, 0x42, 0xff, 0x24, 0x7e, 0x7f, 0x69, 0xcc, 0xef, 0xaf, 0x43, 0x39, 0x90, 0xc2, 0xf6, 0x3d, - 0xf7, 0x3c, 0x4a, 0xf6, 0x44, 0x6d, 0xfe, 0x26, 0x14, 0x14, 0x5d, 0xcd, 0x28, 0xd3, 0x76, 0x79, - 0xce, 0xc2, 0x69, 0x5c, 0x54, 0x66, 0x4e, 0x68, 0xea, 0xb8, 0xf4, 0x09, 0x56, 0xb6, 0x52, 0x10, - 0xbe, 0x06, 0xdc, 0x41, 0x27, 0xc8, 0x75, 0xa5, 0xbd, 0x71, 0xbe, 0xa5, 0x73, 0x30, 0x74, 0x6a, - 0x96, 0xad, 0x19, 0x6f, 0xa2, 0xf5, 0x5f, 0x4c, 0xd6, 0x9f, 0xba, 0x7c, 0xea, 0x84, 0x38, 0xd2, - 0x25, 0x32, 0x0e, 0xe2, 0x36, 0x9e, 0xcb, 0xd1, 0x1e, 0xd5, 0x73, 0x49, 0xd2, 0x9b, 0x24, 0x32, - 0x2f, 0x78, 0xdb, 0xf8, 0x83, 0x6c, 0xec, 0x40, 0x54, 0xa0, 0x70, 0x24, 0x42, 0xa7, 0xab, 0xfd, - 0x49, 0x73, 0xf0, 0x6b, 0x27, 0x42, 0xf9, 0xb6, 0xcf, 0xb2, 0xe8, 0x0b, 0x84, 0x12, 0xad, 0xfe, - 0x65, 0x80, 0xe4, 0xba, 0x0a, 0xcb, 0xe3, 0xde, 0x8c, 0xd6, 0x5b, 0x97, 0x63, 0x10, 0x29, 0x85, - 0xa0, 0xec, 0xb8, 0xd0, 0x8d, 0x9c, 0x49, 0xd2, 0xfd, 0xac, 0x8c, 0x38, 0x9e, 0xaf, 0xa4, 0x0e, - 0xc0, 0x91, 0x74, 0x32, 0x40, 0x36, 0x51, 0xfd, 0x35, 0xab, 0xa2, 0x71, 0x1e, 0x31, 0xd5, 0x51, - 0xb3, 0x90, 0x5c, 0x97, 0x45, 0xdc, 0x9d, 0xe3, 0x2f, 0xd8, 0x12, 0xf6, 0x28, 0xb9, 0x05, 0xc3, - 0x96, 0x91, 0xab, 0xa0, 0x22, 0x81, 0x15, 0x7c, 0x3c, 0xa5, 0xd2, 0x01, 0x86, 0x5f, 0xb5, 0x51, - 0x61, 0xac, 0x62, 0xcf, 0x62, 0xd3, 0x80, 0x71, 0xf4, 0x3d, 0x86, 0x02, 0x1d, 0x01, 0x67, 0x28, - 0x3c, 0xc5, 0xae, 0xe0, 0x50, 0x87, 0xf6, 0x31, 0xbb, 0x8a, 0x24, 0xdd, 0xbe, 0x50, 0xec, 0x1a, - 0xe2, 0xe0, 0xd3, 0x96, 0x0c, 0x70, 0x3d, 0xd9, 0x75, 0xc4, 0x51, 0xa2, 0xc7, 0x6e, 0x34, 0x7e, - 0x3b, 0x29, 0x35, 0x7d, 0x3d, 0x36, 0xd1, 0xe7, 0x11, 0x72, 0x34, 0xe2, 0x67, 0xed, 0xb8, 0x26, - 0xac, 0x06, 0xf2, 0x07, 0x23, 0x67, 0xac, 0x00, 0x3b, 0x77, 0x79, 0x86, 0x7f, 0x9a, 0xa2, 0x71, - 0x0a, 0xab, 0x51, 0xe3, 0x89, 0xa3, 0xfa, 0x14, 0x2d, 0xe1, 0x6f, 0xa6, 0x2a, 0xc4, 0x33, 0x33, - 0x6f, 0xd6, 0xc4, 0x2c, 0x93, 0x8a, 0xf0, 0x38, 0x1a, 0x9e, 0x9d, 0x23, 0x1a, 0xde, 0xf8, 0xdf, - 0xc5, 0x54, 0xc0, 0x44, 0x3b, 0x2d, 0x76, 0xec, 0xb4, 0x4c, 0xe7, 0xf8, 0x92, 0x00, 0x77, 0xf6, - 0x45, 0x02, 0xdc, 0xb3, 0xf2, 0xe5, 0xef, 0xa3, 0x0d, 0x4d, 0xfb, 0xe7, 0xf1, 0x1c, 0xc1, 0xfb, - 0x31, 0x5c, 0xbe, 0x41, 0x19, 0x3b, 0xd1, 0xd6, 0xc5, 0x1c, 0x85, 0x99, 0xf7, 0x35, 0xd2, 0xa9, - 0x39, 0x83, 0x69, 0xa5, 0xa8, 0x52, 0xda, 0xa6, 0x38, 0x4b, 0xdb, 0xa0, 0xff, 0x68, 0xf4, 0x50, - 0xdc, 0xd6, 0xb9, 0x0e, 0xfd, 0x1c, 0xb1, 0xa7, 0x4c, 0x6d, 0xd9, 0x9a, 0x82, 0xa3, 0x15, 0x36, - 0x18, 0xb9, 0xca, 0x31, 0xe1, 0x7c, 0xdd, 0x98, 0xbc, 0x50, 0x56, 0x99, 0xbe, 0x50, 0xf6, 0x21, - 0x40, 0x28, 0x71, 0x77, 0x6c, 0x39, 0x5d, 0x65, 0x4a, 0x3e, 0x6e, 0x5d, 0x34, 0x36, 0x93, 0x84, - 0x48, 0x51, 0x60, 0xff, 0x07, 0xe2, 0x6c, 0x13, 0xad, 0x71, 0x93, 0x9b, 0x8e, 0xdb, 0x93, 0x3a, - 0x78, 0x79, 0x5a, 0x07, 0xbf, 0x09, 0x85, 0xb0, 0xeb, 0x0f, 0x25, 0xdd, 0x89, 0xb8, 0x78, 0x7d, - 0xd7, 0xda, 0x88, 0x64, 0x69, 0x5c, 0x0a, 0xcb, 0xa1, 0x96, 0xf2, 0x03, 0xba, 0x0d, 0x51, 0xb1, - 0xa2, 0xe6, 0x98, 0x1e, 0xbc, 0x3e, 0xae, 0x07, 0xeb, 0x36, 0x14, 0x4d, 0x88, 0x7d, 0xd2, 0x59, - 0x8e, 0x82, 0x73, 0xd9, 0x54, 0x70, 0x2e, 0x2e, 0x2c, 0xcc, 0xa5, 0x0b, 0x0b, 0x27, 0x2e, 0x4c, - 0x15, 0xa6, 0x2e, 0x4c, 0x35, 0x3e, 0x85, 0x02, 0xf5, 0x15, 0x8d, 0x08, 0x3d, 0xcd, 0xda, 0xc6, - 0xc4, 0x41, 0xb1, 0x0c, 0xbf, 0x0a, 0x2c, 0x94, 0x64, 0x84, 0xc8, 0xb6, 0x18, 0x48, 0x52, 0x92, - 0x59, 0x5e, 0x83, 0xab, 0x1a, 0x37, 0x1c, 0x7f, 0x43, 0x96, 0x90, 0xeb, 0x1c, 0x05, 0x22, 0x38, - 0x67, 0xf9, 0xc6, 0x87, 0x94, 0xdd, 0x8d, 0x04, 0xaa, 0x1a, 0x5f, 0x50, 0xd3, 0x6a, 0xd9, 0x36, - 0xda, 0x87, 0x92, 0xf2, 0xc6, 0x3f, 0xd2, 0xa5, 0x4a, 0xe4, 0x80, 0x50, 0x4c, 0x64, 0x31, 0x7d, - 0x12, 0xff, 0x99, 0xed, 0xb7, 0xc6, 0x46, 0xca, 0x94, 0x1b, 0xaf, 0x3d, 0xca, 0xcc, 0x5b, 0x7b, - 0xd4, 0x78, 0x08, 0x2b, 0xd6, 0xb8, 0x4e, 0xe7, 0xef, 0x41, 0xc9, 0x1f, 0xa6, 0xf9, 0x3c, 0x4f, - 0x2e, 0x23, 0xf4, 0xc6, 0x4f, 0x32, 0xb0, 0xd8, 0xf2, 0x94, 0x0c, 0x3c, 0xe1, 0x6e, 0xbb, 0xa2, - 0xc7, 0xdf, 0x8d, 0xb4, 0xd4, 0x6c, 0xff, 0x3b, 0x8d, 0x3b, 0xae, 0xb0, 0x5c, 0x13, 0x4a, 0xe6, - 0xd7, 0x60, 0x55, 0xda, 0x8e, 0xf2, 0x03, 0x6d, 0xc0, 0x46, 0x25, 0x62, 0x57, 0x81, 0x69, 0x70, - 0x9b, 0xb6, 0x44, 0x47, 0x2f, 0x73, 0x0d, 0xae, 0x8e, 0x41, 0x23, 0xeb, 0x34, 0xcb, 0x6f, 0x42, - 0x2d, 0x39, 0x8d, 0xb6, 0x7c, 0x4f, 0xb5, 0x3c, 0x5b, 0x9e, 0x91, 0x29, 0xc4, 0x72, 0x8d, 0xdf, - 0x2c, 0x45, 0x46, 0xd8, 0x63, 0x53, 0x40, 0x16, 0xf8, 0x7e, 0x72, 0x3b, 0xd1, 0xb4, 0x52, 0xb7, - 0x60, 0xb3, 0x73, 0xdc, 0x82, 0xfd, 0x30, 0xb9, 0xc9, 0xa8, 0x0f, 0x8a, 0x97, 0x67, 0x9e, 0x3e, - 0x54, 0xf7, 0x62, 0xcc, 0xee, 0xb6, 0x4c, 0x5d, 0x6b, 0x7c, 0xc3, 0xf8, 0x5a, 0xf9, 0x79, 0x6c, - 0x55, 0x9d, 0x8f, 0x7f, 0x7b, 0xb2, 0x7c, 0x7e, 0xbe, 0xfa, 0xb3, 0x29, 0x73, 0x12, 0x5e, 0xd8, - 0x9c, 0xfc, 0x68, 0xc2, 0xad, 0x29, 0xcf, 0x0c, 0x49, 0x5d, 0x72, 0x39, 0xf0, 0x23, 0x28, 0xf5, - 0x9d, 0x50, 0xf9, 0x81, 0xbe, 0xb0, 0x3a, 0x7d, 0xc1, 0x26, 0x35, 0x5b, 0x3b, 0x1a, 0x91, 0x8a, - 0x85, 0x22, 0x2a, 0xfe, 0x3d, 0x58, 0xa5, 0x89, 0x3f, 0x4c, 0xac, 0x86, 0xb0, 0x56, 0x9d, 0x59, - 0xa4, 0x95, 0x62, 0xb5, 0x31, 0x41, 0x62, 0x4d, 0x33, 0xa9, 0xf7, 0x00, 0x92, 0xf5, 0x99, 0xd2, - 0x62, 0x5f, 0xe2, 0xc2, 0xea, 0x75, 0x28, 0x86, 0xa3, 0xa3, 0x24, 0xe7, 0x64, 0x5a, 0xf5, 0x33, - 0xa8, 0x4f, 0x59, 0x07, 0x87, 0x32, 0xd0, 0xdd, 0xbd, 0xf4, 0xd6, 0xec, 0x87, 0xe9, 0x85, 0xd7, - 0xc2, 0x79, 0xfb, 0x82, 0xd5, 0x8b, 0x39, 0xa7, 0x24, 0xa0, 0xfe, 0x36, 0x54, 0x53, 0x93, 0x8a, - 0x9a, 0x79, 0xe4, 0xd9, 0x7e, 0x14, 0x06, 0xc5, 0x67, 0x7d, 0x6b, 0xc8, 0x8e, 0x02, 0xa1, 0xf4, - 0x5c, 0xb7, 0x80, 0x4d, 0x4e, 0xe0, 0x25, 0xae, 0xef, 0xcb, 0xb0, 0x94, 0x32, 0xe9, 0xe2, 0x10, - 0xd9, 0x38, 0xb0, 0x71, 0x0a, 0x2f, 0xa5, 0xd8, 0x1d, 0xca, 0x60, 0xe0, 0x84, 0x78, 0x90, 0x68, - 0x97, 0x8e, 0xa2, 0x17, 0xb6, 0xf4, 0x94, 0xa3, 0x22, 0x0d, 0x1a, 0xb7, 0xf9, 0x2f, 0x41, 0x61, - 0x28, 0x83, 0x41, 0x68, 0xb4, 0xe8, 0xa4, 0x04, 0xcd, 0x64, 0x1b, 0x5a, 0x9a, 0xa6, 0xf1, 0x0f, - 0x33, 0x50, 0xde, 0x93, 0x4a, 0xa0, 0xed, 0xc0, 0xf7, 0x26, 0xbe, 0x32, 0x9d, 0x27, 0x8d, 0x50, - 0xd7, 0x8c, 0x93, 0xb9, 0xd6, 0x32, 0xf8, 0xa6, 0xbd, 0xb3, 0x90, 0x74, 0xac, 0xbe, 0x01, 0x25, - 0x03, 0xae, 0xbf, 0x0b, 0x2b, 0x13, 0x98, 0x34, 0x2f, 0xda, 0xb6, 0x6f, 0x9f, 0x0f, 0xa2, 0x72, - 0x9d, 0x45, 0x6b, 0x1c, 0xb8, 0x51, 0x81, 0xd2, 0x50, 0x13, 0x34, 0xfe, 0xe0, 0x1a, 0x95, 0x90, - 0x38, 0xc7, 0xe8, 0x6c, 0xcf, 0x3a, 0x59, 0x6f, 0x01, 0xd0, 0xd1, 0xac, 0x0b, 0x0d, 0x74, 0xd8, - 0x32, 0x05, 0xe1, 0xef, 0xc7, 0xf1, 0xe6, 0xfc, 0x4c, 0xa3, 0x2a, 0xcd, 0x7c, 0x32, 0xe8, 0x5c, - 0x83, 0x92, 0x13, 0xee, 0xe2, 0xd1, 0x66, 0xca, 0x6f, 0xa2, 0x26, 0xff, 0x0e, 0x14, 0x9d, 0xc1, - 0xd0, 0x0f, 0x94, 0x09, 0x48, 0x5f, 0xca, 0xb5, 0x45, 0x98, 0x3b, 0x0b, 0x96, 0xa1, 0x41, 0x6a, - 0x79, 0x46, 0xd4, 0xe5, 0xe7, 0x53, 0x37, 0xcf, 0x22, 0x6a, 0x4d, 0xc3, 0x3f, 0x81, 0xa5, 0x9e, - 0x2e, 0x88, 0xd3, 0x8c, 0x8d, 0x12, 0xf9, 0xc6, 0x65, 0x4c, 0x1e, 0xa4, 0x09, 0x76, 0x16, 0xac, - 0x71, 0x0e, 0xc8, 0x12, 0x0d, 0x78, 0x19, 0xaa, 0x8e, 0xff, 0xb1, 0xef, 0x78, 0xe4, 0x94, 0x3e, - 0x87, 0xa5, 0x95, 0x26, 0x40, 0x96, 0x63, 0x1c, 0xf8, 0x3b, 0x68, 0xf1, 0x84, 0xca, 0xdc, 0x19, - 0xbe, 0x7d, 0x19, 0xa7, 0x8e, 0x0c, 0xcd, 0x6d, 0xdf, 0x50, 0xf1, 0x33, 0xa8, 0xa7, 0x36, 0x89, - 0xf9, 0xc8, 0xfa, 0x70, 0x18, 0xf8, 0xe8, 0xd9, 0x2e, 0x11, 0xb7, 0x77, 0x2e, 0xe3, 0x76, 0x78, - 0x21, 0xf5, 0xce, 0x82, 0x75, 0x09, 0x6f, 0xde, 0x41, 0xcf, 0xce, 0x0c, 0x61, 0x57, 0x8a, 0xd3, - 0xe8, 0xc6, 0xf1, 0xdd, 0xb9, 0x66, 0x81, 0x28, 0x76, 0x16, 0xac, 0x09, 0x1e, 0xfc, 0x57, 0x60, - 0x75, 0xec, 0x9b, 0x74, 0xc9, 0x50, 0xdf, 0x47, 0xfe, 0xd6, 0xdc, 0xc3, 0x40, 0xa2, 0x9d, 0x05, - 0x6b, 0x9a, 0x13, 0x1f, 0xc1, 0x57, 0xa6, 0x87, 0xb4, 0x25, 0xbb, 0xae, 0xe3, 0x49, 0x73, 0x75, - 0xf9, 0xed, 0x17, 0x9b, 0x2d, 0x43, 0xbc, 0xb3, 0x60, 0x5d, 0xcc, 0x99, 0xff, 0x15, 0xb8, 0x39, - 0x9c, 0xa9, 0x62, 0xb4, 0xea, 0x32, 0x37, 0x9f, 0xdf, 0x9b, 0xf3, 0xcb, 0x53, 0xf4, 0x3b, 0x0b, - 0xd6, 0xa5, 0xfc, 0xd1, 0x76, 0x26, 0x0f, 0xda, 0xd4, 0xed, 0xea, 0x06, 0xbf, 0x09, 0x15, 0xd1, - 0x75, 0x77, 0xa4, 0xb0, 0xe3, 0x08, 0x7b, 0x02, 0xa8, 0xff, 0x51, 0x06, 0x8a, 0x46, 0xde, 0x6f, - 0xc6, 0x79, 0xf1, 0x58, 0x75, 0x27, 0x00, 0xfe, 0x01, 0x54, 0x64, 0x10, 0xf8, 0xc1, 0xa6, 0x6f, - 0x47, 0x45, 0x83, 0x93, 0xe1, 0x5f, 0xcd, 0x67, 0xad, 0x19, 0xa1, 0x59, 0x09, 0x05, 0x7f, 0x1f, - 0x40, 0xef, 0xf3, 0x4e, 0x72, 0xfd, 0xa2, 0x3e, 0x9b, 0x5e, 0xa7, 0x61, 0x12, 0xec, 0x24, 0x78, - 0x16, 0xe5, 0x40, 0xa2, 0x66, 0xec, 0x70, 0x16, 0x52, 0x0e, 0xe7, 0x4d, 0x13, 0x47, 0xd8, 0xc7, - 0x17, 0xe6, 0x12, 0x52, 0x0c, 0xa8, 0xff, 0xeb, 0x0c, 0x14, 0xb5, 0xf2, 0xe0, 0xcd, 0xe9, 0x11, - 0xbd, 0xfa, 0x7c, 0x9d, 0xb3, 0x36, 0x39, 0xb2, 0xef, 0x00, 0x68, 0x1d, 0x94, 0x1a, 0xd9, 0xcd, - 0x09, 0x3e, 0x86, 0x34, 0xaa, 0x1c, 0x4d, 0xf0, 0x1b, 0xf7, 0xf5, 0x45, 0x19, 0x8a, 0xd5, 0x3e, - 0xda, 0xdd, 0x65, 0x0b, 0x7c, 0x15, 0x96, 0x1e, 0xed, 0x3f, 0xdc, 0x3f, 0x78, 0xb2, 0xff, 0xb4, - 0x69, 0x59, 0x07, 0x96, 0x0e, 0xd9, 0x6e, 0xac, 0x6f, 0x3d, 0x6d, 0xed, 0x1f, 0x3e, 0xea, 0xb0, - 0x6c, 0xfd, 0xa7, 0x19, 0x58, 0x1a, 0xd3, 0x5d, 0x7f, 0xbe, 0x4b, 0x97, 0x9a, 0xfe, 0xdc, 0xec, - 0xe9, 0xcf, 0x5f, 0x34, 0xfd, 0x85, 0xc9, 0xe9, 0xff, 0xbd, 0x0c, 0x2c, 0x8d, 0xe9, 0xc8, 0x34, - 0xf7, 0xcc, 0x38, 0xf7, 0xf4, 0x49, 0x9f, 0x9d, 0x38, 0xe9, 0x1b, 0xb0, 0x18, 0x3d, 0xef, 0x27, - 0x11, 0x87, 0x31, 0x58, 0x1a, 0x87, 0x2a, 0xd5, 0xf3, 0xe3, 0x38, 0x54, 0xad, 0x7e, 0x79, 0x6f, - 0xe9, 0x66, 0x5e, 0x48, 0x17, 0x97, 0xeb, 0x17, 0x6b, 0xd0, 0x4b, 0x86, 0xf0, 0x00, 0xaa, 0xc3, - 0x64, 0x9b, 0xbe, 0x98, 0x59, 0x92, 0xa6, 0x7c, 0x4e, 0x3f, 0x7f, 0x9c, 0x81, 0xe5, 0x71, 0x9d, - 0xfb, 0xff, 0xf5, 0xb4, 0xfe, 0x93, 0x0c, 0xac, 0x4e, 0x69, 0xf2, 0x4b, 0x0d, 0xbb, 0xc9, 0x7e, - 0x65, 0xe7, 0xe8, 0x57, 0x6e, 0x46, 0xbf, 0x2e, 0xd6, 0x24, 0x97, 0xf7, 0xb8, 0x0d, 0x5f, 0xb9, - 0xf0, 0x4c, 0xb8, 0x64, 0xaa, 0xc7, 0x98, 0xe6, 0x26, 0x99, 0xfe, 0x4e, 0x06, 0x6e, 0x5e, 0xa6, - 0xef, 0xff, 0x9f, 0xcb, 0xd5, 0x64, 0x0f, 0x1b, 0xef, 0xc6, 0xc9, 0xf4, 0x2a, 0x94, 0xcc, 0x0f, - 0x02, 0x99, 0x72, 0xe5, 0xbe, 0xff, 0xcc, 0xd3, 0x91, 0x68, 0x4b, 0x0a, 0x73, 0x65, 0xda, 0x92, - 0x43, 0xd7, 0xa1, 0xe4, 0xe5, 0x0d, 0x80, 0x75, 0xf2, 0xeb, 0xa2, 0x1b, 0x0c, 0x9b, 0xbb, 0x07, - 0xed, 0x26, 0x5b, 0x48, 0x1b, 0xb1, 0x9f, 0x46, 0x8a, 0xb8, 0x71, 0x08, 0xc5, 0xa4, 0xb6, 0x7d, - 0x4f, 0x04, 0x27, 0xb6, 0x4e, 0x11, 0x2e, 0x42, 0xf9, 0xd0, 0xb8, 0x50, 0xfa, 0x53, 0x1f, 0xb7, - 0x0f, 0xf6, 0x75, 0xd0, 0x7b, 0xeb, 0xa0, 0xa3, 0x2b, 0xe4, 0xdb, 0x8f, 0x1f, 0xe8, 0x5c, 0xd5, - 0x03, 0x6b, 0xfd, 0x70, 0xe7, 0x29, 0x61, 0x14, 0x1a, 0x3f, 0xcd, 0x46, 0xa7, 0x5a, 0xc3, 0x32, - 0xc9, 0x47, 0x80, 0x22, 0x6a, 0x73, 0xdf, 0x30, 0x8e, 0x3f, 0x43, 0x85, 0xad, 0xcd, 0x33, 0x1d, - 0x87, 0x60, 0x59, 0x5e, 0x84, 0xec, 0xe1, 0x91, 0xae, 0xc6, 0xd9, 0x51, 0x03, 0x57, 0x5f, 0x69, - 0xeb, 0x9c, 0x29, 0x56, 0xc0, 0x87, 0xcd, 0xf0, 0x94, 0x15, 0x1b, 0xff, 0x39, 0x03, 0x95, 0x58, - 0x55, 0xbe, 0x88, 0xea, 0xe6, 0x1c, 0x96, 0x5b, 0xfb, 0x9d, 0xa6, 0xb5, 0xbf, 0xbe, 0x6b, 0x50, - 0x72, 0xbc, 0x06, 0x57, 0xf7, 0x0f, 0x9e, 0x1e, 0x6c, 0x7c, 0xdc, 0xdc, 0xec, 0xb4, 0x9f, 0x76, - 0x0e, 0x9e, 0xb6, 0xf6, 0x0e, 0x0f, 0xac, 0x0e, 0x2b, 0xf0, 0xeb, 0xc0, 0xf5, 0xf3, 0xd3, 0x56, - 0xfb, 0xe9, 0xe6, 0xfa, 0xfe, 0x66, 0x73, 0xb7, 0xb9, 0xc5, 0x8a, 0xfc, 0x55, 0xf8, 0xda, 0x6e, - 0x6b, 0xaf, 0xd5, 0x79, 0x7a, 0xb0, 0xfd, 0xd4, 0x3a, 0x78, 0xd2, 0x7e, 0x7a, 0x60, 0x3d, 0xb5, - 0x9a, 0xbb, 0xeb, 0x9d, 0xd6, 0xc1, 0x7e, 0xfb, 0x69, 0xf3, 0x7b, 0x9b, 0xcd, 0xe6, 0x56, 0x73, - 0x8b, 0x95, 0xf8, 0x15, 0x58, 0xd9, 0x6e, 0xed, 0x36, 0x9f, 0xee, 0x1e, 0xac, 0x6f, 0x99, 0xef, - 0x95, 0xf9, 0x4d, 0xa8, 0xb5, 0xf6, 0xdb, 0x8f, 0xb6, 0xb7, 0x5b, 0x9b, 0xad, 0xe6, 0x7e, 0xe7, - 0xe9, 0x61, 0xd3, 0xda, 0x6b, 0xb5, 0xdb, 0x48, 0xcb, 0x2a, 0x8d, 0xef, 0x42, 0xb1, 0xe5, 0x9d, - 0x3a, 0x8a, 0xc4, 0xcf, 0xac, 0x95, 0x71, 0x48, 0xa2, 0x26, 0x49, 0x8d, 0xd3, 0xf3, 0xe8, 0x26, - 0x33, 0x09, 0xdf, 0xa2, 0x95, 0x00, 0x1a, 0xff, 0x34, 0x0b, 0x4b, 0x9a, 0x45, 0xe4, 0xe0, 0xdc, - 0x81, 0x15, 0x13, 0x29, 0x6c, 0x8d, 0xef, 0xf0, 0x49, 0x30, 0xfd, 0x44, 0x90, 0x06, 0xa5, 0xf6, - 0x79, 0x1a, 0x44, 0xd9, 0x27, 0x62, 0x8e, 0x8e, 0x92, 0xce, 0xbb, 0x25, 0x80, 0x2f, 0xbb, 0xc1, - 0x51, 0x79, 0x68, 0xc4, 0xae, 0xef, 0x6d, 0xc6, 0xf7, 0x07, 0xc6, 0x60, 0xfc, 0x53, 0xb8, 0x11, - 0xb7, 0x9b, 0x5e, 0x37, 0x38, 0x1f, 0xc6, 0xbf, 0xe4, 0x55, 0x9a, 0xe9, 0x71, 0x6f, 0x3b, 0xae, - 0x1c, 0x43, 0xb4, 0x2e, 0x62, 0xd0, 0xf8, 0xe3, 0x4c, 0xca, 0x2d, 0xd4, 0x6e, 0xdf, 0xa5, 0x0a, - 0x71, 0x56, 0x8a, 0x02, 0x1d, 0x33, 0xd3, 0x7d, 0x73, 0x4e, 0x9b, 0x26, 0x3f, 0x04, 0xee, 0x4c, - 0x77, 0x3a, 0x3f, 0x67, 0xa7, 0x67, 0xd0, 0x4e, 0x46, 0x98, 0x0b, 0xd3, 0x11, 0xe6, 0x5b, 0x00, - 0x3d, 0xd7, 0x3f, 0x12, 0x6e, 0xca, 0x0e, 0x4b, 0x41, 0x1a, 0x2e, 0x94, 0xa3, 0xdf, 0x0b, 0xe3, - 0xd7, 0xa1, 0x48, 0xbf, 0x18, 0x16, 0xc7, 0xdb, 0x74, 0x8b, 0xef, 0xc0, 0xb2, 0x1c, 0xef, 0x73, - 0x76, 0xce, 0x3e, 0x4f, 0xd0, 0x35, 0xbe, 0x0d, 0xab, 0x53, 0x48, 0x38, 0x89, 0x43, 0xa1, 0xe2, - 0x4b, 0xc3, 0xf8, 0x3c, 0x9d, 0xe3, 0x6d, 0xfc, 0xfb, 0x2c, 0x2c, 0xee, 0x09, 0xcf, 0x39, 0x96, - 0xa1, 0x8a, 0x7a, 0x1b, 0x76, 0xfb, 0x72, 0x20, 0xa2, 0xde, 0xea, 0x96, 0x71, 0xc2, 0xb3, 0xe9, - 0xf0, 0xf6, 0x54, 0x36, 0xe4, 0x3a, 0x14, 0xc5, 0x48, 0xf5, 0xe3, 0x92, 0x66, 0xd3, 0xc2, 0xb5, - 0x73, 0x9d, 0xae, 0xf4, 0xc2, 0x48, 0x36, 0xa3, 0x66, 0x52, 0xe5, 0x51, 0xbc, 0xa4, 0xca, 0xa3, - 0x34, 0x3d, 0xff, 0xb7, 0xa1, 0x1a, 0x76, 0x03, 0x29, 0xbd, 0xb0, 0xef, 0xab, 0xe8, 0xb7, 0xe6, - 0xd2, 0x20, 0xaa, 0x6e, 0xf2, 0x9f, 0x79, 0xb8, 0x43, 0x77, 0x1d, 0xef, 0xc4, 0x94, 0xf8, 0x8c, - 0xc1, 0x50, 0x06, 0x29, 0x04, 0xe1, 0x7c, 0x2e, 0xc9, 0xfd, 0x2d, 0x58, 0x71, 0x9b, 0x82, 0x0c, - 0x42, 0xc9, 0x9e, 0x1f, 0x38, 0x52, 0x47, 0xda, 0x2a, 0x56, 0x0a, 0x82, 0xb4, 0xae, 0xf0, 0x7a, - 0x23, 0xd1, 0x93, 0x26, 0x67, 0x1a, 0xb7, 0x1b, 0xff, 0xa3, 0x00, 0xb0, 0x27, 0x07, 0x47, 0x32, - 0x08, 0xfb, 0xce, 0x90, 0x32, 0x01, 0x8e, 0x29, 0xe4, 0x5c, 0xb2, 0xe8, 0x99, 0xbf, 0x37, 0x56, - 0x63, 0x3d, 0x9d, 0xbb, 0x4b, 0xc8, 0x27, 0x23, 0x14, 0x38, 0x39, 0x42, 0x49, 0x53, 0x60, 0x43, - 0xf3, 0x9f, 0xb7, 0xd2, 0x20, 0xaa, 0x7d, 0x12, 0x4a, 0x36, 0x3d, 0x5b, 0x47, 0x40, 0xf2, 0x56, - 0xdc, 0xa6, 0x5b, 0x1a, 0xe1, 0xfa, 0x48, 0xf9, 0x96, 0xf4, 0xe4, 0xb3, 0xf8, 0x8a, 0x51, 0x02, - 0xe2, 0x7b, 0xb0, 0x34, 0x14, 0xe7, 0x03, 0xe9, 0xa9, 0x3d, 0xa9, 0xfa, 0xbe, 0x6d, 0xaa, 0x61, - 0x5e, 0xbd, 0xb8, 0x83, 0x87, 0x69, 0x74, 0x6b, 0x9c, 0x1a, 0x65, 0xc2, 0x0b, 0x69, 0x97, 0xe8, - 0x65, 0x34, 0x2d, 0xbe, 0x01, 0xa0, 0x9f, 0xc8, 0xb1, 0x28, 0xcf, 0x0e, 0xd4, 0x88, 0x81, 0x0c, - 0x65, 0x70, 0xea, 0x68, 0x3d, 0xa6, 0x5d, 0xa7, 0x84, 0x0a, 0xb5, 0xde, 0x28, 0x94, 0x41, 0x73, - 0x20, 0x1c, 0xd7, 0x2c, 0x70, 0x02, 0xe0, 0x6f, 0xc1, 0xb5, 0x70, 0x74, 0x84, 0x32, 0x73, 0x24, - 0x3b, 0xfe, 0xbe, 0x7c, 0x16, 0xba, 0x52, 0x29, 0x19, 0x98, 0xf4, 0xfb, 0xec, 0x97, 0x8d, 0x5e, - 0x6c, 0x15, 0xd0, 0xef, 0x1a, 0xe0, 0x53, 0x52, 0xd6, 0x13, 0x83, 0x4c, 0xcd, 0x13, 0xcb, 0x70, - 0x06, 0x8b, 0x1a, 0x64, 0x4a, 0xa2, 0xb2, 0xfc, 0xeb, 0xf0, 0xd5, 0x31, 0x24, 0x4b, 0xe7, 0x49, - 0xc3, 0x6d, 0xc7, 0x13, 0xae, 0xf3, 0xb9, 0xce, 0x5a, 0xe7, 0x1a, 0x43, 0x58, 0x1a, 0x9b, 0x38, - 0x3c, 0xe6, 0xf5, 0x93, 0x29, 0x12, 0x61, 0xb0, 0xa8, 0xdb, 0x6d, 0x15, 0x38, 0x94, 0x00, 0x88, - 0x21, 0x9b, 0xb8, 0xcf, 0x7d, 0x96, 0xe5, 0x57, 0x81, 0x69, 0x48, 0xcb, 0x13, 0xc3, 0xe1, 0xfa, - 0x70, 0xe8, 0x4a, 0x96, 0xa3, 0xab, 0x78, 0x09, 0x54, 0x57, 0x5a, 0xb3, 0x7c, 0xe3, 0x7b, 0x70, - 0x83, 0x66, 0xe6, 0xb1, 0x0c, 0x62, 0xbf, 0xcf, 0x8c, 0xf5, 0x1a, 0xac, 0xea, 0xa7, 0x7d, 0x5f, - 0xe9, 0xd7, 0x64, 0x0b, 0x71, 0x58, 0xd6, 0x60, 0x34, 0x05, 0xda, 0xd2, 0x53, 0xba, 0x56, 0x45, - 0xc3, 0x62, 0xbc, 0x6c, 0xe3, 0x27, 0x45, 0xe0, 0x89, 0x40, 0x74, 0x1c, 0x19, 0x6c, 0x09, 0x25, - 0x52, 0x81, 0xbb, 0xa5, 0x0b, 0x53, 0xcf, 0xcf, 0xaf, 0xe8, 0xba, 0x0e, 0x45, 0x27, 0x44, 0x4f, - 0xc5, 0x54, 0x50, 0x9a, 0x16, 0xdf, 0x05, 0x18, 0xca, 0xc0, 0xf1, 0x6d, 0x92, 0xa0, 0xc2, 0xcc, - 0x52, 0xf7, 0xe9, 0x4e, 0xad, 0x1d, 0xc6, 0x34, 0x56, 0x8a, 0x1e, 0xfb, 0xa1, 0x5b, 0x3a, 0x91, - 0x5b, 0xa4, 0x4e, 0xa7, 0x41, 0xfc, 0x75, 0xb8, 0x32, 0x0c, 0x9c, 0xae, 0xd4, 0xcb, 0xf1, 0x28, - 0xb4, 0x37, 0xe9, 0xd7, 0xc0, 0x4a, 0x84, 0x39, 0xeb, 0x15, 0x4a, 0xa0, 0xf0, 0xc8, 0x7e, 0x0f, - 0x29, 0x75, 0x69, 0xae, 0x82, 0xea, 0x8a, 0xc4, 0x25, 0x6b, 0xf6, 0x4b, 0x7e, 0x17, 0x98, 0x79, - 0xb1, 0xe7, 0x78, 0xbb, 0xd2, 0xeb, 0xa9, 0x3e, 0x09, 0xf7, 0x92, 0x35, 0x05, 0x27, 0x0d, 0xa6, - 0x7f, 0x73, 0x45, 0xa7, 0x35, 0x2a, 0x56, 0xdc, 0xd6, 0xd7, 0x8b, 0x5d, 0x3f, 0x68, 0xab, 0xc0, - 0x14, 0x4b, 0xc6, 0x6d, 0xb4, 0x59, 0x42, 0xea, 0xeb, 0x61, 0xe0, 0xdb, 0x23, 0x0a, 0xba, 0x6b, - 0x25, 0x36, 0x09, 0x4e, 0x30, 0xf7, 0x84, 0x67, 0xca, 0xea, 0x96, 0xd2, 0x98, 0x31, 0x98, 0x5c, - 0x14, 0x3f, 0x4c, 0x18, 0xae, 0x18, 0x17, 0x25, 0x05, 0x33, 0x38, 0x09, 0x2b, 0x16, 0xe3, 0x24, - 0x7c, 0x68, 0xfc, 0x76, 0xe0, 0x3b, 0x76, 0xc2, 0x6b, 0x55, 0x17, 0x3d, 0x4e, 0xc2, 0x53, 0xb8, - 0x09, 0x4f, 0x3e, 0x86, 0x1b, 0xc3, 0x1b, 0x3f, 0xcc, 0x00, 0x24, 0x8b, 0x8f, 0x22, 0x9f, 0xb4, - 0x92, 0x2d, 0x7e, 0x03, 0xae, 0xa4, 0xc1, 0x54, 0x0d, 0x4f, 0xf9, 0x4f, 0x0e, 0xcb, 0xc9, 0x8b, - 0x2d, 0x71, 0x1e, 0xb2, 0xac, 0xae, 0x7e, 0x8c, 0x60, 0x4f, 0xa4, 0xa4, 0x3a, 0xb3, 0xab, 0xc0, - 0x12, 0x20, 0x5d, 0x76, 0x0a, 0x59, 0x7e, 0x1c, 0xf5, 0xfb, 0x52, 0x04, 0x21, 0x2b, 0x34, 0x76, - 0xa0, 0xa8, 0x73, 0x2f, 0x33, 0xb2, 0xa6, 0x2f, 0x56, 0x02, 0xf1, 0x37, 0x33, 0x00, 0x5b, 0xba, - 0xc0, 0x15, 0x4f, 0xf1, 0x19, 0xc9, 0xe8, 0x59, 0x16, 0x95, 0xb0, 0x6d, 0x2a, 0xfd, 0xcd, 0xc5, - 0xbf, 0xe4, 0x81, 0x4d, 0x94, 0x1c, 0x11, 0x15, 0x16, 0xe9, 0x3d, 0x17, 0xb7, 0xf5, 0x01, 0xb2, - 0xe9, 0x7b, 0x9e, 0xec, 0xe2, 0xf1, 0x13, 0x1f, 0x20, 0x31, 0xa8, 0xf1, 0x6f, 0x4a, 0x50, 0xdd, - 0xec, 0x0b, 0xb5, 0x27, 0xc3, 0x50, 0xf4, 0xe4, 0x54, 0x5f, 0x6a, 0x50, 0xf2, 0x03, 0x5b, 0x06, - 0xc9, 0x85, 0x25, 0xd3, 0x4c, 0xa7, 0xe0, 0x73, 0xe3, 0x29, 0xf8, 0x9b, 0x50, 0xd1, 0x01, 0x7e, - 0x7b, 0x5d, 0xab, 0x81, 0x9c, 0x95, 0x00, 0xf0, 0xac, 0x1e, 0xf8, 0x36, 0x29, 0xa3, 0x75, 0x1d, - 0x1b, 0xcf, 0x59, 0x29, 0x88, 0xae, 0x78, 0x18, 0xba, 0xe7, 0x1d, 0xdf, 0xf4, 0xa9, 0x65, 0x27, - 0xb7, 0x3b, 0xc7, 0xe1, 0x7c, 0x13, 0x4a, 0x03, 0xdd, 0x30, 0x71, 0xfe, 0xc9, 0x88, 0x78, 0x6a, - 0x68, 0x6b, 0xe6, 0xaf, 0xb9, 0x60, 0x61, 0x45, 0x94, 0xe8, 0xc1, 0x0a, 0xa5, 0x44, 0xb7, 0x3f, - 0x30, 0x2a, 0x22, 0x37, 0x23, 0xe5, 0x97, 0x66, 0xb4, 0x1e, 0x63, 0x5b, 0x69, 0x4a, 0xbe, 0x01, - 0x95, 0x40, 0x8a, 0xb1, 0xac, 0xe3, 0xcb, 0x97, 0xb0, 0xb1, 0x22, 0x5c, 0x2b, 0x21, 0xab, 0xff, - 0x6e, 0x06, 0x96, 0xc7, 0x3b, 0xfa, 0xe7, 0xf1, 0x63, 0x4c, 0xdf, 0x49, 0x7e, 0x8c, 0xe9, 0x4b, - 0xfc, 0xb0, 0xd1, 0xef, 0x64, 0x00, 0x92, 0x39, 0x40, 0x95, 0xaf, 0x7f, 0x34, 0x26, 0x32, 0x42, - 0x75, 0x8b, 0xef, 0x8c, 0x5d, 0xeb, 0x7e, 0x6b, 0xae, 0x09, 0x4d, 0x3d, 0xa6, 0xaa, 0x76, 0xef, - 0xc1, 0xf2, 0x38, 0x9c, 0x7e, 0x06, 0xa6, 0xb5, 0xdb, 0xd4, 0x11, 0x80, 0xd6, 0xde, 0xfa, 0x83, - 0xa6, 0xb9, 0xd0, 0xd2, 0xda, 0x7f, 0xc8, 0xb2, 0xf5, 0xff, 0x99, 0x81, 0x4a, 0x3c, 0xbd, 0xfc, - 0x93, 0xf4, 0xba, 0xe8, 0x32, 0x82, 0x37, 0xe7, 0x59, 0x97, 0xe4, 0xa9, 0xe9, 0xa9, 0xe0, 0x3c, - 0xbd, 0x4c, 0x3e, 0x2c, 0x8f, 0xbf, 0x9c, 0xa1, 0x13, 0x1e, 0x8c, 0xeb, 0x84, 0x37, 0xe6, 0xfa, - 0x64, 0xe4, 0x79, 0xed, 0x3a, 0xa1, 0x32, 0xea, 0xe2, 0xfd, 0xec, 0x7b, 0x99, 0xfa, 0x6d, 0x58, - 0x4c, 0xbf, 0x9a, 0xbe, 0xb5, 0x76, 0xf7, 0xbf, 0xe4, 0x60, 0x79, 0x3c, 0x13, 0x4f, 0x77, 0x64, - 0x74, 0x15, 0xc8, 0x81, 0x6b, 0xa7, 0x0a, 0x9d, 0x19, 0x5f, 0x81, 0xaa, 0xf1, 0xed, 0x08, 0xb0, - 0x4a, 0x31, 0x06, 0x7f, 0x20, 0xd9, 0xed, 0xf4, 0x0f, 0xce, 0xbd, 0xce, 0x21, 0xba, 0xbd, 0xc4, - 0x86, 0xbc, 0x62, 0x7e, 0x7a, 0xe7, 0x57, 0xb3, 0x7c, 0x29, 0x55, 0x6e, 0xfb, 0x23, 0x34, 0x6c, - 0x56, 0x36, 0x46, 0x9e, 0xed, 0x4a, 0x3b, 0x86, 0xfe, 0x6e, 0x1a, 0x1a, 0x17, 0xcf, 0xfe, 0x6a, - 0x9e, 0x2f, 0x43, 0xa5, 0x3d, 0x3a, 0x32, 0x85, 0xb3, 0x7f, 0x35, 0xcf, 0xaf, 0xc3, 0xaa, 0xc1, - 0x4a, 0x2a, 0xe0, 0xd8, 0x5f, 0x43, 0x15, 0xbc, 0xbc, 0xae, 0xe7, 0xcb, 0x74, 0x94, 0xfd, 0xf5, - 0x3c, 0x76, 0x81, 0x2e, 0xc5, 0xfe, 0x1a, 0xf1, 0x89, 0xaf, 0x10, 0xb0, 0x5f, 0xcf, 0xf3, 0x15, - 0x80, 0x76, 0x27, 0xfe, 0xd0, 0x6f, 0xe6, 0x79, 0x15, 0x8a, 0xed, 0x0e, 0x71, 0xfb, 0x61, 0x9e, - 0x5f, 0x03, 0x96, 0xbc, 0x35, 0x75, 0x81, 0x7f, 0x4b, 0x77, 0x26, 0x2e, 0xf4, 0xfb, 0xad, 0x3c, - 0x8e, 0x2b, 0x9a, 0x65, 0xf6, 0xb7, 0xf3, 0x9c, 0x41, 0x35, 0x15, 0xb9, 0x62, 0x7f, 0x27, 0xcf, - 0x39, 0x2c, 0xed, 0x39, 0x61, 0xe8, 0x78, 0x3d, 0x33, 0x82, 0xdf, 0xa0, 0x2f, 0x6f, 0xc7, 0xb7, - 0x20, 0xd8, 0x6f, 0xe7, 0xf9, 0x0d, 0xe0, 0xe9, 0x68, 0xbd, 0x79, 0xf1, 0x77, 0x89, 0x5a, 0xab, - 0xfd, 0xd0, 0xc0, 0xfe, 0x1e, 0x51, 0xa3, 0x24, 0x18, 0xc0, 0xdf, 0xa7, 0x09, 0xd9, 0x4c, 0x2a, - 0x09, 0x0d, 0xfc, 0x47, 0xf9, 0xbb, 0x3f, 0xa1, 0xc8, 0x6a, 0xba, 0xf8, 0x86, 0x2f, 0x42, 0xd9, - 0xf5, 0xbd, 0x9e, 0xd2, 0x3f, 0xea, 0xb7, 0x04, 0x95, 0xb0, 0xef, 0x07, 0x8a, 0x9a, 0x74, 0x25, - 0xcb, 0xa3, 0xcb, 0xb9, 0xba, 0xb2, 0x5a, 0x3b, 0x24, 0x3a, 0x52, 0xa5, 0x44, 0x8f, 0x55, 0xe3, - 0x7a, 0xc7, 0x7c, 0x5c, 0x93, 0x49, 0x97, 0x84, 0xa3, 0x4b, 0x98, 0xac, 0x88, 0xa8, 0xa3, 0xc0, - 0xd5, 0xb5, 0x99, 0x12, 0x8d, 0x51, 0xfd, 0xeb, 0x5d, 0xc3, 0x3e, 0xda, 0xbc, 0x15, 0x0d, 0xf5, - 0x3f, 0x73, 0xf4, 0xf5, 0x3e, 0x53, 0xea, 0x64, 0x63, 0x3f, 0xe2, 0x6c, 0x3e, 0x93, 0x77, 0x7f, - 0x2b, 0x03, 0x8b, 0xd1, 0xd5, 0x58, 0xa7, 0xe7, 0x78, 0xba, 0xba, 0x33, 0xfa, 0xa9, 0xc4, 0xae, - 0xeb, 0x0c, 0xa3, 0x9f, 0x1e, 0x5b, 0x81, 0xaa, 0x1d, 0x88, 0xde, 0xba, 0x67, 0x6f, 0x05, 0xfe, - 0x50, 0x77, 0x5b, 0xe7, 0x5e, 0x74, 0x55, 0xe9, 0x33, 0x79, 0x84, 0xe8, 0x43, 0x19, 0xb0, 0x3c, - 0x95, 0x51, 0xf5, 0x45, 0xe0, 0x78, 0xbd, 0xe6, 0x99, 0x92, 0x5e, 0xa8, 0xab, 0x4b, 0xab, 0x50, - 0x1a, 0x85, 0xb2, 0x2b, 0x42, 0xc9, 0x8a, 0xd8, 0x38, 0x1a, 0x39, 0xae, 0x72, 0x3c, 0xfd, 0x8b, - 0x5f, 0x71, 0xf9, 0x68, 0xf9, 0xee, 0xef, 0x67, 0xa0, 0x4a, 0x2b, 0x9f, 0x04, 0x15, 0x13, 0xab, - 0xa2, 0x0a, 0xa5, 0xdd, 0xf8, 0x17, 0x9f, 0x8a, 0x90, 0x3d, 0x38, 0xd1, 0x41, 0x45, 0xb3, 0xf2, - 0xfa, 0x62, 0x9b, 0xfe, 0xf1, 0xa7, 0x3c, 0xff, 0x0a, 0x5c, 0xb3, 0xe4, 0xc0, 0x57, 0xf2, 0x89, - 0x70, 0x54, 0xfa, 0x66, 0x45, 0x01, 0x1d, 0x10, 0xfd, 0x2a, 0xba, 0x4a, 0x51, 0x24, 0x07, 0x04, - 0x3f, 0x1b, 0x41, 0x4a, 0x38, 0x68, 0x82, 0x18, 0x8f, 0xa4, 0x1c, 0xa3, 0x7c, 0xec, 0x3b, 0x1e, - 0x7e, 0x8d, 0xae, 0x53, 0x12, 0x84, 0xa2, 0xd3, 0x08, 0x82, 0xbb, 0xfb, 0x70, 0x7d, 0x76, 0x4c, - 0x55, 0x5f, 0xb4, 0xa4, 0x9f, 0x19, 0xa5, 0x5a, 0xfb, 0x27, 0x81, 0xa3, 0xef, 0xcb, 0x55, 0xa0, - 0x70, 0xf0, 0xcc, 0x23, 0x69, 0x58, 0x85, 0xa5, 0x7d, 0x3f, 0x45, 0xc3, 0x72, 0x77, 0xbb, 0x63, - 0x61, 0xf0, 0x64, 0x52, 0xa2, 0x4e, 0x2c, 0xa4, 0xee, 0x91, 0x64, 0x74, 0x80, 0x95, 0x7e, 0x29, - 0x5e, 0x5f, 0x42, 0x37, 0xe1, 0x67, 0x5b, 0x5f, 0x42, 0x8f, 0xbb, 0x99, 0xd7, 0x3f, 0x01, 0xe3, - 0x75, 0xa5, 0x2b, 0x6d, 0x56, 0xb8, 0xfb, 0x1e, 0xac, 0x98, 0xa1, 0x76, 0x65, 0x18, 0x46, 0xf7, - 0x30, 0x0e, 0x03, 0xe7, 0x54, 0x5f, 0x74, 0x5f, 0x84, 0xf2, 0xa1, 0x0c, 0x42, 0xdf, 0xa3, 0x4b, - 0xfe, 0x00, 0xc5, 0x76, 0x5f, 0x04, 0xf8, 0x8d, 0xbb, 0xdf, 0x84, 0x0a, 0xdd, 0xcb, 0x78, 0xe8, - 0x78, 0x36, 0x8e, 0x64, 0xc3, 0x94, 0x22, 0x57, 0xa0, 0xb0, 0xe9, 0x9f, 0xd2, 0xf8, 0xca, 0xfa, - 0xc7, 0x0e, 0x59, 0xf6, 0xee, 0x47, 0xc0, 0x75, 0x38, 0xc7, 0x96, 0x67, 0x8e, 0xd7, 0x8b, 0x6f, - 0xff, 0x02, 0x5d, 0xe5, 0xb7, 0xe5, 0x19, 0x79, 0x4b, 0x55, 0x28, 0x45, 0x8d, 0xe8, 0x07, 0x05, - 0xb6, 0xfd, 0x91, 0x87, 0x5f, 0x7b, 0x0c, 0x57, 0xb5, 0x6c, 0xe0, 0xe7, 0xe9, 0xfe, 0xd7, 0x85, - 0x3e, 0xa6, 0xbe, 0x3c, 0xa3, 0x46, 0x61, 0x8c, 0xcb, 0x32, 0xfc, 0x3a, 0xf0, 0xd8, 0x3f, 0x4b, - 0xe0, 0xd9, 0xbb, 0x0d, 0xb8, 0x32, 0xc3, 0x49, 0x26, 0x85, 0xab, 0x5d, 0x05, 0xb6, 0x70, 0xf7, - 0x43, 0x58, 0xd5, 0x2a, 0x62, 0x5f, 0xdf, 0xe7, 0x89, 0x4e, 0xbb, 0x27, 0xad, 0xed, 0x96, 0x9e, - 0xa2, 0xcd, 0xe6, 0xee, 0xee, 0xa3, 0xdd, 0x75, 0x8b, 0x65, 0x68, 0x21, 0x0f, 0x3a, 0x4f, 0x37, - 0x0f, 0xf6, 0xf7, 0x9b, 0x9b, 0x9d, 0xe6, 0x16, 0xcb, 0x6e, 0xdc, 0xfd, 0xc3, 0x9f, 0xdf, 0xca, - 0xfc, 0xec, 0xe7, 0xb7, 0x32, 0xff, 0xed, 0xe7, 0xb7, 0x32, 0x3f, 0xfc, 0xe2, 0xd6, 0xc2, 0xcf, - 0xbe, 0xb8, 0xb5, 0xf0, 0x9f, 0xbe, 0xb8, 0xb5, 0xf0, 0x29, 0x9b, 0xfc, 0x2f, 0x0d, 0x47, 0x45, - 0xb2, 0x4e, 0xdf, 0xfc, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x68, 0x14, 0x8d, 0xd9, 0xc0, 0x61, - 0x00, 0x00, + 0x76, 0x50, 0xe5, 0x3f, 0xf3, 0x65, 0x7d, 0xbc, 0xbc, 0x7f, 0xb9, 0x39, 0xad, 0x56, 0x2b, 0x77, + 0x76, 0xa6, 0xb7, 0x77, 0xb6, 0x7a, 0xa6, 0xe7, 0xbb, 0xa3, 0x9d, 0x99, 0xad, 0x4f, 0x56, 0x57, + 0x4e, 0xd7, 0x6f, 0x22, 0xb3, 0xbb, 0x77, 0xc7, 0x24, 0x1a, 0xaf, 0x0c, 0xaf, 0xcc, 0x98, 0x8a, + 0x8c, 0xc8, 0x8d, 0xf0, 0xac, 0xae, 0x1a, 0x03, 0x4c, 0x80, 0x90, 0xd0, 0x6d, 0x91, 0x21, 0x3e, + 0x07, 0x4c, 0xbb, 0x37, 0x0c, 0xad, 0x81, 0x71, 0x58, 0x63, 0xc1, 0x90, 0x19, 0xe8, 0x82, 0xcc, + 0xb8, 0x2c, 0x70, 0x00, 0x4e, 0x60, 0x3b, 0x47, 0x4c, 0xc8, 0xc4, 0x49, 0x86, 0x71, 0xc0, 0xde, + 0x73, 0x8f, 0x4f, 0x7e, 0xaa, 0x3a, 0x7b, 0x24, 0x61, 0x9c, 0x2a, 0xfc, 0xc5, 0x7b, 0x2f, 0xfc, + 0xf3, 0xfc, 0xf9, 0xfb, 0x79, 0x16, 0xbc, 0x3c, 0x3c, 0xe9, 0xdd, 0x73, 0x9d, 0xa3, 0x7b, 0xc3, + 0xa3, 0x7b, 0x03, 0xdf, 0x96, 0xee, 0xbd, 0x61, 0xe0, 0x2b, 0x3f, 0xd4, 0x8d, 0x70, 0x8d, 0x5a, + 0x7c, 0x49, 0x78, 0xe7, 0xea, 0x7c, 0x28, 0xd7, 0x08, 0x5a, 0xbf, 0xd9, 0xf3, 0xfd, 0x9e, 0x2b, + 0x35, 0xea, 0xd1, 0xe8, 0xf8, 0x5e, 0xa8, 0x82, 0x51, 0x57, 0x69, 0xe4, 0xc6, 0xcf, 0xf2, 0x70, + 0xbd, 0x3d, 0x10, 0x81, 0xda, 0x70, 0xfd, 0xee, 0x49, 0xdb, 0x13, 0xc3, 0xb0, 0xef, 0xab, 0x0d, + 0x11, 0x4a, 0xfe, 0x1a, 0x14, 0x8f, 0x10, 0x18, 0xd6, 0x32, 0xb7, 0x73, 0x77, 0xaa, 0xf7, 0xaf, + 0xae, 0x8d, 0x31, 0x5e, 0x23, 0x0a, 0xcb, 0xe0, 0xf0, 0x37, 0xa0, 0x64, 0x4b, 0x25, 0x1c, 0x37, + 0xac, 0x65, 0x6f, 0x67, 0xee, 0x54, 0xef, 0xdf, 0x58, 0xd3, 0x1f, 0x5e, 0x8b, 0x3e, 0xbc, 0xd6, + 0xa6, 0x0f, 0x5b, 0x11, 0x1e, 0x7f, 0x17, 0xca, 0xc7, 0x8e, 0x2b, 0x1f, 0xca, 0xf3, 0xb0, 0x96, + 0xbb, 0x94, 0x66, 0x23, 0x5b, 0xcb, 0x58, 0x31, 0x32, 0xdf, 0x84, 0x65, 0x79, 0xa6, 0x02, 0x61, + 0x49, 0x57, 0x28, 0xc7, 0xf7, 0xc2, 0x5a, 0x9e, 0x7a, 0x78, 0x63, 0xa2, 0x87, 0xd1, 0x7b, 0x22, + 0x9f, 0x20, 0xe1, 0xb7, 0xa1, 0xea, 0x1f, 0x7d, 0x26, 0xbb, 0xaa, 0x73, 0x3e, 0x94, 0x61, 0xad, + 0x70, 0x3b, 0x77, 0xa7, 0x62, 0xa5, 0x41, 0xfc, 0x5b, 0x50, 0xed, 0xfa, 0xae, 0x2b, 0xbb, 0xfa, + 0x1b, 0xc5, 0xcb, 0x87, 0x95, 0xc6, 0xe5, 0x6f, 0xc1, 0xb5, 0x40, 0x0e, 0xfc, 0x53, 0x69, 0x6f, + 0xc6, 0x50, 0x1a, 0x67, 0x99, 0x3e, 0x33, 0xfb, 0x25, 0x5f, 0x87, 0xa5, 0xc0, 0xf4, 0x6f, 0xd7, + 0xf1, 0x4e, 0xc2, 0x5a, 0x89, 0x86, 0xf5, 0xd2, 0x05, 0xc3, 0x42, 0x1c, 0x6b, 0x9c, 0x82, 0x33, + 0xc8, 0x9d, 0xc8, 0xf3, 0x5a, 0xe5, 0x76, 0xe6, 0x4e, 0xc5, 0xc2, 0x47, 0xfe, 0x3e, 0xd4, 0xfc, + 0xc0, 0xe9, 0x39, 0x9e, 0x70, 0x37, 0x03, 0x29, 0x94, 0xb4, 0x3b, 0xce, 0x40, 0x86, 0x4a, 0x0c, + 0x86, 0x35, 0xb8, 0x9d, 0xb9, 0x93, 0xb3, 0x2e, 0x7c, 0xcf, 0xdf, 0xd4, 0x2b, 0xd4, 0xf2, 0x8e, + 0xfd, 0x5a, 0xd5, 0x0c, 0x7f, 0xbc, 0x2f, 0xdb, 0xe6, 0xb5, 0x15, 0x23, 0x36, 0xfe, 0x34, 0x0b, + 0xc5, 0xb6, 0x14, 0x41, 0xb7, 0x5f, 0xff, 0xcd, 0x0c, 0x14, 0x2d, 0x19, 0x8e, 0x5c, 0xc5, 0xeb, + 0x50, 0xd6, 0x73, 0xdb, 0xb2, 0x6b, 0x19, 0xea, 0x5d, 0xdc, 0xfe, 0x32, 0xb2, 0xb3, 0x06, 0xf9, + 0x81, 0x54, 0xa2, 0x96, 0xa3, 0x19, 0xaa, 0x4f, 0xf4, 0x4a, 0x7f, 0x7e, 0x6d, 0x4f, 0x2a, 0x61, + 0x11, 0x5e, 0xfd, 0x8b, 0x0c, 0xe4, 0xb1, 0xc9, 0x6f, 0x42, 0xa5, 0xef, 0xf4, 0xfa, 0xae, 0xd3, + 0xeb, 0x2b, 0xd3, 0x91, 0x04, 0xc0, 0x3f, 0x84, 0x95, 0xb8, 0x61, 0x09, 0xaf, 0x27, 0xb1, 0x47, + 0xb3, 0x84, 0x9f, 0x5e, 0x5a, 0x93, 0xc8, 0xbc, 0x06, 0x25, 0xda, 0x0f, 0x2d, 0x9b, 0x24, 0xba, + 0x62, 0x45, 0x4d, 0x14, 0xb7, 0x68, 0xa5, 0x1e, 0xca, 0xf3, 0x5a, 0x9e, 0xde, 0xa6, 0x41, 0x7c, + 0x1d, 0x56, 0xa2, 0xe6, 0x96, 0x99, 0x8d, 0xc2, 0xe5, 0xb3, 0x31, 0x89, 0xdf, 0xf8, 0xcf, 0x2d, + 0x28, 0xd0, 0xb6, 0xe4, 0xcb, 0x90, 0x75, 0xa2, 0x89, 0xce, 0x3a, 0x36, 0xbf, 0x07, 0xc5, 0x63, + 0x47, 0xba, 0xf6, 0x73, 0x67, 0xd8, 0xa0, 0xf1, 0x26, 0x2c, 0x06, 0x32, 0x54, 0x81, 0x63, 0xa4, + 0x5f, 0x6f, 0xd0, 0x5f, 0x9a, 0xa5, 0x03, 0xd6, 0xac, 0x14, 0xa2, 0x35, 0x46, 0x86, 0xc3, 0xee, + 0xf6, 0x1d, 0xd7, 0x0e, 0xa4, 0xd7, 0xb2, 0xf5, 0x3e, 0xad, 0x58, 0x69, 0x10, 0xbf, 0x03, 0x2b, + 0x47, 0xa2, 0x7b, 0xd2, 0x0b, 0xfc, 0x91, 0x87, 0x1b, 0xc2, 0x0f, 0x68, 0xd8, 0x15, 0x6b, 0x12, + 0xcc, 0x5f, 0x87, 0x82, 0x70, 0x9d, 0x9e, 0x47, 0x3b, 0x71, 0x79, 0x6a, 0xd1, 0x75, 0x5f, 0xd6, + 0x11, 0xc3, 0xd2, 0x88, 0x7c, 0x07, 0x96, 0x4e, 0x65, 0xa0, 0x9c, 0xae, 0x70, 0x09, 0x5e, 0x2b, + 0x11, 0x65, 0x63, 0x26, 0xe5, 0xe3, 0x34, 0xa6, 0x35, 0x4e, 0xc8, 0x5b, 0x00, 0x21, 0xaa, 0x49, + 0x5a, 0x4e, 0xb3, 0x17, 0x5e, 0x9d, 0xc9, 0x66, 0xd3, 0xf7, 0x94, 0xf4, 0xd4, 0x5a, 0x3b, 0x46, + 0xdf, 0x59, 0xb0, 0x52, 0xc4, 0xfc, 0x5d, 0xc8, 0x2b, 0x79, 0xa6, 0x6a, 0xcb, 0x97, 0xcc, 0x68, + 0xc4, 0xa4, 0x23, 0xcf, 0xd4, 0xce, 0x82, 0x45, 0x04, 0x48, 0x88, 0x9b, 0xac, 0xb6, 0x32, 0x07, + 0x21, 0xee, 0x4b, 0x24, 0x44, 0x02, 0xfe, 0x01, 0x14, 0x5d, 0x71, 0xee, 0x8f, 0x54, 0x8d, 0x11, + 0xe9, 0x57, 0x2f, 0x25, 0xdd, 0x25, 0xd4, 0x9d, 0x05, 0xcb, 0x10, 0xf1, 0xb7, 0x20, 0x67, 0x3b, + 0xa7, 0xb5, 0x55, 0xa2, 0xbd, 0x7d, 0x29, 0xed, 0x96, 0x73, 0xba, 0xb3, 0x60, 0x21, 0x3a, 0xdf, + 0x84, 0xf2, 0x91, 0xef, 0x9f, 0x0c, 0x44, 0x70, 0x52, 0xe3, 0x44, 0xfa, 0xb5, 0x4b, 0x49, 0x37, + 0x0c, 0xf2, 0xce, 0x82, 0x15, 0x13, 0xe2, 0x90, 0x9d, 0xae, 0xef, 0xd5, 0xae, 0xcc, 0x31, 0xe4, + 0x56, 0xd7, 0xf7, 0x70, 0xc8, 0x48, 0x80, 0x84, 0xae, 0xe3, 0x9d, 0xd4, 0xae, 0xce, 0x41, 0x88, + 0x9a, 0x13, 0x09, 0x91, 0x00, 0xbb, 0x6d, 0x0b, 0x25, 0x4e, 0x1d, 0xf9, 0xac, 0x76, 0x6d, 0x8e, + 0x6e, 0x6f, 0x19, 0x64, 0xec, 0x76, 0x44, 0x88, 0x4c, 0xa2, 0xad, 0x59, 0xbb, 0x3e, 0x07, 0x93, + 0x48, 0xa3, 0x23, 0x93, 0x88, 0x90, 0xff, 0x25, 0x58, 0x3d, 0x96, 0x42, 0x8d, 0x02, 0x69, 0x27, + 0x07, 0xdd, 0x0d, 0xe2, 0xb6, 0x76, 0xf9, 0xda, 0x4f, 0x52, 0xed, 0x2c, 0x58, 0xd3, 0xac, 0xf8, + 0xfb, 0x50, 0x70, 0x85, 0x92, 0x67, 0xb5, 0x1a, 0xf1, 0x6c, 0x3c, 0x47, 0x28, 0x94, 0x3c, 0xdb, + 0x59, 0xb0, 0x34, 0x09, 0xff, 0x2e, 0xac, 0x28, 0x71, 0xe4, 0xca, 0x83, 0x63, 0x83, 0x10, 0xd6, + 0xbe, 0x42, 0x5c, 0x5e, 0xbb, 0x5c, 0x9c, 0xc7, 0x69, 0x76, 0x16, 0xac, 0x49, 0x36, 0xd8, 0x2b, + 0x02, 0xd5, 0xea, 0x73, 0xf4, 0x8a, 0xf8, 0x61, 0xaf, 0x88, 0x84, 0xef, 0x42, 0x95, 0x1e, 0x36, + 0x7d, 0x77, 0x34, 0xf0, 0x6a, 0x2f, 0x11, 0x87, 0x3b, 0xcf, 0xe7, 0xa0, 0xf1, 0x77, 0x16, 0xac, + 0x34, 0x39, 0x2e, 0x22, 0x35, 0x2d, 0xff, 0x59, 0xed, 0xe6, 0x1c, 0x8b, 0xd8, 0x31, 0xc8, 0xb8, + 0x88, 0x11, 0x21, 0x6e, 0xbd, 0x67, 0x8e, 0xdd, 0x93, 0xaa, 0xf6, 0x0b, 0x73, 0x6c, 0xbd, 0x27, + 0x84, 0x8a, 0x5b, 0x4f, 0x13, 0xa1, 0x18, 0x77, 0xfb, 0x42, 0xd5, 0x6e, 0xcd, 0x21, 0xc6, 0x9b, + 0x7d, 0x41, 0xba, 0x02, 0x09, 0xea, 0x9f, 0xc3, 0x62, 0x5a, 0x2b, 0x73, 0x0e, 0xf9, 0x40, 0x0a, + 0x7d, 0x22, 0x94, 0x2d, 0x7a, 0x46, 0x98, 0xb4, 0x1d, 0x45, 0x27, 0x42, 0xd9, 0xa2, 0x67, 0x7e, + 0x1d, 0x8a, 0xda, 0x36, 0x21, 0x85, 0x5f, 0xb6, 0x4c, 0x0b, 0x71, 0xed, 0x40, 0xf4, 0xe8, 0xdc, + 0x2a, 0x5b, 0xf4, 0x8c, 0xb8, 0x76, 0xe0, 0x0f, 0x0f, 0x3c, 0x52, 0xd8, 0x65, 0xcb, 0xb4, 0xea, + 0xff, 0xea, 0x7d, 0x28, 0x99, 0x4e, 0xd5, 0xff, 0x51, 0x06, 0x8a, 0x5a, 0xa1, 0xf0, 0x8f, 0xa0, + 0x10, 0xaa, 0x73, 0x57, 0x52, 0x1f, 0x96, 0xef, 0x7f, 0x7d, 0x0e, 0x25, 0xb4, 0xd6, 0x46, 0x02, + 0x4b, 0xd3, 0x35, 0x2c, 0x28, 0x50, 0x9b, 0x97, 0x20, 0x67, 0xf9, 0xcf, 0xd8, 0x02, 0x07, 0x28, + 0xea, 0xc5, 0x62, 0x19, 0x04, 0x6e, 0x39, 0xa7, 0x2c, 0x8b, 0xc0, 0x1d, 0x29, 0x6c, 0x19, 0xb0, + 0x1c, 0x5f, 0x82, 0x4a, 0xb4, 0x2c, 0x21, 0xcb, 0x73, 0x06, 0x8b, 0xa9, 0x05, 0x0f, 0x59, 0xa1, + 0xfe, 0xbf, 0xf2, 0x90, 0xc7, 0xfd, 0xcf, 0x5f, 0x86, 0x25, 0x25, 0x82, 0x9e, 0xd4, 0x86, 0x70, + 0x6c, 0xa4, 0x8c, 0x03, 0xf9, 0x07, 0xd1, 0x18, 0xb2, 0x34, 0x86, 0x57, 0x9f, 0xab, 0x57, 0xc6, + 0x46, 0x90, 0x3a, 0x85, 0x73, 0xf3, 0x9d, 0xc2, 0xdb, 0x50, 0x46, 0x75, 0xd6, 0x76, 0x3e, 0x97, + 0x34, 0xf5, 0xcb, 0xf7, 0xef, 0x3e, 0xff, 0x93, 0x2d, 0x43, 0x61, 0xc5, 0xb4, 0xbc, 0x05, 0x95, + 0xae, 0x08, 0x6c, 0xea, 0x0c, 0xad, 0xd6, 0xf2, 0xfd, 0x6f, 0x3c, 0x9f, 0xd1, 0x66, 0x44, 0x62, + 0x25, 0xd4, 0xfc, 0x00, 0xaa, 0xb6, 0x0c, 0xbb, 0x81, 0x33, 0x24, 0xf5, 0xa6, 0xcf, 0xe2, 0x6f, + 0x3e, 0x9f, 0xd9, 0x56, 0x42, 0x64, 0xa5, 0x39, 0xa0, 0x45, 0x16, 0xc4, 0xfa, 0xad, 0x44, 0x06, + 0x42, 0x02, 0x68, 0xbc, 0x0b, 0xe5, 0x68, 0x3c, 0x7c, 0x11, 0xca, 0xf8, 0x77, 0xdf, 0xf7, 0x24, + 0x5b, 0xc0, 0xb5, 0xc5, 0x56, 0x7b, 0x20, 0x5c, 0x97, 0x65, 0xf8, 0x32, 0x00, 0x36, 0xf7, 0xa4, + 0xed, 0x8c, 0x06, 0x2c, 0xdb, 0xf8, 0xe5, 0x48, 0x5a, 0xca, 0x90, 0x3f, 0x14, 0x3d, 0xa4, 0x58, + 0x84, 0x72, 0xa4, 0xae, 0x59, 0x06, 0xe9, 0xb7, 0x44, 0xd8, 0x3f, 0xf2, 0x45, 0x60, 0xb3, 0x2c, + 0xaf, 0x42, 0x69, 0x3d, 0xe8, 0xf6, 0x9d, 0x53, 0xc9, 0x72, 0x8d, 0x7b, 0x50, 0x4d, 0xf5, 0x17, + 0x59, 0x98, 0x8f, 0x56, 0xa0, 0xb0, 0x6e, 0xdb, 0xd2, 0x66, 0x19, 0x24, 0x30, 0x03, 0x64, 0xd9, + 0xc6, 0x37, 0xa0, 0x12, 0xcf, 0x16, 0xa2, 0xe3, 0xc1, 0xcd, 0x16, 0xf0, 0x09, 0xc1, 0x2c, 0x83, + 0x52, 0xd9, 0xf2, 0x5c, 0xc7, 0x93, 0x2c, 0x5b, 0xff, 0xcb, 0x24, 0xaa, 0xfc, 0xdb, 0xe3, 0x1b, + 0xe2, 0x95, 0xe7, 0x9d, 0xac, 0xe3, 0xbb, 0xe1, 0xa5, 0xd4, 0xf8, 0x76, 0x1d, 0xea, 0x5c, 0x19, + 0xf2, 0x5b, 0xbe, 0x0a, 0x59, 0xa6, 0xfe, 0x3f, 0xb2, 0x50, 0x8e, 0x0e, 0x54, 0xf4, 0x09, 0x46, + 0x81, 0x6b, 0x04, 0x1a, 0x1f, 0xf9, 0x55, 0x28, 0x28, 0x47, 0x19, 0x31, 0xae, 0x58, 0xba, 0x81, + 0xb6, 0x5a, 0x7a, 0x65, 0xb5, 0x01, 0x3b, 0xb9, 0x54, 0xce, 0x40, 0xf4, 0xe4, 0x8e, 0x08, 0xfb, + 0xc6, 0x84, 0x4d, 0x00, 0x48, 0x7f, 0x2c, 0x4e, 0x51, 0xe6, 0xe8, 0xbd, 0xb6, 0xe2, 0xd2, 0x20, + 0xfe, 0x26, 0xe4, 0x71, 0x80, 0x46, 0x68, 0x7e, 0x71, 0x62, 0xc0, 0x28, 0x26, 0x87, 0x81, 0xc4, + 0xe5, 0x59, 0x43, 0x0f, 0xcc, 0x22, 0x64, 0xfe, 0x0a, 0x2c, 0xeb, 0x4d, 0x78, 0x10, 0xf9, 0x0f, + 0x25, 0xe2, 0x3c, 0x01, 0xe5, 0xeb, 0x38, 0x9d, 0x42, 0xc9, 0x5a, 0x79, 0x0e, 0xf9, 0x8e, 0x26, + 0x67, 0xad, 0x8d, 0x24, 0x96, 0xa6, 0x6c, 0xbc, 0x8d, 0x73, 0x2a, 0x94, 0xc4, 0x65, 0x6e, 0x0e, + 0x86, 0xea, 0x5c, 0x0b, 0xcd, 0xb6, 0x54, 0xdd, 0xbe, 0xe3, 0xf5, 0x58, 0x46, 0x4f, 0x31, 0x2e, + 0x22, 0xa1, 0x04, 0x81, 0x1f, 0xb0, 0x5c, 0xbd, 0x0e, 0x79, 0x94, 0x51, 0x54, 0x92, 0x9e, 0x18, + 0x48, 0x33, 0xd3, 0xf4, 0x5c, 0xbf, 0x02, 0xab, 0x53, 0xe7, 0x71, 0xfd, 0x5f, 0x16, 0xb5, 0x84, + 0x20, 0x05, 0xd9, 0x82, 0x86, 0x82, 0xcc, 0xbc, 0x17, 0xd2, 0x31, 0xc8, 0x65, 0x5c, 0xc7, 0x7c, + 0x00, 0x05, 0x1c, 0x58, 0xa4, 0x62, 0xe6, 0x20, 0xdf, 0x43, 0x74, 0x4b, 0x53, 0xa1, 0x07, 0xd3, + 0xed, 0xcb, 0xee, 0x89, 0xb4, 0x8d, 0xae, 0x8f, 0x9a, 0x28, 0x34, 0xdd, 0x94, 0x79, 0xae, 0x1b, + 0x24, 0x12, 0x5d, 0xdf, 0x6b, 0x0e, 0xfc, 0xcf, 0x1c, 0x5a, 0x57, 0x14, 0x89, 0x08, 0x10, 0xbd, + 0x6d, 0xa1, 0x8c, 0x98, 0x65, 0x4b, 0x00, 0xf5, 0x26, 0x14, 0xe8, 0xdb, 0xb8, 0x13, 0x74, 0x9f, + 0x75, 0xa4, 0xe1, 0x95, 0xf9, 0xfa, 0x6c, 0xba, 0x5c, 0xff, 0x71, 0x16, 0xf2, 0xd8, 0xe6, 0x77, + 0xa1, 0x10, 0xa0, 0x1f, 0x46, 0xd3, 0x79, 0x91, 0xcf, 0xa6, 0x51, 0xf8, 0x47, 0x46, 0x14, 0xb3, + 0x73, 0x08, 0x4b, 0xfc, 0xc5, 0xb4, 0x58, 0x5e, 0x85, 0xc2, 0x50, 0x04, 0x62, 0x60, 0xf6, 0x89, + 0x6e, 0x34, 0x7e, 0x98, 0x81, 0x3c, 0x22, 0xf1, 0x55, 0x58, 0x6a, 0xab, 0xc0, 0x39, 0x91, 0xaa, + 0x1f, 0xf8, 0xa3, 0x5e, 0x5f, 0x4b, 0xd2, 0x43, 0x79, 0xae, 0xf5, 0x8d, 0x56, 0x08, 0x4a, 0xb8, + 0x4e, 0x97, 0x65, 0x51, 0xaa, 0x36, 0x7c, 0xd7, 0x66, 0x39, 0xbe, 0x02, 0xd5, 0x47, 0x9e, 0x2d, + 0x83, 0xb0, 0xeb, 0x07, 0xd2, 0x66, 0x79, 0xb3, 0xbb, 0x4f, 0x58, 0x81, 0xce, 0x32, 0x79, 0xa6, + 0xc8, 0x17, 0x62, 0x45, 0x7e, 0x05, 0x56, 0x36, 0xc6, 0x1d, 0x24, 0x56, 0x42, 0x9d, 0xb4, 0x27, + 0x3d, 0x14, 0x32, 0x56, 0xd6, 0x42, 0xec, 0x7f, 0xe6, 0xb0, 0x0a, 0x7e, 0x4c, 0xef, 0x13, 0x06, + 0x8d, 0x7f, 0x9d, 0x89, 0x34, 0xc7, 0x12, 0x54, 0x0e, 0x45, 0x20, 0x7a, 0x81, 0x18, 0x62, 0xff, + 0xaa, 0x50, 0xd2, 0x07, 0xe7, 0x1b, 0x5a, 0xbb, 0xe9, 0xc6, 0x7d, 0xad, 0x1b, 0x75, 0xe3, 0x4d, + 0x96, 0x4b, 0x1a, 0x6f, 0xb1, 0x3c, 0x7e, 0xe3, 0x93, 0x91, 0xaf, 0x24, 0x2b, 0x90, 0xae, 0xf3, + 0x6d, 0xc9, 0x8a, 0x08, 0xec, 0xa0, 0x46, 0x61, 0x25, 0x1c, 0xf3, 0x26, 0xca, 0xcf, 0x91, 0x7f, + 0xc6, 0xca, 0xd8, 0x0d, 0x9c, 0x46, 0x69, 0xb3, 0x0a, 0xbe, 0xd9, 0x1f, 0x0d, 0x8e, 0x24, 0x0e, + 0x13, 0xf0, 0x4d, 0xc7, 0xef, 0xf5, 0x5c, 0xc9, 0xaa, 0x38, 0x07, 0x29, 0xe5, 0xcb, 0x16, 0x49, + 0xd3, 0x0a, 0xd7, 0xf5, 0x47, 0x8a, 0x2d, 0xd5, 0xff, 0x34, 0x07, 0x79, 0xf4, 0x6e, 0x70, 0xef, + 0xf4, 0x51, 0xcf, 0x98, 0xbd, 0x83, 0xcf, 0xf1, 0x0e, 0xcc, 0x26, 0x3b, 0x90, 0xbf, 0x6f, 0x56, + 0x3a, 0x37, 0x87, 0x96, 0x45, 0xc6, 0xe9, 0x45, 0xe6, 0x90, 0x1f, 0x38, 0x03, 0x69, 0x74, 0x1d, + 0x3d, 0x23, 0x2c, 0xc4, 0xf3, 0xb8, 0x40, 0xc1, 0x13, 0x7a, 0xc6, 0x5d, 0x23, 0xf0, 0x58, 0x58, + 0x57, 0xb4, 0x07, 0x72, 0x56, 0xd4, 0x9c, 0xa1, 0xbd, 0x2a, 0x33, 0xb5, 0xd7, 0x07, 0x91, 0xf6, + 0x2a, 0xcd, 0xb1, 0xeb, 0xa9, 0x9b, 0x69, 0xcd, 0x95, 0x28, 0x8d, 0xf2, 0xfc, 0xe4, 0xa9, 0xc3, + 0x64, 0xcb, 0x48, 0x6d, 0x72, 0xd0, 0x95, 0xf5, 0x2c, 0xb3, 0x0c, 0xae, 0x26, 0x6d, 0x57, 0xad, + 0xf3, 0x1e, 0x3b, 0xb6, 0xf4, 0x59, 0x8e, 0x0e, 0xc2, 0x91, 0xed, 0xf8, 0x2c, 0x8f, 0x96, 0xd7, + 0xe1, 0xd6, 0x36, 0x2b, 0x34, 0x5e, 0x49, 0x1d, 0x49, 0xeb, 0x23, 0xe5, 0x6b, 0x36, 0x24, 0xbe, + 0x19, 0x2d, 0x8d, 0x47, 0xd2, 0x66, 0xd9, 0xc6, 0x3b, 0x33, 0xd4, 0xec, 0x12, 0x54, 0x1e, 0x0d, + 0x5d, 0x5f, 0xd8, 0x97, 0xe8, 0xd9, 0x45, 0x80, 0xc4, 0xab, 0xae, 0xff, 0xd1, 0x2f, 0x26, 0xc7, + 0x39, 0xda, 0xa2, 0xa1, 0x3f, 0x0a, 0xba, 0x92, 0x54, 0x48, 0xc5, 0x32, 0x2d, 0xfe, 0x1d, 0x28, + 0xe0, 0xfb, 0x28, 0x8c, 0x73, 0x77, 0x2e, 0x5f, 0x6e, 0xed, 0xb1, 0x23, 0x9f, 0x59, 0x9a, 0x90, + 0xdf, 0x02, 0x10, 0x5d, 0xe5, 0x9c, 0x4a, 0x04, 0x9a, 0xcd, 0x9e, 0x82, 0xf0, 0xb7, 0xd3, 0xe6, + 0xcb, 0xe5, 0x71, 0xc8, 0x94, 0x5d, 0xc3, 0x2d, 0xa8, 0xe2, 0xd6, 0x1d, 0x1e, 0x04, 0xb8, 0xdb, + 0x6b, 0x8b, 0x44, 0xf8, 0xfa, 0x7c, 0xdd, 0x7b, 0x10, 0x13, 0x5a, 0x69, 0x26, 0xfc, 0x11, 0x2c, + 0xea, 0x98, 0x9a, 0x61, 0xba, 0x44, 0x4c, 0xdf, 0x98, 0x8f, 0xe9, 0x41, 0x42, 0x69, 0x8d, 0xb1, + 0x99, 0x0e, 0x4b, 0x16, 0x5e, 0x38, 0x2c, 0xf9, 0x0a, 0x2c, 0x77, 0xc6, 0x77, 0x81, 0x3e, 0x2a, + 0x26, 0xa0, 0xbc, 0x01, 0x8b, 0x4e, 0x98, 0x44, 0x45, 0x29, 0x46, 0x52, 0xb6, 0xc6, 0x60, 0xf5, + 0xff, 0x50, 0x84, 0x3c, 0xcd, 0xfc, 0x64, 0x8c, 0x6b, 0x73, 0x4c, 0xa5, 0xdf, 0x9b, 0x7f, 0xa9, + 0x27, 0x76, 0x3c, 0x69, 0x90, 0x5c, 0x4a, 0x83, 0x7c, 0x07, 0x0a, 0xa1, 0x1f, 0xa8, 0x68, 0x79, + 0xe7, 0x14, 0xa2, 0xb6, 0x1f, 0x28, 0x4b, 0x13, 0xf2, 0x6d, 0x28, 0x1d, 0x3b, 0xae, 0xc2, 0x45, + 0xd1, 0x93, 0xf7, 0xda, 0x7c, 0x3c, 0xb6, 0x89, 0xc8, 0x8a, 0x88, 0xf9, 0x6e, 0x5a, 0xd8, 0x8a, + 0xc4, 0x69, 0x6d, 0x3e, 0x4e, 0xb3, 0x64, 0xf0, 0x2e, 0xb0, 0xae, 0x7f, 0x2a, 0x03, 0x2b, 0x15, + 0x98, 0xd4, 0x87, 0xf4, 0x14, 0x9c, 0xd7, 0xa1, 0xdc, 0x77, 0x6c, 0x89, 0x76, 0x0e, 0xe9, 0x98, + 0xb2, 0x15, 0xb7, 0xf9, 0x43, 0x28, 0x93, 0x7f, 0x80, 0x5a, 0xb1, 0xf2, 0xc2, 0x93, 0xaf, 0x5d, + 0x95, 0x88, 0x01, 0x7e, 0x88, 0x3e, 0xbe, 0xed, 0x28, 0x8a, 0x4f, 0x97, 0xad, 0xb8, 0x8d, 0x1d, + 0x26, 0x79, 0x4f, 0x77, 0xb8, 0xaa, 0x3b, 0x3c, 0x09, 0xe7, 0x6f, 0xc1, 0x35, 0x82, 0x4d, 0x1c, + 0x92, 0xb8, 0xd5, 0x90, 0xe9, 0xec, 0x97, 0x68, 0xb0, 0x0c, 0x45, 0x4f, 0xee, 0x3a, 0x03, 0x47, + 0xd5, 0x96, 0x6e, 0x67, 0xee, 0x14, 0xac, 0x04, 0xc0, 0x5f, 0x83, 0x55, 0x5b, 0x1e, 0x8b, 0x91, + 0xab, 0x3a, 0x72, 0x30, 0x74, 0x85, 0x92, 0x2d, 0x9b, 0x64, 0xb4, 0x62, 0x4d, 0xbf, 0xe0, 0xaf, + 0xc3, 0x15, 0x03, 0x3c, 0x88, 0xb3, 0x0a, 0x2d, 0x9b, 0xc2, 0x77, 0x15, 0x6b, 0xd6, 0xab, 0xc6, + 0x9e, 0x51, 0xc3, 0x78, 0x80, 0xa2, 0x9f, 0x1a, 0x29, 0xd0, 0x50, 0xe9, 0x13, 0xf9, 0x81, 0x70, + 0x5d, 0x19, 0x9c, 0x6b, 0x27, 0xf7, 0xa1, 0xf0, 0x8e, 0x84, 0xc7, 0x72, 0x74, 0xc6, 0x0a, 0x57, + 0x7a, 0xb6, 0x08, 0xf4, 0x89, 0xfc, 0x80, 0x0e, 0xf4, 0x42, 0xe3, 0x0e, 0xe4, 0x69, 0x4a, 0x2b, + 0x50, 0xd0, 0x5e, 0x12, 0x79, 0xcc, 0xc6, 0x43, 0x22, 0x8d, 0xbc, 0x8b, 0xdb, 0x8f, 0x65, 0xeb, + 0x3f, 0xcd, 0x41, 0x39, 0x9a, 0xbc, 0x28, 0x87, 0x90, 0x49, 0x72, 0x08, 0x68, 0xc6, 0x85, 0x8f, + 0x9d, 0xd0, 0x39, 0x32, 0x66, 0x69, 0xd9, 0x4a, 0x00, 0x68, 0x09, 0x3d, 0x73, 0x6c, 0xd5, 0xa7, + 0x3d, 0x53, 0xb0, 0x74, 0x83, 0xdf, 0x81, 0x15, 0x1b, 0xe7, 0xc1, 0xeb, 0xba, 0x23, 0x5b, 0x76, + 0xf0, 0x14, 0xd5, 0x61, 0x82, 0x49, 0x30, 0xff, 0x1e, 0x80, 0x72, 0x06, 0x72, 0xdb, 0x0f, 0x06, + 0x42, 0x19, 0xdf, 0xe0, 0x5b, 0x2f, 0x26, 0xd5, 0x6b, 0x9d, 0x98, 0x81, 0x95, 0x62, 0x86, 0xac, + 0xf1, 0x6b, 0x86, 0x75, 0xe9, 0x4b, 0xb1, 0xde, 0x8a, 0x19, 0x58, 0x29, 0x66, 0x8d, 0x5f, 0x01, + 0x48, 0xde, 0xf0, 0xeb, 0xc0, 0xf7, 0x7c, 0x4f, 0xf5, 0xd7, 0x8f, 0x8e, 0x82, 0x0d, 0x79, 0xec, + 0x07, 0x72, 0x4b, 0xe0, 0xb1, 0x76, 0x0d, 0x56, 0x63, 0xf8, 0xfa, 0xb1, 0x92, 0x01, 0x82, 0x69, + 0xea, 0xdb, 0x7d, 0x3f, 0x50, 0xda, 0xb6, 0xa2, 0xc7, 0x47, 0x6d, 0x96, 0xc3, 0xa3, 0xb4, 0xd5, + 0x3e, 0x60, 0xf9, 0xc6, 0x1d, 0x80, 0x64, 0x48, 0xe4, 0x83, 0xd0, 0xd3, 0x1b, 0xf7, 0x8d, 0x47, + 0x42, 0xad, 0xfb, 0x6f, 0xb1, 0x4c, 0xfd, 0x0f, 0x73, 0x90, 0x47, 0x55, 0x83, 0xee, 0x57, 0x7a, + 0x5f, 0xe8, 0xe5, 0x4b, 0x83, 0xbe, 0x9c, 0x82, 0x44, 0xde, 0x69, 0x05, 0xf9, 0x1e, 0x54, 0xbb, + 0xa3, 0x50, 0xf9, 0x03, 0x3a, 0x1d, 0x4c, 0x02, 0xe6, 0xfa, 0x54, 0x20, 0xe3, 0xb1, 0x70, 0x47, + 0xd2, 0x4a, 0xa3, 0xf2, 0xb7, 0xa1, 0x78, 0xac, 0x17, 0x42, 0x87, 0x32, 0x7e, 0xe1, 0x82, 0x03, + 0xc4, 0x4c, 0xb6, 0x41, 0xc6, 0x71, 0x39, 0x53, 0x42, 0x94, 0x06, 0x99, 0x83, 0xa0, 0x18, 0x1f, + 0x04, 0xbf, 0x02, 0xcb, 0x12, 0xcd, 0x8a, 0x43, 0x57, 0x74, 0xe5, 0x40, 0x7a, 0xd1, 0xca, 0xbf, + 0xf5, 0x02, 0x23, 0x26, 0xbb, 0x84, 0x86, 0x3d, 0xc1, 0xab, 0xf1, 0x35, 0xb3, 0x49, 0x4b, 0x90, + 0x5b, 0x0f, 0xbb, 0xc6, 0xed, 0x96, 0x61, 0x57, 0xdb, 0xf4, 0x9b, 0x34, 0x60, 0x96, 0x6d, 0xbc, + 0x01, 0x95, 0x98, 0x07, 0x67, 0xb0, 0xb8, 0xef, 0xab, 0xf6, 0x50, 0x76, 0x9d, 0x63, 0x47, 0xda, + 0x3a, 0x90, 0xd0, 0x56, 0x22, 0x50, 0x3a, 0x72, 0xd5, 0xf4, 0x6c, 0x96, 0xad, 0xff, 0x5e, 0x19, + 0x8a, 0x5a, 0xe3, 0x9b, 0x21, 0x55, 0xe2, 0x21, 0x7d, 0x02, 0x65, 0x7f, 0x28, 0x03, 0xa1, 0xfc, + 0xc0, 0x84, 0x0b, 0xde, 0x7e, 0x91, 0x13, 0x64, 0xed, 0xc0, 0x10, 0x5b, 0x31, 0x9b, 0x49, 0x79, + 0xc9, 0x4e, 0xcb, 0xcb, 0x5d, 0x60, 0xd1, 0x61, 0x71, 0x18, 0x20, 0x9d, 0x3a, 0x37, 0xce, 0xdf, + 0x14, 0x9c, 0x77, 0xa0, 0xd2, 0xf5, 0x3d, 0xdb, 0x89, 0x43, 0x07, 0xcb, 0xf7, 0xdf, 0x79, 0xa1, + 0x1e, 0x6e, 0x46, 0xd4, 0x56, 0xc2, 0x88, 0xbf, 0x06, 0x85, 0x53, 0x14, 0x24, 0x92, 0x98, 0x8b, + 0xc5, 0x4c, 0x23, 0xf1, 0x4f, 0xa1, 0xfa, 0xfd, 0x91, 0xd3, 0x3d, 0x39, 0x48, 0x87, 0xa6, 0xde, + 0x7b, 0xa1, 0x5e, 0x7c, 0x92, 0xd0, 0x5b, 0x69, 0x66, 0x29, 0xe1, 0x2d, 0xfd, 0x19, 0x84, 0xb7, + 0x3c, 0x2d, 0xbc, 0x16, 0x2c, 0x79, 0x32, 0x54, 0xd2, 0xde, 0x36, 0x06, 0x02, 0x7c, 0x09, 0x03, + 0x61, 0x9c, 0x45, 0xe3, 0xab, 0x50, 0x8e, 0x16, 0x9c, 0x17, 0x21, 0xbb, 0x8f, 0x96, 0x78, 0x11, + 0xb2, 0x07, 0x81, 0x96, 0xb6, 0x75, 0x94, 0xb6, 0xc6, 0x1f, 0x67, 0xa0, 0x12, 0x4f, 0xfa, 0x78, + 0x88, 0xab, 0xf9, 0xfd, 0x91, 0x70, 0x59, 0x86, 0x7c, 0x34, 0x5f, 0xe9, 0x16, 0x69, 0xaa, 0x07, + 0x94, 0x21, 0x0e, 0x58, 0x8e, 0xce, 0x25, 0x19, 0x86, 0x2c, 0xcf, 0x39, 0x2c, 0x1b, 0xf0, 0x41, + 0xa0, 0x51, 0x0b, 0xe8, 0xc2, 0xe1, 0xdb, 0x08, 0x50, 0xd4, 0xc7, 0xd8, 0x89, 0xd4, 0x2e, 0xea, + 0xbe, 0xaf, 0xa8, 0x51, 0xc6, 0x4e, 0xb5, 0x3c, 0x56, 0xc1, 0x6f, 0xee, 0xfb, 0xaa, 0xe5, 0x31, + 0x48, 0x7c, 0x82, 0x6a, 0xf4, 0x79, 0x6a, 0x2d, 0x92, 0xc7, 0xe1, 0xba, 0x2d, 0x8f, 0x2d, 0x99, + 0x17, 0xba, 0xb5, 0x8c, 0x1c, 0x9b, 0x67, 0xa2, 0x8b, 0xe4, 0x2b, 0x7c, 0x19, 0x00, 0x69, 0x4c, + 0x9b, 0xe1, 0x96, 0x6c, 0x9e, 0x39, 0xa1, 0x0a, 0xd9, 0x6a, 0xe3, 0xdf, 0x67, 0xa0, 0x9a, 0x5a, + 0x60, 0xf4, 0x39, 0x08, 0x11, 0xf5, 0xb8, 0x76, 0x41, 0xbe, 0x87, 0xd3, 0x18, 0xd8, 0x91, 0x8e, + 0xee, 0xf8, 0xf8, 0x98, 0xc5, 0xef, 0x75, 0xfc, 0x81, 0x1f, 0x04, 0xfe, 0x33, 0x7d, 0xde, 0xee, + 0x8a, 0x50, 0x3d, 0x91, 0xf2, 0x84, 0xe5, 0x71, 0xa8, 0x9b, 0xa3, 0x20, 0x90, 0x9e, 0x06, 0x14, + 0xa8, 0x73, 0xf2, 0x4c, 0xb7, 0x8a, 0xc8, 0x14, 0x91, 0xe9, 0x10, 0x60, 0x25, 0x54, 0x04, 0x06, + 0x5b, 0x43, 0xca, 0x88, 0x80, 0xe8, 0xba, 0x59, 0x41, 0xb7, 0x5e, 0xbb, 0xc5, 0x07, 0xc7, 0x5b, + 0xe2, 0x3c, 0x5c, 0xef, 0xf9, 0x0c, 0x26, 0x81, 0xfb, 0xfe, 0x33, 0x56, 0xad, 0x8f, 0x00, 0x12, + 0x47, 0x00, 0x1d, 0x20, 0x14, 0x88, 0x38, 0x70, 0x6d, 0x5a, 0xfc, 0x00, 0x00, 0x9f, 0x08, 0x33, + 0xf2, 0x82, 0x5e, 0xc0, 0x3a, 0x23, 0x3a, 0x2b, 0xc5, 0xa2, 0xfe, 0x57, 0xa1, 0x12, 0xbf, 0x40, + 0xbf, 0x97, 0xec, 0xa8, 0xf8, 0xb3, 0x51, 0x13, 0x8d, 0x02, 0xc7, 0xb3, 0xe5, 0x19, 0xe9, 0x95, + 0x82, 0xa5, 0x1b, 0xd8, 0xcb, 0xbe, 0x63, 0xdb, 0xd2, 0x8b, 0xd2, 0x0b, 0xba, 0x35, 0x2b, 0x09, + 0x9c, 0x9f, 0x99, 0x04, 0xae, 0xff, 0x2a, 0x54, 0x53, 0x9e, 0xca, 0x85, 0xc3, 0x4e, 0x75, 0x2c, + 0x3b, 0xde, 0xb1, 0x9b, 0x50, 0x89, 0x0a, 0x0f, 0x42, 0x3a, 0xbd, 0x2a, 0x56, 0x02, 0xa8, 0xff, + 0x8b, 0x2c, 0x9a, 0x4f, 0x38, 0xb4, 0x49, 0xef, 0x62, 0x1b, 0x8a, 0xe8, 0x6a, 0x8f, 0xa2, 0x0c, + 0xfa, 0x9c, 0x1b, 0xb4, 0x4d, 0x34, 0x3b, 0x0b, 0x96, 0xa1, 0xe6, 0x1f, 0x40, 0x4e, 0x89, 0x9e, + 0x89, 0xce, 0x7d, 0x7d, 0x3e, 0x26, 0x1d, 0xd1, 0xdb, 0x59, 0xb0, 0x90, 0x8e, 0xef, 0x42, 0xb9, + 0x6b, 0x02, 0x2a, 0x46, 0x29, 0xce, 0xe9, 0x00, 0x44, 0x61, 0x98, 0x9d, 0x05, 0x2b, 0xe6, 0xc0, + 0xbf, 0x03, 0x79, 0x34, 0x69, 0x4c, 0xa1, 0xc1, 0x9c, 0x8e, 0x0d, 0x6e, 0x97, 0x9d, 0x05, 0x8b, + 0x28, 0x37, 0x4a, 0x50, 0x20, 0x1d, 0x5c, 0xaf, 0x41, 0x51, 0x8f, 0x75, 0x72, 0xe6, 0xea, 0x37, + 0x20, 0xd7, 0x11, 0x3d, 0x34, 0x2b, 0x1d, 0x3b, 0x34, 0xfe, 0x39, 0x3e, 0xd6, 0x5f, 0x4e, 0x82, + 0x43, 0xe9, 0xb8, 0x63, 0x66, 0x2c, 0xee, 0x58, 0x2f, 0x42, 0x1e, 0xbf, 0x58, 0xbf, 0x79, 0x99, + 0x89, 0x5a, 0xff, 0x27, 0x39, 0xb4, 0x66, 0x95, 0x3c, 0x9b, 0x19, 0x53, 0xfd, 0x18, 0x2a, 0xc3, + 0xc0, 0xef, 0xca, 0x30, 0xf4, 0x03, 0x63, 0xfe, 0xbc, 0xf6, 0xfc, 0x7c, 0xe7, 0xda, 0x61, 0x44, + 0x63, 0x25, 0xe4, 0x8d, 0x7f, 0x93, 0x85, 0x4a, 0xfc, 0x42, 0x1b, 0xd1, 0x4a, 0x9e, 0xe9, 0xf8, + 0xd9, 0x9e, 0x0c, 0x06, 0xc2, 0xb1, 0xb5, 0xf6, 0xd8, 0xec, 0x8b, 0xc8, 0xc2, 0xfb, 0x9e, 0x3f, + 0x52, 0xa3, 0x23, 0xa9, 0xe3, 0x26, 0x8f, 0x9d, 0x81, 0xf4, 0x59, 0x9e, 0x32, 0x16, 0x28, 0xd8, + 0x5d, 0xd7, 0x1f, 0xd9, 0xac, 0x80, 0xed, 0x07, 0x74, 0xbc, 0xed, 0x89, 0x61, 0xa8, 0x75, 0xe6, + 0x9e, 0x13, 0xf8, 0xac, 0x84, 0x44, 0xdb, 0x4e, 0x6f, 0x20, 0x58, 0x19, 0x99, 0x75, 0x9e, 0x39, + 0x0a, 0x95, 0x70, 0x85, 0xaf, 0xc2, 0xd2, 0xc1, 0x50, 0x7a, 0x6d, 0x15, 0x48, 0xa9, 0xf6, 0xc4, + 0x50, 0x07, 0xd2, 0x2c, 0x69, 0xdb, 0x8e, 0xd2, 0xfa, 0x73, 0x5b, 0x74, 0xe5, 0x91, 0xef, 0x9f, + 0xb0, 0x45, 0x54, 0x34, 0x2d, 0x2f, 0x54, 0xa2, 0x17, 0x88, 0x81, 0xd6, 0xa1, 0x1d, 0xe9, 0x4a, + 0x6a, 0x2d, 0xd3, 0xb7, 0x1d, 0xd5, 0x1f, 0x1d, 0x3d, 0x40, 0x67, 0x63, 0x45, 0x27, 0x37, 0x6c, + 0x39, 0x94, 0xa8, 0x43, 0x17, 0xa1, 0xbc, 0xe1, 0xb8, 0xce, 0x91, 0xe3, 0x3a, 0x6c, 0x15, 0x51, + 0x9b, 0x67, 0x5d, 0xe1, 0x3a, 0x76, 0x20, 0x9e, 0x31, 0x8e, 0x9d, 0x7b, 0x18, 0xf8, 0x27, 0x0e, + 0xbb, 0x82, 0x88, 0xe4, 0x7b, 0x9c, 0x3a, 0x9f, 0xb3, 0xab, 0x94, 0xa0, 0x39, 0x91, 0xaa, 0xdb, + 0x3f, 0x16, 0x47, 0xec, 0x5a, 0x12, 0x47, 0xba, 0x5e, 0x5f, 0x85, 0x95, 0x89, 0x54, 0x70, 0xbd, + 0x64, 0x5c, 0x9e, 0xfa, 0x12, 0x54, 0x53, 0x39, 0xba, 0xfa, 0x2b, 0x50, 0x8e, 0x32, 0x78, 0xe8, + 0x1a, 0x3a, 0xa1, 0x8e, 0x3d, 0x1a, 0x21, 0x89, 0xdb, 0xf5, 0xdf, 0xcf, 0x40, 0x51, 0xa7, 0x4f, + 0xf9, 0x46, 0x5c, 0xee, 0x90, 0x99, 0x23, 0x65, 0xa6, 0x89, 0x4c, 0xc2, 0x31, 0xae, 0x79, 0xb8, + 0x0a, 0x05, 0x97, 0x7c, 0x40, 0xa3, 0xbe, 0xa8, 0x91, 0xd2, 0x36, 0xb9, 0xb4, 0xb6, 0x69, 0xac, + 0xc7, 0x49, 0xce, 0x28, 0xde, 0x45, 0x56, 0x61, 0x27, 0x90, 0x52, 0xc7, 0xb2, 0xc8, 0x85, 0xcb, + 0xd2, 0x59, 0xe1, 0x0f, 0x86, 0xa2, 0xab, 0x08, 0x40, 0xa7, 0x28, 0x2a, 0x53, 0x96, 0x47, 0x29, + 0xdf, 0xec, 0x0b, 0xd5, 0x38, 0x86, 0xf2, 0xa1, 0x1f, 0x4e, 0x9e, 0xc9, 0x25, 0xc8, 0x75, 0xfc, + 0xa1, 0xb6, 0x30, 0x37, 0x7c, 0x45, 0x16, 0xa6, 0x3e, 0x82, 0x8f, 0x95, 0x16, 0x2a, 0xcb, 0xe9, + 0xf5, 0x95, 0x76, 0xff, 0x5a, 0x9e, 0x27, 0x03, 0x56, 0xc0, 0x35, 0xb4, 0xe4, 0x10, 0xed, 0x56, + 0x56, 0xc4, 0x55, 0x23, 0xf8, 0xb6, 0x13, 0x84, 0x8a, 0x95, 0x1a, 0x2d, 0x3c, 0x4d, 0x9d, 0x1e, + 0x1d, 0x82, 0xf4, 0x40, 0xac, 0x16, 0xb0, 0x8b, 0xd4, 0xdc, 0x94, 0x1e, 0xca, 0x18, 0xe5, 0xd5, + 0x74, 0x45, 0x0c, 0x7d, 0x20, 0x8b, 0x27, 0x18, 0xb5, 0x3f, 0x1e, 0x85, 0xca, 0x39, 0x3e, 0x67, + 0xb9, 0xc6, 0x13, 0x58, 0x1a, 0xab, 0x9d, 0xe1, 0x57, 0x81, 0x8d, 0x01, 0xb0, 0xeb, 0x0b, 0xfc, + 0x06, 0x5c, 0x19, 0x83, 0xee, 0x39, 0xb6, 0x4d, 0x01, 0xc6, 0xc9, 0x17, 0xd1, 0x00, 0x37, 0x2a, + 0x50, 0xea, 0xea, 0x55, 0x6a, 0x1c, 0xc2, 0x12, 0x2d, 0xdb, 0x9e, 0x54, 0xe2, 0xc0, 0x73, 0xcf, + 0xff, 0xcc, 0x05, 0x4e, 0x8d, 0x6f, 0x40, 0x81, 0x12, 0x02, 0xa8, 0x2f, 0x8e, 0x03, 0x7f, 0x40, + 0xbc, 0x0a, 0x16, 0x3d, 0x23, 0x77, 0xe5, 0x9b, 0xb5, 0xcf, 0x2a, 0xbf, 0xf1, 0x45, 0x19, 0x4a, + 0xeb, 0xdd, 0xae, 0x3f, 0xf2, 0xd4, 0xd4, 0x97, 0xdf, 0x86, 0x62, 0xd7, 0xf7, 0x8e, 0x9d, 0x9e, + 0xd1, 0xc7, 0x93, 0x96, 0xa1, 0xa1, 0x43, 0x81, 0x3b, 0x76, 0x7a, 0x96, 0x41, 0x46, 0x32, 0x73, + 0x9e, 0x14, 0x2e, 0x25, 0xd3, 0x4a, 0x35, 0x3e, 0x3e, 0xee, 0x41, 0xde, 0xf1, 0x8e, 0x7d, 0x53, + 0x8d, 0xf8, 0xd2, 0x05, 0x44, 0x54, 0x92, 0x47, 0x88, 0xf5, 0xff, 0x96, 0x81, 0xa2, 0xfe, 0x34, + 0x7f, 0x05, 0x96, 0xa5, 0x87, 0x9b, 0x29, 0x52, 0xe5, 0x66, 0x17, 0x4d, 0x40, 0xd1, 0x68, 0x35, + 0x10, 0x79, 0x34, 0xea, 0x19, 0x87, 0x3f, 0x0d, 0xe2, 0xef, 0xc1, 0x0d, 0xdd, 0x3c, 0x0c, 0x64, + 0x20, 0x5d, 0x29, 0x42, 0xb9, 0xd9, 0x17, 0x9e, 0x27, 0x5d, 0x73, 0xb0, 0x5f, 0xf4, 0x9a, 0x37, + 0x60, 0x51, 0xbf, 0x6a, 0x0f, 0x45, 0x57, 0x86, 0x26, 0xc9, 0x34, 0x06, 0xe3, 0xdf, 0x84, 0x02, + 0x15, 0x6b, 0xd6, 0xec, 0xcb, 0x97, 0x52, 0x63, 0xd5, 0xfd, 0xf8, 0xe4, 0x59, 0x07, 0xd0, 0xd3, + 0x84, 0x4e, 0x97, 0xd9, 0xfd, 0xbf, 0x74, 0xe9, 0xbc, 0x92, 0x87, 0x97, 0x22, 0xc2, 0xfe, 0xd9, + 0xd2, 0x95, 0x54, 0x55, 0x87, 0x27, 0x63, 0x96, 0xc2, 0xf9, 0x63, 0xb0, 0xfa, 0xaf, 0xe7, 0x21, + 0x8f, 0x33, 0x8c, 0xc8, 0x7d, 0x7f, 0x20, 0xe3, 0xa0, 0xa6, 0x36, 0x35, 0xc6, 0x60, 0x68, 0xda, + 0x08, 0x9d, 0x57, 0x8e, 0xd1, 0xb4, 0xf2, 0x98, 0x04, 0x23, 0xe6, 0x30, 0xf0, 0x8f, 0x1d, 0x37, + 0xc1, 0x34, 0x46, 0xd0, 0x04, 0x98, 0xbf, 0x03, 0xd7, 0x07, 0x22, 0x38, 0x91, 0x8a, 0x76, 0xf7, + 0x13, 0x3f, 0x38, 0x09, 0x71, 0xe6, 0x5a, 0xb6, 0x89, 0x86, 0x5d, 0xf0, 0x16, 0x15, 0xa8, 0x2d, + 0x4f, 0x1d, 0xc2, 0x2c, 0xeb, 0x22, 0xcc, 0xa8, 0x8d, 0xc2, 0x21, 0xf4, 0xd4, 0xb4, 0x0d, 0x2f, + 0x93, 0xa8, 0x18, 0x87, 0xa2, 0xfd, 0xa4, 0x8b, 0x53, 0xc2, 0x96, 0x4d, 0x01, 0xba, 0x8a, 0x95, + 0x00, 0x50, 0x74, 0xe8, 0x63, 0x8f, 0xb5, 0x9a, 0x5c, 0xd2, 0x4e, 0x65, 0x0a, 0x84, 0x18, 0x4a, + 0x76, 0xfb, 0xd1, 0x47, 0x74, 0xf4, 0x2c, 0x0d, 0xe2, 0xb7, 0x00, 0x7a, 0x42, 0xc9, 0x67, 0xe2, + 0xfc, 0x51, 0xe0, 0xd6, 0xa4, 0x8e, 0xb8, 0x27, 0x10, 0x74, 0x4b, 0x5d, 0xbf, 0x2b, 0xdc, 0xb6, + 0xf2, 0x03, 0xd1, 0x93, 0x87, 0x42, 0xf5, 0x6b, 0x3d, 0xed, 0x96, 0x4e, 0xc2, 0x71, 0xc4, 0xca, + 0x19, 0xc8, 0x4f, 0x7d, 0x4f, 0xd6, 0xfa, 0x7a, 0xc4, 0x51, 0x1b, 0x7b, 0x22, 0x3c, 0xe1, 0x9e, + 0x2b, 0xa7, 0x8b, 0x63, 0x71, 0x74, 0x4f, 0x52, 0x20, 0x1c, 0xab, 0x27, 0xd5, 0x33, 0x3f, 0x38, + 0x69, 0xd9, 0xb5, 0xcf, 0xf4, 0x58, 0x63, 0x40, 0xe3, 0x00, 0x20, 0x11, 0x22, 0xd4, 0xcc, 0xeb, + 0x94, 0x15, 0x60, 0x0b, 0x68, 0xaf, 0x1f, 0x4a, 0xcf, 0x76, 0xbc, 0xde, 0x96, 0x91, 0x1b, 0x96, + 0x41, 0x20, 0x79, 0xfc, 0xd2, 0x8e, 0x81, 0x64, 0x1b, 0x50, 0x4b, 0xda, 0x2c, 0xd7, 0xf8, 0x3f, + 0x19, 0xa8, 0xa6, 0x92, 0xe0, 0x7f, 0x8e, 0x89, 0x7b, 0x3c, 0x39, 0xf1, 0xec, 0xc5, 0x09, 0xd5, + 0x32, 0x15, 0xb7, 0x71, 0xba, 0x4d, 0x8e, 0x1e, 0xdf, 0x6a, 0xff, 0x3e, 0x05, 0xf9, 0x52, 0x49, + 0xfb, 0xc6, 0x7d, 0x13, 0x24, 0xa9, 0x42, 0xe9, 0x91, 0x77, 0xe2, 0xf9, 0xcf, 0x3c, 0x7d, 0x24, + 0x52, 0x25, 0xc6, 0x58, 0x4e, 0x29, 0x2a, 0x96, 0xc8, 0x35, 0xfe, 0x69, 0x7e, 0xa2, 0x68, 0xa9, + 0x09, 0x45, 0x6d, 0x99, 0x93, 0xd1, 0x38, 0x5d, 0x65, 0x92, 0x46, 0x36, 0xf9, 0x8b, 0x14, 0xc8, + 0x32, 0xc4, 0x68, 0x32, 0xc7, 0x25, 0x7d, 0xd9, 0x99, 0x79, 0x96, 0x31, 0x46, 0x91, 0x1a, 0x1c, + 0xab, 0x6a, 0x8d, 0x39, 0xd4, 0xff, 0x56, 0x06, 0xae, 0xce, 0x42, 0x49, 0xd7, 0xfe, 0x66, 0xc6, + 0x6b, 0x7f, 0xdb, 0x13, 0xb5, 0xb4, 0x59, 0x1a, 0xcd, 0xbd, 0x17, 0xec, 0xc4, 0x78, 0x65, 0x6d, + 0xe3, 0xc7, 0x19, 0x58, 0x9d, 0x1a, 0x73, 0xca, 0x64, 0x00, 0x28, 0x6a, 0xc9, 0xd2, 0xa5, 0x2e, + 0x71, 0xf1, 0x81, 0x0e, 0x1e, 0xd3, 0x61, 0x1a, 0xea, 0x6c, 0xae, 0xa9, 0x1e, 0xd6, 0x16, 0x29, + 0xae, 0x1a, 0xea, 0xea, 0x9e, 0x64, 0x05, 0x3c, 0xeb, 0xb5, 0x5d, 0x63, 0x20, 0x45, 0x6d, 0x35, + 0xea, 0x08, 0x37, 0x2b, 0x51, 0x09, 0xcd, 0x68, 0xe8, 0x3a, 0x5d, 0x6c, 0x96, 0x79, 0x1d, 0xae, + 0xeb, 0x12, 0x72, 0xe3, 0xa1, 0x1d, 0x77, 0xfa, 0x0e, 0x6d, 0x0e, 0x56, 0x69, 0x58, 0x70, 0x65, + 0xc6, 0x98, 0xa8, 0x97, 0x8f, 0x4d, 0x8f, 0x97, 0x01, 0xb6, 0x1e, 0x47, 0xfd, 0x64, 0x19, 0xce, + 0x61, 0x79, 0xeb, 0x71, 0x9a, 0xa1, 0xd9, 0x2f, 0x8f, 0x51, 0x93, 0x84, 0x2c, 0xd7, 0xf8, 0x8d, + 0x4c, 0x94, 0xd6, 0xae, 0xff, 0x15, 0x58, 0xd2, 0x7d, 0x3c, 0x14, 0xe7, 0xae, 0x2f, 0x6c, 0xde, + 0x84, 0xe5, 0x30, 0xbe, 0xd7, 0x90, 0x3a, 0x0e, 0x26, 0x8f, 0xd9, 0xf6, 0x18, 0x92, 0x35, 0x41, + 0x14, 0x39, 0x1a, 0xd9, 0x24, 0x16, 0xce, 0xc9, 0x65, 0x12, 0xb4, 0xcb, 0x16, 0xc9, 0x09, 0x12, + 0x8d, 0x6f, 0xc2, 0x2a, 0x29, 0x2f, 0xdd, 0x19, 0x6d, 0x91, 0xa2, 0x3c, 0x68, 0xbd, 0xbb, 0x15, + 0xc9, 0x83, 0x69, 0x36, 0xfe, 0x53, 0x11, 0x20, 0x89, 0xfb, 0xcf, 0xd8, 0xe6, 0xb3, 0xd2, 0xd8, + 0x53, 0x59, 0xb8, 0xdc, 0x0b, 0x67, 0xe1, 0xde, 0x8b, 0x0d, 0x63, 0x1d, 0x80, 0x9d, 0xac, 0xe5, + 0x4d, 0xfa, 0x34, 0x69, 0x0e, 0x8f, 0x55, 0x79, 0x14, 0x26, 0xab, 0x3c, 0x6e, 0x4f, 0x97, 0x84, + 0x4d, 0xe8, 0x9f, 0xc4, 0xef, 0x2f, 0x8d, 0xf9, 0xfd, 0x75, 0x28, 0x07, 0x52, 0xd8, 0xbe, 0xe7, + 0x9e, 0x47, 0xc9, 0x9e, 0xa8, 0xcd, 0xdf, 0x84, 0x82, 0xa2, 0xab, 0x19, 0x65, 0xda, 0x2e, 0xcf, + 0x59, 0x38, 0x8d, 0x8b, 0xca, 0xcc, 0x09, 0x4d, 0x1d, 0x97, 0x3e, 0xc1, 0xca, 0x56, 0x0a, 0xc2, + 0xd7, 0x80, 0x3b, 0xe8, 0x04, 0xb9, 0xae, 0xb4, 0x37, 0xce, 0xb7, 0x74, 0x0e, 0x86, 0x4e, 0xcd, + 0xb2, 0x35, 0xe3, 0x4d, 0xb4, 0xfe, 0x8b, 0xc9, 0xfa, 0x53, 0x97, 0x4f, 0x9d, 0x10, 0x47, 0xba, + 0x44, 0xc6, 0x41, 0xdc, 0xc6, 0x73, 0x39, 0xda, 0xa3, 0x7a, 0x2e, 0x49, 0x7a, 0x93, 0x44, 0xe6, + 0x05, 0x6f, 0x1b, 0x7f, 0x90, 0x8d, 0x1d, 0x88, 0x0a, 0x14, 0x8e, 0x44, 0xe8, 0x74, 0xb5, 0x3f, + 0x69, 0x0e, 0x7e, 0xed, 0x44, 0x28, 0xdf, 0xf6, 0x59, 0x16, 0x7d, 0x81, 0x50, 0xa2, 0xd5, 0xbf, + 0x0c, 0x90, 0x5c, 0x57, 0x61, 0x79, 0xdc, 0x9b, 0xd1, 0x7a, 0xeb, 0x72, 0x0c, 0x22, 0xa5, 0x10, + 0x94, 0x1d, 0x17, 0xba, 0x91, 0x33, 0x49, 0xba, 0x9f, 0x95, 0x11, 0xc7, 0xf3, 0x95, 0xd4, 0x01, + 0x38, 0x92, 0x4e, 0x06, 0xc8, 0x26, 0xaa, 0xbf, 0x66, 0x55, 0x34, 0xce, 0x23, 0xa6, 0x3a, 0x6a, + 0x16, 0x92, 0xeb, 0xb2, 0x88, 0xbb, 0x73, 0xfc, 0x05, 0x5b, 0xc2, 0x1e, 0x25, 0xb7, 0x60, 0xd8, + 0x32, 0x72, 0x15, 0x54, 0x24, 0xb0, 0x82, 0x8f, 0xa7, 0x54, 0x3a, 0xc0, 0xf0, 0xab, 0x36, 0x2a, + 0x8c, 0x55, 0xec, 0x59, 0x6c, 0x1a, 0x30, 0x8e, 0xbe, 0xc7, 0x50, 0xa0, 0x23, 0xe0, 0x0c, 0x85, + 0xa7, 0xd8, 0x15, 0x1c, 0xea, 0xd0, 0x3e, 0x66, 0x57, 0x91, 0xa4, 0xdb, 0x17, 0x8a, 0x5d, 0x43, + 0x1c, 0x7c, 0xda, 0x92, 0x01, 0xae, 0x27, 0xbb, 0x8e, 0x38, 0x4a, 0xf4, 0xd8, 0x8d, 0xc6, 0xef, + 0x24, 0xa5, 0xa6, 0xaf, 0xc7, 0x26, 0xfa, 0x3c, 0x42, 0x8e, 0x46, 0xfc, 0xac, 0x1d, 0xd7, 0x84, + 0xd5, 0x40, 0x7e, 0x7f, 0xe4, 0x8c, 0x15, 0x60, 0xe7, 0x2e, 0xcf, 0xf0, 0x4f, 0x53, 0x34, 0x4e, + 0x61, 0x35, 0x6a, 0x3c, 0x71, 0x54, 0x9f, 0xa2, 0x25, 0xfc, 0xcd, 0x54, 0x85, 0x78, 0x66, 0xe6, + 0xcd, 0x9a, 0x98, 0x65, 0x52, 0x11, 0x1e, 0x47, 0xc3, 0xb3, 0x73, 0x44, 0xc3, 0x1b, 0xff, 0xbb, + 0x98, 0x0a, 0x98, 0x68, 0xa7, 0xc5, 0x8e, 0x9d, 0x96, 0xe9, 0x1c, 0x5f, 0x12, 0xe0, 0xce, 0xbe, + 0x48, 0x80, 0x7b, 0x56, 0xbe, 0xfc, 0x7d, 0xb4, 0xa1, 0x69, 0xff, 0x3c, 0x9e, 0x23, 0x78, 0x3f, + 0x86, 0xcb, 0x37, 0x28, 0x63, 0x27, 0xda, 0xba, 0x98, 0xa3, 0x30, 0xf3, 0xbe, 0x46, 0x3a, 0x35, + 0x67, 0x30, 0xad, 0x14, 0x55, 0x4a, 0xdb, 0x14, 0x67, 0x69, 0x1b, 0xf4, 0x1f, 0x8d, 0x1e, 0x8a, + 0xdb, 0x3a, 0xd7, 0xa1, 0x9f, 0x23, 0xf6, 0x94, 0xa9, 0x2d, 0x5b, 0x53, 0x70, 0xb4, 0xc2, 0x06, + 0x23, 0x57, 0x39, 0x26, 0x9c, 0xaf, 0x1b, 0x93, 0x17, 0xca, 0x2a, 0xd3, 0x17, 0xca, 0x3e, 0x04, + 0x08, 0x25, 0xee, 0x8e, 0x2d, 0xa7, 0xab, 0x4c, 0xc9, 0xc7, 0xad, 0x8b, 0xc6, 0x66, 0x92, 0x10, + 0x29, 0x0a, 0xec, 0xff, 0x40, 0x9c, 0x6d, 0xa2, 0x35, 0x6e, 0x72, 0xd3, 0x71, 0x7b, 0x52, 0x07, + 0x2f, 0x4f, 0xeb, 0xe0, 0x37, 0xa1, 0x10, 0x76, 0xfd, 0xa1, 0xa4, 0x3b, 0x11, 0x17, 0xaf, 0xef, + 0x5a, 0x1b, 0x91, 0x2c, 0x8d, 0x4b, 0x61, 0x39, 0xd4, 0x52, 0x7e, 0x40, 0xb7, 0x21, 0x2a, 0x56, + 0xd4, 0x1c, 0xd3, 0x83, 0xd7, 0xc7, 0xf5, 0x60, 0xdd, 0x86, 0xa2, 0x09, 0xb1, 0x4f, 0x3a, 0xcb, + 0x51, 0x70, 0x2e, 0x9b, 0x0a, 0xce, 0xc5, 0x85, 0x85, 0xb9, 0x74, 0x61, 0xe1, 0xc4, 0x85, 0xa9, + 0xc2, 0xd4, 0x85, 0xa9, 0xc6, 0xa7, 0x50, 0xa0, 0xbe, 0xa2, 0x11, 0xa1, 0xa7, 0x59, 0xdb, 0x98, + 0x38, 0x28, 0x96, 0xe1, 0x57, 0x81, 0x85, 0x92, 0x8c, 0x10, 0xd9, 0x16, 0x03, 0x49, 0x4a, 0x32, + 0xcb, 0x6b, 0x70, 0x55, 0xe3, 0x86, 0xe3, 0x6f, 0xc8, 0x12, 0x72, 0x9d, 0xa3, 0x40, 0x04, 0xe7, + 0x2c, 0xdf, 0xf8, 0x90, 0xb2, 0xbb, 0x91, 0x40, 0x55, 0xe3, 0x0b, 0x6a, 0x5a, 0x2d, 0xdb, 0x46, + 0xfb, 0x50, 0x52, 0xde, 0xf8, 0x47, 0xba, 0x54, 0x89, 0x1c, 0x10, 0x8a, 0x89, 0x2c, 0xa6, 0x4f, + 0xe2, 0x3f, 0xb7, 0xfd, 0xd6, 0xd8, 0x48, 0x99, 0x72, 0xe3, 0xb5, 0x47, 0x99, 0x79, 0x6b, 0x8f, + 0x1a, 0x0f, 0x61, 0xc5, 0x1a, 0xd7, 0xe9, 0xfc, 0x3d, 0x28, 0xf9, 0xc3, 0x34, 0x9f, 0xe7, 0xc9, + 0x65, 0x84, 0xde, 0xf8, 0x49, 0x06, 0x16, 0x5b, 0x9e, 0x92, 0x81, 0x27, 0xdc, 0x6d, 0x57, 0xf4, + 0xf8, 0xbb, 0x91, 0x96, 0x9a, 0xed, 0x7f, 0xa7, 0x71, 0xc7, 0x15, 0x96, 0x6b, 0x42, 0xc9, 0xfc, + 0x1a, 0xac, 0x4a, 0xdb, 0x51, 0x7e, 0xa0, 0x0d, 0xd8, 0xa8, 0x44, 0xec, 0x2a, 0x30, 0x0d, 0x6e, + 0xd3, 0x96, 0xe8, 0xe8, 0x65, 0xae, 0xc1, 0xd5, 0x31, 0x68, 0x64, 0x9d, 0x66, 0xf9, 0x4d, 0xa8, + 0x25, 0xa7, 0xd1, 0x96, 0xef, 0xa9, 0x96, 0x67, 0xcb, 0x33, 0x32, 0x85, 0x58, 0xae, 0xf1, 0x5b, + 0xa5, 0xc8, 0x08, 0x7b, 0x6c, 0x0a, 0xc8, 0x02, 0xdf, 0x4f, 0x6e, 0x27, 0x9a, 0x56, 0xea, 0x16, + 0x6c, 0x76, 0x8e, 0x5b, 0xb0, 0x1f, 0x26, 0x37, 0x19, 0xf5, 0x41, 0xf1, 0xf2, 0xcc, 0xd3, 0x87, + 0xea, 0x5e, 0x8c, 0xd9, 0xdd, 0x96, 0xa9, 0x6b, 0x8d, 0x6f, 0x18, 0x5f, 0x2b, 0x3f, 0x8f, 0xad, + 0xaa, 0xf3, 0xf1, 0x6f, 0x4f, 0x96, 0xcf, 0xcf, 0x57, 0x7f, 0x36, 0x65, 0x4e, 0xc2, 0x0b, 0x9b, + 0x93, 0x1f, 0x4d, 0xb8, 0x35, 0xe5, 0x99, 0x21, 0xa9, 0x4b, 0x2e, 0x07, 0x7e, 0x04, 0xa5, 0xbe, + 0x13, 0x2a, 0x3f, 0xd0, 0x17, 0x56, 0xa7, 0x2f, 0xd8, 0xa4, 0x66, 0x6b, 0x47, 0x23, 0x52, 0xb1, + 0x50, 0x44, 0xc5, 0xbf, 0x0b, 0xab, 0x34, 0xf1, 0x87, 0x89, 0xd5, 0x10, 0xd6, 0xaa, 0x33, 0x8b, + 0xb4, 0x52, 0xac, 0x36, 0x26, 0x48, 0xac, 0x69, 0x26, 0xf5, 0x1e, 0x40, 0xb2, 0x3e, 0x53, 0x5a, + 0xec, 0x4b, 0x5c, 0x58, 0xbd, 0x0e, 0xc5, 0x70, 0x74, 0x94, 0xe4, 0x9c, 0x4c, 0xab, 0x7e, 0x06, + 0xf5, 0x29, 0xeb, 0xe0, 0x50, 0x06, 0xba, 0xbb, 0x97, 0xde, 0x9a, 0xfd, 0x30, 0xbd, 0xf0, 0x5a, + 0x38, 0x6f, 0x5f, 0xb0, 0x7a, 0x31, 0xe7, 0x94, 0x04, 0xd4, 0xdf, 0x86, 0x6a, 0x6a, 0x52, 0x51, + 0x33, 0x8f, 0x3c, 0xdb, 0x8f, 0xc2, 0xa0, 0xf8, 0xac, 0x6f, 0x0d, 0xd9, 0x51, 0x20, 0x94, 0x9e, + 0xeb, 0x16, 0xb0, 0xc9, 0x09, 0xbc, 0xc4, 0xf5, 0x7d, 0x19, 0x96, 0x52, 0x26, 0x5d, 0x1c, 0x22, + 0x1b, 0x07, 0x36, 0x4e, 0xe1, 0xa5, 0x14, 0xbb, 0x43, 0x19, 0x0c, 0x9c, 0x10, 0x0f, 0x12, 0xed, + 0xd2, 0x51, 0xf4, 0xc2, 0x96, 0x9e, 0x72, 0x54, 0xa4, 0x41, 0xe3, 0x36, 0xff, 0x65, 0x28, 0x0c, + 0x65, 0x30, 0x08, 0x8d, 0x16, 0x9d, 0x94, 0xa0, 0x99, 0x6c, 0x43, 0x4b, 0xd3, 0x34, 0xfe, 0x71, + 0x06, 0xca, 0x7b, 0x52, 0x09, 0xb4, 0x1d, 0xf8, 0xde, 0xc4, 0x57, 0xa6, 0xf3, 0xa4, 0x11, 0xea, + 0x9a, 0x71, 0x32, 0xd7, 0x5a, 0x06, 0xdf, 0xb4, 0x77, 0x16, 0x92, 0x8e, 0xd5, 0x37, 0xa0, 0x64, + 0xc0, 0xf5, 0x77, 0x61, 0x65, 0x02, 0x93, 0xe6, 0x45, 0xdb, 0xf6, 0xed, 0xf3, 0x41, 0x54, 0xae, + 0xb3, 0x68, 0x8d, 0x03, 0x37, 0x2a, 0x50, 0x1a, 0x6a, 0x82, 0xc6, 0x1f, 0x5c, 0xa3, 0x12, 0x12, + 0xe7, 0x18, 0x9d, 0xed, 0x59, 0x27, 0xeb, 0x2d, 0x00, 0x3a, 0x9a, 0x75, 0xa1, 0x81, 0x0e, 0x5b, + 0xa6, 0x20, 0xfc, 0xfd, 0x38, 0xde, 0x9c, 0x9f, 0x69, 0x54, 0xa5, 0x99, 0x4f, 0x06, 0x9d, 0x6b, + 0x50, 0x72, 0xc2, 0x5d, 0x3c, 0xda, 0x4c, 0xf9, 0x4d, 0xd4, 0xe4, 0xdf, 0x86, 0xa2, 0x33, 0x18, + 0xfa, 0x81, 0x32, 0x01, 0xe9, 0x4b, 0xb9, 0xb6, 0x08, 0x73, 0x67, 0xc1, 0x32, 0x34, 0x48, 0x2d, + 0xcf, 0x88, 0xba, 0xfc, 0x7c, 0xea, 0xe6, 0x59, 0x44, 0xad, 0x69, 0xf8, 0x27, 0xb0, 0xd4, 0xd3, + 0x05, 0x71, 0x9a, 0xb1, 0x51, 0x22, 0x5f, 0xbf, 0x8c, 0xc9, 0x83, 0x34, 0xc1, 0xce, 0x82, 0x35, + 0xce, 0x01, 0x59, 0xa2, 0x01, 0x2f, 0x43, 0xd5, 0xf1, 0x3f, 0xf6, 0x1d, 0x8f, 0x9c, 0xd2, 0xe7, + 0xb0, 0xb4, 0xd2, 0x04, 0xc8, 0x72, 0x8c, 0x03, 0x7f, 0x07, 0x2d, 0x9e, 0x50, 0x99, 0x3b, 0xc3, + 0xb7, 0x2f, 0xe3, 0xd4, 0x91, 0xa1, 0xb9, 0xed, 0x1b, 0x2a, 0x7e, 0x06, 0xf5, 0xd4, 0x26, 0x31, + 0x1f, 0x59, 0x1f, 0x0e, 0x03, 0x1f, 0x3d, 0xdb, 0x25, 0xe2, 0xf6, 0xce, 0x65, 0xdc, 0x0e, 0x2f, + 0xa4, 0xde, 0x59, 0xb0, 0x2e, 0xe1, 0xcd, 0x3b, 0xe8, 0xd9, 0x99, 0x21, 0xec, 0x4a, 0x71, 0x1a, + 0xdd, 0x38, 0xbe, 0x3b, 0xd7, 0x2c, 0x10, 0xc5, 0xce, 0x82, 0x35, 0xc1, 0x83, 0xff, 0x2a, 0xac, + 0x8e, 0x7d, 0x93, 0x2e, 0x19, 0xea, 0xfb, 0xc8, 0xdf, 0x9c, 0x7b, 0x18, 0x48, 0xb4, 0xb3, 0x60, + 0x4d, 0x73, 0xe2, 0x23, 0xf8, 0xca, 0xf4, 0x90, 0xb6, 0x64, 0xd7, 0x75, 0x3c, 0x69, 0xae, 0x2e, + 0xbf, 0xfd, 0x62, 0xb3, 0x65, 0x88, 0x77, 0x16, 0xac, 0x8b, 0x39, 0xf3, 0xbf, 0x06, 0x37, 0x87, + 0x33, 0x55, 0x8c, 0x56, 0x5d, 0xe6, 0xe6, 0xf3, 0x7b, 0x73, 0x7e, 0x79, 0x8a, 0x7e, 0x67, 0xc1, + 0xba, 0x94, 0x3f, 0xda, 0xce, 0xe4, 0x41, 0x9b, 0xba, 0x5d, 0xdd, 0xe0, 0x37, 0xa1, 0x22, 0xba, + 0xee, 0x8e, 0x14, 0x76, 0x1c, 0x61, 0x4f, 0x00, 0xf5, 0x3f, 0xca, 0x40, 0xd1, 0xc8, 0xfb, 0xcd, + 0x38, 0x2f, 0x1e, 0xab, 0xee, 0x04, 0xc0, 0x3f, 0x80, 0x8a, 0x0c, 0x02, 0x3f, 0xd8, 0xf4, 0xed, + 0xa8, 0x68, 0x70, 0x32, 0xfc, 0xab, 0xf9, 0xac, 0x35, 0x23, 0x34, 0x2b, 0xa1, 0xe0, 0xef, 0x03, + 0xe8, 0x7d, 0xde, 0x49, 0xae, 0x5f, 0xd4, 0x67, 0xd3, 0xeb, 0x34, 0x4c, 0x82, 0x9d, 0x04, 0xcf, + 0xa2, 0x1c, 0x48, 0xd4, 0x8c, 0x1d, 0xce, 0x42, 0xca, 0xe1, 0xbc, 0x69, 0xe2, 0x08, 0xfb, 0xf8, + 0xc2, 0x5c, 0x42, 0x8a, 0x01, 0xf5, 0x7f, 0x9b, 0x81, 0xa2, 0x56, 0x1e, 0xbc, 0x39, 0x3d, 0xa2, + 0x57, 0x9f, 0xaf, 0x73, 0xd6, 0x26, 0x47, 0xf6, 0x6d, 0x00, 0xad, 0x83, 0x52, 0x23, 0xbb, 0x39, + 0xc1, 0xc7, 0x90, 0x46, 0x95, 0xa3, 0x09, 0x7e, 0xe3, 0xbe, 0xbe, 0x28, 0x43, 0xb1, 0xda, 0x47, + 0xbb, 0xbb, 0x6c, 0x81, 0xaf, 0xc2, 0xd2, 0xa3, 0xfd, 0x87, 0xfb, 0x07, 0x4f, 0xf6, 0x9f, 0x36, + 0x2d, 0xeb, 0xc0, 0xd2, 0x21, 0xdb, 0x8d, 0xf5, 0xad, 0xa7, 0xad, 0xfd, 0xc3, 0x47, 0x1d, 0x96, + 0xad, 0xff, 0x34, 0x03, 0x4b, 0x63, 0xba, 0xeb, 0x2f, 0x76, 0xe9, 0x52, 0xd3, 0x9f, 0x9b, 0x3d, + 0xfd, 0xf9, 0x8b, 0xa6, 0xbf, 0x30, 0x39, 0xfd, 0xbf, 0x97, 0x81, 0xa5, 0x31, 0x1d, 0x99, 0xe6, + 0x9e, 0x19, 0xe7, 0x9e, 0x3e, 0xe9, 0xb3, 0x13, 0x27, 0x7d, 0x03, 0x16, 0xa3, 0xe7, 0xfd, 0x24, + 0xe2, 0x30, 0x06, 0x4b, 0xe3, 0x50, 0xa5, 0x7a, 0x7e, 0x1c, 0x87, 0xaa, 0xd5, 0x2f, 0xef, 0x2d, + 0xdd, 0xcc, 0x0b, 0xe9, 0xe2, 0x72, 0xfd, 0x62, 0x0d, 0x7a, 0xc9, 0x10, 0x1e, 0x40, 0x75, 0x98, + 0x6c, 0xd3, 0x17, 0x33, 0x4b, 0xd2, 0x94, 0xcf, 0xe9, 0xe7, 0x8f, 0x33, 0xb0, 0x3c, 0xae, 0x73, + 0xff, 0xbf, 0x9e, 0xd6, 0x7f, 0x96, 0x81, 0xd5, 0x29, 0x4d, 0x7e, 0xa9, 0x61, 0x37, 0xd9, 0xaf, + 0xec, 0x1c, 0xfd, 0xca, 0xcd, 0xe8, 0xd7, 0xc5, 0x9a, 0xe4, 0xf2, 0x1e, 0xb7, 0xe1, 0x2b, 0x17, + 0x9e, 0x09, 0x97, 0x4c, 0xf5, 0x18, 0xd3, 0xdc, 0x24, 0xd3, 0xdf, 0xcd, 0xc0, 0xcd, 0xcb, 0xf4, + 0xfd, 0xff, 0x73, 0xb9, 0x9a, 0xec, 0x61, 0xe3, 0xdd, 0x38, 0x99, 0x5e, 0x85, 0x92, 0xf9, 0x41, + 0x20, 0x53, 0xae, 0xdc, 0xf7, 0x9f, 0x79, 0x3a, 0x12, 0x6d, 0x49, 0x61, 0xae, 0x4c, 0x5b, 0x72, + 0xe8, 0x3a, 0x94, 0xbc, 0xbc, 0x01, 0xb0, 0x4e, 0x7e, 0x5d, 0x74, 0x83, 0x61, 0x73, 0xf7, 0xa0, + 0xdd, 0x64, 0x0b, 0x69, 0x23, 0xf6, 0xd3, 0x48, 0x11, 0x37, 0x0e, 0xa1, 0x98, 0xd4, 0xb6, 0xef, + 0x89, 0xe0, 0xc4, 0xd6, 0x29, 0xc2, 0x45, 0x28, 0x1f, 0x1a, 0x17, 0x4a, 0x7f, 0xea, 0xe3, 0xf6, + 0xc1, 0xbe, 0x0e, 0x7a, 0x6f, 0x1d, 0x74, 0x74, 0x85, 0x7c, 0xfb, 0xf1, 0x03, 0x9d, 0xab, 0x7a, + 0x60, 0xad, 0x1f, 0xee, 0x3c, 0x25, 0x8c, 0x42, 0xe3, 0xa7, 0xd9, 0xe8, 0x54, 0x6b, 0x58, 0x26, + 0xf9, 0x08, 0x50, 0x44, 0x6d, 0xee, 0x1b, 0xc6, 0xf1, 0x67, 0xa8, 0xb0, 0xb5, 0x79, 0xa6, 0xe3, + 0x10, 0x2c, 0xcb, 0x8b, 0x90, 0x3d, 0x3c, 0xd2, 0xd5, 0x38, 0x3b, 0x6a, 0xe0, 0xea, 0x2b, 0x6d, + 0x9d, 0x33, 0xc5, 0x0a, 0xf8, 0xb0, 0x19, 0x9e, 0xb2, 0x62, 0xe3, 0xbf, 0x66, 0xa0, 0x12, 0xab, + 0xca, 0x17, 0x51, 0xdd, 0x9c, 0xc3, 0x72, 0x6b, 0xbf, 0xd3, 0xb4, 0xf6, 0xd7, 0x77, 0x0d, 0x4a, + 0x8e, 0xd7, 0xe0, 0xea, 0xfe, 0xc1, 0xd3, 0x83, 0x8d, 0x8f, 0x9b, 0x9b, 0x9d, 0xf6, 0xd3, 0xce, + 0xc1, 0xd3, 0xd6, 0xde, 0xe1, 0x81, 0xd5, 0x61, 0x05, 0x7e, 0x1d, 0xb8, 0x7e, 0x7e, 0xda, 0x6a, + 0x3f, 0xdd, 0x5c, 0xdf, 0xdf, 0x6c, 0xee, 0x36, 0xb7, 0x58, 0x91, 0xbf, 0x0a, 0x5f, 0xdd, 0x6d, + 0xed, 0xb5, 0x3a, 0x4f, 0x0f, 0xb6, 0x9f, 0x5a, 0x07, 0x4f, 0xda, 0x4f, 0x0f, 0xac, 0xa7, 0x56, + 0x73, 0x77, 0xbd, 0xd3, 0x3a, 0xd8, 0x6f, 0x3f, 0x6d, 0x7e, 0x77, 0xb3, 0xd9, 0xdc, 0x6a, 0x6e, + 0xb1, 0x12, 0xbf, 0x02, 0x2b, 0xdb, 0xad, 0xdd, 0xe6, 0xd3, 0xdd, 0x83, 0xf5, 0x2d, 0xf3, 0xbd, + 0x32, 0xbf, 0x09, 0xb5, 0xd6, 0x7e, 0xfb, 0xd1, 0xf6, 0x76, 0x6b, 0xb3, 0xd5, 0xdc, 0xef, 0x3c, + 0x3d, 0x6c, 0x5a, 0x7b, 0xad, 0x76, 0x1b, 0x69, 0x59, 0xa5, 0xf1, 0x1d, 0x28, 0xb6, 0xbc, 0x53, + 0x47, 0x91, 0xf8, 0x99, 0xb5, 0x32, 0x0e, 0x49, 0xd4, 0x24, 0xa9, 0x71, 0x7a, 0x1e, 0xdd, 0x64, + 0x26, 0xe1, 0x5b, 0xb4, 0x12, 0x40, 0xe3, 0x9f, 0x67, 0x61, 0x49, 0xb3, 0x88, 0x1c, 0x9c, 0x3b, + 0xb0, 0x62, 0x22, 0x85, 0xad, 0xf1, 0x1d, 0x3e, 0x09, 0xa6, 0x9f, 0x08, 0xd2, 0xa0, 0xd4, 0x3e, + 0x4f, 0x83, 0x28, 0xfb, 0x44, 0xcc, 0xd1, 0x51, 0xd2, 0x79, 0xb7, 0x04, 0xf0, 0x65, 0x37, 0x38, + 0x2a, 0x0f, 0x8d, 0xd8, 0xf5, 0xbd, 0xcd, 0xf8, 0xfe, 0xc0, 0x18, 0x8c, 0x7f, 0x0a, 0x37, 0xe2, + 0x76, 0xd3, 0xeb, 0x06, 0xe7, 0xc3, 0xf8, 0x97, 0xbc, 0x4a, 0x33, 0x3d, 0xee, 0x6d, 0xc7, 0x95, + 0x63, 0x88, 0xd6, 0x45, 0x0c, 0x1a, 0x7f, 0x9c, 0x49, 0xb9, 0x85, 0xda, 0xed, 0xbb, 0x54, 0x21, + 0xce, 0x4a, 0x51, 0xa0, 0x63, 0x66, 0xba, 0x6f, 0xce, 0x69, 0xd3, 0xe4, 0x87, 0xc0, 0x9d, 0xe9, + 0x4e, 0xe7, 0xe7, 0xec, 0xf4, 0x0c, 0xda, 0xc9, 0x08, 0x73, 0x61, 0x3a, 0xc2, 0x7c, 0x0b, 0xa0, + 0xe7, 0xfa, 0x47, 0xc2, 0x4d, 0xd9, 0x61, 0x29, 0x48, 0xc3, 0x85, 0x72, 0xf4, 0x7b, 0x61, 0xfc, + 0x3a, 0x14, 0xe9, 0x17, 0xc3, 0xe2, 0x78, 0x9b, 0x6e, 0xf1, 0x1d, 0x58, 0x96, 0xe3, 0x7d, 0xce, + 0xce, 0xd9, 0xe7, 0x09, 0xba, 0xc6, 0xb7, 0x60, 0x75, 0x0a, 0x09, 0x27, 0x71, 0x28, 0x54, 0x7c, + 0x69, 0x18, 0x9f, 0xa7, 0x73, 0xbc, 0x8d, 0xff, 0x98, 0x85, 0xc5, 0x3d, 0xe1, 0x39, 0xc7, 0x32, + 0x54, 0x51, 0x6f, 0xc3, 0x6e, 0x5f, 0x0e, 0x44, 0xd4, 0x5b, 0xdd, 0x32, 0x4e, 0x78, 0x36, 0x1d, + 0xde, 0x9e, 0xca, 0x86, 0x5c, 0x87, 0xa2, 0x18, 0xa9, 0x7e, 0x5c, 0xd2, 0x6c, 0x5a, 0xb8, 0x76, + 0xae, 0xd3, 0x95, 0x5e, 0x18, 0xc9, 0x66, 0xd4, 0x4c, 0xaa, 0x3c, 0x8a, 0x97, 0x54, 0x79, 0x94, + 0xa6, 0xe7, 0xff, 0x36, 0x54, 0xc3, 0x6e, 0x20, 0xa5, 0x17, 0xf6, 0x7d, 0x15, 0xfd, 0xd6, 0x5c, + 0x1a, 0x44, 0xd5, 0x4d, 0xfe, 0x33, 0x0f, 0x77, 0xe8, 0xae, 0xe3, 0x9d, 0x98, 0x12, 0x9f, 0x31, + 0x18, 0xca, 0x20, 0x85, 0x20, 0x9c, 0xcf, 0x25, 0xb9, 0xbf, 0x05, 0x2b, 0x6e, 0x53, 0x90, 0x41, + 0x28, 0xd9, 0xf3, 0x03, 0x47, 0xea, 0x48, 0x5b, 0xc5, 0x4a, 0x41, 0x90, 0xd6, 0x15, 0x5e, 0x6f, + 0x24, 0x7a, 0xd2, 0xe4, 0x4c, 0xe3, 0x76, 0xe3, 0x7f, 0x16, 0x00, 0xf6, 0xe4, 0xe0, 0x48, 0x06, + 0x61, 0xdf, 0x19, 0x52, 0x26, 0xc0, 0x31, 0x85, 0x9c, 0x4b, 0x16, 0x3d, 0xf3, 0xf7, 0xc6, 0x6a, + 0xac, 0xa7, 0x73, 0x77, 0x09, 0xf9, 0x64, 0x84, 0x02, 0x27, 0x47, 0x28, 0x69, 0x0a, 0x6c, 0x68, + 0xfe, 0xf3, 0x56, 0x1a, 0x44, 0xb5, 0x4f, 0x42, 0xc9, 0xa6, 0x67, 0xeb, 0x08, 0x48, 0xde, 0x8a, + 0xdb, 0x74, 0x4b, 0x23, 0x5c, 0x1f, 0x29, 0xdf, 0x92, 0x9e, 0x7c, 0x16, 0x5f, 0x31, 0x4a, 0x40, + 0x7c, 0x0f, 0x96, 0x86, 0xe2, 0x7c, 0x20, 0x3d, 0xb5, 0x27, 0x55, 0xdf, 0xb7, 0x4d, 0x35, 0xcc, + 0xab, 0x17, 0x77, 0xf0, 0x30, 0x8d, 0x6e, 0x8d, 0x53, 0xa3, 0x4c, 0x78, 0x21, 0xed, 0x12, 0xbd, + 0x8c, 0xa6, 0xc5, 0x37, 0x00, 0xf4, 0x13, 0x39, 0x16, 0xe5, 0xd9, 0x81, 0x1a, 0x31, 0x90, 0xa1, + 0x0c, 0x4e, 0x1d, 0xad, 0xc7, 0xb4, 0xeb, 0x94, 0x50, 0xa1, 0xd6, 0x1b, 0x85, 0x32, 0x68, 0x0e, + 0x84, 0xe3, 0x9a, 0x05, 0x4e, 0x00, 0xfc, 0x2d, 0xb8, 0x16, 0x8e, 0x8e, 0x50, 0x66, 0x8e, 0x64, + 0xc7, 0xdf, 0x97, 0xcf, 0x42, 0x57, 0x2a, 0x25, 0x03, 0x93, 0x7e, 0x9f, 0xfd, 0xb2, 0xd1, 0x8b, + 0xad, 0x02, 0xfa, 0x5d, 0x03, 0x7c, 0x4a, 0xca, 0x7a, 0x62, 0x90, 0xa9, 0x79, 0x62, 0x19, 0xce, + 0x60, 0x51, 0x83, 0x4c, 0x49, 0x54, 0x96, 0x7f, 0x0d, 0x7e, 0x69, 0x0c, 0xc9, 0xd2, 0x79, 0xd2, + 0x70, 0xdb, 0xf1, 0x84, 0xeb, 0x7c, 0xae, 0xb3, 0xd6, 0xb9, 0xc6, 0x10, 0x96, 0xc6, 0x26, 0x0e, + 0x8f, 0x79, 0xfd, 0x64, 0x8a, 0x44, 0x18, 0x2c, 0xea, 0x76, 0x5b, 0x05, 0x0e, 0x25, 0x00, 0x62, + 0xc8, 0x26, 0xee, 0x73, 0x9f, 0x65, 0xf9, 0x55, 0x60, 0x1a, 0xd2, 0xf2, 0xc4, 0x70, 0xb8, 0x3e, + 0x1c, 0xba, 0x92, 0xe5, 0xe8, 0x2a, 0x5e, 0x02, 0xd5, 0x95, 0xd6, 0x2c, 0xdf, 0xf8, 0x2e, 0xdc, + 0xa0, 0x99, 0x79, 0x2c, 0x83, 0xd8, 0xef, 0x33, 0x63, 0xbd, 0x06, 0xab, 0xfa, 0x69, 0xdf, 0x57, + 0xfa, 0x35, 0xd9, 0x42, 0x1c, 0x96, 0x35, 0x18, 0x4d, 0x81, 0xb6, 0xf4, 0x94, 0xae, 0x55, 0xd1, + 0xb0, 0x18, 0x2f, 0xdb, 0xf8, 0x49, 0x11, 0x78, 0x22, 0x10, 0x1d, 0x47, 0x06, 0x5b, 0x42, 0x89, + 0x54, 0xe0, 0x6e, 0xe9, 0xc2, 0xd4, 0xf3, 0xf3, 0x2b, 0xba, 0xae, 0x43, 0xd1, 0x09, 0xd1, 0x53, + 0x31, 0x15, 0x94, 0xa6, 0xc5, 0x77, 0x01, 0x86, 0x32, 0x70, 0x7c, 0x9b, 0x24, 0xa8, 0x30, 0xb3, + 0xd4, 0x7d, 0xba, 0x53, 0x6b, 0x87, 0x31, 0x8d, 0x95, 0xa2, 0xc7, 0x7e, 0xe8, 0x96, 0x4e, 0xe4, + 0x16, 0xa9, 0xd3, 0x69, 0x10, 0x7f, 0x1d, 0xae, 0x0c, 0x03, 0xa7, 0x2b, 0xf5, 0x72, 0x3c, 0x0a, + 0xed, 0x4d, 0xfa, 0x35, 0xb0, 0x12, 0x61, 0xce, 0x7a, 0x85, 0x12, 0x28, 0x3c, 0xb2, 0xdf, 0x43, + 0x4a, 0x5d, 0x9a, 0xab, 0xa0, 0xba, 0x22, 0x71, 0xc9, 0x9a, 0xfd, 0x92, 0xdf, 0x05, 0x66, 0x5e, + 0xec, 0x39, 0xde, 0xae, 0xf4, 0x7a, 0xaa, 0x4f, 0xc2, 0xbd, 0x64, 0x4d, 0xc1, 0x49, 0x83, 0xe9, + 0xdf, 0x5c, 0xd1, 0x69, 0x8d, 0x8a, 0x15, 0xb7, 0xf5, 0xf5, 0x62, 0xd7, 0x0f, 0xda, 0x2a, 0x30, + 0xc5, 0x92, 0x71, 0x1b, 0x6d, 0x96, 0x90, 0xfa, 0x7a, 0x18, 0xf8, 0xf6, 0x88, 0x82, 0xee, 0x5a, + 0x89, 0x4d, 0x82, 0x13, 0xcc, 0x3d, 0xe1, 0x99, 0xb2, 0xba, 0xa5, 0x34, 0x66, 0x0c, 0x26, 0x17, + 0xc5, 0x0f, 0x13, 0x86, 0x2b, 0xc6, 0x45, 0x49, 0xc1, 0x0c, 0x4e, 0xc2, 0x8a, 0xc5, 0x38, 0x09, + 0x1f, 0x1a, 0xbf, 0x1d, 0xf8, 0x8e, 0x9d, 0xf0, 0x5a, 0xd5, 0x45, 0x8f, 0x93, 0xf0, 0x14, 0x6e, + 0xc2, 0x93, 0x8f, 0xe1, 0xc6, 0xf0, 0xc6, 0x0f, 0x32, 0x00, 0xc9, 0xe2, 0xa3, 0xc8, 0x27, 0xad, + 0x64, 0x8b, 0xdf, 0x80, 0x2b, 0x69, 0x30, 0x55, 0xc3, 0x53, 0xfe, 0x93, 0xc3, 0x72, 0xf2, 0x62, + 0x4b, 0x9c, 0x87, 0x2c, 0xab, 0xab, 0x1f, 0x23, 0xd8, 0x13, 0x29, 0xa9, 0xce, 0xec, 0x2a, 0xb0, + 0x04, 0x48, 0x97, 0x9d, 0x42, 0x96, 0x1f, 0x47, 0xfd, 0x9e, 0x14, 0x41, 0xc8, 0x0a, 0x8d, 0x1d, + 0x28, 0xea, 0xdc, 0xcb, 0x8c, 0xac, 0xe9, 0x8b, 0x95, 0x40, 0xfc, 0xed, 0x0c, 0xc0, 0x96, 0x2e, + 0x70, 0xc5, 0x53, 0x7c, 0x46, 0x32, 0x7a, 0x96, 0x45, 0x25, 0x6c, 0x9b, 0x4a, 0x7f, 0x73, 0xf1, + 0x2f, 0x79, 0x60, 0x13, 0x25, 0x47, 0x44, 0x85, 0x45, 0x7a, 0xcf, 0xc5, 0x6d, 0x7d, 0x80, 0x6c, + 0xfa, 0x9e, 0x27, 0xbb, 0x78, 0xfc, 0xc4, 0x07, 0x48, 0x0c, 0x6a, 0xfc, 0xbb, 0x12, 0x54, 0x37, + 0xfb, 0x42, 0xed, 0xc9, 0x30, 0x14, 0x3d, 0x39, 0xd5, 0x97, 0x1a, 0x94, 0xfc, 0xc0, 0x96, 0x41, + 0x72, 0x61, 0xc9, 0x34, 0xd3, 0x29, 0xf8, 0xdc, 0x78, 0x0a, 0xfe, 0x26, 0x54, 0x74, 0x80, 0xdf, + 0x5e, 0xd7, 0x6a, 0x20, 0x67, 0x25, 0x00, 0x3c, 0xab, 0x07, 0xbe, 0x4d, 0xca, 0x68, 0x5d, 0xc7, + 0xc6, 0x73, 0x56, 0x0a, 0xa2, 0x2b, 0x1e, 0x86, 0xee, 0x79, 0xc7, 0x37, 0x7d, 0x6a, 0xd9, 0xc9, + 0xed, 0xce, 0x71, 0x38, 0xdf, 0x84, 0xd2, 0x40, 0x37, 0x4c, 0x9c, 0x7f, 0x32, 0x22, 0x9e, 0x1a, + 0xda, 0x9a, 0xf9, 0x6b, 0x2e, 0x58, 0x58, 0x11, 0x25, 0x7a, 0xb0, 0x42, 0x29, 0xd1, 0xed, 0x0f, + 0x8c, 0x8a, 0xc8, 0xcd, 0x48, 0xf9, 0xa5, 0x19, 0xad, 0xc7, 0xd8, 0x56, 0x9a, 0x92, 0x6f, 0x40, + 0x25, 0x90, 0x62, 0x2c, 0xeb, 0xf8, 0xf2, 0x25, 0x6c, 0xac, 0x08, 0xd7, 0x4a, 0xc8, 0xea, 0x3f, + 0xca, 0xc0, 0xf2, 0x78, 0x47, 0xff, 0x22, 0x7e, 0x8c, 0xe9, 0xdb, 0xc9, 0x8f, 0x31, 0x7d, 0x89, + 0x1f, 0x36, 0xfa, 0xdd, 0x0c, 0x40, 0x32, 0x07, 0xa8, 0xf2, 0xf5, 0x8f, 0xc6, 0x44, 0x46, 0xa8, + 0x6e, 0xf1, 0x9d, 0xb1, 0x6b, 0xdd, 0x6f, 0xcd, 0x35, 0xa1, 0xa9, 0xc7, 0x54, 0xd5, 0xee, 0x3d, + 0x58, 0x1e, 0x87, 0xd3, 0xcf, 0xc0, 0xb4, 0x76, 0x9b, 0x3a, 0x02, 0xd0, 0xda, 0x5b, 0x7f, 0xd0, + 0x34, 0x17, 0x5a, 0x5a, 0xfb, 0x0f, 0x59, 0xb6, 0xfe, 0x27, 0x19, 0xa8, 0xc4, 0xd3, 0xcb, 0x3f, + 0x49, 0xaf, 0x8b, 0x2e, 0x23, 0x78, 0x73, 0x9e, 0x75, 0x49, 0x9e, 0x9a, 0x9e, 0x0a, 0xce, 0xd3, + 0xcb, 0xe4, 0xc3, 0xf2, 0xf8, 0xcb, 0x19, 0x3a, 0xe1, 0xc1, 0xb8, 0x4e, 0x78, 0x63, 0xae, 0x4f, + 0x46, 0x9e, 0xd7, 0xae, 0x13, 0x2a, 0xa3, 0x2e, 0xde, 0xcf, 0xbe, 0x97, 0xa9, 0xdf, 0x86, 0xc5, + 0xf4, 0xab, 0xe9, 0x5b, 0x6b, 0x77, 0xff, 0x24, 0x07, 0xcb, 0xe3, 0x99, 0x78, 0xba, 0x23, 0xa3, + 0xab, 0x40, 0x0e, 0x5c, 0x3b, 0x55, 0xe8, 0xcc, 0xf8, 0x0a, 0x54, 0x8d, 0x6f, 0x47, 0x80, 0x55, + 0x8a, 0x31, 0xf8, 0x03, 0xc9, 0x6e, 0xa7, 0x7f, 0x70, 0xee, 0x75, 0x0e, 0xd1, 0xed, 0x25, 0x36, + 0xe4, 0x15, 0xf3, 0xd3, 0x3b, 0xbf, 0x96, 0xe5, 0x4b, 0xa9, 0x72, 0xdb, 0x1f, 0xa2, 0x61, 0xb3, + 0xb2, 0x31, 0xf2, 0x6c, 0x57, 0xda, 0x31, 0xf4, 0x47, 0x69, 0x68, 0x5c, 0x3c, 0xfb, 0x6b, 0x79, + 0xbe, 0x0c, 0x95, 0xf6, 0xe8, 0xc8, 0x14, 0xce, 0xfe, 0xf5, 0x3c, 0xbf, 0x0e, 0xab, 0x06, 0x2b, + 0xa9, 0x80, 0x63, 0x7f, 0x03, 0x55, 0xf0, 0xf2, 0xba, 0x9e, 0x2f, 0xd3, 0x51, 0xf6, 0x37, 0xf3, + 0xd8, 0x05, 0xba, 0x14, 0xfb, 0xeb, 0xc4, 0x27, 0xbe, 0x42, 0xc0, 0x7e, 0x23, 0xcf, 0x57, 0x00, + 0xda, 0x9d, 0xf8, 0x43, 0xbf, 0x95, 0xe7, 0x55, 0x28, 0xb6, 0x3b, 0xc4, 0xed, 0x07, 0x79, 0x7e, + 0x0d, 0x58, 0xf2, 0xd6, 0xd4, 0x05, 0xfe, 0x1d, 0xdd, 0x99, 0xb8, 0xd0, 0xef, 0xb7, 0xf3, 0x38, + 0xae, 0x68, 0x96, 0xd9, 0xdf, 0xcd, 0x73, 0x06, 0xd5, 0x54, 0xe4, 0x8a, 0xfd, 0xbd, 0x3c, 0xe7, + 0xb0, 0xb4, 0xe7, 0x84, 0xa1, 0xe3, 0xf5, 0xcc, 0x08, 0x7e, 0x93, 0xbe, 0xbc, 0x1d, 0xdf, 0x82, + 0x60, 0xbf, 0x93, 0xe7, 0x37, 0x80, 0xa7, 0xa3, 0xf5, 0xe6, 0xc5, 0xdf, 0x27, 0x6a, 0xad, 0xf6, + 0x43, 0x03, 0xfb, 0x07, 0x44, 0x8d, 0x92, 0x60, 0x00, 0xff, 0x90, 0x26, 0x64, 0x33, 0xa9, 0x24, + 0x34, 0xf0, 0x1f, 0x12, 0x71, 0xb4, 0x98, 0x1a, 0xf6, 0xa3, 0xfc, 0xdd, 0x9f, 0x50, 0xb4, 0x35, + 0x5d, 0x90, 0xc3, 0x17, 0xa1, 0xec, 0xfa, 0x5e, 0x4f, 0xe9, 0x1f, 0xfa, 0x5b, 0x82, 0x4a, 0xd8, + 0xf7, 0x03, 0x45, 0x4d, 0xba, 0xa6, 0xe5, 0xd1, 0x85, 0x5d, 0x5d, 0x6d, 0xad, 0x9d, 0x14, 0x1d, + 0xbd, 0x52, 0xa2, 0xc7, 0xaa, 0x71, 0x0d, 0x64, 0x3e, 0xae, 0xd3, 0xa4, 0x8b, 0xc3, 0xd1, 0xc5, + 0x4c, 0x56, 0x44, 0xd4, 0x51, 0xe0, 0xea, 0x7a, 0x4d, 0x89, 0x06, 0xaa, 0xfe, 0x45, 0xaf, 0x61, + 0x1f, 0xed, 0xe0, 0x8a, 0x86, 0xfa, 0x9f, 0x39, 0xfa, 0xca, 0x9f, 0x29, 0x7f, 0xb2, 0xb1, 0x1f, + 0x71, 0x86, 0x9f, 0xc9, 0xbb, 0xbf, 0x9d, 0x81, 0xc5, 0xe8, 0xba, 0xac, 0xd3, 0x73, 0x3c, 0x5d, + 0xf1, 0x19, 0xfd, 0x7c, 0x62, 0xd7, 0x75, 0x86, 0xd1, 0xcf, 0x91, 0xad, 0x40, 0xd5, 0x0e, 0x44, + 0x6f, 0xdd, 0xb3, 0xb7, 0x02, 0x7f, 0xa8, 0xbb, 0xad, 0xf3, 0x31, 0xba, 0xd2, 0xf4, 0x99, 0x3c, + 0x42, 0xf4, 0xa1, 0x0c, 0x58, 0x9e, 0x4a, 0xab, 0xfa, 0x22, 0x70, 0xbc, 0x5e, 0xf3, 0x4c, 0x49, + 0x2f, 0xd4, 0x15, 0xa7, 0x55, 0x28, 0x8d, 0x42, 0xd9, 0x15, 0xa1, 0x64, 0x45, 0x6c, 0x1c, 0x8d, + 0x1c, 0x57, 0x39, 0x9e, 0xfe, 0x15, 0xb0, 0xb8, 0xa4, 0xb4, 0x7c, 0xf7, 0xf7, 0x33, 0x50, 0x25, + 0x69, 0x48, 0x02, 0x8d, 0x89, 0xa5, 0x51, 0x85, 0xd2, 0x6e, 0xfc, 0x2b, 0x50, 0x45, 0xc8, 0x1e, + 0x9c, 0xe8, 0x40, 0xa3, 0x91, 0x06, 0x7d, 0xd9, 0x4d, 0xff, 0x20, 0x54, 0x9e, 0x7f, 0x05, 0xae, + 0x59, 0x72, 0xe0, 0x2b, 0xf9, 0x44, 0x38, 0x2a, 0x7d, 0xdb, 0xa2, 0x80, 0x4e, 0x89, 0x7e, 0x15, + 0x5d, 0xaf, 0x28, 0x92, 0x53, 0x82, 0x9f, 0x8d, 0x20, 0x25, 0x1c, 0x34, 0x41, 0x8c, 0x97, 0x52, + 0x8e, 0x51, 0x3e, 0xf6, 0x1d, 0x0f, 0xbf, 0x46, 0x57, 0x2c, 0x09, 0x42, 0x11, 0x6b, 0x04, 0xc1, + 0xdd, 0x7d, 0xb8, 0x3e, 0x3b, 0xce, 0xaa, 0x2f, 0x5f, 0xd2, 0x4f, 0x8f, 0x52, 0xfd, 0xfd, 0x93, + 0xc0, 0xd1, 0x77, 0xe8, 0x2a, 0x50, 0x38, 0x78, 0xe6, 0x91, 0x34, 0xac, 0xc2, 0xd2, 0xbe, 0x9f, + 0xa2, 0x61, 0xb9, 0xbb, 0xdd, 0xb1, 0xd0, 0x78, 0x32, 0x29, 0x51, 0x27, 0x16, 0x52, 0x77, 0x4b, + 0x32, 0x3a, 0xe8, 0x4a, 0xbf, 0x1e, 0xaf, 0x2f, 0xa6, 0x9b, 0x90, 0xb4, 0xad, 0x2f, 0xa6, 0xc7, + 0xdd, 0xcc, 0xeb, 0x9f, 0x85, 0xf1, 0xba, 0xd2, 0x95, 0x36, 0x2b, 0xdc, 0x7d, 0x0f, 0x56, 0xcc, + 0x50, 0xbb, 0x32, 0x0c, 0xa3, 0xbb, 0x19, 0x87, 0x81, 0x73, 0xaa, 0x2f, 0xbf, 0x2f, 0x42, 0xf9, + 0x50, 0x06, 0xa1, 0xef, 0xd1, 0xc5, 0x7f, 0x80, 0x62, 0xbb, 0x2f, 0x02, 0xfc, 0xc6, 0xdd, 0x6f, + 0x40, 0x85, 0xee, 0x6a, 0x3c, 0x74, 0x3c, 0x1b, 0x47, 0xb2, 0x61, 0xca, 0x93, 0x2b, 0x50, 0xd8, + 0xf4, 0x4f, 0x69, 0x7c, 0x65, 0xfd, 0x03, 0x88, 0x2c, 0x7b, 0xf7, 0x23, 0xe0, 0x3a, 0xc4, 0x63, + 0xcb, 0x33, 0xc7, 0xeb, 0xc5, 0x37, 0x82, 0x81, 0xae, 0xf7, 0xdb, 0xf2, 0x8c, 0x3c, 0xa8, 0x2a, + 0x94, 0xa2, 0x46, 0xf4, 0x23, 0x03, 0xdb, 0xfe, 0xc8, 0xc3, 0xaf, 0x3d, 0x86, 0xab, 0x5a, 0x36, + 0xf0, 0xf3, 0x74, 0x27, 0xec, 0x42, 0xbf, 0x53, 0x5f, 0xa8, 0x51, 0xa3, 0x30, 0xc6, 0x65, 0x19, + 0x7e, 0x1d, 0x78, 0xec, 0xb3, 0x25, 0xf0, 0xec, 0xdd, 0x06, 0x5c, 0x99, 0xe1, 0x38, 0x93, 0x12, + 0xd6, 0xee, 0x03, 0x5b, 0xb8, 0xfb, 0x21, 0xac, 0x6a, 0xb5, 0xb1, 0xaf, 0xef, 0xf8, 0x44, 0x27, + 0xe0, 0x93, 0xd6, 0x76, 0x4b, 0x4f, 0xd1, 0x66, 0x73, 0x77, 0xf7, 0xd1, 0xee, 0xba, 0xc5, 0x32, + 0xb4, 0x90, 0x07, 0x9d, 0xa7, 0x9b, 0x07, 0xfb, 0xfb, 0xcd, 0xcd, 0x4e, 0x73, 0x8b, 0x65, 0x37, + 0xee, 0xfe, 0xe1, 0xcf, 0x6f, 0x65, 0x7e, 0xf6, 0xf3, 0x5b, 0x99, 0xff, 0xfe, 0xf3, 0x5b, 0x99, + 0x1f, 0x7c, 0x71, 0x6b, 0xe1, 0x67, 0x5f, 0xdc, 0x5a, 0xf8, 0x2f, 0x5f, 0xdc, 0x5a, 0xf8, 0x94, + 0x4d, 0xfe, 0xe7, 0x86, 0xa3, 0x22, 0x59, 0xac, 0x6f, 0xfe, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x03, 0x05, 0xfb, 0xeb, 0xd4, 0x61, 0x00, 0x00, } func (m *SmartBlockSnapshotBase) Marshal() (dAtA []byte, err error) { diff --git a/pkg/lib/pb/model/protos/models.proto b/pkg/lib/pb/model/protos/models.proto index 8534bb002b..899a580b59 100644 --- a/pkg/lib/pb/model/protos/models.proto +++ b/pkg/lib/pb/model/protos/models.proto @@ -51,9 +51,9 @@ enum SmartBlockType { NotificationObject = 0x217; DevicesObject = 0x218; - ChatObject = 0x219; // Container for any-store based chats ChatDerivedObject = 0x220; // Any-store based object for chat + AccountObject = 0x221; // Container for account data in tech space } message Search { @@ -805,7 +805,7 @@ message Relation { string description = 14; // on-store fields, injected only locally - Scope scope = 20; // scope from which this relation have been aggregated + Scope scope = 20; // deprecated, to be removed string creator = 21; // creator profile id int64 revision = 22; // revision of system relation. Used to check if we should change relation content or not @@ -1359,4 +1359,4 @@ message ChatMessage { repeated string ids = 1; // List of user IDs } } -} \ No newline at end of file +} diff --git a/space/clientspace/space.go b/space/clientspace/space.go index 7e43e37629..16727c9d88 100644 --- a/space/clientspace/space.go +++ b/space/clientspace/space.go @@ -2,6 +2,7 @@ package clientspace import ( "context" + "errors" "fmt" "time" @@ -15,6 +16,7 @@ import ( "github.com/anyproto/any-sync/util/crypto" "github.com/gogo/protobuf/types" "go.uber.org/zap" + "golang.org/x/exp/slices" "github.com/anyproto/anytype-heart/core/block/editor/profilemigration" "github.com/anyproto/anytype-heart/core/block/editor/smartblock" @@ -66,7 +68,7 @@ type spaceIndexer interface { type bundledObjectsInstaller interface { InstallBundledObjects(ctx context.Context, spc Space, ids []string, isNewSpace bool) ([]string, []*types.Struct, error) - BundledObjectsIdsToInstall(ctx context.Context, spc Space, sourceObjectIds []string) (objectIds []string, err error) + BundledObjectsIdsToInstall(ctx context.Context, spc Space, sourceObjectIds []string) (ids domain.BundledObjectIds, err error) } var log = logger.NewNamed("client.space") @@ -87,6 +89,9 @@ type space struct { loadMandatoryObjectsCh chan struct{} loadMandatoryObjectsErr error + + loadMissingBundledObjectsCtx context.Context + loadMissingBundledObjectsCtxCancel context.CancelFunc } type SpaceDeps struct { @@ -112,6 +117,7 @@ func BuildSpace(ctx context.Context, deps SpaceDeps) (Space, error) { myIdentity: deps.AccountService.Account().SignKey.GetPublic(), loadMandatoryObjectsCh: make(chan struct{}), } + sp.loadMissingBundledObjectsCtx, sp.loadMissingBundledObjectsCtxCancel = context.WithCancel(context.Background()) sp.Cache = objectcache.New(deps.AccountService, deps.ObjectFactory, deps.PersonalSpaceId, sp) sp.ObjectProvider = objectprovider.NewObjectProvider(deps.CommonSpace.Id(), deps.PersonalSpaceId, sp.Cache) var err error @@ -128,7 +134,8 @@ func BuildSpace(ctx context.Context, deps SpaceDeps) (Space, error) { if err != nil { return nil, fmt.Errorf("unmark space created: %w", err) } - if err = sp.InstallBundledObjects(ctx); err != nil { + ids := getBundledObjectsToInstall() + if _, _, err = sp.installer.InstallBundledObjects(ctx, sp, ids, true); err != nil { return nil, fmt.Errorf("install bundled objects: %w", err) } } @@ -136,6 +143,21 @@ func BuildSpace(ctx context.Context, deps SpaceDeps) (Space, error) { return sp, nil } +func (s *space) tryLoadBundledAndInstallIfMissing() { + ctxWithPeerTimeout := context.WithValue(s.loadMissingBundledObjectsCtx, peermanager.ContextPeerFindDeadlineKey, time.Now().Add(BundledObjectsPeerFindTimeout)) + missingSourceIds, err := s.TryLoadBundledObjects(ctxWithPeerTimeout) + if err != nil { + if errors.Is(err, context.Canceled) { + return // we are closing, skip installation, + } + log.Error("failed to load bundled objects", zap.Error(err)) + } + _, _, err = s.installer.InstallBundledObjects(s.loadMissingBundledObjectsCtx, s, missingSourceIds, true) + if err != nil { + log.Error("failed to install bundled objects", zap.Error(err)) + } +} + func (s *space) mandatoryObjectsLoad(ctx context.Context, disableRemoteLoad bool) { defer close(s.loadMandatoryObjectsCh) s.loadMandatoryObjectsErr = s.indexer.ReindexSpace(s) @@ -150,11 +172,7 @@ func (s *space) mandatoryObjectsLoad(ctx context.Context, disableRemoteLoad bool if s.loadMandatoryObjectsErr != nil { return } - ctxWithPeerTimeout := context.WithValue(loadCtx, peermanager.ContextPeerFindDeadlineKey, time.Now().Add(BundledObjectsPeerFindTimeout)) - if err := s.TryLoadBundledObjects(ctxWithPeerTimeout); err != nil { - log.Error("failed to load bundled objects", zap.Error(err)) - } - s.loadMandatoryObjectsErr = s.InstallBundledObjects(ctx) + go s.tryLoadBundledAndInstallIfMissing() if s.loadMandatoryObjectsErr != nil { return } @@ -246,6 +264,10 @@ func (s *space) Close(ctx context.Context) error { if s == nil { return nil } + if s.loadMissingBundledObjectsCtxCancel != nil { + s.loadMissingBundledObjectsCtxCancel() + } + err := s.Cache.Close(ctx) if err != nil { return err @@ -257,7 +279,7 @@ func (s *space) Close(ctx context.Context) error { return s.common.Close() } -func (s *space) InstallBundledObjects(ctx context.Context) error { +func getBundledObjectsToInstall() []string { ids := make([]string, 0, len(bundle.SystemTypes)+len(bundle.SystemRelations)) for _, ot := range bundle.SystemTypes { ids = append(ids, ot.BundledURL()) @@ -265,14 +287,10 @@ func (s *space) InstallBundledObjects(ctx context.Context) error { for _, rk := range bundle.SystemRelations { ids = append(ids, rk.BundledURL()) } - _, _, err := s.installer.InstallBundledObjects(ctx, s, ids, true) - if err != nil { - return err - } - return nil + return ids } -func (s *space) TryLoadBundledObjects(ctx context.Context) error { +func (s *space) TryLoadBundledObjects(ctx context.Context) (missingSourceIds []string, err error) { st := time.Now() defer func() { if dur := time.Since(st); dur > time.Millisecond*200 { @@ -280,19 +298,34 @@ func (s *space) TryLoadBundledObjects(ctx context.Context) error { } }() - ids := make([]string, 0, len(bundle.SystemTypes)+len(bundle.SystemRelations)) - for _, ot := range bundle.SystemTypes { - ids = append(ids, ot.BundledURL()) + ids := getBundledObjectsToInstall() + bundledObjectIds, err := s.installer.BundledObjectsIdsToInstall(ctx, s, ids) + if err != nil { + return nil, err } - for _, rk := range bundle.SystemRelations { - ids = append(ids, rk.BundledURL()) + storedIds, err := s.Storage().StoredIds() + if err != nil { + return nil, err } - objectIds, err := s.installer.BundledObjectsIdsToInstall(ctx, s, ids) + + missingIds := bundledObjectIds.Filter(func(bo domain.BundledObjectId) bool { + return !slices.Contains(storedIds, bo.DerivedObjectId) + }) + + // only load objects that are not already stored + s.LoadObjectsIgnoreErrs(ctx, missingIds.DerivedObjectIds()) + // todo: make LoadObjectsIgnoreErrs return list of loaded ids + + storedIds, err = s.Storage().StoredIds() if err != nil { - return err + return nil, err } - s.LoadObjectsIgnoreErrs(ctx, objectIds) - return nil + + missingIds = bundledObjectIds.Filter(func(bo domain.BundledObjectId) bool { + return !slices.Contains(storedIds, bo.DerivedObjectId) + }) + + return missingIds.SourceIds(), nil } func (s *space) migrationProfileObject(ctx context.Context) error { diff --git a/space/clientspace/techspace.go b/space/clientspace/techspace.go index b9acba0102..008b10fe53 100644 --- a/space/clientspace/techspace.go +++ b/space/clientspace/techspace.go @@ -45,6 +45,9 @@ func NewTechSpace(deps TechSpaceDeps) *TechSpace { } func (s *TechSpace) Close(ctx context.Context) error { + if s == nil || s.space == nil { + return nil + } err := s.space.Close(ctx) if err != nil { log.Error("close tech space", zap.Error(err)) diff --git a/space/clientspace/virtualspace.go b/space/clientspace/virtualspace.go index e285834974..f8ca69a808 100644 --- a/space/clientspace/virtualspace.go +++ b/space/clientspace/virtualspace.go @@ -10,12 +10,13 @@ import ( "github.com/anyproto/any-sync/commonspace/headsync" "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/treesyncer" - "github.com/anyproto/any-sync/commonspace/objectsync" "github.com/anyproto/any-sync/commonspace/objecttreebuilder" "github.com/anyproto/any-sync/commonspace/spacestorage" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/sync/objectsync/objectmessages" "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/net/peer" + "storj.io/drpc" "github.com/anyproto/anytype-heart/core/block/object/objectcache" "github.com/anyproto/anytype-heart/core/domain" @@ -68,6 +69,22 @@ type virtualCommonSpace struct { spaceId string } +func (c *virtualCommonSpace) HandleMessage(ctx context.Context, msg *objectmessages.HeadUpdate) (err error) { + return nil +} + +func (c *virtualCommonSpace) HandleStreamSyncRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage, stream drpc.Stream) (err error) { + return nil +} + +func (c *virtualCommonSpace) HandleDeprecatedObjectSyncRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + return +} + +func (c *virtualCommonSpace) HandleStream(stream spacesyncproto.DRPCSpaceSync_ObjectSyncStreamStream) error { + return nil +} + func (c *virtualCommonSpace) AclClient() aclclient.AclSpaceClient { return nil } @@ -124,14 +141,6 @@ func (c *virtualCommonSpace) GetNodePeers(ctx context.Context) (peer []peer.Peer return } -func (c *virtualCommonSpace) HandleMessage(ctx context.Context, msg objectsync.HandleMessage) (err error) { - return -} - -func (c *virtualCommonSpace) HandleSyncRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { - return -} - func (c *virtualCommonSpace) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) { return } diff --git a/space/init.go b/space/init.go index 077db8144b..4e4db049ec 100644 --- a/space/init.go +++ b/space/init.go @@ -26,7 +26,7 @@ func (s *service) initMarketplaceSpace(ctx context.Context) error { return nil } -func (s *service) initTechSpace(ctx context.Context) (err error) { +func (s *service) createTechSpace(ctx context.Context) (err error) { if s.techSpace, err = s.factory.CreateAndSetTechSpace(ctx); err != nil { return err } @@ -34,9 +34,10 @@ func (s *service) initTechSpace(ctx context.Context) (err error) { return } -func (s *service) initPersonalSpace(ctx context.Context) (err error) { - if s.newAccount { - return s.createPersonalSpace(ctx) +func (s *service) loadTechSpace(ctx context.Context) (err error) { + if s.techSpace, err = s.factory.LoadAndSetTechSpace(ctx); err != nil { + return err } - return s.loadPersonalSpace(ctx) + close(s.techSpaceReady) + return } diff --git a/space/internal/components/aclobjectmanager/aclobjectmanager.go b/space/internal/components/aclobjectmanager/aclobjectmanager.go index c59c696ab9..aa3905151c 100644 --- a/space/internal/components/aclobjectmanager/aclobjectmanager.go +++ b/space/internal/components/aclobjectmanager/aclobjectmanager.go @@ -105,7 +105,6 @@ func (a *aclObjectManager) Name() (name string) { func (a *aclObjectManager) Run(ctx context.Context) (err error) { a.started = true a.ctx, a.cancel = context.WithCancel(context.Background()) - go a.waitSpace() go a.process() return } @@ -123,30 +122,18 @@ func (a *aclObjectManager) Close(ctx context.Context) (err error) { return } -func (a *aclObjectManager) waitSpace() { - a.sp, a.loadErr = a.spaceLoader.WaitLoad(a.ctx) - if a.loadErr == nil { - err := a.inviteMigrator.MigrateExistingInvites(a.sp) - if err != nil { - log.Warn("migrate existing invites", zap.Error(err)) - } - } - close(a.waitLoad) -} - func (a *aclObjectManager) process() { defer close(a.wait) - select { - case <-a.ctx.Done(): + a.sp, a.loadErr = a.spaceLoader.WaitLoad(a.ctx) + if a.loadErr != nil { + log.Error("load space", zap.Error(a.loadErr)) return - case <-a.waitLoad: - if a.loadErr != nil { - return - } - break } - - err := a.participantWatcher.UpdateAccountParticipantFromProfile(a.ctx, a.sp) + err := a.inviteMigrator.MigrateExistingInvites(a.sp) + if err != nil { + log.Warn("migrate existing invites", zap.Error(err)) + } + err = a.participantWatcher.UpdateAccountParticipantFromProfile(a.ctx, a.sp) if err != nil { log.Error("init my identity", zap.Error(err)) } @@ -169,6 +156,11 @@ func (a *aclObjectManager) processAcl() (err error) { aclState = acl.AclState() upToDate bool ) + firstRec, err := acl.GetIndex(0) + if err != nil { + return + } + createdDate := firstRec.Timestamp defer func() { if err == nil { permissions := aclState.Permissions(aclState.AccountKey().GetPublic()) @@ -197,6 +189,14 @@ func (a *aclObjectManager) processAcl() (err error) { if err != nil { return } + for _, st := range states { + if st.Permissions.IsOwner() { + err = a.status.SetOwner(st.PubKey.Account(), createdDate) + if err != nil { + return + } + } + } statusAclHeadId := a.status.GetLatestAclHeadId() upToDate = statusAclHeadId == "" || acl.HasHead(statusAclHeadId) diff --git a/space/internal/components/aclobjectmanager/aclobjectmananger_test.go b/space/internal/components/aclobjectmanager/aclobjectmananger_test.go index bb46f11cfe..824e1d38f6 100644 --- a/space/internal/components/aclobjectmanager/aclobjectmananger_test.go +++ b/space/internal/components/aclobjectmanager/aclobjectmananger_test.go @@ -11,10 +11,14 @@ import ( "github.com/anyproto/any-sync/commonspace/object/acl/syncacl" "github.com/anyproto/any-sync/commonspace/object/acl/syncacl/headupdater" "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/sync/syncdeps" + "github.com/anyproto/any-sync/commonspace/syncstatus" "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/protobuf/proto" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" + "storj.io/drpc" "github.com/anyproto/anytype-heart/space/clientspace" "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" @@ -47,6 +51,7 @@ func TestAclObjectManager(t *testing.T) { fx.mockSpace.EXPECT().CommonSpace().Return(fx.mockCommonSpace) fx.mockCommonSpace.EXPECT().Acl().AnyTimes().Return(acl) fx.mockStatus.EXPECT().GetLatestAclHeadId().Return("") + fx.mockStatus.EXPECT().SetOwner(acl.AclState().Identity().Account(), mock.Anything).Return(nil) fx.mockParticipantWatcher.EXPECT().UpdateParticipantFromAclState(mock.Anything, fx.mockSpace, mock.Anything). RunAndReturn(func(_ context.Context, space clientspace.Space, state list.AccountState) error { require.True(t, state.PubKey.Equals(acl.AclState().Identity())) @@ -84,6 +89,7 @@ func TestAclObjectManager(t *testing.T) { fx.mockParticipantWatcher.EXPECT().UpdateAccountParticipantFromProfile(mock.Anything, fx.mockSpace).Return(nil) fx.mockSpace.EXPECT().CommonSpace().Return(fx.mockCommonSpace) fx.mockCommonSpace.EXPECT().Acl().AnyTimes().Return(acl) + fx.mockStatus.EXPECT().SetOwner(a.ActualAccounts()["a"].Acl.AclState().Identity().Account(), mock.Anything).Return(nil) fx.mockStatus.EXPECT().GetLatestAclHeadId().Return("") var callCounter atomic.Bool fx.mockParticipantWatcher.EXPECT().UpdateParticipantFromAclState(mock.Anything, fx.mockSpace, mock.Anything). @@ -126,6 +132,7 @@ func TestAclObjectManager(t *testing.T) { defer fx.finish(t) fx.mockLoader.EXPECT().WaitLoad(mock.Anything).Return(fx.mockSpace, nil) fx.mockInviteMigrator.EXPECT().MigrateExistingInvites(fx.mockSpace).Return(nil) + fx.mockStatus.EXPECT().SetOwner(a.ActualAccounts()["a"].Acl.AclState().Identity().Account(), mock.Anything).Return(nil) fx.mockParticipantWatcher.EXPECT().UpdateAccountParticipantFromProfile(mock.Anything, fx.mockSpace).Return(nil) fx.mockSpace.EXPECT().CommonSpace().Return(fx.mockCommonSpace) fx.mockCommonSpace.EXPECT().Acl().AnyTimes().Return(acl) @@ -205,6 +212,8 @@ type syncAclStub struct { updater headupdater.AclUpdater } +var _ syncacl.SyncAcl = &syncAclStub{} + func (s *syncAclStub) HandleMessage(ctx context.Context, senderId string, protoVersion uint32, message *spacesyncproto.ObjectSyncMessage) (err error) { return } @@ -237,3 +246,20 @@ func (s *syncAclStub) SetAclUpdater(updater headupdater.AclUpdater) { s.updater = updater return } + +func (s *syncAclStub) HandleHeadUpdate(ctx context.Context, statusUpdater syncstatus.StatusUpdater, headUpdate drpc.Message) (syncdeps.Request, error) { + return nil, nil +} +func (s *syncAclStub) HandleStreamRequest(ctx context.Context, rq syncdeps.Request, updater syncdeps.QueueSizeUpdater, send func(resp proto.Message) error) (syncdeps.Request, error) { + return nil, nil +} +func (s *syncAclStub) HandleDeprecatedRequest(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { + return nil, nil +} + +func (s *syncAclStub) HandleResponse(ctx context.Context, peerId string, objectId string, resp syncdeps.Response) error { + return nil +} +func (s *syncAclStub) ResponseCollector() syncdeps.ResponseCollector { + return nil +} diff --git a/space/internal/components/dependencies/bundledobjects.go b/space/internal/components/dependencies/bundledobjects.go index ea97c9f49e..a9e467f331 100644 --- a/space/internal/components/dependencies/bundledobjects.go +++ b/space/internal/components/dependencies/bundledobjects.go @@ -5,10 +5,11 @@ import ( "github.com/gogo/protobuf/types" + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/space/clientspace" ) type BundledObjectsInstaller interface { InstallBundledObjects(ctx context.Context, spc clientspace.Space, ids []string, isNewSpace bool) ([]string, []*types.Struct, error) - BundledObjectsIdsToInstall(ctx context.Context, spc clientspace.Space, sourceObjectIds []string) (objectIds []string, err error) + BundledObjectsIdsToInstall(ctx context.Context, spc clientspace.Space, sourceObjectIds []string) (ids domain.BundledObjectIds, err error) } diff --git a/space/internal/components/dependencies/spacewithctx.go b/space/internal/components/dependencies/spacewithctx.go index 64eb4f773e..04cdcade76 100644 --- a/space/internal/components/dependencies/spacewithctx.go +++ b/space/internal/components/dependencies/spacewithctx.go @@ -5,10 +5,12 @@ import ( "github.com/anyproto/anytype-heart/core/block/editor/smartblock" "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pkg/lib/threads" ) type SpaceWithCtx interface { DoCtx(ctx context.Context, objectId string, apply func(sb smartblock.SmartBlock) error) error Id() string + DerivedIDs() threads.DerivedSmartblockIds DeriveObjectID(ctx context.Context, uniqueKey domain.UniqueKey) (id string, err error) } diff --git a/space/internal/components/migration/readonlyfixer/relationsfixer.go b/space/internal/components/migration/readonlyfixer/relationsfixer.go index 7a0cc163a7..1b6ab119a5 100644 --- a/space/internal/components/migration/readonlyfixer/relationsfixer.go +++ b/space/internal/components/migration/readonlyfixer/relationsfixer.go @@ -80,11 +80,6 @@ func listReadonlyTagAndStatusRelations(store dependencies.QueryableStore, spaceI Condition: model.BlockContentDataviewFilter_In, Value: pbtypes.IntList(int(model.RelationFormat_status), int(model.RelationFormat_tag)), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, { RelationKey: bundle.RelationKeyRelationReadonlyValue.String(), Condition: model.BlockContentDataviewFilter_Equal, diff --git a/space/internal/components/migration/readonlyfixer/relationsfixer_test.go b/space/internal/components/migration/readonlyfixer/relationsfixer_test.go index 758dccaf51..3a256da6b2 100644 --- a/space/internal/components/migration/readonlyfixer/relationsfixer_test.go +++ b/space/internal/components/migration/readonlyfixer/relationsfixer_test.go @@ -19,7 +19,7 @@ import ( func TestFixReadonlyInRelations(t *testing.T) { store := objectstore.NewStoreFixture(t) - store.AddObjects(t, []objectstore.TestObject{ + store.AddObjects(t, "space1", []objectstore.TestObject{ // space1 { bundle.RelationKeySpaceId: pbtypes.String("space1"), @@ -33,7 +33,8 @@ func TestFixReadonlyInRelations(t *testing.T) { bundle.RelationKeyId: pbtypes.String("rel-customTag"), bundle.RelationKeyRelationReadonlyValue: pbtypes.Bool(true), }, - + }) + store.AddObjects(t, "space2", []objectstore.TestObject{ // space2 { bundle.RelationKeySpaceId: pbtypes.String("space2"), @@ -47,7 +48,8 @@ func TestFixReadonlyInRelations(t *testing.T) { bundle.RelationKeyId: pbtypes.String("rel-relationFormat"), bundle.RelationKeyRelationReadonlyValue: pbtypes.Bool(true), }, - + }) + store.AddObjects(t, "space3", []objectstore.TestObject{ // space3 { bundle.RelationKeySpaceId: pbtypes.String("space3"), @@ -80,7 +82,7 @@ func TestFixReadonlyInRelations(t *testing.T) { ).Times(2) // when - migrated, toMigrate, err := fixer.Run(ctx, log, store, spc) + migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space1"), spc) // then assert.NoError(t, err) @@ -97,7 +99,7 @@ func TestFixReadonlyInRelations(t *testing.T) { // sp.EXPECT().Do(mock.Anything, mock.Anything).Times(1).Return(nil) // when - migrated, toMigrate, err := fixer.Run(ctx, log, store, spc) + migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space2"), spc) // then assert.NoError(t, err) @@ -114,7 +116,7 @@ func TestFixReadonlyInRelations(t *testing.T) { // sp.EXPECT().Do(mock.Anything, mock.Anything).Times(1).Return(nil) // when - migrated, toMigrate, err := fixer.Run(ctx, log, store, spc) + migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space3"), spc) // then assert.NoError(t, err) diff --git a/space/internal/components/migration/runner.go b/space/internal/components/migration/runner.go index 2f18ce2cf0..d75c8f9c99 100644 --- a/space/internal/components/migration/runner.go +++ b/space/internal/components/migration/runner.go @@ -54,7 +54,6 @@ func (r *Runner) Name() string { func (r *Runner) Init(a *app.App) error { r.store = app.MustComponent[objectstore.ObjectStore](a) r.spaceLoader = app.MustComponent[spaceloader.SpaceLoader](a) - r.waitLoad = make(chan struct{}) return nil } @@ -91,7 +90,12 @@ func (r *Runner) runMigrations() { break } - if err := r.run(systemobjectreviser.Migration{}, readonlyfixer.Migration{}); err != nil { + migrations := []Migration{ + systemobjectreviser.Migration{}, + readonlyfixer.Migration{}, + } + + if err := r.run(migrations...); err != nil { log.Error("failed to run default migrations", zap.String("spaceId", r.spc.Id()), zap.Error(err)) } } @@ -99,12 +103,14 @@ func (r *Runner) runMigrations() { func (r *Runner) run(migrations ...Migration) (err error) { spaceId := r.spc.Id() + store := r.store.SpaceIndex(spaceId) + for _, m := range migrations { if e := r.ctx.Err(); e != nil { err = errors.Join(err, e) return } - toMigrate, migrated, e := m.Run(r.ctx, log, r.store, r.spc) + toMigrate, migrated, e := m.Run(r.ctx, log, store, r.spc) if e != nil { err = errors.Join(err, wrapError(e, m.Name(), spaceId, migrated, toMigrate)) continue diff --git a/space/internal/components/migration/runner_test.go b/space/internal/components/migration/runner_test.go index 1fb11fdeaa..8179ffd301 100644 --- a/space/internal/components/migration/runner_test.go +++ b/space/internal/components/migration/runner_test.go @@ -46,6 +46,7 @@ func TestRunner(t *testing.T) { t.Run("context exceeds + space operation in progress -> context.Canceled", func(t *testing.T) { // given + store := objectstore.NewStoreFixture(t) ctx, cancel := context.WithCancel(context.Background()) space := mock_space.NewMockSpace(t) space.EXPECT().Id().Times(1).Return("") @@ -60,7 +61,7 @@ func TestRunner(t *testing.T) { } }, ) - runner := Runner{ctx: ctx, spc: space} + runner := Runner{ctx: ctx, spc: space, store: store} // when go func() { @@ -97,7 +98,7 @@ func TestRunner(t *testing.T) { // given store := objectstore.NewStoreFixture(t) space := mock_space.NewMockSpace(t) - space.EXPECT().Id().Return("").Maybe() + space.EXPECT().Id().Return("spaceId").Maybe() runner := Runner{ctx: context.Background(), store: store, spc: space} // when @@ -110,7 +111,7 @@ func TestRunner(t *testing.T) { t.Run("no ctx exceed + migration failure -> error", func(t *testing.T) { // given store := objectstore.NewStoreFixture(t) - store.AddObjects(t, []objectstore.TestObject{{ + store.AddObjects(t, "space1", []objectstore.TestObject{{ bundle.RelationKeySpaceId: pbtypes.String("space1"), bundle.RelationKeyRelationFormat: pbtypes.Int64(int64(model.RelationFormat_status)), bundle.RelationKeyId: pbtypes.String("rel-tag"), diff --git a/space/internal/components/migration/systemobjectreviser/systemobjectreviser.go b/space/internal/components/migration/systemobjectreviser/systemobjectreviser.go index 262ae92ae2..08a8066064 100644 --- a/space/internal/components/migration/systemobjectreviser/systemobjectreviser.go +++ b/space/internal/components/migration/systemobjectreviser/systemobjectreviser.go @@ -77,11 +77,6 @@ func listAllTypesAndRelations(store dependencies.QueryableStore, spaceId string) Condition: model.BlockContentDataviewFilter_In, Value: pbtypes.IntList(int(model.ObjectType_objectType), int(model.ObjectType_relation)), }, - { - RelationKey: bundle.RelationKeySpaceId.String(), - Condition: model.BlockContentDataviewFilter_Equal, - Value: pbtypes.String(spaceId), - }, }, }) if err != nil { diff --git a/space/internal/components/personalmigration/mock_personalmigration/mock_fileObjectGetter.go b/space/internal/components/personalmigration/mock_personalmigration/mock_fileObjectGetter.go new file mode 100644 index 0000000000..ba851e417e --- /dev/null +++ b/space/internal/components/personalmigration/mock_personalmigration/mock_fileObjectGetter.go @@ -0,0 +1,259 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_personalmigration + +import ( + context "context" + + app "github.com/anyproto/any-sync/app" + + domain "github.com/anyproto/anytype-heart/core/domain" + + filemodels "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" + + mock "github.com/stretchr/testify/mock" + + types "github.com/gogo/protobuf/types" +) + +// MockfileObjectGetter is an autogenerated mock type for the fileObjectGetter type +type MockfileObjectGetter struct { + mock.Mock +} + +type MockfileObjectGetter_Expecter struct { + mock *mock.Mock +} + +func (_m *MockfileObjectGetter) EXPECT() *MockfileObjectGetter_Expecter { + return &MockfileObjectGetter_Expecter{mock: &_m.Mock} +} + +// Create provides a mock function with given fields: ctx, spaceId, req +func (_m *MockfileObjectGetter) Create(ctx context.Context, spaceId string, req filemodels.CreateRequest) (string, *types.Struct, error) { + ret := _m.Called(ctx, spaceId, req) + + if len(ret) == 0 { + panic("no return value specified for Create") + } + + var r0 string + var r1 *types.Struct + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, string, filemodels.CreateRequest) (string, *types.Struct, error)); ok { + return rf(ctx, spaceId, req) + } + if rf, ok := ret.Get(0).(func(context.Context, string, filemodels.CreateRequest) string); ok { + r0 = rf(ctx, spaceId, req) + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func(context.Context, string, filemodels.CreateRequest) *types.Struct); ok { + r1 = rf(ctx, spaceId, req) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*types.Struct) + } + } + + if rf, ok := ret.Get(2).(func(context.Context, string, filemodels.CreateRequest) error); ok { + r2 = rf(ctx, spaceId, req) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockfileObjectGetter_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create' +type MockfileObjectGetter_Create_Call struct { + *mock.Call +} + +// Create is a helper method to define mock.On call +// - ctx context.Context +// - spaceId string +// - req filemodels.CreateRequest +func (_e *MockfileObjectGetter_Expecter) Create(ctx interface{}, spaceId interface{}, req interface{}) *MockfileObjectGetter_Create_Call { + return &MockfileObjectGetter_Create_Call{Call: _e.mock.On("Create", ctx, spaceId, req)} +} + +func (_c *MockfileObjectGetter_Create_Call) Run(run func(ctx context.Context, spaceId string, req filemodels.CreateRequest)) *MockfileObjectGetter_Create_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(filemodels.CreateRequest)) + }) + return _c +} + +func (_c *MockfileObjectGetter_Create_Call) Return(id string, object *types.Struct, err error) *MockfileObjectGetter_Create_Call { + _c.Call.Return(id, object, err) + return _c +} + +func (_c *MockfileObjectGetter_Create_Call) RunAndReturn(run func(context.Context, string, filemodels.CreateRequest) (string, *types.Struct, error)) *MockfileObjectGetter_Create_Call { + _c.Call.Return(run) + return _c +} + +// GetFileIdFromObjectWaitLoad provides a mock function with given fields: ctx, objectId +func (_m *MockfileObjectGetter) GetFileIdFromObjectWaitLoad(ctx context.Context, objectId string) (domain.FullFileId, error) { + ret := _m.Called(ctx, objectId) + + if len(ret) == 0 { + panic("no return value specified for GetFileIdFromObjectWaitLoad") + } + + var r0 domain.FullFileId + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (domain.FullFileId, error)); ok { + return rf(ctx, objectId) + } + if rf, ok := ret.Get(0).(func(context.Context, string) domain.FullFileId); ok { + r0 = rf(ctx, objectId) + } else { + r0 = ret.Get(0).(domain.FullFileId) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, objectId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetFileIdFromObjectWaitLoad' +type MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call struct { + *mock.Call +} + +// GetFileIdFromObjectWaitLoad is a helper method to define mock.On call +// - ctx context.Context +// - objectId string +func (_e *MockfileObjectGetter_Expecter) GetFileIdFromObjectWaitLoad(ctx interface{}, objectId interface{}) *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call { + return &MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call{Call: _e.mock.On("GetFileIdFromObjectWaitLoad", ctx, objectId)} +} + +func (_c *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call) Run(run func(ctx context.Context, objectId string)) *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call) Return(_a0 domain.FullFileId, _a1 error) *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call) RunAndReturn(run func(context.Context, string) (domain.FullFileId, error)) *MockfileObjectGetter_GetFileIdFromObjectWaitLoad_Call { + _c.Call.Return(run) + return _c +} + +// Init provides a mock function with given fields: a +func (_m *MockfileObjectGetter) Init(a *app.App) error { + ret := _m.Called(a) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*app.App) error); ok { + r0 = rf(a) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockfileObjectGetter_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' +type MockfileObjectGetter_Init_Call struct { + *mock.Call +} + +// Init is a helper method to define mock.On call +// - a *app.App +func (_e *MockfileObjectGetter_Expecter) Init(a interface{}) *MockfileObjectGetter_Init_Call { + return &MockfileObjectGetter_Init_Call{Call: _e.mock.On("Init", a)} +} + +func (_c *MockfileObjectGetter_Init_Call) Run(run func(a *app.App)) *MockfileObjectGetter_Init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*app.App)) + }) + return _c +} + +func (_c *MockfileObjectGetter_Init_Call) Return(err error) *MockfileObjectGetter_Init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockfileObjectGetter_Init_Call) RunAndReturn(run func(*app.App) error) *MockfileObjectGetter_Init_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: +func (_m *MockfileObjectGetter) Name() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockfileObjectGetter_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockfileObjectGetter_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockfileObjectGetter_Expecter) Name() *MockfileObjectGetter_Name_Call { + return &MockfileObjectGetter_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockfileObjectGetter_Name_Call) Run(run func()) *MockfileObjectGetter_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockfileObjectGetter_Name_Call) Return(name string) *MockfileObjectGetter_Name_Call { + _c.Call.Return(name) + return _c +} + +func (_c *MockfileObjectGetter_Name_Call) RunAndReturn(run func() string) *MockfileObjectGetter_Name_Call { + _c.Call.Return(run) + return _c +} + +// NewMockfileObjectGetter creates a new instance of MockfileObjectGetter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockfileObjectGetter(t interface { + mock.TestingT + Cleanup(func()) +}) *MockfileObjectGetter { + mock := &MockfileObjectGetter{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/space/internal/components/personalmigration/personalmigration.go b/space/internal/components/personalmigration/personalmigration.go new file mode 100644 index 0000000000..1d9172ea6b --- /dev/null +++ b/space/internal/components/personalmigration/personalmigration.go @@ -0,0 +1,199 @@ +package personalmigration + +import ( + "context" + + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/app/logger" + "github.com/gogo/protobuf/types" + "go.uber.org/zap" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/core/domain/objectorigin" + "github.com/anyproto/anytype-heart/core/files/fileobject/filemodels" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/space/clientspace" + "github.com/anyproto/anytype-heart/space/internal/components/spaceloader" + "github.com/anyproto/anytype-heart/space/techspace" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +const ( + CName = "common.components.personalmigration" +) + +var log = logger.NewNamed(CName) + +type Runner interface { + app.ComponentRunnable + WaitProfile(ctx context.Context) error +} + +func New() Runner { + return &runner{} +} + +type fileObjectGetter interface { + app.Component + GetFileIdFromObjectWaitLoad(ctx context.Context, objectId string) (domain.FullFileId, error) + Create(ctx context.Context, spaceId string, req filemodels.CreateRequest) (id string, object *types.Struct, err error) +} + +type runner struct { + spaceLoader spaceloader.SpaceLoader + techSpace techspace.TechSpace + fileObjectGetter fileObjectGetter + + ctx context.Context + cancel context.CancelFunc + spc clientspace.Space + loadErr error + waitMigrateProfile chan struct{} + waitMigrate chan struct{} + started bool + + app.ComponentRunnable +} + +func (r *runner) Name() string { + return CName +} + +func (r *runner) Init(a *app.App) error { + r.spaceLoader = app.MustComponent[spaceloader.SpaceLoader](a) + r.techSpace = app.MustComponent[techspace.TechSpace](a) + r.fileObjectGetter = app.MustComponent[fileObjectGetter](a) + + r.waitMigrateProfile = make(chan struct{}) + r.waitMigrate = make(chan struct{}) + return nil +} + +func (r *runner) Run(context.Context) error { + r.started = true + r.ctx, r.cancel = context.WithCancel(context.Background()) + go r.runMigrations() + return nil +} + +func (r *runner) Close(context.Context) error { + if r.started { + r.cancel() + } + <-r.waitMigrate + return nil +} + +func (r *runner) migrateProfile() (hasIcon bool, oldIcon string, err error) { + defer close(r.waitMigrateProfile) + shouldMigrateProfile := true + err = r.techSpace.DoAccountObject(r.ctx, func(accountObject techspace.AccountObject) error { + if accountObject.CombinedDetails().GetFields()[bundle.RelationKeyName.String()].GetStringValue() != "" { + shouldMigrateProfile = false + hasIcon, err = accountObject.IsIconMigrated() + return err + } + return nil + }) + if !shouldMigrateProfile && hasIcon { + return + } + space := r.spc + ids := space.DerivedIDs() + var details *types.Struct + err = space.DoCtx(r.ctx, ids.Profile, func(sb smartblock.SmartBlock) error { + details = pbtypes.CopyStructFields(sb.CombinedDetails(), + bundle.RelationKeyName.String(), + bundle.RelationKeyDescription.String(), + bundle.RelationKeyIconOption.String()) + oldIcon = sb.CombinedDetails().GetFields()[bundle.RelationKeyIconImage.String()].GetStringValue() + return nil + }) + if err != nil { + return + } + if !shouldMigrateProfile { + return + } + var analyticsId string + err = space.DoCtx(r.ctx, ids.Workspace, func(sb smartblock.SmartBlock) error { + analyticsId = sb.NewState().GetSetting(state.SettingsAnalyticsId).GetStringValue() + return nil + }) + if err != nil { + return + } + err = r.techSpace.DoAccountObject(r.ctx, func(accountObject techspace.AccountObject) error { + err = accountObject.SetAnalyticsId(analyticsId) + if err != nil { + return err + } + return accountObject.SetProfileDetails(details) + }) + return +} + +func (r *runner) migrateIcon(oldIcon string) (err error) { + if oldIcon == "" { + err = r.techSpace.DoAccountObject(r.ctx, func(accountObject techspace.AccountObject) error { + return accountObject.MigrateIconImage("") + }) + return + } + _, err = r.fileObjectGetter.GetFileIdFromObjectWaitLoad(r.ctx, oldIcon) + if err != nil { + return + } + var fileInfo state.FileInfo + err = r.spc.DoCtx(r.ctx, oldIcon, func(sb smartblock.SmartBlock) error { + st := sb.NewState() + fileInfo = st.GetFileInfo() + return nil + }) + if err != nil { + return err + } + id, _, err := r.fileObjectGetter.Create(r.ctx, r.spc.Id(), filemodels.CreateRequest{ + FileId: fileInfo.FileId, + EncryptionKeys: fileInfo.EncryptionKeys, + ObjectOrigin: objectorigin.None(), + }) + if err != nil { + return + } + err = r.techSpace.DoAccountObject(r.ctx, func(accountObject techspace.AccountObject) error { + return accountObject.MigrateIconImage(id) + }) + return +} + +func (r *runner) runMigrations() { + defer close(r.waitMigrate) + r.spc, r.loadErr = r.spaceLoader.WaitLoad(r.ctx) + if r.loadErr != nil { + log.Error("failed to load space", zap.Error(r.loadErr)) + return + } + hasIcon, iconId, err := r.migrateProfile() + if err != nil { + log.Error("failed to migrate profile", zap.String("spaceId", r.spc.Id())) + return + } + if !hasIcon { + err = r.migrateIcon(iconId) + if err != nil { + log.Error("failed to migrate icon", zap.String("spaceId", r.spc.Id())) + } + } +} + +func (r *runner) WaitProfile(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + case <-r.waitMigrateProfile: + return nil + } +} diff --git a/space/internal/components/personalmigration/personalmigration_test.go b/space/internal/components/personalmigration/personalmigration_test.go new file mode 100644 index 0000000000..75b8410f65 --- /dev/null +++ b/space/internal/components/personalmigration/personalmigration_test.go @@ -0,0 +1,196 @@ +package personalmigration + +import ( + "context" + "testing" + + "github.com/anyproto/any-sync/app" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + "github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest" + "github.com/anyproto/anytype-heart/core/block/editor/state" + "github.com/anyproto/anytype-heart/core/domain" + "github.com/anyproto/anytype-heart/pkg/lib/bundle" + "github.com/anyproto/anytype-heart/pkg/lib/threads" + "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" + "github.com/anyproto/anytype-heart/space/internal/components/personalmigration/mock_personalmigration" + "github.com/anyproto/anytype-heart/space/internal/components/spaceloader/mock_spaceloader" + "github.com/anyproto/anytype-heart/space/techspace" + "github.com/anyproto/anytype-heart/space/techspace/mock_techspace" + "github.com/anyproto/anytype-heart/tests/testutil" + "github.com/anyproto/anytype-heart/util/pbtypes" +) + +type fixture struct { + *runner + a *app.App + spaceLoader *mock_spaceloader.MockSpaceLoader + getter *mock_personalmigration.MockfileObjectGetter + techSpace *mock_techspace.MockTechSpace + accountObject *mock_techspace.MockAccountObject + space *mock_clientspace.MockSpace + smartBlock *smarttest.SmartTest +} + +var ctx = context.Background() + +func newFixture(t *testing.T) *fixture { + a := &app.App{} + fx := &fixture{ + runner: New().(*runner), + a: a, + spaceLoader: mock_spaceloader.NewMockSpaceLoader(t), + getter: mock_personalmigration.NewMockfileObjectGetter(t), + techSpace: mock_techspace.NewMockTechSpace(t), + accountObject: mock_techspace.NewMockAccountObject(t), + space: mock_clientspace.NewMockSpace(t), + smartBlock: smarttest.New("Workspace"), + } + fx.a.Register(testutil.PrepareMock(ctx, fx.a, fx.spaceLoader)). + Register(testutil.PrepareMock(ctx, fx.a, fx.techSpace)). + Register(testutil.PrepareMock(ctx, fx.a, fx.getter)). + Register(fx) + fx.spaceLoader.EXPECT().WaitLoad(mock.Anything).Return(fx.space, nil) + return fx +} + +func (fx *fixture) run(t *testing.T) { + require.NoError(t, fx.a.Start(ctx)) + t.Cleanup(func() { + require.NoError(t, fx.a.Close(ctx)) + }) + <-fx.waitMigrate +} + +func TestRunner_Run(t *testing.T) { + t.Run("full migration", func(t *testing.T) { + fx := newFixture(t) + st := fx.smartBlock.NewState() + st.SetSetting(state.SettingsAnalyticsId, pbtypes.String("analyticsId")) + fileInfo := state.FileInfo{ + FileId: "fileId", + EncryptionKeys: map[string]string{ + "path": "key", + }, + } + st.SetFileInfo(fileInfo) + st.SetDetails(pbtypes.ToStruct(map[string]any{ + bundle.RelationKeyName.String(): "name", + bundle.RelationKeyDescription.String(): "description", + bundle.RelationKeyIconImage.String(): "iconImage", + })) + err := fx.smartBlock.Apply(st) + require.NoError(t, err) + initDetails := pbtypes.ToStruct(map[string]any{}) + fx.accountObject.EXPECT().CombinedDetails().Return(initDetails) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(fx.accountObject) + }) + fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{ + Profile: "Profile", + Workspace: "Workspace", + }) + fx.space.EXPECT().DoCtx(mock.Anything, "Profile", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.space.EXPECT().DoCtx(mock.Anything, "Workspace", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.accountObject.EXPECT().SetAnalyticsId("analyticsId").Return(nil) + fx.accountObject.EXPECT().SetProfileDetails(mock.Anything).Return(nil) + fx.getter.EXPECT().GetFileIdFromObjectWaitLoad(mock.Anything, "iconImage").Return(domain.FullFileId{}, nil) + fx.space.EXPECT().DoCtx(mock.Anything, "iconImage", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.space.EXPECT().Id().Return("spaceId") + fx.getter.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("iconMigratedId", nil, nil) + fx.accountObject.EXPECT().MigrateIconImage("iconMigratedId").Return(nil) + fx.run(t) + }) + t.Run("migrate only profile without icon", func(t *testing.T) { + fx := newFixture(t) + st := fx.smartBlock.NewState() + st.SetSetting(state.SettingsAnalyticsId, pbtypes.String("analyticsId")) + st.SetDetails(pbtypes.ToStruct(map[string]any{ + bundle.RelationKeyName.String(): "name", + bundle.RelationKeyDescription.String(): "description", + })) + err := fx.smartBlock.Apply(st) + require.NoError(t, err) + initDetails := pbtypes.ToStruct(map[string]any{}) + fx.accountObject.EXPECT().CombinedDetails().Return(initDetails) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(fx.accountObject) + }) + fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{ + Profile: "Profile", + Workspace: "Workspace", + }) + fx.space.EXPECT().DoCtx(mock.Anything, "Profile", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.space.EXPECT().DoCtx(mock.Anything, "Workspace", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.accountObject.EXPECT().SetAnalyticsId("analyticsId").Return(nil) + fx.accountObject.EXPECT().SetProfileDetails(mock.Anything).Return(nil) + fx.accountObject.EXPECT().MigrateIconImage("").Return(nil) + fx.run(t) + }) + t.Run("already migrated but not icon", func(t *testing.T) { + fx := newFixture(t) + st := fx.smartBlock.NewState() + st.SetSetting(state.SettingsAnalyticsId, pbtypes.String("analyticsId")) + fileInfo := state.FileInfo{ + FileId: "fileId", + EncryptionKeys: map[string]string{ + "path": "key", + }, + } + st.SetFileInfo(fileInfo) + st.SetDetails(pbtypes.ToStruct(map[string]any{ + bundle.RelationKeyName.String(): "name", + bundle.RelationKeyDescription.String(): "description", + bundle.RelationKeyIconImage.String(): "iconImage", + })) + err := fx.smartBlock.Apply(st) + require.NoError(t, err) + initDetails := pbtypes.ToStruct(map[string]any{ + bundle.RelationKeyName.String(): "name", + }) + fx.accountObject.EXPECT().CombinedDetails().Return(initDetails) + fx.accountObject.EXPECT().IsIconMigrated().Return(false, nil) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(fx.accountObject) + }) + fx.space.EXPECT().DerivedIDs().Return(threads.DerivedSmartblockIds{ + Profile: "Profile", + Workspace: "Workspace", + }) + fx.space.EXPECT().DoCtx(mock.Anything, "Profile", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.getter.EXPECT().GetFileIdFromObjectWaitLoad(mock.Anything, "iconImage").Return(domain.FullFileId{}, nil) + fx.space.EXPECT().DoCtx(mock.Anything, "iconImage", mock.Anything).RunAndReturn(func(ctx2 context.Context, s string, f func(smartblock.SmartBlock) error) error { + return f(fx.smartBlock) + }).Times(1) + fx.space.EXPECT().Id().Return("spaceId") + fx.getter.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return("iconMigratedId", nil, nil) + fx.accountObject.EXPECT().MigrateIconImage("iconMigratedId").Return(nil) + fx.run(t) + }) + t.Run("already migrated fully", func(t *testing.T) { + fx := newFixture(t) + initDetails := pbtypes.ToStruct(map[string]any{ + bundle.RelationKeyName.String(): "name", + }) + fx.accountObject.EXPECT().CombinedDetails().Return(initDetails) + fx.accountObject.EXPECT().IsIconMigrated().Return(true, nil) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(fx.accountObject) + }) + fx.run(t) + }) +} diff --git a/space/internal/components/spacestatus/mock_spacestatus/mock_SpaceStatus.go b/space/internal/components/spacestatus/mock_spacestatus/mock_SpaceStatus.go index 6b07d9d020..1683d0de0b 100644 --- a/space/internal/components/spacestatus/mock_spacestatus/mock_SpaceStatus.go +++ b/space/internal/components/spacestatus/mock_spacestatus/mock_SpaceStatus.go @@ -576,6 +576,53 @@ func (_c *MockSpaceStatus_SetLocalStatus_Call) RunAndReturn(run func(spaceinfo.L return _c } +// SetOwner provides a mock function with given fields: ownerIdentity, createdDate +func (_m *MockSpaceStatus) SetOwner(ownerIdentity string, createdDate int64) error { + ret := _m.Called(ownerIdentity, createdDate) + + if len(ret) == 0 { + panic("no return value specified for SetOwner") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, int64) error); ok { + r0 = rf(ownerIdentity, createdDate) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockSpaceStatus_SetOwner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOwner' +type MockSpaceStatus_SetOwner_Call struct { + *mock.Call +} + +// SetOwner is a helper method to define mock.On call +// - ownerIdentity string +// - createdDate int64 +func (_e *MockSpaceStatus_Expecter) SetOwner(ownerIdentity interface{}, createdDate interface{}) *MockSpaceStatus_SetOwner_Call { + return &MockSpaceStatus_SetOwner_Call{Call: _e.mock.On("SetOwner", ownerIdentity, createdDate)} +} + +func (_c *MockSpaceStatus_SetOwner_Call) Run(run func(ownerIdentity string, createdDate int64)) *MockSpaceStatus_SetOwner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(int64)) + }) + return _c +} + +func (_c *MockSpaceStatus_SetOwner_Call) Return(err error) *MockSpaceStatus_SetOwner_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockSpaceStatus_SetOwner_Call) RunAndReturn(run func(string, int64) error) *MockSpaceStatus_SetOwner_Call { + _c.Call.Return(run) + return _c +} + // SetPersistentInfo provides a mock function with given fields: info func (_m *MockSpaceStatus) SetPersistentInfo(info spaceinfo.SpacePersistentInfo) error { ret := _m.Called(info) diff --git a/space/internal/components/spacestatus/status.go b/space/internal/components/spacestatus/status.go index 315210f5f1..4d07b33bc9 100644 --- a/space/internal/components/spacestatus/status.go +++ b/space/internal/components/spacestatus/status.go @@ -6,6 +6,7 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/debugstat" + "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/space/spaceinfo" "github.com/anyproto/anytype-heart/space/techspace" ) @@ -24,6 +25,7 @@ type SpaceStatus interface { SetLocalInfo(info spaceinfo.SpaceLocalInfo) (err error) SetAccessType(status spaceinfo.AccessType) (err error) SetAclIsEmpty(isEmpty bool) (err error) + SetOwner(ownerIdentity string, createdDate int64) (err error) GetSpaceView() techspace.SpaceView } @@ -132,6 +134,12 @@ func (s *spaceStatus) SetLocalStatus(status spaceinfo.LocalStatus) error { return s.SetLocalInfo(info) } +func (s *spaceStatus) SetOwner(ownerIdentity string, createdDate int64) (err error) { + return doSpaceView(s.spaceView, func(view techspace.SpaceView) error { + return view.SetOwner(domain.NewParticipantId(s.spaceId, ownerIdentity), createdDate) + }) +} + func (s *spaceStatus) SetLocalInfo(info spaceinfo.SpaceLocalInfo) (err error) { return doSpaceView(s.spaceView, func(view techspace.SpaceView) error { return view.SetSpaceLocalInfo(info) diff --git a/space/internal/objectprovider/objectprovider.go b/space/internal/objectprovider/objectprovider.go index 4ae8421c56..44b5ab405c 100644 --- a/space/internal/objectprovider/objectprovider.go +++ b/space/internal/objectprovider/objectprovider.go @@ -138,6 +138,8 @@ func (o *objectProvider) loadObjectsAsync(ctx context.Context, objIDs []string) for _, id := range objIDs { select { case <-ctx.Done(): + log.WarnCtx(ctx, "loadObjectsAsync context done", zap.Error(ctx.Err()), zap.String("spaceId", o.spaceId), zap.String("objectId", id)) + results <- ctx.Err() continue case limiter <- struct{}{}: @@ -148,6 +150,8 @@ func (o *objectProvider) loadObjectsAsync(ctx context.Context, objIDs []string) }() _, err := o.cache.GetObject(ctx, id) if err != nil { + log.WarnCtx(ctx, "loadObjectsAsync failed", zap.Error(err), zap.String("spaceId", o.spaceId), zap.String("objectId", id)) + // we had a bug that allowed some users to remove their profile // this workaround is to allow these users to load their accounts without errors and export their anytype data if id == o.derivedObjectIds.Profile { diff --git a/space/internal/personalspace/personal.go b/space/internal/personalspace/personal.go index ba59a53137..279cc402c7 100644 --- a/space/internal/personalspace/personal.go +++ b/space/internal/personalspace/personal.go @@ -2,29 +2,77 @@ package personalspace import ( "context" + "sync" "github.com/anyproto/any-sync/app" - "go.uber.org/multierr" + "github.com/anyproto/any-sync/app/logger" + "go.uber.org/zap" + "github.com/anyproto/anytype-heart/space/internal/components/personalmigration" "github.com/anyproto/anytype-heart/space/internal/components/spacestatus" "github.com/anyproto/anytype-heart/space/internal/spacecontroller" + "github.com/anyproto/anytype-heart/space/internal/spaceprocess/initial" "github.com/anyproto/anytype-heart/space/internal/spaceprocess/loader" "github.com/anyproto/anytype-heart/space/internal/spaceprocess/mode" + "github.com/anyproto/anytype-heart/space/internal/spaceprocess/offloader" "github.com/anyproto/anytype-heart/space/spacecore" "github.com/anyproto/anytype-heart/space/spaceinfo" "github.com/anyproto/anytype-heart/space/techspace" ) -func NewSpaceController(spaceId string, metadata []byte, a *app.App) spacecontroller.SpaceController { +type Personal interface { + spacecontroller.SpaceController + WaitMigrations(ctx context.Context) error +} + +var log = logger.NewNamed("common.space.personalspace") + +type ctxKey int + +const SkipCheckSpaceViewKey ctxKey = iota + +func shouldCheckSpaceView(ctx context.Context) bool { + skip, ok := ctx.Value(SkipCheckSpaceViewKey).(bool) + return !ok || !skip +} + +func NewSpaceController(ctx context.Context, spaceId string, metadata []byte, a *app.App) (spacecontroller.SpaceController, error) { techSpace := a.MustComponent(techspace.CName).(techspace.TechSpace) spaceCore := a.MustComponent(spacecore.CName).(spacecore.SpaceCoreService) - return &spaceController{ - app: a, + var ( + exists bool + err error + ) + if shouldCheckSpaceView(ctx) { + exists, err = techSpace.SpaceViewExists(ctx, spaceId) + } + // This could happen for old accounts + if !exists || err != nil { + info := spaceinfo.NewSpacePersistentInfo(spaceId) + info.SetAccountStatus(spaceinfo.AccountStatusUnknown) + err = techSpace.SpaceViewCreate(ctx, spaceId, false, info) + if err != nil { + return nil, err + } + } + newApp, err := makeStatusApp(a, spaceId) + if err != nil { + return nil, err + } + s := &spaceController{ + app: newApp, spaceId: spaceId, techSpace: techSpace, + status: newApp.MustComponent(spacestatus.CName).(spacestatus.SpaceStatus), spaceCore: spaceCore, metadata: metadata, } + sm, err := mode.NewStateMachine(s, log.With(zap.String("spaceId", s.spaceId))) + if err != nil { + return nil, err + } + s.sm = sm + return s, nil } func makeStatusApp(a *app.App, spaceId string) (*app.App, error) { @@ -38,45 +86,52 @@ func makeStatusApp(a *app.App, spaceId string) (*app.App, error) { } type spaceController struct { - app *app.App - spaceId string - metadata []byte + app *app.App + spaceId string + metadata []byte + lastUpdatedStatus spaceinfo.AccountStatus loader loader.Loader spaceCore spacecore.SpaceCoreService techSpace techspace.TechSpace + status spacestatus.SpaceStatus + + personalMigration personalmigration.Runner + + sm *mode.StateMachine + mx sync.Mutex } func (s *spaceController) Start(ctx context.Context) (err error) { - // Check that space exists. If not, probably user is migrating from legacy version - _, err = s.spaceCore.Get(ctx, s.spaceId) - if err != nil { - return + switch s.status.GetPersistentStatus() { + case spaceinfo.AccountStatusDeleted: + _, err := s.sm.ChangeMode(mode.ModeOffloading) + return err + default: + _, err := s.sm.ChangeMode(mode.ModeLoading) + return err } - exists, err := s.techSpace.SpaceViewExists(ctx, s.spaceId) - // This could happen for old accounts - if !exists || err != nil { - info := spaceinfo.NewSpacePersistentInfo(s.spaceId) - info.SetAccountStatus(spaceinfo.AccountStatusUnknown) - err = s.techSpace.SpaceViewCreate(ctx, s.spaceId, false, info) - if err != nil { - return +} + +func (s *spaceController) Process(md mode.Mode) mode.Process { + switch md { + case mode.ModeInitial: + return initial.New() + case mode.ModeOffloading: + return offloader.New(s.app) + default: + return &personalLoader{ + newLoader: s.newLoader, } } - s.app, err = makeStatusApp(s.app, s.spaceId) - if err != nil { - return - } - s.loader = s.newLoader() - return s.loader.Start(ctx) } func (s *spaceController) Mode() mode.Mode { - return mode.ModeLoading + return s.sm.GetMode() } func (s *spaceController) Current() any { - return s.loader + return s.sm.GetProcess() } func (s *spaceController) SpaceId() string { @@ -84,38 +139,81 @@ func (s *spaceController) SpaceId() string { } func (s *spaceController) newLoader() loader.Loader { + s.mx.Lock() + s.personalMigration = personalmigration.New() + s.mx.Unlock() return loader.New(s.app, loader.Params{ SpaceId: s.spaceId, IsPersonal: true, OwnerMetadata: s.metadata, + AdditionalComps: []app.Component{ + s.personalMigration, + }, }) } func (s *spaceController) Update() error { - return nil + s.mx.Lock() + status := s.status.GetPersistentStatus() + if s.lastUpdatedStatus == status { + s.mx.Unlock() + return nil + } + s.lastUpdatedStatus = status + s.mx.Unlock() + updateStatus := func(mode mode.Mode) error { + _, err := s.sm.ChangeMode(mode) + return err + } + switch status { + case spaceinfo.AccountStatusDeleted: + return updateStatus(mode.ModeOffloading) + default: + return updateStatus(mode.ModeLoading) + } } func (s *spaceController) SetPersistentInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) error { - return nil + err := s.status.SetPersistentInfo(info) + if err != nil { + return err + } + return s.Update() } func (s *spaceController) SetLocalInfo(ctx context.Context, info spaceinfo.SpaceLocalInfo) error { - return nil + return s.status.SetLocalInfo(info) } -func (s *spaceController) Close(ctx context.Context) error { - if s.loader == nil { - return nil +func (s *spaceController) Delete(ctx context.Context) error { + offloading, err := s.sm.ChangeMode(mode.ModeOffloading) + if err != nil { + return err } - loaderErr := s.loader.Close(ctx) - appErr := s.app.Close(ctx) - return multierr.Combine(loaderErr, appErr) + of := offloading.(offloader.Offloader) + return of.WaitOffload(ctx) +} + +func (s *spaceController) Close(ctx context.Context) error { + s.sm.Close() + // this closes status + return s.app.Close(ctx) } func (s *spaceController) GetStatus() spaceinfo.AccountStatus { - return spaceinfo.AccountStatusUnknown + return s.status.GetPersistentStatus() } func (s *spaceController) GetLocalStatus() spaceinfo.LocalStatus { - return spaceinfo.LocalStatusOk + return s.status.GetLocalStatus() +} + +func (s *spaceController) WaitMigrations(ctx context.Context) error { + s.mx.Lock() + if s.personalMigration == nil { + s.mx.Unlock() + return nil + } + s.mx.Unlock() + return s.personalMigration.WaitProfile(ctx) } diff --git a/space/internal/personalspace/personalloader.go b/space/internal/personalspace/personalloader.go new file mode 100644 index 0000000000..0ffabcacb3 --- /dev/null +++ b/space/internal/personalspace/personalloader.go @@ -0,0 +1,17 @@ +package personalspace + +import ( + "context" + + "github.com/anyproto/anytype-heart/space/internal/spaceprocess/loader" +) + +type personalLoader struct { + loader.Loader + newLoader func() loader.Loader +} + +func (p *personalLoader) Start(ctx context.Context) (err error) { + p.Loader = p.newLoader() + return p.Loader.Start(ctx) +} diff --git a/space/internal/shareablespace/shareable_test.go b/space/internal/shareablespace/shareable_test.go index 95d8963faa..b0c497f32f 100644 --- a/space/internal/shareablespace/shareable_test.go +++ b/space/internal/shareablespace/shareable_test.go @@ -133,6 +133,10 @@ func (s *spaceStatusStub) GetLocalStatus() spaceinfo.LocalStatus { return s.localStatus } +func (s *spaceStatusStub) SetOwner(ownerIdentity string, createdDate int64) (err error) { + return +} + func (s *spaceStatusStub) GetRemoteStatus() spaceinfo.RemoteStatus { s.Lock() defer s.Unlock() diff --git a/space/internal/spaceprocess/loader/loader.go b/space/internal/spaceprocess/loader/loader.go index a2f94cefee..df1ee77503 100644 --- a/space/internal/spaceprocess/loader/loader.go +++ b/space/internal/spaceprocess/loader/loader.go @@ -30,9 +30,10 @@ type Loader interface { } type Params struct { - SpaceId string - IsPersonal bool - OwnerMetadata []byte + SpaceId string + IsPersonal bool + OwnerMetadata []byte + AdditionalComps []app.Component } func New(app *app.App, params Params) Loader { @@ -44,6 +45,9 @@ func New(app *app.App, params Params) Loader { Register(invitemigrator.New()). Register(participantwatcher.New()). Register(migration.New()) + for _, comp := range params.AdditionalComps { + child.Register(comp) + } return &loader{ app: child, } diff --git a/space/load.go b/space/load.go index 88bcccf0ee..6c692265f4 100644 --- a/space/load.go +++ b/space/load.go @@ -74,7 +74,11 @@ func (s *service) startStatus(ctx context.Context, info spaceinfo.SpacePersisten wait: wait, } s.mu.Unlock() - ctrl, err = s.factory.NewShareableSpace(ctx, info.SpaceID, info) + if info.SpaceID == s.personalSpaceId { + ctrl, err = s.factory.NewPersonalSpace(ctx, s.accountMetadataPayload) + } else { + ctrl, err = s.factory.NewShareableSpace(ctx, info.SpaceID, info) + } s.mu.Lock() close(wait) if err != nil { @@ -101,28 +105,6 @@ func (s *service) waitLoad(ctx context.Context, ctrl spacecontroller.SpaceContro return nil, fmt.Errorf("failed to load space, mode is %d: %w", ctrl.Mode(), ErrFailedToLoad) } -func (s *service) loadPersonalSpace(ctx context.Context) (err error) { - s.mu.Lock() - wait := make(chan struct{}) - s.waiting[s.personalSpaceId] = controllerWaiter{ - wait: wait, - } - s.mu.Unlock() - ctrl, err := s.factory.NewPersonalSpace(ctx, s.accountMetadataPayload) - if err != nil { - return - } - _, err = ctrl.Current().(loader.LoadWaiter).WaitLoad(ctx) - s.mu.Lock() - defer s.mu.Unlock() - if err != nil { - return err - } - close(wait) - s.spaceControllers[s.personalSpaceId] = ctrl - return -} - func convertSpaceError(err error) error { switch { case errors.Is(err, spacesyncproto.ErrSpaceIsDeleted): diff --git a/space/mock_space/mock_NotificationSender.go b/space/mock_space/mock_NotificationSender.go new file mode 100644 index 0000000000..bcec9e549e --- /dev/null +++ b/space/mock_space/mock_NotificationSender.go @@ -0,0 +1,174 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_space + +import ( + app "github.com/anyproto/any-sync/app" + mock "github.com/stretchr/testify/mock" + + model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" +) + +// MockNotificationSender is an autogenerated mock type for the NotificationSender type +type MockNotificationSender struct { + mock.Mock +} + +type MockNotificationSender_Expecter struct { + mock *mock.Mock +} + +func (_m *MockNotificationSender) EXPECT() *MockNotificationSender_Expecter { + return &MockNotificationSender_Expecter{mock: &_m.Mock} +} + +// CreateAndSend provides a mock function with given fields: notification +func (_m *MockNotificationSender) CreateAndSend(notification *model.Notification) error { + ret := _m.Called(notification) + + if len(ret) == 0 { + panic("no return value specified for CreateAndSend") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*model.Notification) error); ok { + r0 = rf(notification) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockNotificationSender_CreateAndSend_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateAndSend' +type MockNotificationSender_CreateAndSend_Call struct { + *mock.Call +} + +// CreateAndSend is a helper method to define mock.On call +// - notification *model.Notification +func (_e *MockNotificationSender_Expecter) CreateAndSend(notification interface{}) *MockNotificationSender_CreateAndSend_Call { + return &MockNotificationSender_CreateAndSend_Call{Call: _e.mock.On("CreateAndSend", notification)} +} + +func (_c *MockNotificationSender_CreateAndSend_Call) Run(run func(notification *model.Notification)) *MockNotificationSender_CreateAndSend_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*model.Notification)) + }) + return _c +} + +func (_c *MockNotificationSender_CreateAndSend_Call) Return(_a0 error) *MockNotificationSender_CreateAndSend_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockNotificationSender_CreateAndSend_Call) RunAndReturn(run func(*model.Notification) error) *MockNotificationSender_CreateAndSend_Call { + _c.Call.Return(run) + return _c +} + +// Init provides a mock function with given fields: a +func (_m *MockNotificationSender) Init(a *app.App) error { + ret := _m.Called(a) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*app.App) error); ok { + r0 = rf(a) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockNotificationSender_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' +type MockNotificationSender_Init_Call struct { + *mock.Call +} + +// Init is a helper method to define mock.On call +// - a *app.App +func (_e *MockNotificationSender_Expecter) Init(a interface{}) *MockNotificationSender_Init_Call { + return &MockNotificationSender_Init_Call{Call: _e.mock.On("Init", a)} +} + +func (_c *MockNotificationSender_Init_Call) Run(run func(a *app.App)) *MockNotificationSender_Init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*app.App)) + }) + return _c +} + +func (_c *MockNotificationSender_Init_Call) Return(err error) *MockNotificationSender_Init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockNotificationSender_Init_Call) RunAndReturn(run func(*app.App) error) *MockNotificationSender_Init_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: +func (_m *MockNotificationSender) Name() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockNotificationSender_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockNotificationSender_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockNotificationSender_Expecter) Name() *MockNotificationSender_Name_Call { + return &MockNotificationSender_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockNotificationSender_Name_Call) Run(run func()) *MockNotificationSender_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockNotificationSender_Name_Call) Return(name string) *MockNotificationSender_Name_Call { + _c.Call.Return(name) + return _c +} + +func (_c *MockNotificationSender_Name_Call) RunAndReturn(run func() string) *MockNotificationSender_Name_Call { + _c.Call.Return(run) + return _c +} + +// NewMockNotificationSender creates a new instance of MockNotificationSender. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockNotificationSender(t interface { + mock.TestingT + Cleanup(func()) +}) *MockNotificationSender { + mock := &MockNotificationSender{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/space/mock_space/mock_Service.go b/space/mock_space/mock_Service.go index 0d2c54e189..6a38d0132c 100644 --- a/space/mock_space/mock_Service.go +++ b/space/mock_space/mock_Service.go @@ -632,6 +632,51 @@ func (_c *MockService_Name_Call) RunAndReturn(run func() string) *MockService_Na return _c } +// PersonalSpaceId provides a mock function with given fields: +func (_m *MockService) PersonalSpaceId() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for PersonalSpaceId") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockService_PersonalSpaceId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PersonalSpaceId' +type MockService_PersonalSpaceId_Call struct { + *mock.Call +} + +// PersonalSpaceId is a helper method to define mock.On call +func (_e *MockService_Expecter) PersonalSpaceId() *MockService_PersonalSpaceId_Call { + return &MockService_PersonalSpaceId_Call{Call: _e.mock.On("PersonalSpaceId")} +} + +func (_c *MockService_PersonalSpaceId_Call) Run(run func()) *MockService_PersonalSpaceId_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockService_PersonalSpaceId_Call) Return(_a0 string) *MockService_PersonalSpaceId_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockService_PersonalSpaceId_Call) RunAndReturn(run func() string) *MockService_PersonalSpaceId_Call { + _c.Call.Return(run) + return _c +} + // Run provides a mock function with given fields: ctx func (_m *MockService) Run(ctx context.Context) error { ret := _m.Called(ctx) @@ -885,6 +930,52 @@ func (_c *MockService_Wait_Call) RunAndReturn(run func(context.Context, string) return _c } +// WaitPersonalSpaceMigration provides a mock function with given fields: ctx +func (_m *MockService) WaitPersonalSpaceMigration(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for WaitPersonalSpaceMigration") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockService_WaitPersonalSpaceMigration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WaitPersonalSpaceMigration' +type MockService_WaitPersonalSpaceMigration_Call struct { + *mock.Call +} + +// WaitPersonalSpaceMigration is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockService_Expecter) WaitPersonalSpaceMigration(ctx interface{}) *MockService_WaitPersonalSpaceMigration_Call { + return &MockService_WaitPersonalSpaceMigration_Call{Call: _e.mock.On("WaitPersonalSpaceMigration", ctx)} +} + +func (_c *MockService_WaitPersonalSpaceMigration_Call) Run(run func(ctx context.Context)) *MockService_WaitPersonalSpaceMigration_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockService_WaitPersonalSpaceMigration_Call) Return(err error) *MockService_WaitPersonalSpaceMigration_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockService_WaitPersonalSpaceMigration_Call) RunAndReturn(run func(context.Context) error) *MockService_WaitPersonalSpaceMigration_Call { + _c.Call.Return(run) + return _c +} + // NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewMockService(t interface { diff --git a/space/mock_space/mock_coordinatorStatusUpdater.go b/space/mock_space/mock_coordinatorStatusUpdater.go new file mode 100644 index 0000000000..a9ae96625f --- /dev/null +++ b/space/mock_space/mock_coordinatorStatusUpdater.go @@ -0,0 +1,158 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_space + +import ( + app "github.com/anyproto/any-sync/app" + mock "github.com/stretchr/testify/mock" +) + +// MockcoordinatorStatusUpdater is an autogenerated mock type for the coordinatorStatusUpdater type +type MockcoordinatorStatusUpdater struct { + mock.Mock +} + +type MockcoordinatorStatusUpdater_Expecter struct { + mock *mock.Mock +} + +func (_m *MockcoordinatorStatusUpdater) EXPECT() *MockcoordinatorStatusUpdater_Expecter { + return &MockcoordinatorStatusUpdater_Expecter{mock: &_m.Mock} +} + +// Init provides a mock function with given fields: a +func (_m *MockcoordinatorStatusUpdater) Init(a *app.App) error { + ret := _m.Called(a) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*app.App) error); ok { + r0 = rf(a) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockcoordinatorStatusUpdater_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' +type MockcoordinatorStatusUpdater_Init_Call struct { + *mock.Call +} + +// Init is a helper method to define mock.On call +// - a *app.App +func (_e *MockcoordinatorStatusUpdater_Expecter) Init(a interface{}) *MockcoordinatorStatusUpdater_Init_Call { + return &MockcoordinatorStatusUpdater_Init_Call{Call: _e.mock.On("Init", a)} +} + +func (_c *MockcoordinatorStatusUpdater_Init_Call) Run(run func(a *app.App)) *MockcoordinatorStatusUpdater_Init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*app.App)) + }) + return _c +} + +func (_c *MockcoordinatorStatusUpdater_Init_Call) Return(err error) *MockcoordinatorStatusUpdater_Init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockcoordinatorStatusUpdater_Init_Call) RunAndReturn(run func(*app.App) error) *MockcoordinatorStatusUpdater_Init_Call { + _c.Call.Return(run) + return _c +} + +// Name provides a mock function with given fields: +func (_m *MockcoordinatorStatusUpdater) Name() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Name") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockcoordinatorStatusUpdater_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' +type MockcoordinatorStatusUpdater_Name_Call struct { + *mock.Call +} + +// Name is a helper method to define mock.On call +func (_e *MockcoordinatorStatusUpdater_Expecter) Name() *MockcoordinatorStatusUpdater_Name_Call { + return &MockcoordinatorStatusUpdater_Name_Call{Call: _e.mock.On("Name")} +} + +func (_c *MockcoordinatorStatusUpdater_Name_Call) Run(run func()) *MockcoordinatorStatusUpdater_Name_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockcoordinatorStatusUpdater_Name_Call) Return(name string) *MockcoordinatorStatusUpdater_Name_Call { + _c.Call.Return(name) + return _c +} + +func (_c *MockcoordinatorStatusUpdater_Name_Call) RunAndReturn(run func() string) *MockcoordinatorStatusUpdater_Name_Call { + _c.Call.Return(run) + return _c +} + +// UpdateCoordinatorStatus provides a mock function with given fields: +func (_m *MockcoordinatorStatusUpdater) UpdateCoordinatorStatus() { + _m.Called() +} + +// MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateCoordinatorStatus' +type MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call struct { + *mock.Call +} + +// UpdateCoordinatorStatus is a helper method to define mock.On call +func (_e *MockcoordinatorStatusUpdater_Expecter) UpdateCoordinatorStatus() *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call { + return &MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call{Call: _e.mock.On("UpdateCoordinatorStatus")} +} + +func (_c *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call) Run(run func()) *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call) Return() *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call { + _c.Call.Return() + return _c +} + +func (_c *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call) RunAndReturn(run func()) *MockcoordinatorStatusUpdater_UpdateCoordinatorStatus_Call { + _c.Call.Return(run) + return _c +} + +// NewMockcoordinatorStatusUpdater creates a new instance of MockcoordinatorStatusUpdater. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockcoordinatorStatusUpdater(t interface { + mock.TestingT + Cleanup(func()) +}) *MockcoordinatorStatusUpdater { + mock := &MockcoordinatorStatusUpdater{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/space/mock_space/mock_isNewAccount.go b/space/mock_space/mock_isNewAccount.go deleted file mode 100644 index 41978a30b3..0000000000 --- a/space/mock_space/mock_isNewAccount.go +++ /dev/null @@ -1,171 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_space - -import ( - app "github.com/anyproto/any-sync/app" - mock "github.com/stretchr/testify/mock" -) - -// MockisNewAccount is an autogenerated mock type for the isNewAccount type -type MockisNewAccount struct { - mock.Mock -} - -type MockisNewAccount_Expecter struct { - mock *mock.Mock -} - -func (_m *MockisNewAccount) EXPECT() *MockisNewAccount_Expecter { - return &MockisNewAccount_Expecter{mock: &_m.Mock} -} - -// Init provides a mock function with given fields: a -func (_m *MockisNewAccount) Init(a *app.App) error { - ret := _m.Called(a) - - if len(ret) == 0 { - panic("no return value specified for Init") - } - - var r0 error - if rf, ok := ret.Get(0).(func(*app.App) error); ok { - r0 = rf(a) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// MockisNewAccount_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' -type MockisNewAccount_Init_Call struct { - *mock.Call -} - -// Init is a helper method to define mock.On call -// - a *app.App -func (_e *MockisNewAccount_Expecter) Init(a interface{}) *MockisNewAccount_Init_Call { - return &MockisNewAccount_Init_Call{Call: _e.mock.On("Init", a)} -} - -func (_c *MockisNewAccount_Init_Call) Run(run func(a *app.App)) *MockisNewAccount_Init_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(*app.App)) - }) - return _c -} - -func (_c *MockisNewAccount_Init_Call) Return(err error) *MockisNewAccount_Init_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockisNewAccount_Init_Call) RunAndReturn(run func(*app.App) error) *MockisNewAccount_Init_Call { - _c.Call.Return(run) - return _c -} - -// IsNewAccount provides a mock function with given fields: -func (_m *MockisNewAccount) IsNewAccount() bool { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for IsNewAccount") - } - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// MockisNewAccount_IsNewAccount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsNewAccount' -type MockisNewAccount_IsNewAccount_Call struct { - *mock.Call -} - -// IsNewAccount is a helper method to define mock.On call -func (_e *MockisNewAccount_Expecter) IsNewAccount() *MockisNewAccount_IsNewAccount_Call { - return &MockisNewAccount_IsNewAccount_Call{Call: _e.mock.On("IsNewAccount")} -} - -func (_c *MockisNewAccount_IsNewAccount_Call) Run(run func()) *MockisNewAccount_IsNewAccount_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockisNewAccount_IsNewAccount_Call) Return(_a0 bool) *MockisNewAccount_IsNewAccount_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *MockisNewAccount_IsNewAccount_Call) RunAndReturn(run func() bool) *MockisNewAccount_IsNewAccount_Call { - _c.Call.Return(run) - return _c -} - -// Name provides a mock function with given fields: -func (_m *MockisNewAccount) Name() string { - ret := _m.Called() - - if len(ret) == 0 { - panic("no return value specified for Name") - } - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// MockisNewAccount_Name_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Name' -type MockisNewAccount_Name_Call struct { - *mock.Call -} - -// Name is a helper method to define mock.On call -func (_e *MockisNewAccount_Expecter) Name() *MockisNewAccount_Name_Call { - return &MockisNewAccount_Name_Call{Call: _e.mock.On("Name")} -} - -func (_c *MockisNewAccount_Name_Call) Run(run func()) *MockisNewAccount_Name_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockisNewAccount_Name_Call) Return(name string) *MockisNewAccount_Name_Call { - _c.Call.Return(name) - return _c -} - -func (_c *MockisNewAccount_Name_Call) RunAndReturn(run func() string) *MockisNewAccount_Name_Call { - _c.Call.Return(run) - return _c -} - -// NewMockisNewAccount creates a new instance of MockisNewAccount. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewMockisNewAccount(t interface { - mock.TestingT - Cleanup(func()) -}) *MockisNewAccount { - mock := &MockisNewAccount{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/space/service.go b/space/service.go index 7b43b370d7..8dd1f843d9 100644 --- a/space/service.go +++ b/space/service.go @@ -23,6 +23,7 @@ import ( "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/space/clientspace" + "github.com/anyproto/anytype-heart/space/internal/personalspace" "github.com/anyproto/anytype-heart/space/internal/spacecontroller" "github.com/anyproto/anytype-heart/space/spacecore" "github.com/anyproto/anytype-heart/space/spacefactory" @@ -34,7 +35,10 @@ const CName = "client.space" var log = logger.NewNamed(CName) -var waitSpaceDelay = 500 * time.Millisecond +var ( + waitSpaceDelay = 500 * time.Millisecond + loadTechSpaceDeadline = 15 * time.Second +) var ( ErrIncorrectSpaceID = errors.New("incorrect space id") @@ -49,11 +53,6 @@ func New() Service { return &service{} } -type isNewAccount interface { - IsNewAccount() bool - app.Component -} - type Service interface { Create(ctx context.Context) (space clientspace.Space, err error) @@ -63,21 +62,24 @@ type Service interface { Wait(ctx context.Context, spaceId string) (sp clientspace.Space, err error) Delete(ctx context.Context, id string) (err error) TechSpaceId() string + PersonalSpaceId() string TechSpace() *clientspace.TechSpace GetPersonalSpace(ctx context.Context) (space clientspace.Space, err error) GetTechSpace(ctx context.Context) (space clientspace.Space, err error) SpaceViewId(spaceId string) (spaceViewId string, err error) AccountMetadataSymKey() crypto.SymKey AccountMetadataPayload() []byte - + WaitPersonalSpaceMigration(ctx context.Context) (err error) app.ComponentRunnable } type coordinatorStatusUpdater interface { + app.Component UpdateCoordinatorStatus() } type NotificationSender interface { + app.Component CreateAndSend(notification *model.Notification) error } @@ -130,13 +132,15 @@ func (s *service) TechSpace() *clientspace.TechSpace { } func (s *service) Init(a *app.App) (err error) { - s.newAccount = app.MustComponent[isNewAccount](a).IsNewAccount() s.factory = app.MustComponent[spacefactory.SpaceFactory](a) s.spaceCore = app.MustComponent[spacecore.SpaceCoreService](a) s.accountService = app.MustComponent[accountservice.Service](a) s.config = app.MustComponent[*config.Config](a) + s.newAccount = s.config.IsNewAccount() s.spaceControllers = make(map[string]spacecontroller.SpaceController) s.updater = app.MustComponent[coordinatorStatusUpdater](a) + s.notificationService = app.MustComponent[NotificationSender](a) + s.spaceNameGetter = app.MustComponent[objectstore.SpaceNameGetter](a) s.waiting = make(map[string]controllerWaiter) s.techSpaceReady = make(chan struct{}) s.personalSpaceId, err = s.spaceCore.DeriveID(context.Background(), spacecore.SpaceType) @@ -159,8 +163,6 @@ func (s *service) Init(a *app.App) (err error) { s.repKey, err = getRepKey(s.personalSpaceId) s.ctx, s.ctxCancel = context.WithCancel(context.Background()) - s.notificationService = app.MustComponent[NotificationSender](a) - s.spaceNameGetter = app.MustComponent[objectstore.SpaceNameGetter](a) return err } @@ -169,15 +171,112 @@ func (s *service) Name() (name string) { } func (s *service) Run(ctx context.Context) (err error) { + defer s.updater.UpdateCoordinatorStatus() + if s.newAccount { + return s.createAccount(ctx) + } + return s.initAccount(ctx) +} + +func (s *service) createTechSpaceForOldAccounts(ctx context.Context) (err error) { + // check if we have a personal space + _, err = s.spaceCore.Get(ctx, s.personalSpaceId) + if err != nil { + // then we don't have a personal space, so we have nothing, sorry, there is no point in creating tech space + return fmt.Errorf("init tech space: %w", err) + } + // this is an old account + err = s.createTechSpace(ctx) + if err != nil { + return fmt.Errorf("init tech space: %w", err) + } + // skipping check for space view because we don't have it + ctx = context.WithValue(ctx, personalspace.SkipCheckSpaceViewKey, true) + _, err = s.startStatus(ctx, spaceinfo.NewSpacePersistentInfo(s.personalSpaceId)) + if err != nil { + return fmt.Errorf("start personal space: %w", err) + } + return nil +} + +func (s *service) initAccount(ctx context.Context) (err error) { err = s.initMarketplaceSpace(ctx) if err != nil { return fmt.Errorf("init marketplace space: %w", err) } - err = s.initTechSpace(ctx) + timeoutCtx, cancel := context.WithTimeout(ctx, loadTechSpaceDeadline) + err = s.loadTechSpace(timeoutCtx) + cancel() + // this crazy logic is needed if the person is restoring the old account locally with no connection and no tech space + // nolint:nestif + if errors.Is(err, context.DeadlineExceeded) { + var personalExists bool + // checking if personal space exists locally + personalExists, err = s.spaceCore.StorageExistsLocally(ctx, s.personalSpaceId) + if err != nil { + return fmt.Errorf("check personal space: %w", err) + } + // ok no space locally, then we have to get a reply from server to know if we have a tech space + if !personalExists { + // trying again to load space with normal ctx + err = s.loadTechSpace(ctx) + } else { + // personal exists, then we have to create tech space + err = s.createTechSpaceForOldAccounts(ctx) + if err != nil { + return fmt.Errorf("create tech space for old accounts: %w", err) + } + } + } + if err != nil && !errors.Is(err, spacesyncproto.ErrSpaceMissing) { + return fmt.Errorf("init tech space: %w", err) + } + // nolint:nestif + if errors.Is(err, spacesyncproto.ErrSpaceMissing) { + // no tech space on nodes, this is our only chance + err = s.createTechSpaceForOldAccounts(ctx) + if err != nil { + return fmt.Errorf("create tech space for old accounts: %w", err) + } + } else { + var id string + // have we migrated analytics id? we should have it in account object + err = s.techSpace.DoAccountObject(ctx, func(accountObject techspace.AccountObject) error { + id, err = accountObject.GetAnalyticsId() + return err + }) + // this error can arise only from database issues + if err != nil { + return fmt.Errorf("get analytics id: %w", err) + } + // we still didn't migrate analytics id, then there is a chance that space view was not created for old accounts + if id == "" { + // creating a space view under the hood + _, err = s.startStatus(ctx, spaceinfo.NewSpacePersistentInfo(s.personalSpaceId)) + if err != nil { + return fmt.Errorf("start personal space: %w", err) + } + } + } + s.techSpace.WakeUpViews() + // only persist networkId after successful space init + err = s.config.PersistAccountNetworkId() + if err != nil { + log.Error("persist network id to config", zap.Error(err)) + } + return nil +} + +func (s *service) createAccount(ctx context.Context) (err error) { + err = s.initMarketplaceSpace(ctx) + if err != nil { + return fmt.Errorf("init marketplace space: %w", err) + } + err = s.createTechSpace(ctx) if err != nil { return fmt.Errorf("init tech space: %w", err) } - err = s.initPersonalSpace(ctx) + err = s.createPersonalSpace(ctx) if err != nil { if errors.Is(err, spacesyncproto.ErrSpaceMissing) || errors.Is(err, treechangeproto.ErrGetTree) { err = ErrSpaceNotExists @@ -210,6 +309,18 @@ func (s *service) Wait(ctx context.Context, spaceId string) (sp clientspace.Spac return waiter.waitSpace(ctx, spaceId) } +func (s *service) WaitPersonalSpaceMigration(ctx context.Context) (err error) { + waiter := newSpaceWaiter(s, s.ctx, waitSpaceDelay) + _, err = waiter.waitSpace(ctx, s.personalSpaceId) + if err != nil { + return fmt.Errorf("wait personal space: %w", err) + } + s.mu.Lock() + ctrl := s.spaceControllers[s.personalSpaceId] + s.mu.Unlock() + return ctrl.(personalspace.Personal).WaitMigrations(ctx) +} + func (s *service) Get(ctx context.Context, spaceId string) (sp clientspace.Space, err error) { if spaceId == s.techSpaceId { return s.getTechSpace(ctx) @@ -222,8 +333,8 @@ func (s *service) Get(ctx context.Context, spaceId string) (sp clientspace.Space } func (s *service) UpdateSharedLimits(ctx context.Context, limits int) error { - return s.techSpace.DoSpaceView(ctx, s.personalSpaceId, func(spaceView techspace.SpaceView) error { - return spaceView.SetSharedSpacesLimit(limits) + return s.techSpace.DoAccountObject(ctx, func(accObj techspace.AccountObject) error { + return accObj.SetSharedSpacesLimit(limits) }) } @@ -331,12 +442,18 @@ func (s *service) Close(ctx context.Context) error { } s.mu.Unlock() + wg := sync.WaitGroup{} for _, ctrl := range ctrls { - err := ctrl.Close(ctx) - if err != nil { - log.Error("close space", zap.String("spaceId", ctrl.SpaceId()), zap.Error(err)) - } + wg.Add(1) + go func(ctrl spacecontroller.SpaceController) { + defer wg.Done() + err := ctrl.Close(ctx) + if err != nil { + log.Error("close space", zap.String("spaceId", ctrl.SpaceId()), zap.Error(err)) + } + }(ctrl) } + wg.Wait() err := s.techSpace.Close(ctx) if err != nil { log.Error("close tech space", zap.Error(err)) diff --git a/space/service_test.go b/space/service_test.go index 7888109bbc..c7469445b9 100644 --- a/space/service_test.go +++ b/space/service_test.go @@ -2,15 +2,16 @@ package space import ( "context" - "fmt" + "os" "strings" "testing" "time" - "github.com/anyproto/any-sync/accountservice/mock_accountservice" "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/commonspace/object/accountdata" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/coordinator/coordinatorclient/mock_coordinatorclient" + "github.com/anyproto/any-sync/testutil/accounttest" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -21,7 +22,6 @@ import ( "github.com/anyproto/anytype-heart/core/domain" "github.com/anyproto/anytype-heart/core/notifications/mock_notifications" "github.com/anyproto/anytype-heart/core/wallet/mock_wallet" - "github.com/anyproto/anytype-heart/pb" "github.com/anyproto/anytype-heart/pkg/lib/bundle" "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" @@ -29,7 +29,8 @@ import ( "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" "github.com/anyproto/anytype-heart/space/internal/spacecontroller" "github.com/anyproto/anytype-heart/space/internal/spacecontroller/mock_spacecontroller" - "github.com/anyproto/anytype-heart/space/internal/spaceprocess/mode" + "github.com/anyproto/anytype-heart/space/mock_space" + "github.com/anyproto/anytype-heart/space/spacecore" "github.com/anyproto/anytype-heart/space/spacecore/mock_spacecore" "github.com/anyproto/anytype-heart/space/spacefactory/mock_spacefactory" "github.com/anyproto/anytype-heart/space/spaceinfo" @@ -64,22 +65,84 @@ func TestService_Init(t *testing.T) { ctx2, ctxCancel2 := context.WithTimeout(context.Background(), time.Millisecond) defer ctxCancel2() - factory.EXPECT().CreateAndSetTechSpace(ctx2).Return(&clientspace.TechSpace{}, nil) - require.NoError(t, serv.initTechSpace(ctx2)) + factory.EXPECT().LoadAndSetTechSpace(ctx2).Return(&clientspace.TechSpace{}, nil) + require.NoError(t, serv.loadTechSpace(ctx2)) s, err := serv.Get(ctx2, serv.techSpaceId) require.NoError(t, err) assert.NotNil(t, s) }) - t.Run("existing account", func(t *testing.T) { - t.Skip("@roman should revive this test") - fx := newFixture(t, false) - defer fx.finish(t) - }) t.Run("new account", func(t *testing.T) { - t.Skip("@roman should revive this test") - fx := newFixture(t, true) - defer fx.finish(t) + newFixture(t, nil) + }) + t.Run("old account, analytics id migrated", func(t *testing.T) { + newFixture(t, func(t *testing.T, fx *fixture) { + fx.factory.EXPECT().LoadAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + accObject := mock_techspace.NewMockAccountObject(t) + accObject.EXPECT().GetAnalyticsId().Return("analyticsId", nil) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(accObject) + }) + fx.techSpace.EXPECT().WakeUpViews() + }) + }) + t.Run("old account, analytics id not migrated", func(t *testing.T) { + newFixture(t, func(t *testing.T, fx *fixture) { + fx.factory.EXPECT().LoadAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + accObject := mock_techspace.NewMockAccountObject(t) + accObject.EXPECT().GetAnalyticsId().Return("", nil) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(accObject) + }) + prCtrl := mock_spacecontroller.NewMockSpaceController(t) + fx.factory.EXPECT().NewPersonalSpace(mock.Anything, mock.Anything).Return(prCtrl, nil) + prCtrl.EXPECT().Close(mock.Anything).Return(nil) + fx.techSpace.EXPECT().WakeUpViews() + }) + }) + t.Run("old account, no internet, then internet appeared", func(t *testing.T) { + newFixture(t, func(t *testing.T, fx *fixture) { + fx.factory.EXPECT().LoadAndSetTechSpace(mock.Anything).Return(nil, context.DeadlineExceeded).Times(1) + fx.spaceCore.EXPECT().StorageExistsLocally(mock.Anything, fx.spaceId).Return(false, nil) + fx.factory.EXPECT().LoadAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + accObject := mock_techspace.NewMockAccountObject(t) + accObject.EXPECT().GetAnalyticsId().Return("", nil) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(accObject) + }) + prCtrl := mock_spacecontroller.NewMockSpaceController(t) + fx.factory.EXPECT().NewPersonalSpace(mock.Anything, mock.Anything).Return(prCtrl, nil) + prCtrl.EXPECT().Close(mock.Anything).Return(nil) + fx.techSpace.EXPECT().WakeUpViews() + }) + }) + t.Run("old account, no internet, but personal space exists", func(t *testing.T) { + newFixture(t, func(t *testing.T, fx *fixture) { + fx.factory.EXPECT().LoadAndSetTechSpace(mock.Anything).Return(nil, context.DeadlineExceeded).Times(1) + fx.spaceCore.EXPECT().StorageExistsLocally(mock.Anything, fx.spaceId).Return(true, nil) + fx.spaceCore.EXPECT().Get(mock.Anything, fx.spaceId).Return(nil, nil) + fx.factory.EXPECT().CreateAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + prCtrl := mock_spacecontroller.NewMockSpaceController(t) + fx.factory.EXPECT().NewPersonalSpace(mock.Anything, mock.Anything).Return(prCtrl, nil) + prCtrl.EXPECT().Close(mock.Anything).Return(nil) + accObject := mock_techspace.NewMockAccountObject(t) + accObject.EXPECT().GetAnalyticsId().Return("", nil) + fx.techSpace.EXPECT().DoAccountObject(mock.Anything, mock.Anything).RunAndReturn(func(ctx2 context.Context, f func(techspace.AccountObject) error) error { + return f(accObject) + }) + fx.techSpace.EXPECT().WakeUpViews() + }) + }) + t.Run("very old account without tech space", func(t *testing.T) { + newFixture(t, func(t *testing.T, fx *fixture) { + fx.factory.EXPECT().LoadAndSetTechSpace(mock.Anything).Return(nil, spacesyncproto.ErrSpaceMissing) + fx.spaceCore.EXPECT().Get(mock.Anything, fx.spaceId).Return(nil, nil) + fx.factory.EXPECT().CreateAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: fx.techSpace}, nil) + prCtrl := mock_spacecontroller.NewMockSpaceController(t) + fx.factory.EXPECT().NewPersonalSpace(mock.Anything, mock.Anything).Return(prCtrl, nil) + prCtrl.EXPECT().Close(mock.Anything).Return(nil) + fx.techSpace.EXPECT().WakeUpViews() + }) }) } @@ -210,7 +273,7 @@ func TestService_UpdateRemoteStatus(t *testing.T) { }).Return(nil) storeFixture := objectstore.NewStoreFixture(t) - storeFixture.AddObjects(t, []objectstore.TestObject{map[domain.RelationKey]*types.Value{ + storeFixture.AddObjects(t, storeFixture.TechSpaceId(), []objectstore.TestObject{map[domain.RelationKey]*types.Value{ bundle.RelationKeyLayout: pbtypes.Int64(int64(model.ObjectType_spaceView)), bundle.RelationKeyId: pbtypes.String("spaceViewId"), bundle.RelationKeyTargetSpaceId: pbtypes.String(spaceID), @@ -240,12 +303,12 @@ func TestService_UpdateSharedLimits(t *testing.T) { personalSpaceId: "spaceId", techSpace: &clientspace.TechSpace{TechSpace: mockTechSpace}, } - mockSpaceView := mock_techspace.NewMockSpaceView(t) - mockTechSpace.EXPECT().DoSpaceView(ctx, "spaceId", mock.Anything).RunAndReturn( - func(ctx context.Context, spaceId string, f func(view techspace.SpaceView) error) error { - return f(mockSpaceView) + mockAccountObject := mock_techspace.NewMockAccountObject(t) + mockTechSpace.EXPECT().DoAccountObject(ctx, mock.Anything).RunAndReturn( + func(ctx context.Context, f func(view techspace.AccountObject) error) error { + return f(mockAccountObject) }) - mockSpaceView.EXPECT().SetSharedSpacesLimit(10).Return(nil) + mockAccountObject.EXPECT().SetSharedSpacesLimit(10).Return(nil) // when err := s.UpdateSharedLimits(ctx, 10) @@ -255,52 +318,66 @@ func TestService_UpdateSharedLimits(t *testing.T) { }) } -func newFixture(t *testing.T, newAccount bool) *fixture { +func newFixture(t *testing.T, expectOldAccount func(t *testing.T, fx *fixture)) *fixture { ctrl := gomock.NewController(t) fx := &fixture{ - service: New().(*service), - a: new(app.App), - ctrl: ctrl, - spaceCore: mock_spacecore.NewMockSpaceCoreService(t), - accountService: mock_accountservice.NewMockService(ctrl), - coordClient: mock_coordinatorclient.NewMockCoordinatorClient(ctrl), - factory: mock_spacefactory.NewMockSpaceFactory(t), - isNewAccount: NewMockisNewAccount(t), - objectStore: objectstore.NewStoreFixture(t), + spaceId: "bafyreifhyhdwrhwc23yi52w42osr4erqhiu2domqd3vwnngdee23kulpre.3aop5yrnf383q", + service: New().(*service), + a: new(app.App), + ctrl: ctrl, + spaceCore: mock_spacecore.NewMockSpaceCoreService(t), + coordClient: mock_coordinatorclient.NewMockCoordinatorClient(ctrl), + factory: mock_spacefactory.NewMockSpaceFactory(t), + notificationSender: mock_space.NewMockNotificationSender(t), + objectStore: objectstore.NewStoreFixture(t), + updater: mock_space.NewMockcoordinatorStatusUpdater(t), + config: config.New(config.WithNewAccount(expectOldAccount == nil)), } + keys, err := accountdata.NewRandom() + require.NoError(t, err) + fx.config.PeferYamuxTransport = true wallet := mock_wallet.NewMockWallet(t) - wallet.EXPECT().RepoPath().Return("repo/path") + path, err := os.MkdirTemp("", "repo") + require.NoError(t, err) + defer os.RemoveAll(path) + wallet.EXPECT().Account().Return(keys) + wallet.EXPECT().RepoPath().Return(path) - fx.a.Register(testutil.PrepareMock(ctx, fx.a, fx.spaceCore)). + fx.a. + Register(testutil.PrepareMock(ctx, fx.a, wallet)). + Register(fx.config). + Register(testutil.PrepareMock(ctx, fx.a, fx.notificationSender)). + Register(testutil.PrepareMock(ctx, fx.a, fx.updater)). + Register(testutil.PrepareMock(ctx, fx.a, fx.spaceCore)). Register(testutil.PrepareMock(ctx, fx.a, fx.coordClient)). - Register(testutil.PrepareMock(ctx, fx.a, fx.accountService)). - Register(testutil.PrepareMock(ctx, fx.a, fx.isNewAccount)). Register(testutil.PrepareMock(ctx, fx.a, fx.factory)). Register(testutil.PrepareMock(ctx, fx.a, mock_notifications.NewMockNotifications(t))). - Register(testutil.PrepareMock(ctx, fx.a, wallet)). - Register(&config.Config{DisableFileConfig: true, NetworkMode: pb.RpcAccount_LocalOnly, PeferYamuxTransport: true}). Register(fx.objectStore). Register(fx.service) - fx.isNewAccount.EXPECT().IsNewAccount().Return(newAccount) - fx.spaceCore.EXPECT().DeriveID(mock.Anything, mock.Anything).Return(testPersonalSpaceID, nil) - fx.accountService.EXPECT().Account().Return(&accountdata.AccountKeys{}) - fx.expectRun(t, newAccount) + fx.expectRun(t, expectOldAccount) require.NoError(t, fx.a.Start(ctx)) - + t.Cleanup(func() { + require.NoError(t, fx.a.Close(ctx)) + }) return fx } type fixture struct { *service - a *app.App - factory *mock_spacefactory.MockSpaceFactory - spaceCore *mock_spacecore.MockSpaceCoreService - accountService *mock_accountservice.MockService - coordClient *mock_coordinatorclient.MockCoordinatorClient - ctrl *gomock.Controller - isNewAccount *MockisNewAccount - objectStore *objectstore.StoreFixture + spaceId string + a *app.App + config *config.Config + factory *mock_spacefactory.MockSpaceFactory + spaceCore *mock_spacecore.MockSpaceCoreService + updater *mock_space.MockcoordinatorStatusUpdater + notificationSender *mock_space.MockNotificationSender + accountService *accounttest.AccountTestService + coordClient *mock_coordinatorclient.MockCoordinatorClient + ctrl *gomock.Controller + techSpace *mock_techspace.MockTechSpace + clientSpace *mock_clientspace.MockSpace + objectStore *objectstore.StoreFixture } type lwMock struct { @@ -311,28 +388,29 @@ func (l lwMock) WaitLoad(ctx context.Context) (sp clientspace.Space, err error) return l.sp, nil } -func (fx *fixture) expectRun(t *testing.T, newAccount bool) { +func (fx *fixture) expectRun(t *testing.T, expectOldAccount func(t *testing.T, fx *fixture)) { + fx.spaceCore.EXPECT().DeriveID(mock.Anything, spacecore.SpaceType).Return(fx.spaceId, nil).Times(1) + fx.spaceCore.EXPECT().DeriveID(mock.Anything, spacecore.TechSpaceType).Return("techSpaceId", nil).Times(1) + fx.updater.EXPECT().UpdateCoordinatorStatus() clientSpace := mock_clientspace.NewMockSpace(t) mpCtrl := mock_spacecontroller.NewMockSpaceController(t) fx.factory.EXPECT().CreateMarketplaceSpace(mock.Anything).Return(mpCtrl, nil) mpCtrl.EXPECT().Start(mock.Anything).Return(nil) + mpCtrl.EXPECT().Close(mock.Anything).Return(nil) ts := mock_techspace.NewMockTechSpace(t) - fx.factory.EXPECT().CreateAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: ts}, nil) - prCtrl := mock_spacecontroller.NewMockSpaceController(t) - fx.coordClient.EXPECT().StatusCheckMany(gomock.Any(), gomock.Any()).AnyTimes().Return(nil, fmt.Errorf("test not check statuses")) - if newAccount { + fx.techSpace = ts + fx.clientSpace = clientSpace + if expectOldAccount == nil { + fx.factory.EXPECT().CreateAndSetTechSpace(mock.Anything).Return(&clientspace.TechSpace{TechSpace: ts}, nil) + prCtrl := mock_spacecontroller.NewMockSpaceController(t) fx.factory.EXPECT().CreatePersonalSpace(mock.Anything, mock.Anything).Return(prCtrl, nil) lw := lwMock{clientSpace} prCtrl.EXPECT().Current().Return(lw) + prCtrl.EXPECT().Close(mock.Anything).Return(nil) + ts.EXPECT().WakeUpViews() } else { - fx.factory.EXPECT().NewPersonalSpace(mock.Anything, mock.Anything).Return(prCtrl, nil) - lw := lwMock{clientSpace} - prCtrl.EXPECT().Current().Return(lw) + expectOldAccount(t, fx) } - prCtrl.EXPECT().Mode().Return(mode.ModeLoading) - ts.EXPECT().Close(mock.Anything).Return(nil) - mpCtrl.EXPECT().Close(mock.Anything).Return(nil) - prCtrl.EXPECT().Close(mock.Anything).Return(nil) return } diff --git a/space/spacecore/mock_spacecore/mock_SpaceCoreService.go b/space/spacecore/mock_spacecore/mock_SpaceCoreService.go index e430e49b70..144a4634eb 100644 --- a/space/spacecore/mock_spacecore/mock_SpaceCoreService.go +++ b/space/spacecore/mock_spacecore/mock_SpaceCoreService.go @@ -10,8 +10,6 @@ import ( mock "github.com/stretchr/testify/mock" spacecore "github.com/anyproto/anytype-heart/space/spacecore" - - streampool "github.com/anyproto/any-sync/net/streampool" ) // MockSpaceCoreService is an autogenerated mock type for the SpaceCoreService type @@ -180,9 +178,9 @@ func (_c *MockSpaceCoreService_Create_Call) RunAndReturn(run func(context.Contex return _c } -// Delete provides a mock function with given fields: ctx, spaceID -func (_m *MockSpaceCoreService) Delete(ctx context.Context, spaceID string) error { - ret := _m.Called(ctx, spaceID) +// Delete provides a mock function with given fields: ctx, spaceId +func (_m *MockSpaceCoreService) Delete(ctx context.Context, spaceId string) error { + ret := _m.Called(ctx, spaceId) if len(ret) == 0 { panic("no return value specified for Delete") @@ -190,7 +188,7 @@ func (_m *MockSpaceCoreService) Delete(ctx context.Context, spaceID string) erro var r0 error if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = rf(ctx, spaceID) + r0 = rf(ctx, spaceId) } else { r0 = ret.Error(0) } @@ -205,12 +203,12 @@ type MockSpaceCoreService_Delete_Call struct { // Delete is a helper method to define mock.On call // - ctx context.Context -// - spaceID string -func (_e *MockSpaceCoreService_Expecter) Delete(ctx interface{}, spaceID interface{}) *MockSpaceCoreService_Delete_Call { - return &MockSpaceCoreService_Delete_Call{Call: _e.mock.On("Delete", ctx, spaceID)} +// - spaceId string +func (_e *MockSpaceCoreService_Expecter) Delete(ctx interface{}, spaceId interface{}) *MockSpaceCoreService_Delete_Call { + return &MockSpaceCoreService_Delete_Call{Call: _e.mock.On("Delete", ctx, spaceId)} } -func (_c *MockSpaceCoreService_Delete_Call) Run(run func(ctx context.Context, spaceID string)) *MockSpaceCoreService_Delete_Call { +func (_c *MockSpaceCoreService_Delete_Call) Run(run func(ctx context.Context, spaceId string)) *MockSpaceCoreService_Delete_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(string)) }) @@ -598,49 +596,59 @@ func (_c *MockSpaceCoreService_Run_Call) RunAndReturn(run func(context.Context) return _c } -// StreamPool provides a mock function with given fields: -func (_m *MockSpaceCoreService) StreamPool() streampool.StreamPool { - ret := _m.Called() +// StorageExistsLocally provides a mock function with given fields: ctx, spaceId +func (_m *MockSpaceCoreService) StorageExistsLocally(ctx context.Context, spaceId string) (bool, error) { + ret := _m.Called(ctx, spaceId) if len(ret) == 0 { - panic("no return value specified for StreamPool") + panic("no return value specified for StorageExistsLocally") } - var r0 streampool.StreamPool - if rf, ok := ret.Get(0).(func() streampool.StreamPool); ok { - r0 = rf() + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok { + return rf(ctx, spaceId) + } + if rf, ok := ret.Get(0).(func(context.Context, string) bool); ok { + r0 = rf(ctx, spaceId) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(streampool.StreamPool) - } + r0 = ret.Get(0).(bool) } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, spaceId) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// MockSpaceCoreService_StreamPool_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StreamPool' -type MockSpaceCoreService_StreamPool_Call struct { +// MockSpaceCoreService_StorageExistsLocally_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StorageExistsLocally' +type MockSpaceCoreService_StorageExistsLocally_Call struct { *mock.Call } -// StreamPool is a helper method to define mock.On call -func (_e *MockSpaceCoreService_Expecter) StreamPool() *MockSpaceCoreService_StreamPool_Call { - return &MockSpaceCoreService_StreamPool_Call{Call: _e.mock.On("StreamPool")} +// StorageExistsLocally is a helper method to define mock.On call +// - ctx context.Context +// - spaceId string +func (_e *MockSpaceCoreService_Expecter) StorageExistsLocally(ctx interface{}, spaceId interface{}) *MockSpaceCoreService_StorageExistsLocally_Call { + return &MockSpaceCoreService_StorageExistsLocally_Call{Call: _e.mock.On("StorageExistsLocally", ctx, spaceId)} } -func (_c *MockSpaceCoreService_StreamPool_Call) Run(run func()) *MockSpaceCoreService_StreamPool_Call { +func (_c *MockSpaceCoreService_StorageExistsLocally_Call) Run(run func(ctx context.Context, spaceId string)) *MockSpaceCoreService_StorageExistsLocally_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context), args[1].(string)) }) return _c } -func (_c *MockSpaceCoreService_StreamPool_Call) Return(_a0 streampool.StreamPool) *MockSpaceCoreService_StreamPool_Call { - _c.Call.Return(_a0) +func (_c *MockSpaceCoreService_StorageExistsLocally_Call) Return(exists bool, err error) *MockSpaceCoreService_StorageExistsLocally_Call { + _c.Call.Return(exists, err) return _c } -func (_c *MockSpaceCoreService_StreamPool_Call) RunAndReturn(run func() streampool.StreamPool) *MockSpaceCoreService_StreamPool_Call { +func (_c *MockSpaceCoreService_StorageExistsLocally_Call) RunAndReturn(run func(context.Context, string) (bool, error)) *MockSpaceCoreService_StorageExistsLocally_Call { _c.Call.Return(run) return _c } diff --git a/space/spacecore/peermanager/manager.go b/space/spacecore/peermanager/manager.go index b68ee8afdf..426ecc7ca1 100644 --- a/space/spacecore/peermanager/manager.go +++ b/space/spacecore/peermanager/manager.go @@ -9,9 +9,11 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" + "github.com/anyproto/any-sync/net/streampool" + "storj.io/drpc" + //nolint:misspell "github.com/anyproto/any-sync/commonspace/peermanager" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" "github.com/anyproto/any-sync/net/peer" "go.uber.org/zap" @@ -54,6 +56,7 @@ type clientPeerManager struct { availableResponsiblePeers chan struct{} nodeStatus NodeStatus spaceSyncService Updater + streamPool streampool.StreamPool ctx context.Context ctxCancel context.CancelFunc @@ -69,6 +72,7 @@ func (n *clientPeerManager) Init(a *app.App) (err error) { n.watchingPeers = make(map[string]struct{}) n.availableResponsiblePeers = make(chan struct{}) n.nodeStatus = app.MustComponent[NodeStatus](a) + n.streamPool = app.MustComponent[streampool.StreamPool](a) n.spaceSyncService = app.MustComponent[Updater](a) n.peerToPeerStatus = app.MustComponent[PeerToPeerStatus](a) return @@ -92,25 +96,21 @@ func (n *clientPeerManager) GetNodePeers(ctx context.Context) (peers []peer.Peer return } -func (n *clientPeerManager) SendPeer(ctx context.Context, peerId string, msg *spacesyncproto.ObjectSyncMessage) (err error) { - // TODO: peer manager will be changed to not have this possibility - // use context.Background() - // - // explanation: +func (n *clientPeerManager) BroadcastMessage(ctx context.Context, msg drpc.Message) (err error) { // the context which comes here should not be used. It can be cancelled and thus kill the stream, - // because the stream will be opened with this context + // because the stream can be opened with this context ctx = logger.CtxWithFields(context.Background(), logger.CtxGetFields(ctx)...) - return n.p.streamPool.Send(ctx, msg, func(ctx context.Context) (peers []peer.Peer, err error) { - return n.getExactPeer(ctx, peerId) + return n.streamPool.Send(ctx, msg, func(ctx context.Context) (peers []peer.Peer, err error) { + return n.getStreamResponsiblePeers(ctx) }) } -func (n *clientPeerManager) Broadcast(ctx context.Context, msg *spacesyncproto.ObjectSyncMessage) (err error) { +func (n *clientPeerManager) SendMessage(ctx context.Context, peerId string, msg drpc.Message) (err error) { // the context which comes here should not be used. It can be cancelled and thus kill the stream, // because the stream can be opened with this context ctx = logger.CtxWithFields(context.Background(), logger.CtxGetFields(ctx)...) - return n.p.streamPool.Send(ctx, msg, func(ctx context.Context) (peers []peer.Peer, err error) { - return n.getStreamResponsiblePeers(ctx) + return n.streamPool.Send(ctx, msg, func(ctx context.Context) (peers []peer.Peer, err error) { + return n.getExactPeer(ctx, peerId) }) } diff --git a/space/spacecore/peermanager/provider.go b/space/spacecore/peermanager/provider.go index 15cc5f4655..120c38cb2c 100644 --- a/space/spacecore/peermanager/provider.go +++ b/space/spacecore/peermanager/provider.go @@ -7,9 +7,7 @@ import ( "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace/peermanager" "github.com/anyproto/any-sync/net/pool" - "github.com/anyproto/any-sync/net/streampool" - "github.com/anyproto/anytype-heart/space/spacecore" "github.com/anyproto/anytype-heart/space/spacecore/peerstore" ) @@ -22,16 +20,14 @@ const CName = peermanager.CName var log = logger.NewNamed(CName) type provider struct { - pool pool.Pool - streamPool streampool.StreamPool - peerStore peerstore.PeerStore + pool pool.Pool + peerStore peerstore.PeerStore } func (p *provider) Init(a *app.App) (err error) { p.peerStore = a.MustComponent(peerstore.CName).(peerstore.PeerStore) poolService := a.MustComponent(pool.CName).(pool.Service) p.pool = poolService - p.streamPool = a.MustComponent(spacecore.CName).(spacecore.SpaceCoreService).StreamPool() return nil } diff --git a/space/spacecore/rpchandler.go b/space/spacecore/rpchandler.go index 07509fea12..1e845dc086 100644 --- a/space/spacecore/rpchandler.go +++ b/space/spacecore/rpchandler.go @@ -29,15 +29,15 @@ func (r *rpcHandler) AclGetRecords(ctx context.Context, request *spacesyncproto. } func (r *rpcHandler) ObjectSync(ctx context.Context, req *spacesyncproto.ObjectSyncMessage) (resp *spacesyncproto.ObjectSyncMessage, err error) { - sp, err := r.s.Get(ctx, req.SpaceId) + return nil, fmt.Errorf("nt implemented") +} + +func (r *rpcHandler) ObjectSyncRequestStream(req *spacesyncproto.ObjectSyncMessage, stream spacesyncproto.DRPCSpaceSync_ObjectSyncRequestStreamStream) (err error) { + sp, err := r.s.Get(stream.Context(), req.SpaceId) if err != nil { - if err != spacesyncproto.ErrSpaceMissing { - err = spacesyncproto.ErrUnexpected - } - return + return err } - resp, err = sp.HandleSyncRequest(ctx, req) - return + return sp.HandleStreamSyncRequest(stream.Context(), req, stream) } func (r *rpcHandler) SpaceExchange(ctx context.Context, request *clientspaceproto.SpaceExchangeRequest) (resp *clientspaceproto.SpaceExchangeResponse, err error) { @@ -129,5 +129,5 @@ func (r *rpcHandler) HeadSync(ctx context.Context, req *spacesyncproto.HeadSyncR } func (r *rpcHandler) ObjectSyncStream(stream spacesyncproto.DRPCSpaceSync_ObjectSyncStreamStream) error { - return r.s.streamPool.ReadStream(stream) + return r.s.streamPool.ReadStream(stream, 300) } diff --git a/space/spacecore/service.go b/space/spacecore/service.go index 4ca2e36d2a..9a76d7ef3e 100644 --- a/space/spacecore/service.go +++ b/space/spacecore/service.go @@ -2,6 +2,7 @@ package spacecore import ( "context" + "errors" "fmt" "time" @@ -24,7 +25,6 @@ import ( "github.com/anyproto/any-sync/net/streampool" "github.com/anyproto/any-sync/nodeconf" "github.com/anyproto/any-sync/util/crypto" - "go.uber.org/zap" "github.com/anyproto/anytype-heart/core/anytype/config" "github.com/anyproto/anytype-heart/core/block/object/treesyncer" @@ -58,12 +58,12 @@ type SpaceCoreService interface { Create(ctx context.Context, replicationKey uint64, metadataPayload []byte) (*AnySpace, error) Derive(ctx context.Context, spaceType string) (space *AnySpace, err error) DeriveID(ctx context.Context, spaceType string) (id string, err error) - Delete(ctx context.Context, spaceID string) (err error) + Delete(ctx context.Context, spaceId string) (err error) Get(ctx context.Context, id string) (*AnySpace, error) Pick(ctx context.Context, id string) (*AnySpace, error) CloseSpace(ctx context.Context, id string) error + StorageExistsLocally(ctx context.Context, spaceId string) (exists bool, err error) - StreamPool() streampool.StreamPool app.ComponentRunnable } @@ -80,7 +80,6 @@ type service struct { peerStore peerstore.PeerStore peerService peerservice.PeerService poolManager PoolManager - streamHandler *streamHandler } func (s *service) Init(a *app.App) (err error) { @@ -97,20 +96,13 @@ func (s *service) Init(a *app.App) (err error) { s.peerService = a.MustComponent(peerservice.CName).(peerservice.PeerService) localDiscovery := a.MustComponent(localdiscovery.CName).(localdiscovery.LocalDiscovery) localDiscovery.SetNotifier(s) - s.streamHandler = &streamHandler{spaceCore: s} - - s.streamPool = a.MustComponent(streampool.CName).(streampool.Service).NewStreamPool(s.streamHandler, streampool.StreamConfig{ - SendQueueSize: 300, - DialQueueWorkers: 4, - DialQueueSize: 300, - }) s.spaceCache = ocache.New( s.loadSpace, ocache.WithLogger(log.Sugar()), ocache.WithGCPeriod(time.Minute), ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second), ) - + s.streamPool = a.MustComponent(streampool.CName).(streampool.StreamPool) err = spacesyncproto.DRPCRegisterSpaceSync(a.MustComponent(server.CName).(server.DRPCServer), &rpcHandler{s}) if err != nil { return @@ -198,30 +190,28 @@ func (s *service) Pick(ctx context.Context, id string) (space *AnySpace, err err return v.(*AnySpace), nil } -func (s *service) HandleMessage(ctx context.Context, senderId string, req *spacesyncproto.ObjectSyncMessage) (err error) { - var msg = &spacesyncproto.SpaceSubscription{} - if err = msg.Unmarshal(req.Payload); err != nil { - return +func (s *service) StorageExistsLocally(ctx context.Context, spaceId string) (exists bool, err error) { + st, err := s.spaceStorageProvider.WaitSpaceStorage(ctx, spaceId) + if err != nil && !errors.Is(err, spacestorage.ErrSpaceStorageMissing) { + return false, err } - log.InfoCtx(ctx, "got subscription message", zap.Strings("spaceIds", msg.SpaceIds)) - if msg.Action == spacesyncproto.SpaceSubscriptionAction_Subscribe { - return s.streamPool.AddTagsCtx(ctx, msg.SpaceIds...) - } else { - return s.streamPool.RemoveTagsCtx(ctx, msg.SpaceIds...) + if errors.Is(err, spacestorage.ErrSpaceStorageMissing) { + return false, nil } + err = st.Close(ctx) + if err != nil { + return false, err + } + return true, nil } -func (s *service) StreamPool() streampool.StreamPool { - return s.streamPool -} - -func (s *service) Delete(ctx context.Context, spaceID string) (err error) { +func (s *service) Delete(ctx context.Context, spaceId string) (err error) { networkID := s.nodeConf.Configuration().NetworkId - delConf, err := coordinatorproto.PrepareDeleteConfirmation(s.accountKeys.SignKey, spaceID, s.accountKeys.PeerId, networkID) + delConf, err := coordinatorproto.PrepareDeleteConfirmation(s.accountKeys.SignKey, spaceId, s.accountKeys.PeerId, networkID) if err != nil { return } - err = s.coordinator.SpaceDelete(ctx, spaceID, delConf) + err = s.coordinator.SpaceDelete(ctx, spaceId, delConf) if err != nil { err = convertCoordError(err) return @@ -231,7 +221,10 @@ func (s *service) Delete(ctx context.Context, spaceID string) (err error) { func (s *service) loadSpace(ctx context.Context, id string) (value ocache.Object, err error) { statusService := objectsyncstatus.NewSyncStatusService() - cc, err := s.commonSpace.NewSpace(ctx, id, commonspace.Deps{TreeSyncer: treesyncer.NewTreeSyncer(id), SyncStatus: statusService}) + cc, err := s.commonSpace.NewSpace(ctx, id, commonspace.Deps{ + TreeSyncer: treesyncer.NewTreeSyncer(id), + SyncStatus: statusService, + }) if err != nil { return } diff --git a/space/spacecore/storage/badgerstorage/spacestorage.go b/space/spacecore/storage/badgerstorage/spacestorage.go index bff4aaf970..0e31c8533d 100644 --- a/space/spacecore/storage/badgerstorage/spacestorage.go +++ b/space/spacecore/storage/badgerstorage/spacestorage.go @@ -154,12 +154,6 @@ func (s *spaceStorage) WriteSpaceHash(hash string) error { }) } -func (s *spaceStorage) WriteOldSpaceHash(hash string) error { - return s.objDb.Update(func(txn *badger.Txn) error { - return txn.Set(s.keys.OldSpaceHash(), []byte(hash)) - }) -} - func (s *spaceStorage) ReadSpaceHash() (hash string, err error) { err = s.objDb.View(func(txn *badger.Txn) error { res, err := getTxn(txn, s.keys.SpaceHash()) @@ -172,18 +166,6 @@ func (s *spaceStorage) ReadSpaceHash() (hash string, err error) { return } -func (s *spaceStorage) ReadOldSpaceHash() (hash string, err error) { - err = s.objDb.View(func(txn *badger.Txn) error { - res, err := getTxn(txn, s.keys.OldSpaceHash()) - if err != nil { - return err - } - hash = string(res) - return nil - }) - return -} - func (s *spaceStorage) StoredIds() (ids []string, err error) { err = s.objDb.View(func(txn *badger.Txn) error { opts := badger.DefaultIteratorOptions diff --git a/space/spacecore/storage/badgerstorage/treestorage.go b/space/spacecore/storage/badgerstorage/treestorage.go index 9188ed9b94..f82b58dacc 100644 --- a/space/spacecore/storage/badgerstorage/treestorage.go +++ b/space/spacecore/storage/badgerstorage/treestorage.go @@ -2,6 +2,7 @@ package badgerstorage import ( "context" + "fmt" "github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto" "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" @@ -106,6 +107,10 @@ func (t *treeStorage) Heads() (heads []string, err error) { return } +func (t *treeStorage) GetAllChangeIds() (chs []string, err error) { + return nil, fmt.Errorf("get all change ids should not be called") +} + func (t *treeStorage) SetHeads(heads []string) (err error) { payload := treestorage.CreateHeadsPayload(heads) return putDB(t.db, t.keys.HeadsKey(), payload) @@ -141,6 +146,10 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (raw *treecha return } +func (t *treeStorage) GetAppendRawChange(ctx context.Context, buf []byte, id string) (raw *treechangeproto.RawTreeChangeWithId, err error) { + return t.GetRawChange(ctx, id) +} + func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { return hasDB(t.db, t.keys.RawChangeKey(id)), nil } diff --git a/space/spacecore/storage/sqlitestorage/space.go b/space/spacecore/storage/sqlitestorage/space.go index bc06e33e50..aac8f8f6ee 100644 --- a/space/spacecore/storage/sqlitestorage/space.go +++ b/space/spacecore/storage/sqlitestorage/space.go @@ -264,28 +264,12 @@ func (s *spaceStorage) WriteSpaceHash(hash string) error { return nil } -func (s *spaceStorage) WriteOldSpaceHash(hash string) error { - s.mu.Lock() - defer s.mu.Unlock() - if _, err := s.service.stmt.updateSpaceOldHash.Exec(hash, s.spaceId); err != nil { - return err - } - s.oldHash = hash - return nil -} - func (s *spaceStorage) ReadSpaceHash() (hash string, err error) { s.mu.RLock() defer s.mu.RUnlock() return s.hash, nil } -func (s *spaceStorage) ReadOldSpaceHash() (hash string, err error) { - s.mu.RLock() - defer s.mu.RUnlock() - return s.oldHash, nil -} - func (s *spaceStorage) Close(_ context.Context) (err error) { s.service.unlockSpaceStorage(s.spaceId) return nil diff --git a/space/spacecore/storage/sqlitestorage/space_test.go b/space/spacecore/storage/sqlitestorage/space_test.go index f816e01c90..0eec0e0eda 100644 --- a/space/spacecore/storage/sqlitestorage/space_test.go +++ b/space/spacecore/storage/sqlitestorage/space_test.go @@ -175,20 +175,13 @@ func TestSpaceStorage_ReadSpaceHash(t *testing.T) { hash, err := ss.ReadSpaceHash() require.NoError(t, err) assert.Empty(t, hash) - oldHash, err := ss.ReadOldSpaceHash() - require.NoError(t, err) - assert.Empty(t, oldHash) require.NoError(t, ss.WriteSpaceHash("hash")) - require.NoError(t, ss.WriteOldSpaceHash("oldHash")) var checkHashes = func(ss spacestorage.SpaceStorage) { hash, err = ss.ReadSpaceHash() require.NoError(t, err) assert.Equal(t, "hash", hash) - oldHash, err = ss.ReadOldSpaceHash() - require.NoError(t, err) - assert.Equal(t, "oldHash", oldHash) } checkHashes(ss) diff --git a/space/spacecore/storage/sqlitestorage/tree.go b/space/spacecore/storage/sqlitestorage/tree.go index 0ce2b9a4b6..4839d703fe 100644 --- a/space/spacecore/storage/sqlitestorage/tree.go +++ b/space/spacecore/storage/sqlitestorage/tree.go @@ -98,6 +98,10 @@ func (t *treeStorage) Heads() ([]string, error) { return t.heads, nil } +func (t *treeStorage) GetAllChangeIds() (chs []string, err error) { + return nil, fmt.Errorf("get all change ids should not be called") +} + func (t *treeStorage) SetHeads(heads []string) error { t.mu.Lock() defer t.mu.Unlock() @@ -158,6 +162,10 @@ func (t *treeStorage) GetRawChange(ctx context.Context, id string) (*treechangep return ch, nil } +func (t *treeStorage) GetAppendRawChange(ctx context.Context, buf []byte, id string) (*treechangeproto.RawTreeChangeWithId, error) { + return t.GetRawChange(ctx, id) +} + func (t *treeStorage) HasChange(ctx context.Context, id string) (bool, error) { var res int if err := t.service.stmt.hasChange.QueryRow(id, t.treeId).Scan(&res); err != nil { diff --git a/space/spacecore/streamhandler.go b/space/spacecore/streamhandler.go deleted file mode 100644 index fa96ca50e3..0000000000 --- a/space/spacecore/streamhandler.go +++ /dev/null @@ -1,86 +0,0 @@ -package spacecore - -import ( - "errors" - "sync/atomic" - "time" - - "github.com/anyproto/any-sync/commonspace/objectsync" - "github.com/anyproto/any-sync/commonspace/spacesyncproto" - "github.com/anyproto/any-sync/net/peer" - "golang.org/x/net/context" - "storj.io/drpc" -) - -var ( - errUnexpectedMessage = errors.New("unexpected message") -) - -var lastMsgId atomic.Uint64 - -type streamHandler struct { - spaceCore *service -} - -func (s *streamHandler) OpenStream(ctx context.Context, p peer.Peer) (stream drpc.Stream, tags []string, err error) { - return s.OpenSpaceStream(ctx, p, s.spaceCore.getOpenedSpaceIds()) -} - -func (s *streamHandler) OpenSpaceStream(ctx context.Context, p peer.Peer, spaceIds []string) (stream drpc.Stream, tags []string, err error) { - conn, err := p.AcquireDrpcConn(ctx) - if err != nil { - return - } - objectStream, err := spacesyncproto.NewDRPCSpaceSyncClient(conn).ObjectSyncStream(ctx) - if err != nil { - return - } - if len(spaceIds) > 0 { - var msg = &spacesyncproto.SpaceSubscription{ - SpaceIds: spaceIds, - Action: spacesyncproto.SpaceSubscriptionAction_Subscribe, - } - payload, merr := msg.Marshal() - if merr != nil { - err = merr - return - } - if err = objectStream.Send(&spacesyncproto.ObjectSyncMessage{ - Payload: payload, - }); err != nil { - return - } - } - return objectStream, nil, nil -} - -func (s *streamHandler) HandleMessage(ctx context.Context, peerId string, msg drpc.Message) (err error) { - syncMsg, ok := msg.(*spacesyncproto.ObjectSyncMessage) - if !ok { - err = errUnexpectedMessage - return - } - ctx = peer.CtxWithPeerId(ctx, peerId) - - if syncMsg.SpaceId == "" { - return s.spaceCore.HandleMessage(ctx, peerId, syncMsg) - } - - space, err := s.spaceCore.Get(ctx, syncMsg.SpaceId) - if err != nil { - return - } - err = space.HandleMessage(ctx, objectsync.HandleMessage{ - Id: lastMsgId.Add(1), - Deadline: time.Now().Add(time.Minute), - SenderId: peerId, - Message: syncMsg, - PeerCtx: ctx, - }) - return -} - -func (s *streamHandler) NewReadMessage() drpc.Message { - // TODO: we can use sync.Pool here - return new(spacesyncproto.ObjectSyncMessage) -} diff --git a/space/spacecore/streamopener.go b/space/spacecore/streamopener.go new file mode 100644 index 0000000000..ef0d14f8cb --- /dev/null +++ b/space/spacecore/streamopener.go @@ -0,0 +1,96 @@ +package spacecore + +import ( + "errors" + + "github.com/anyproto/any-sync/app" + "github.com/anyproto/any-sync/commonspace/spacesyncproto" + "github.com/anyproto/any-sync/commonspace/sync/objectsync/objectmessages" + "github.com/anyproto/any-sync/net/peer" + "github.com/anyproto/any-sync/net/streampool" + "github.com/anyproto/any-sync/net/streampool/streamhandler" + "go.uber.org/zap" + "golang.org/x/net/context" + "storj.io/drpc" +) + +var ( + errUnexpectedMessage = errors.New("unexpected message") +) + +func NewStreamOpener() streamhandler.StreamHandler { + return &streamOpener{} +} + +type streamOpener struct { + spaceCore *service + streamPool streampool.StreamPool +} + +func (s *streamOpener) Init(a *app.App) (err error) { + s.spaceCore = app.MustComponent[SpaceCoreService](a).(*service) + s.streamPool = app.MustComponent[streampool.StreamPool](a) + return nil +} + +func (s *streamOpener) Name() (name string) { + return streamhandler.CName +} + +func (s *streamOpener) OpenStream(ctx context.Context, p peer.Peer) (stream drpc.Stream, tags []string, queueSize int, err error) { + spaceIds := s.spaceCore.getOpenedSpaceIds() + conn, err := p.AcquireDrpcConn(ctx) + if err != nil { + return + } + objectStream, err := spacesyncproto.NewDRPCSpaceSyncClient(conn).ObjectSyncStream(ctx) + if err != nil { + return + } + if len(spaceIds) > 0 { + var msg = &spacesyncproto.SpaceSubscription{ + SpaceIds: spaceIds, + Action: spacesyncproto.SpaceSubscriptionAction_Subscribe, + } + payload, merr := msg.Marshal() + if merr != nil { + err = merr + return + } + if err = objectStream.Send(&spacesyncproto.ObjectSyncMessage{ + Payload: payload, + }); err != nil { + return + } + } + return objectStream, nil, 300, nil +} + +func (s *streamOpener) HandleMessage(peerCtx context.Context, peerId string, msg drpc.Message) (err error) { + syncMsg, ok := msg.(*objectmessages.HeadUpdate) + if !ok { + err = errUnexpectedMessage + return + } + if syncMsg.SpaceId() == "" { + var msg = &spacesyncproto.SpaceSubscription{} + if err = msg.Unmarshal(syncMsg.Bytes); err != nil { + return + } + log.InfoCtx(peerCtx, "got subscription message", zap.Strings("spaceIds", msg.SpaceIds)) + if msg.Action == spacesyncproto.SpaceSubscriptionAction_Subscribe { + return s.streamPool.AddTagsCtx(peerCtx, msg.SpaceIds...) + } else { + return s.streamPool.RemoveTagsCtx(peerCtx, msg.SpaceIds...) + } + } + sp, err := s.spaceCore.Get(peerCtx, syncMsg.SpaceId()) + if err != nil { + return + } + return sp.HandleMessage(peerCtx, syncMsg) +} + +func (s *streamOpener) NewReadMessage() drpc.Message { + return &objectmessages.HeadUpdate{} +} diff --git a/space/spacefactory/mock_spacefactory/mock_SpaceFactory.go b/space/spacefactory/mock_spacefactory/mock_SpaceFactory.go index 86f69f8562..df4712d1bd 100644 --- a/space/spacefactory/mock_spacefactory/mock_SpaceFactory.go +++ b/space/spacefactory/mock_spacefactory/mock_SpaceFactory.go @@ -368,6 +368,64 @@ func (_c *MockSpaceFactory_Init_Call) RunAndReturn(run func(*app.App) error) *Mo return _c } +// LoadAndSetTechSpace provides a mock function with given fields: ctx +func (_m *MockSpaceFactory) LoadAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for LoadAndSetTechSpace") + } + + var r0 *clientspace.TechSpace + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*clientspace.TechSpace, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *clientspace.TechSpace); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*clientspace.TechSpace) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockSpaceFactory_LoadAndSetTechSpace_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LoadAndSetTechSpace' +type MockSpaceFactory_LoadAndSetTechSpace_Call struct { + *mock.Call +} + +// LoadAndSetTechSpace is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockSpaceFactory_Expecter) LoadAndSetTechSpace(ctx interface{}) *MockSpaceFactory_LoadAndSetTechSpace_Call { + return &MockSpaceFactory_LoadAndSetTechSpace_Call{Call: _e.mock.On("LoadAndSetTechSpace", ctx)} +} + +func (_c *MockSpaceFactory_LoadAndSetTechSpace_Call) Run(run func(ctx context.Context)) *MockSpaceFactory_LoadAndSetTechSpace_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockSpaceFactory_LoadAndSetTechSpace_Call) Return(_a0 *clientspace.TechSpace, _a1 error) *MockSpaceFactory_LoadAndSetTechSpace_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockSpaceFactory_LoadAndSetTechSpace_Call) RunAndReturn(run func(context.Context) (*clientspace.TechSpace, error)) *MockSpaceFactory_LoadAndSetTechSpace_Call { + _c.Call.Return(run) + return _c +} + // Name provides a mock function with given fields: func (_m *MockSpaceFactory) Name() string { ret := _m.Called() diff --git a/space/spacefactory/spacefactory.go b/space/spacefactory/spacefactory.go index d07a23d5c8..9af99e52f8 100644 --- a/space/spacefactory/spacefactory.go +++ b/space/spacefactory/spacefactory.go @@ -29,6 +29,7 @@ type SpaceFactory interface { NewShareableSpace(ctx context.Context, id string, info spaceinfo.SpacePersistentInfo) (spacecontroller.SpaceController, error) CreateMarketplaceSpace(ctx context.Context) (sp spacecontroller.SpaceController, err error) CreateAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error) + LoadAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error) CreateInvitingSpace(ctx context.Context, id, aclHeadId string) (sp spacecontroller.SpaceController, err error) } @@ -82,17 +83,23 @@ func (s *spaceFactory) CreatePersonalSpace(ctx context.Context, metadata []byte) } return nil, err } - ctrl := personalspace.NewSpaceController(coreSpace.Id(), metadata, s.app) + ctrl, err := personalspace.NewSpaceController(ctx, coreSpace.Id(), metadata, s.app) + if err != nil { + return nil, err + } err = ctrl.Start(ctx) return ctrl, err } func (s *spaceFactory) NewPersonalSpace(ctx context.Context, metadata []byte) (ctrl spacecontroller.SpaceController, err error) { - coreSpace, err := s.spaceCore.Derive(ctx, spacecore.SpaceType) + id, err := s.spaceCore.DeriveID(ctx, spacecore.SpaceType) + if err != nil { + return nil, err + } + ctrl, err = personalspace.NewSpaceController(ctx, id, metadata, s.app) if err != nil { return nil, err } - ctrl = personalspace.NewSpaceController(coreSpace.Id(), metadata, s.app) err = ctrl.Start(ctx) return ctrl, err } @@ -116,7 +123,38 @@ func (s *spaceFactory) CreateAndSetTechSpace(ctx context.Context) (*clientspace. s.techSpace = ts s.app = s.app.ChildApp() s.app.Register(s.techSpace) - err = ts.Run(techCoreSpace, ts.Cache) + err = ts.Run(techCoreSpace, ts.Cache, true) + if err != nil { + return nil, fmt.Errorf("run tech space: %w", err) + } + + return ts, nil +} + +func (s *spaceFactory) LoadAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error) { + techSpace := techspace.New() + id, err := s.spaceCore.DeriveID(ctx, spacecore.TechSpaceType) + if err != nil { + return nil, fmt.Errorf("derive tech space id: %w", err) + } + techCoreSpace, err := s.spaceCore.Get(ctx, id) + if err != nil { + return nil, fmt.Errorf("derive tech space: %w", err) + } + deps := clientspace.TechSpaceDeps{ + CommonSpace: techCoreSpace, + ObjectFactory: s.objectFactory, + AccountService: s.accountService, + PersonalSpaceId: s.personalSpaceId, + Indexer: s.indexer, + Installer: s.installer, + TechSpace: techSpace, + } + ts := clientspace.NewTechSpace(deps) + s.techSpace = ts + s.app = s.app.ChildApp() + s.app.Register(s.techSpace) + err = ts.Run(techCoreSpace, ts.Cache, false) if err != nil { return nil, fmt.Errorf("run tech space: %w", err) } diff --git a/space/techspace/mock_techspace/mock_AccountObject.go b/space/techspace/mock_techspace/mock_AccountObject.go new file mode 100644 index 0000000000..6ce5b07f8e --- /dev/null +++ b/space/techspace/mock_techspace/mock_AccountObject.go @@ -0,0 +1,2884 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_techspace + +import ( + domain "github.com/anyproto/anytype-heart/core/domain" + coresmartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" + + mock "github.com/stretchr/testify/mock" + + model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" + + objecttree "github.com/anyproto/any-sync/commonspace/object/tree/objecttree" + + pb "github.com/anyproto/anytype-heart/pb" + + pbtypes "github.com/anyproto/anytype-heart/util/pbtypes" + + relationutils "github.com/anyproto/anytype-heart/core/relationutils" + + restriction "github.com/anyproto/anytype-heart/core/block/restriction" + + session "github.com/anyproto/anytype-heart/core/session" + + simple "github.com/anyproto/anytype-heart/core/block/simple" + + smartblock "github.com/anyproto/anytype-heart/core/block/editor/smartblock" + + state "github.com/anyproto/anytype-heart/core/block/editor/state" + + time "time" + + types "github.com/gogo/protobuf/types" + + undo "github.com/anyproto/anytype-heart/core/block/undo" +) + +// MockAccountObject is an autogenerated mock type for the AccountObject type +type MockAccountObject struct { + mock.Mock +} + +type MockAccountObject_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAccountObject) EXPECT() *MockAccountObject_Expecter { + return &MockAccountObject_Expecter{mock: &_m.Mock} +} + +// AddHook provides a mock function with given fields: f, events +func (_m *MockAccountObject) AddHook(f smartblock.HookCallback, events ...smartblock.Hook) { + _va := make([]interface{}, len(events)) + for _i := range events { + _va[_i] = events[_i] + } + var _ca []interface{} + _ca = append(_ca, f) + _ca = append(_ca, _va...) + _m.Called(_ca...) +} + +// MockAccountObject_AddHook_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddHook' +type MockAccountObject_AddHook_Call struct { + *mock.Call +} + +// AddHook is a helper method to define mock.On call +// - f smartblock.HookCallback +// - events ...smartblock.Hook +func (_e *MockAccountObject_Expecter) AddHook(f interface{}, events ...interface{}) *MockAccountObject_AddHook_Call { + return &MockAccountObject_AddHook_Call{Call: _e.mock.On("AddHook", + append([]interface{}{f}, events...)...)} +} + +func (_c *MockAccountObject_AddHook_Call) Run(run func(f smartblock.HookCallback, events ...smartblock.Hook)) *MockAccountObject_AddHook_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]smartblock.Hook, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(smartblock.Hook) + } + } + run(args[0].(smartblock.HookCallback), variadicArgs...) + }) + return _c +} + +func (_c *MockAccountObject_AddHook_Call) Return() *MockAccountObject_AddHook_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_AddHook_Call) RunAndReturn(run func(smartblock.HookCallback, ...smartblock.Hook)) *MockAccountObject_AddHook_Call { + _c.Call.Return(run) + return _c +} + +// AddHookOnce provides a mock function with given fields: id, f, events +func (_m *MockAccountObject) AddHookOnce(id string, f smartblock.HookCallback, events ...smartblock.Hook) { + _va := make([]interface{}, len(events)) + for _i := range events { + _va[_i] = events[_i] + } + var _ca []interface{} + _ca = append(_ca, id, f) + _ca = append(_ca, _va...) + _m.Called(_ca...) +} + +// MockAccountObject_AddHookOnce_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddHookOnce' +type MockAccountObject_AddHookOnce_Call struct { + *mock.Call +} + +// AddHookOnce is a helper method to define mock.On call +// - id string +// - f smartblock.HookCallback +// - events ...smartblock.Hook +func (_e *MockAccountObject_Expecter) AddHookOnce(id interface{}, f interface{}, events ...interface{}) *MockAccountObject_AddHookOnce_Call { + return &MockAccountObject_AddHookOnce_Call{Call: _e.mock.On("AddHookOnce", + append([]interface{}{id, f}, events...)...)} +} + +func (_c *MockAccountObject_AddHookOnce_Call) Run(run func(id string, f smartblock.HookCallback, events ...smartblock.Hook)) *MockAccountObject_AddHookOnce_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]smartblock.Hook, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(smartblock.Hook) + } + } + run(args[0].(string), args[1].(smartblock.HookCallback), variadicArgs...) + }) + return _c +} + +func (_c *MockAccountObject_AddHookOnce_Call) Return() *MockAccountObject_AddHookOnce_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_AddHookOnce_Call) RunAndReturn(run func(string, smartblock.HookCallback, ...smartblock.Hook)) *MockAccountObject_AddHookOnce_Call { + _c.Call.Return(run) + return _c +} + +// AddRelationLinks provides a mock function with given fields: ctx, relationIds +func (_m *MockAccountObject) AddRelationLinks(ctx session.Context, relationIds ...string) error { + _va := make([]interface{}, len(relationIds)) + for _i := range relationIds { + _va[_i] = relationIds[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for AddRelationLinks") + } + + var r0 error + if rf, ok := ret.Get(0).(func(session.Context, ...string) error); ok { + r0 = rf(ctx, relationIds...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_AddRelationLinks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddRelationLinks' +type MockAccountObject_AddRelationLinks_Call struct { + *mock.Call +} + +// AddRelationLinks is a helper method to define mock.On call +// - ctx session.Context +// - relationIds ...string +func (_e *MockAccountObject_Expecter) AddRelationLinks(ctx interface{}, relationIds ...interface{}) *MockAccountObject_AddRelationLinks_Call { + return &MockAccountObject_AddRelationLinks_Call{Call: _e.mock.On("AddRelationLinks", + append([]interface{}{ctx}, relationIds...)...)} +} + +func (_c *MockAccountObject_AddRelationLinks_Call) Run(run func(ctx session.Context, relationIds ...string)) *MockAccountObject_AddRelationLinks_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]string, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(string) + } + } + run(args[0].(session.Context), variadicArgs...) + }) + return _c +} + +func (_c *MockAccountObject_AddRelationLinks_Call) Return(err error) *MockAccountObject_AddRelationLinks_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_AddRelationLinks_Call) RunAndReturn(run func(session.Context, ...string) error) *MockAccountObject_AddRelationLinks_Call { + _c.Call.Return(run) + return _c +} + +// AddRelationLinksToState provides a mock function with given fields: s, relationIds +func (_m *MockAccountObject) AddRelationLinksToState(s *state.State, relationIds ...string) error { + _va := make([]interface{}, len(relationIds)) + for _i := range relationIds { + _va[_i] = relationIds[_i] + } + var _ca []interface{} + _ca = append(_ca, s) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for AddRelationLinksToState") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*state.State, ...string) error); ok { + r0 = rf(s, relationIds...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_AddRelationLinksToState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddRelationLinksToState' +type MockAccountObject_AddRelationLinksToState_Call struct { + *mock.Call +} + +// AddRelationLinksToState is a helper method to define mock.On call +// - s *state.State +// - relationIds ...string +func (_e *MockAccountObject_Expecter) AddRelationLinksToState(s interface{}, relationIds ...interface{}) *MockAccountObject_AddRelationLinksToState_Call { + return &MockAccountObject_AddRelationLinksToState_Call{Call: _e.mock.On("AddRelationLinksToState", + append([]interface{}{s}, relationIds...)...)} +} + +func (_c *MockAccountObject_AddRelationLinksToState_Call) Run(run func(s *state.State, relationIds ...string)) *MockAccountObject_AddRelationLinksToState_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]string, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(string) + } + } + run(args[0].(*state.State), variadicArgs...) + }) + return _c +} + +func (_c *MockAccountObject_AddRelationLinksToState_Call) Return(err error) *MockAccountObject_AddRelationLinksToState_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_AddRelationLinksToState_Call) RunAndReturn(run func(*state.State, ...string) error) *MockAccountObject_AddRelationLinksToState_Call { + _c.Call.Return(run) + return _c +} + +// Apply provides a mock function with given fields: s, flags +func (_m *MockAccountObject) Apply(s *state.State, flags ...smartblock.ApplyFlag) error { + _va := make([]interface{}, len(flags)) + for _i := range flags { + _va[_i] = flags[_i] + } + var _ca []interface{} + _ca = append(_ca, s) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for Apply") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*state.State, ...smartblock.ApplyFlag) error); ok { + r0 = rf(s, flags...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_Apply_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Apply' +type MockAccountObject_Apply_Call struct { + *mock.Call +} + +// Apply is a helper method to define mock.On call +// - s *state.State +// - flags ...smartblock.ApplyFlag +func (_e *MockAccountObject_Expecter) Apply(s interface{}, flags ...interface{}) *MockAccountObject_Apply_Call { + return &MockAccountObject_Apply_Call{Call: _e.mock.On("Apply", + append([]interface{}{s}, flags...)...)} +} + +func (_c *MockAccountObject_Apply_Call) Run(run func(s *state.State, flags ...smartblock.ApplyFlag)) *MockAccountObject_Apply_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]smartblock.ApplyFlag, len(args)-1) + for i, a := range args[1:] { + if a != nil { + variadicArgs[i] = a.(smartblock.ApplyFlag) + } + } + run(args[0].(*state.State), variadicArgs...) + }) + return _c +} + +func (_c *MockAccountObject_Apply_Call) Return(_a0 error) *MockAccountObject_Apply_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Apply_Call) RunAndReturn(run func(*state.State, ...smartblock.ApplyFlag) error) *MockAccountObject_Apply_Call { + _c.Call.Return(run) + return _c +} + +// Blocks provides a mock function with given fields: +func (_m *MockAccountObject) Blocks() []*model.Block { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Blocks") + } + + var r0 []*model.Block + if rf, ok := ret.Get(0).(func() []*model.Block); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.Block) + } + } + + return r0 +} + +// MockAccountObject_Blocks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Blocks' +type MockAccountObject_Blocks_Call struct { + *mock.Call +} + +// Blocks is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Blocks() *MockAccountObject_Blocks_Call { + return &MockAccountObject_Blocks_Call{Call: _e.mock.On("Blocks")} +} + +func (_c *MockAccountObject_Blocks_Call) Run(run func()) *MockAccountObject_Blocks_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Blocks_Call) Return(_a0 []*model.Block) *MockAccountObject_Blocks_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Blocks_Call) RunAndReturn(run func() []*model.Block) *MockAccountObject_Blocks_Call { + _c.Call.Return(run) + return _c +} + +// BlocksInit provides a mock function with given fields: ds +func (_m *MockAccountObject) BlocksInit(ds simple.DetailsService) { + _m.Called(ds) +} + +// MockAccountObject_BlocksInit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BlocksInit' +type MockAccountObject_BlocksInit_Call struct { + *mock.Call +} + +// BlocksInit is a helper method to define mock.On call +// - ds simple.DetailsService +func (_e *MockAccountObject_Expecter) BlocksInit(ds interface{}) *MockAccountObject_BlocksInit_Call { + return &MockAccountObject_BlocksInit_Call{Call: _e.mock.On("BlocksInit", ds)} +} + +func (_c *MockAccountObject_BlocksInit_Call) Run(run func(ds simple.DetailsService)) *MockAccountObject_BlocksInit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(simple.DetailsService)) + }) + return _c +} + +func (_c *MockAccountObject_BlocksInit_Call) Return() *MockAccountObject_BlocksInit_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_BlocksInit_Call) RunAndReturn(run func(simple.DetailsService)) *MockAccountObject_BlocksInit_Call { + _c.Call.Return(run) + return _c +} + +// ChangeId provides a mock function with given fields: +func (_m *MockAccountObject) ChangeId() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ChangeId") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_ChangeId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ChangeId' +type MockAccountObject_ChangeId_Call struct { + *mock.Call +} + +// ChangeId is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) ChangeId() *MockAccountObject_ChangeId_Call { + return &MockAccountObject_ChangeId_Call{Call: _e.mock.On("ChangeId")} +} + +func (_c *MockAccountObject_ChangeId_Call) Run(run func()) *MockAccountObject_ChangeId_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_ChangeId_Call) Return(_a0 string) *MockAccountObject_ChangeId_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_ChangeId_Call) RunAndReturn(run func() string) *MockAccountObject_ChangeId_Call { + _c.Call.Return(run) + return _c +} + +// CheckSubscriptions provides a mock function with given fields: +func (_m *MockAccountObject) CheckSubscriptions() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CheckSubscriptions") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockAccountObject_CheckSubscriptions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckSubscriptions' +type MockAccountObject_CheckSubscriptions_Call struct { + *mock.Call +} + +// CheckSubscriptions is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) CheckSubscriptions() *MockAccountObject_CheckSubscriptions_Call { + return &MockAccountObject_CheckSubscriptions_Call{Call: _e.mock.On("CheckSubscriptions")} +} + +func (_c *MockAccountObject_CheckSubscriptions_Call) Run(run func()) *MockAccountObject_CheckSubscriptions_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_CheckSubscriptions_Call) Return(changed bool) *MockAccountObject_CheckSubscriptions_Call { + _c.Call.Return(changed) + return _c +} + +func (_c *MockAccountObject_CheckSubscriptions_Call) RunAndReturn(run func() bool) *MockAccountObject_CheckSubscriptions_Call { + _c.Call.Return(run) + return _c +} + +// Close provides a mock function with given fields: +func (_m *MockAccountObject) Close() error { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Close") + } + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type MockAccountObject_Close_Call struct { + *mock.Call +} + +// Close is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Close() *MockAccountObject_Close_Call { + return &MockAccountObject_Close_Call{Call: _e.mock.On("Close")} +} + +func (_c *MockAccountObject_Close_Call) Run(run func()) *MockAccountObject_Close_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Close_Call) Return(err error) *MockAccountObject_Close_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_Close_Call) RunAndReturn(run func() error) *MockAccountObject_Close_Call { + _c.Call.Return(run) + return _c +} + +// CombinedDetails provides a mock function with given fields: +func (_m *MockAccountObject) CombinedDetails() *types.Struct { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for CombinedDetails") + } + + var r0 *types.Struct + if rf, ok := ret.Get(0).(func() *types.Struct); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Struct) + } + } + + return r0 +} + +// MockAccountObject_CombinedDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CombinedDetails' +type MockAccountObject_CombinedDetails_Call struct { + *mock.Call +} + +// CombinedDetails is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) CombinedDetails() *MockAccountObject_CombinedDetails_Call { + return &MockAccountObject_CombinedDetails_Call{Call: _e.mock.On("CombinedDetails")} +} + +func (_c *MockAccountObject_CombinedDetails_Call) Run(run func()) *MockAccountObject_CombinedDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_CombinedDetails_Call) Return(_a0 *types.Struct) *MockAccountObject_CombinedDetails_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_CombinedDetails_Call) RunAndReturn(run func() *types.Struct) *MockAccountObject_CombinedDetails_Call { + _c.Call.Return(run) + return _c +} + +// Details provides a mock function with given fields: +func (_m *MockAccountObject) Details() *types.Struct { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Details") + } + + var r0 *types.Struct + if rf, ok := ret.Get(0).(func() *types.Struct); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Struct) + } + } + + return r0 +} + +// MockAccountObject_Details_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Details' +type MockAccountObject_Details_Call struct { + *mock.Call +} + +// Details is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Details() *MockAccountObject_Details_Call { + return &MockAccountObject_Details_Call{Call: _e.mock.On("Details")} +} + +func (_c *MockAccountObject_Details_Call) Run(run func()) *MockAccountObject_Details_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Details_Call) Return(_a0 *types.Struct) *MockAccountObject_Details_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Details_Call) RunAndReturn(run func() *types.Struct) *MockAccountObject_Details_Call { + _c.Call.Return(run) + return _c +} + +// DisableLayouts provides a mock function with given fields: +func (_m *MockAccountObject) DisableLayouts() { + _m.Called() +} + +// MockAccountObject_DisableLayouts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DisableLayouts' +type MockAccountObject_DisableLayouts_Call struct { + *mock.Call +} + +// DisableLayouts is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) DisableLayouts() *MockAccountObject_DisableLayouts_Call { + return &MockAccountObject_DisableLayouts_Call{Call: _e.mock.On("DisableLayouts")} +} + +func (_c *MockAccountObject_DisableLayouts_Call) Run(run func()) *MockAccountObject_DisableLayouts_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_DisableLayouts_Call) Return() *MockAccountObject_DisableLayouts_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_DisableLayouts_Call) RunAndReturn(run func()) *MockAccountObject_DisableLayouts_Call { + _c.Call.Return(run) + return _c +} + +// EnabledRelationAsDependentObjects provides a mock function with given fields: +func (_m *MockAccountObject) EnabledRelationAsDependentObjects() { + _m.Called() +} + +// MockAccountObject_EnabledRelationAsDependentObjects_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EnabledRelationAsDependentObjects' +type MockAccountObject_EnabledRelationAsDependentObjects_Call struct { + *mock.Call +} + +// EnabledRelationAsDependentObjects is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) EnabledRelationAsDependentObjects() *MockAccountObject_EnabledRelationAsDependentObjects_Call { + return &MockAccountObject_EnabledRelationAsDependentObjects_Call{Call: _e.mock.On("EnabledRelationAsDependentObjects")} +} + +func (_c *MockAccountObject_EnabledRelationAsDependentObjects_Call) Run(run func()) *MockAccountObject_EnabledRelationAsDependentObjects_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_EnabledRelationAsDependentObjects_Call) Return() *MockAccountObject_EnabledRelationAsDependentObjects_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_EnabledRelationAsDependentObjects_Call) RunAndReturn(run func()) *MockAccountObject_EnabledRelationAsDependentObjects_Call { + _c.Call.Return(run) + return _c +} + +// GetAnalyticsId provides a mock function with given fields: +func (_m *MockAccountObject) GetAnalyticsId() (string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetAnalyticsId") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAccountObject_GetAnalyticsId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAnalyticsId' +type MockAccountObject_GetAnalyticsId_Call struct { + *mock.Call +} + +// GetAnalyticsId is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) GetAnalyticsId() *MockAccountObject_GetAnalyticsId_Call { + return &MockAccountObject_GetAnalyticsId_Call{Call: _e.mock.On("GetAnalyticsId")} +} + +func (_c *MockAccountObject_GetAnalyticsId_Call) Run(run func()) *MockAccountObject_GetAnalyticsId_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_GetAnalyticsId_Call) Return(_a0 string, _a1 error) *MockAccountObject_GetAnalyticsId_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAccountObject_GetAnalyticsId_Call) RunAndReturn(run func() (string, error)) *MockAccountObject_GetAnalyticsId_Call { + _c.Call.Return(run) + return _c +} + +// GetAndUnsetFileKeys provides a mock function with given fields: +func (_m *MockAccountObject) GetAndUnsetFileKeys() []pb.ChangeFileKeys { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetAndUnsetFileKeys") + } + + var r0 []pb.ChangeFileKeys + if rf, ok := ret.Get(0).(func() []pb.ChangeFileKeys); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]pb.ChangeFileKeys) + } + } + + return r0 +} + +// MockAccountObject_GetAndUnsetFileKeys_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAndUnsetFileKeys' +type MockAccountObject_GetAndUnsetFileKeys_Call struct { + *mock.Call +} + +// GetAndUnsetFileKeys is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) GetAndUnsetFileKeys() *MockAccountObject_GetAndUnsetFileKeys_Call { + return &MockAccountObject_GetAndUnsetFileKeys_Call{Call: _e.mock.On("GetAndUnsetFileKeys")} +} + +func (_c *MockAccountObject_GetAndUnsetFileKeys_Call) Run(run func()) *MockAccountObject_GetAndUnsetFileKeys_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_GetAndUnsetFileKeys_Call) Return(_a0 []pb.ChangeFileKeys) *MockAccountObject_GetAndUnsetFileKeys_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_GetAndUnsetFileKeys_Call) RunAndReturn(run func() []pb.ChangeFileKeys) *MockAccountObject_GetAndUnsetFileKeys_Call { + _c.Call.Return(run) + return _c +} + +// GetDocInfo provides a mock function with given fields: +func (_m *MockAccountObject) GetDocInfo() smartblock.DocInfo { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetDocInfo") + } + + var r0 smartblock.DocInfo + if rf, ok := ret.Get(0).(func() smartblock.DocInfo); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(smartblock.DocInfo) + } + + return r0 +} + +// MockAccountObject_GetDocInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDocInfo' +type MockAccountObject_GetDocInfo_Call struct { + *mock.Call +} + +// GetDocInfo is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) GetDocInfo() *MockAccountObject_GetDocInfo_Call { + return &MockAccountObject_GetDocInfo_Call{Call: _e.mock.On("GetDocInfo")} +} + +func (_c *MockAccountObject_GetDocInfo_Call) Run(run func()) *MockAccountObject_GetDocInfo_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_GetDocInfo_Call) Return(_a0 smartblock.DocInfo) *MockAccountObject_GetDocInfo_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_GetDocInfo_Call) RunAndReturn(run func() smartblock.DocInfo) *MockAccountObject_GetDocInfo_Call { + _c.Call.Return(run) + return _c +} + +// GetPrivateAnalyticsId provides a mock function with given fields: +func (_m *MockAccountObject) GetPrivateAnalyticsId() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetPrivateAnalyticsId") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_GetPrivateAnalyticsId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPrivateAnalyticsId' +type MockAccountObject_GetPrivateAnalyticsId_Call struct { + *mock.Call +} + +// GetPrivateAnalyticsId is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) GetPrivateAnalyticsId() *MockAccountObject_GetPrivateAnalyticsId_Call { + return &MockAccountObject_GetPrivateAnalyticsId_Call{Call: _e.mock.On("GetPrivateAnalyticsId")} +} + +func (_c *MockAccountObject_GetPrivateAnalyticsId_Call) Run(run func()) *MockAccountObject_GetPrivateAnalyticsId_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_GetPrivateAnalyticsId_Call) Return(_a0 string) *MockAccountObject_GetPrivateAnalyticsId_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_GetPrivateAnalyticsId_Call) RunAndReturn(run func() string) *MockAccountObject_GetPrivateAnalyticsId_Call { + _c.Call.Return(run) + return _c +} + +// GetRelationLinks provides a mock function with given fields: +func (_m *MockAccountObject) GetRelationLinks() pbtypes.RelationLinks { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for GetRelationLinks") + } + + var r0 pbtypes.RelationLinks + if rf, ok := ret.Get(0).(func() pbtypes.RelationLinks); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(pbtypes.RelationLinks) + } + } + + return r0 +} + +// MockAccountObject_GetRelationLinks_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRelationLinks' +type MockAccountObject_GetRelationLinks_Call struct { + *mock.Call +} + +// GetRelationLinks is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) GetRelationLinks() *MockAccountObject_GetRelationLinks_Call { + return &MockAccountObject_GetRelationLinks_Call{Call: _e.mock.On("GetRelationLinks")} +} + +func (_c *MockAccountObject_GetRelationLinks_Call) Run(run func()) *MockAccountObject_GetRelationLinks_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_GetRelationLinks_Call) Return(_a0 pbtypes.RelationLinks) *MockAccountObject_GetRelationLinks_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_GetRelationLinks_Call) RunAndReturn(run func() pbtypes.RelationLinks) *MockAccountObject_GetRelationLinks_Call { + _c.Call.Return(run) + return _c +} + +// HasRelation provides a mock function with given fields: s, relationKey +func (_m *MockAccountObject) HasRelation(s *state.State, relationKey string) bool { + ret := _m.Called(s, relationKey) + + if len(ret) == 0 { + panic("no return value specified for HasRelation") + } + + var r0 bool + if rf, ok := ret.Get(0).(func(*state.State, string) bool); ok { + r0 = rf(s, relationKey) + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockAccountObject_HasRelation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'HasRelation' +type MockAccountObject_HasRelation_Call struct { + *mock.Call +} + +// HasRelation is a helper method to define mock.On call +// - s *state.State +// - relationKey string +func (_e *MockAccountObject_Expecter) HasRelation(s interface{}, relationKey interface{}) *MockAccountObject_HasRelation_Call { + return &MockAccountObject_HasRelation_Call{Call: _e.mock.On("HasRelation", s, relationKey)} +} + +func (_c *MockAccountObject_HasRelation_Call) Run(run func(s *state.State, relationKey string)) *MockAccountObject_HasRelation_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*state.State), args[1].(string)) + }) + return _c +} + +func (_c *MockAccountObject_HasRelation_Call) Return(_a0 bool) *MockAccountObject_HasRelation_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_HasRelation_Call) RunAndReturn(run func(*state.State, string) bool) *MockAccountObject_HasRelation_Call { + _c.Call.Return(run) + return _c +} + +// History provides a mock function with given fields: +func (_m *MockAccountObject) History() undo.History { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for History") + } + + var r0 undo.History + if rf, ok := ret.Get(0).(func() undo.History); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(undo.History) + } + } + + return r0 +} + +// MockAccountObject_History_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'History' +type MockAccountObject_History_Call struct { + *mock.Call +} + +// History is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) History() *MockAccountObject_History_Call { + return &MockAccountObject_History_Call{Call: _e.mock.On("History")} +} + +func (_c *MockAccountObject_History_Call) Run(run func()) *MockAccountObject_History_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_History_Call) Return(_a0 undo.History) *MockAccountObject_History_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_History_Call) RunAndReturn(run func() undo.History) *MockAccountObject_History_Call { + _c.Call.Return(run) + return _c +} + +// Id provides a mock function with given fields: +func (_m *MockAccountObject) Id() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Id") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_Id_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Id' +type MockAccountObject_Id_Call struct { + *mock.Call +} + +// Id is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Id() *MockAccountObject_Id_Call { + return &MockAccountObject_Id_Call{Call: _e.mock.On("Id")} +} + +func (_c *MockAccountObject_Id_Call) Run(run func()) *MockAccountObject_Id_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Id_Call) Return(_a0 string) *MockAccountObject_Id_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Id_Call) RunAndReturn(run func() string) *MockAccountObject_Id_Call { + _c.Call.Return(run) + return _c +} + +// Init provides a mock function with given fields: ctx +func (_m *MockAccountObject) Init(ctx *smartblock.InitContext) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Init") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*smartblock.InitContext) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_Init_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Init' +type MockAccountObject_Init_Call struct { + *mock.Call +} + +// Init is a helper method to define mock.On call +// - ctx *smartblock.InitContext +func (_e *MockAccountObject_Expecter) Init(ctx interface{}) *MockAccountObject_Init_Call { + return &MockAccountObject_Init_Call{Call: _e.mock.On("Init", ctx)} +} + +func (_c *MockAccountObject_Init_Call) Run(run func(ctx *smartblock.InitContext)) *MockAccountObject_Init_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*smartblock.InitContext)) + }) + return _c +} + +func (_c *MockAccountObject_Init_Call) Return(err error) *MockAccountObject_Init_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_Init_Call) RunAndReturn(run func(*smartblock.InitContext) error) *MockAccountObject_Init_Call { + _c.Call.Return(run) + return _c +} + +// IsDeleted provides a mock function with given fields: +func (_m *MockAccountObject) IsDeleted() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsDeleted") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockAccountObject_IsDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsDeleted' +type MockAccountObject_IsDeleted_Call struct { + *mock.Call +} + +// IsDeleted is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) IsDeleted() *MockAccountObject_IsDeleted_Call { + return &MockAccountObject_IsDeleted_Call{Call: _e.mock.On("IsDeleted")} +} + +func (_c *MockAccountObject_IsDeleted_Call) Run(run func()) *MockAccountObject_IsDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_IsDeleted_Call) Return(_a0 bool) *MockAccountObject_IsDeleted_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_IsDeleted_Call) RunAndReturn(run func() bool) *MockAccountObject_IsDeleted_Call { + _c.Call.Return(run) + return _c +} + +// IsIconMigrated provides a mock function with given fields: +func (_m *MockAccountObject) IsIconMigrated() (bool, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsIconMigrated") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func() (bool, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAccountObject_IsIconMigrated_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsIconMigrated' +type MockAccountObject_IsIconMigrated_Call struct { + *mock.Call +} + +// IsIconMigrated is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) IsIconMigrated() *MockAccountObject_IsIconMigrated_Call { + return &MockAccountObject_IsIconMigrated_Call{Call: _e.mock.On("IsIconMigrated")} +} + +func (_c *MockAccountObject_IsIconMigrated_Call) Run(run func()) *MockAccountObject_IsIconMigrated_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_IsIconMigrated_Call) Return(_a0 bool, _a1 error) *MockAccountObject_IsIconMigrated_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAccountObject_IsIconMigrated_Call) RunAndReturn(run func() (bool, error)) *MockAccountObject_IsIconMigrated_Call { + _c.Call.Return(run) + return _c +} + +// IsLocked provides a mock function with given fields: +func (_m *MockAccountObject) IsLocked() bool { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for IsLocked") + } + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// MockAccountObject_IsLocked_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsLocked' +type MockAccountObject_IsLocked_Call struct { + *mock.Call +} + +// IsLocked is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) IsLocked() *MockAccountObject_IsLocked_Call { + return &MockAccountObject_IsLocked_Call{Call: _e.mock.On("IsLocked")} +} + +func (_c *MockAccountObject_IsLocked_Call) Run(run func()) *MockAccountObject_IsLocked_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_IsLocked_Call) Return(_a0 bool) *MockAccountObject_IsLocked_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_IsLocked_Call) RunAndReturn(run func() bool) *MockAccountObject_IsLocked_Call { + _c.Call.Return(run) + return _c +} + +// Iterate provides a mock function with given fields: f +func (_m *MockAccountObject) Iterate(f func(simple.Block) bool) error { + ret := _m.Called(f) + + if len(ret) == 0 { + panic("no return value specified for Iterate") + } + + var r0 error + if rf, ok := ret.Get(0).(func(func(simple.Block) bool) error); ok { + r0 = rf(f) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_Iterate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Iterate' +type MockAccountObject_Iterate_Call struct { + *mock.Call +} + +// Iterate is a helper method to define mock.On call +// - f func(simple.Block) bool +func (_e *MockAccountObject_Expecter) Iterate(f interface{}) *MockAccountObject_Iterate_Call { + return &MockAccountObject_Iterate_Call{Call: _e.mock.On("Iterate", f)} +} + +func (_c *MockAccountObject_Iterate_Call) Run(run func(f func(simple.Block) bool)) *MockAccountObject_Iterate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(func(simple.Block) bool)) + }) + return _c +} + +func (_c *MockAccountObject_Iterate_Call) Return(err error) *MockAccountObject_Iterate_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_Iterate_Call) RunAndReturn(run func(func(simple.Block) bool) error) *MockAccountObject_Iterate_Call { + _c.Call.Return(run) + return _c +} + +// Layout provides a mock function with given fields: +func (_m *MockAccountObject) Layout() (model.ObjectTypeLayout, bool) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Layout") + } + + var r0 model.ObjectTypeLayout + var r1 bool + if rf, ok := ret.Get(0).(func() (model.ObjectTypeLayout, bool)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() model.ObjectTypeLayout); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(model.ObjectTypeLayout) + } + + if rf, ok := ret.Get(1).(func() bool); ok { + r1 = rf() + } else { + r1 = ret.Get(1).(bool) + } + + return r0, r1 +} + +// MockAccountObject_Layout_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Layout' +type MockAccountObject_Layout_Call struct { + *mock.Call +} + +// Layout is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Layout() *MockAccountObject_Layout_Call { + return &MockAccountObject_Layout_Call{Call: _e.mock.On("Layout")} +} + +func (_c *MockAccountObject_Layout_Call) Run(run func()) *MockAccountObject_Layout_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Layout_Call) Return(_a0 model.ObjectTypeLayout, _a1 bool) *MockAccountObject_Layout_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAccountObject_Layout_Call) RunAndReturn(run func() (model.ObjectTypeLayout, bool)) *MockAccountObject_Layout_Call { + _c.Call.Return(run) + return _c +} + +// LocalDetails provides a mock function with given fields: +func (_m *MockAccountObject) LocalDetails() *types.Struct { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for LocalDetails") + } + + var r0 *types.Struct + if rf, ok := ret.Get(0).(func() *types.Struct); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Struct) + } + } + + return r0 +} + +// MockAccountObject_LocalDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LocalDetails' +type MockAccountObject_LocalDetails_Call struct { + *mock.Call +} + +// LocalDetails is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) LocalDetails() *MockAccountObject_LocalDetails_Call { + return &MockAccountObject_LocalDetails_Call{Call: _e.mock.On("LocalDetails")} +} + +func (_c *MockAccountObject_LocalDetails_Call) Run(run func()) *MockAccountObject_LocalDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_LocalDetails_Call) Return(_a0 *types.Struct) *MockAccountObject_LocalDetails_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_LocalDetails_Call) RunAndReturn(run func() *types.Struct) *MockAccountObject_LocalDetails_Call { + _c.Call.Return(run) + return _c +} + +// Lock provides a mock function with given fields: +func (_m *MockAccountObject) Lock() { + _m.Called() +} + +// MockAccountObject_Lock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Lock' +type MockAccountObject_Lock_Call struct { + *mock.Call +} + +// Lock is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Lock() *MockAccountObject_Lock_Call { + return &MockAccountObject_Lock_Call{Call: _e.mock.On("Lock")} +} + +func (_c *MockAccountObject_Lock_Call) Run(run func()) *MockAccountObject_Lock_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Lock_Call) Return() *MockAccountObject_Lock_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_Lock_Call) RunAndReturn(run func()) *MockAccountObject_Lock_Call { + _c.Call.Return(run) + return _c +} + +// MigrateIconImage provides a mock function with given fields: image +func (_m *MockAccountObject) MigrateIconImage(image string) error { + ret := _m.Called(image) + + if len(ret) == 0 { + panic("no return value specified for MigrateIconImage") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(image) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_MigrateIconImage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'MigrateIconImage' +type MockAccountObject_MigrateIconImage_Call struct { + *mock.Call +} + +// MigrateIconImage is a helper method to define mock.On call +// - image string +func (_e *MockAccountObject_Expecter) MigrateIconImage(image interface{}) *MockAccountObject_MigrateIconImage_Call { + return &MockAccountObject_MigrateIconImage_Call{Call: _e.mock.On("MigrateIconImage", image)} +} + +func (_c *MockAccountObject_MigrateIconImage_Call) Run(run func(image string)) *MockAccountObject_MigrateIconImage_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *MockAccountObject_MigrateIconImage_Call) Return(err error) *MockAccountObject_MigrateIconImage_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_MigrateIconImage_Call) RunAndReturn(run func(string) error) *MockAccountObject_MigrateIconImage_Call { + _c.Call.Return(run) + return _c +} + +// NewState provides a mock function with given fields: +func (_m *MockAccountObject) NewState() *state.State { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for NewState") + } + + var r0 *state.State + if rf, ok := ret.Get(0).(func() *state.State); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.State) + } + } + + return r0 +} + +// MockAccountObject_NewState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewState' +type MockAccountObject_NewState_Call struct { + *mock.Call +} + +// NewState is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) NewState() *MockAccountObject_NewState_Call { + return &MockAccountObject_NewState_Call{Call: _e.mock.On("NewState")} +} + +func (_c *MockAccountObject_NewState_Call) Run(run func()) *MockAccountObject_NewState_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_NewState_Call) Return(_a0 *state.State) *MockAccountObject_NewState_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_NewState_Call) RunAndReturn(run func() *state.State) *MockAccountObject_NewState_Call { + _c.Call.Return(run) + return _c +} + +// NewStateCtx provides a mock function with given fields: ctx +func (_m *MockAccountObject) NewStateCtx(ctx session.Context) *state.State { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for NewStateCtx") + } + + var r0 *state.State + if rf, ok := ret.Get(0).(func(session.Context) *state.State); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.State) + } + } + + return r0 +} + +// MockAccountObject_NewStateCtx_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewStateCtx' +type MockAccountObject_NewStateCtx_Call struct { + *mock.Call +} + +// NewStateCtx is a helper method to define mock.On call +// - ctx session.Context +func (_e *MockAccountObject_Expecter) NewStateCtx(ctx interface{}) *MockAccountObject_NewStateCtx_Call { + return &MockAccountObject_NewStateCtx_Call{Call: _e.mock.On("NewStateCtx", ctx)} +} + +func (_c *MockAccountObject_NewStateCtx_Call) Run(run func(ctx session.Context)) *MockAccountObject_NewStateCtx_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(session.Context)) + }) + return _c +} + +func (_c *MockAccountObject_NewStateCtx_Call) Return(_a0 *state.State) *MockAccountObject_NewStateCtx_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_NewStateCtx_Call) RunAndReturn(run func(session.Context) *state.State) *MockAccountObject_NewStateCtx_Call { + _c.Call.Return(run) + return _c +} + +// ObjectClose provides a mock function with given fields: ctx +func (_m *MockAccountObject) ObjectClose(ctx session.Context) { + _m.Called(ctx) +} + +// MockAccountObject_ObjectClose_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ObjectClose' +type MockAccountObject_ObjectClose_Call struct { + *mock.Call +} + +// ObjectClose is a helper method to define mock.On call +// - ctx session.Context +func (_e *MockAccountObject_Expecter) ObjectClose(ctx interface{}) *MockAccountObject_ObjectClose_Call { + return &MockAccountObject_ObjectClose_Call{Call: _e.mock.On("ObjectClose", ctx)} +} + +func (_c *MockAccountObject_ObjectClose_Call) Run(run func(ctx session.Context)) *MockAccountObject_ObjectClose_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(session.Context)) + }) + return _c +} + +func (_c *MockAccountObject_ObjectClose_Call) Return() *MockAccountObject_ObjectClose_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_ObjectClose_Call) RunAndReturn(run func(session.Context)) *MockAccountObject_ObjectClose_Call { + _c.Call.Return(run) + return _c +} + +// ObjectCloseAllSessions provides a mock function with given fields: +func (_m *MockAccountObject) ObjectCloseAllSessions() { + _m.Called() +} + +// MockAccountObject_ObjectCloseAllSessions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ObjectCloseAllSessions' +type MockAccountObject_ObjectCloseAllSessions_Call struct { + *mock.Call +} + +// ObjectCloseAllSessions is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) ObjectCloseAllSessions() *MockAccountObject_ObjectCloseAllSessions_Call { + return &MockAccountObject_ObjectCloseAllSessions_Call{Call: _e.mock.On("ObjectCloseAllSessions")} +} + +func (_c *MockAccountObject_ObjectCloseAllSessions_Call) Run(run func()) *MockAccountObject_ObjectCloseAllSessions_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_ObjectCloseAllSessions_Call) Return() *MockAccountObject_ObjectCloseAllSessions_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_ObjectCloseAllSessions_Call) RunAndReturn(run func()) *MockAccountObject_ObjectCloseAllSessions_Call { + _c.Call.Return(run) + return _c +} + +// ObjectTypeKey provides a mock function with given fields: +func (_m *MockAccountObject) ObjectTypeKey() domain.TypeKey { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ObjectTypeKey") + } + + var r0 domain.TypeKey + if rf, ok := ret.Get(0).(func() domain.TypeKey); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(domain.TypeKey) + } + + return r0 +} + +// MockAccountObject_ObjectTypeKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ObjectTypeKey' +type MockAccountObject_ObjectTypeKey_Call struct { + *mock.Call +} + +// ObjectTypeKey is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) ObjectTypeKey() *MockAccountObject_ObjectTypeKey_Call { + return &MockAccountObject_ObjectTypeKey_Call{Call: _e.mock.On("ObjectTypeKey")} +} + +func (_c *MockAccountObject_ObjectTypeKey_Call) Run(run func()) *MockAccountObject_ObjectTypeKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_ObjectTypeKey_Call) Return(_a0 domain.TypeKey) *MockAccountObject_ObjectTypeKey_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_ObjectTypeKey_Call) RunAndReturn(run func() domain.TypeKey) *MockAccountObject_ObjectTypeKey_Call { + _c.Call.Return(run) + return _c +} + +// ObjectTypeKeys provides a mock function with given fields: +func (_m *MockAccountObject) ObjectTypeKeys() []domain.TypeKey { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for ObjectTypeKeys") + } + + var r0 []domain.TypeKey + if rf, ok := ret.Get(0).(func() []domain.TypeKey); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]domain.TypeKey) + } + } + + return r0 +} + +// MockAccountObject_ObjectTypeKeys_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ObjectTypeKeys' +type MockAccountObject_ObjectTypeKeys_Call struct { + *mock.Call +} + +// ObjectTypeKeys is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) ObjectTypeKeys() *MockAccountObject_ObjectTypeKeys_Call { + return &MockAccountObject_ObjectTypeKeys_Call{Call: _e.mock.On("ObjectTypeKeys")} +} + +func (_c *MockAccountObject_ObjectTypeKeys_Call) Run(run func()) *MockAccountObject_ObjectTypeKeys_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_ObjectTypeKeys_Call) Return(_a0 []domain.TypeKey) *MockAccountObject_ObjectTypeKeys_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_ObjectTypeKeys_Call) RunAndReturn(run func() []domain.TypeKey) *MockAccountObject_ObjectTypeKeys_Call { + _c.Call.Return(run) + return _c +} + +// Pick provides a mock function with given fields: id +func (_m *MockAccountObject) Pick(id string) simple.Block { + ret := _m.Called(id) + + if len(ret) == 0 { + panic("no return value specified for Pick") + } + + var r0 simple.Block + if rf, ok := ret.Get(0).(func(string) simple.Block); ok { + r0 = rf(id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(simple.Block) + } + } + + return r0 +} + +// MockAccountObject_Pick_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Pick' +type MockAccountObject_Pick_Call struct { + *mock.Call +} + +// Pick is a helper method to define mock.On call +// - id string +func (_e *MockAccountObject_Expecter) Pick(id interface{}) *MockAccountObject_Pick_Call { + return &MockAccountObject_Pick_Call{Call: _e.mock.On("Pick", id)} +} + +func (_c *MockAccountObject_Pick_Call) Run(run func(id string)) *MockAccountObject_Pick_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *MockAccountObject_Pick_Call) Return(b simple.Block) *MockAccountObject_Pick_Call { + _c.Call.Return(b) + return _c +} + +func (_c *MockAccountObject_Pick_Call) RunAndReturn(run func(string) simple.Block) *MockAccountObject_Pick_Call { + _c.Call.Return(run) + return _c +} + +// RegisterSession provides a mock function with given fields: _a0 +func (_m *MockAccountObject) RegisterSession(_a0 session.Context) { + _m.Called(_a0) +} + +// MockAccountObject_RegisterSession_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegisterSession' +type MockAccountObject_RegisterSession_Call struct { + *mock.Call +} + +// RegisterSession is a helper method to define mock.On call +// - _a0 session.Context +func (_e *MockAccountObject_Expecter) RegisterSession(_a0 interface{}) *MockAccountObject_RegisterSession_Call { + return &MockAccountObject_RegisterSession_Call{Call: _e.mock.On("RegisterSession", _a0)} +} + +func (_c *MockAccountObject_RegisterSession_Call) Run(run func(_a0 session.Context)) *MockAccountObject_RegisterSession_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(session.Context)) + }) + return _c +} + +func (_c *MockAccountObject_RegisterSession_Call) Return() *MockAccountObject_RegisterSession_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_RegisterSession_Call) RunAndReturn(run func(session.Context)) *MockAccountObject_RegisterSession_Call { + _c.Call.Return(run) + return _c +} + +// Relations provides a mock function with given fields: s +func (_m *MockAccountObject) Relations(s *state.State) relationutils.Relations { + ret := _m.Called(s) + + if len(ret) == 0 { + panic("no return value specified for Relations") + } + + var r0 relationutils.Relations + if rf, ok := ret.Get(0).(func(*state.State) relationutils.Relations); ok { + r0 = rf(s) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(relationutils.Relations) + } + } + + return r0 +} + +// MockAccountObject_Relations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Relations' +type MockAccountObject_Relations_Call struct { + *mock.Call +} + +// Relations is a helper method to define mock.On call +// - s *state.State +func (_e *MockAccountObject_Expecter) Relations(s interface{}) *MockAccountObject_Relations_Call { + return &MockAccountObject_Relations_Call{Call: _e.mock.On("Relations", s)} +} + +func (_c *MockAccountObject_Relations_Call) Run(run func(s *state.State)) *MockAccountObject_Relations_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*state.State)) + }) + return _c +} + +func (_c *MockAccountObject_Relations_Call) Return(_a0 relationutils.Relations) *MockAccountObject_Relations_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Relations_Call) RunAndReturn(run func(*state.State) relationutils.Relations) *MockAccountObject_Relations_Call { + _c.Call.Return(run) + return _c +} + +// RemoveExtraRelations provides a mock function with given fields: ctx, relationKeys +func (_m *MockAccountObject) RemoveExtraRelations(ctx session.Context, relationKeys []string) error { + ret := _m.Called(ctx, relationKeys) + + if len(ret) == 0 { + panic("no return value specified for RemoveExtraRelations") + } + + var r0 error + if rf, ok := ret.Get(0).(func(session.Context, []string) error); ok { + r0 = rf(ctx, relationKeys) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_RemoveExtraRelations_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveExtraRelations' +type MockAccountObject_RemoveExtraRelations_Call struct { + *mock.Call +} + +// RemoveExtraRelations is a helper method to define mock.On call +// - ctx session.Context +// - relationKeys []string +func (_e *MockAccountObject_Expecter) RemoveExtraRelations(ctx interface{}, relationKeys interface{}) *MockAccountObject_RemoveExtraRelations_Call { + return &MockAccountObject_RemoveExtraRelations_Call{Call: _e.mock.On("RemoveExtraRelations", ctx, relationKeys)} +} + +func (_c *MockAccountObject_RemoveExtraRelations_Call) Run(run func(ctx session.Context, relationKeys []string)) *MockAccountObject_RemoveExtraRelations_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(session.Context), args[1].([]string)) + }) + return _c +} + +func (_c *MockAccountObject_RemoveExtraRelations_Call) Return(err error) *MockAccountObject_RemoveExtraRelations_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_RemoveExtraRelations_Call) RunAndReturn(run func(session.Context, []string) error) *MockAccountObject_RemoveExtraRelations_Call { + _c.Call.Return(run) + return _c +} + +// ResetToVersion provides a mock function with given fields: s +func (_m *MockAccountObject) ResetToVersion(s *state.State) error { + ret := _m.Called(s) + + if len(ret) == 0 { + panic("no return value specified for ResetToVersion") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*state.State) error); ok { + r0 = rf(s) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_ResetToVersion_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ResetToVersion' +type MockAccountObject_ResetToVersion_Call struct { + *mock.Call +} + +// ResetToVersion is a helper method to define mock.On call +// - s *state.State +func (_e *MockAccountObject_Expecter) ResetToVersion(s interface{}) *MockAccountObject_ResetToVersion_Call { + return &MockAccountObject_ResetToVersion_Call{Call: _e.mock.On("ResetToVersion", s)} +} + +func (_c *MockAccountObject_ResetToVersion_Call) Run(run func(s *state.State)) *MockAccountObject_ResetToVersion_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*state.State)) + }) + return _c +} + +func (_c *MockAccountObject_ResetToVersion_Call) Return(err error) *MockAccountObject_ResetToVersion_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_ResetToVersion_Call) RunAndReturn(run func(*state.State) error) *MockAccountObject_ResetToVersion_Call { + _c.Call.Return(run) + return _c +} + +// Restrictions provides a mock function with given fields: +func (_m *MockAccountObject) Restrictions() restriction.Restrictions { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Restrictions") + } + + var r0 restriction.Restrictions + if rf, ok := ret.Get(0).(func() restriction.Restrictions); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(restriction.Restrictions) + } + + return r0 +} + +// MockAccountObject_Restrictions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Restrictions' +type MockAccountObject_Restrictions_Call struct { + *mock.Call +} + +// Restrictions is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Restrictions() *MockAccountObject_Restrictions_Call { + return &MockAccountObject_Restrictions_Call{Call: _e.mock.On("Restrictions")} +} + +func (_c *MockAccountObject_Restrictions_Call) Run(run func()) *MockAccountObject_Restrictions_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Restrictions_Call) Return(_a0 restriction.Restrictions) *MockAccountObject_Restrictions_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Restrictions_Call) RunAndReturn(run func() restriction.Restrictions) *MockAccountObject_Restrictions_Call { + _c.Call.Return(run) + return _c +} + +// RootId provides a mock function with given fields: +func (_m *MockAccountObject) RootId() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for RootId") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_RootId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RootId' +type MockAccountObject_RootId_Call struct { + *mock.Call +} + +// RootId is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) RootId() *MockAccountObject_RootId_Call { + return &MockAccountObject_RootId_Call{Call: _e.mock.On("RootId")} +} + +func (_c *MockAccountObject_RootId_Call) Run(run func()) *MockAccountObject_RootId_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_RootId_Call) Return(_a0 string) *MockAccountObject_RootId_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_RootId_Call) RunAndReturn(run func() string) *MockAccountObject_RootId_Call { + _c.Call.Return(run) + return _c +} + +// SearchText provides a mock function with given fields: +func (_m *MockAccountObject) SearchText() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SearchText") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_SearchText_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SearchText' +type MockAccountObject_SearchText_Call struct { + *mock.Call +} + +// SearchText is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) SearchText() *MockAccountObject_SearchText_Call { + return &MockAccountObject_SearchText_Call{Call: _e.mock.On("SearchText")} +} + +func (_c *MockAccountObject_SearchText_Call) Run(run func()) *MockAccountObject_SearchText_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_SearchText_Call) Return(_a0 string) *MockAccountObject_SearchText_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_SearchText_Call) RunAndReturn(run func() string) *MockAccountObject_SearchText_Call { + _c.Call.Return(run) + return _c +} + +// SendEvent provides a mock function with given fields: msgs +func (_m *MockAccountObject) SendEvent(msgs []*pb.EventMessage) { + _m.Called(msgs) +} + +// MockAccountObject_SendEvent_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendEvent' +type MockAccountObject_SendEvent_Call struct { + *mock.Call +} + +// SendEvent is a helper method to define mock.On call +// - msgs []*pb.EventMessage +func (_e *MockAccountObject_Expecter) SendEvent(msgs interface{}) *MockAccountObject_SendEvent_Call { + return &MockAccountObject_SendEvent_Call{Call: _e.mock.On("SendEvent", msgs)} +} + +func (_c *MockAccountObject_SendEvent_Call) Run(run func(msgs []*pb.EventMessage)) *MockAccountObject_SendEvent_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].([]*pb.EventMessage)) + }) + return _c +} + +func (_c *MockAccountObject_SendEvent_Call) Return() *MockAccountObject_SendEvent_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_SendEvent_Call) RunAndReturn(run func([]*pb.EventMessage)) *MockAccountObject_SendEvent_Call { + _c.Call.Return(run) + return _c +} + +// SetAnalyticsId provides a mock function with given fields: analyticsId +func (_m *MockAccountObject) SetAnalyticsId(analyticsId string) error { + ret := _m.Called(analyticsId) + + if len(ret) == 0 { + panic("no return value specified for SetAnalyticsId") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(analyticsId) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_SetAnalyticsId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetAnalyticsId' +type MockAccountObject_SetAnalyticsId_Call struct { + *mock.Call +} + +// SetAnalyticsId is a helper method to define mock.On call +// - analyticsId string +func (_e *MockAccountObject_Expecter) SetAnalyticsId(analyticsId interface{}) *MockAccountObject_SetAnalyticsId_Call { + return &MockAccountObject_SetAnalyticsId_Call{Call: _e.mock.On("SetAnalyticsId", analyticsId)} +} + +func (_c *MockAccountObject_SetAnalyticsId_Call) Run(run func(analyticsId string)) *MockAccountObject_SetAnalyticsId_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string)) + }) + return _c +} + +func (_c *MockAccountObject_SetAnalyticsId_Call) Return(err error) *MockAccountObject_SetAnalyticsId_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_SetAnalyticsId_Call) RunAndReturn(run func(string) error) *MockAccountObject_SetAnalyticsId_Call { + _c.Call.Return(run) + return _c +} + +// SetIsDeleted provides a mock function with given fields: +func (_m *MockAccountObject) SetIsDeleted() { + _m.Called() +} + +// MockAccountObject_SetIsDeleted_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetIsDeleted' +type MockAccountObject_SetIsDeleted_Call struct { + *mock.Call +} + +// SetIsDeleted is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) SetIsDeleted() *MockAccountObject_SetIsDeleted_Call { + return &MockAccountObject_SetIsDeleted_Call{Call: _e.mock.On("SetIsDeleted")} +} + +func (_c *MockAccountObject_SetIsDeleted_Call) Run(run func()) *MockAccountObject_SetIsDeleted_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_SetIsDeleted_Call) Return() *MockAccountObject_SetIsDeleted_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_SetIsDeleted_Call) RunAndReturn(run func()) *MockAccountObject_SetIsDeleted_Call { + _c.Call.Return(run) + return _c +} + +// SetLocker provides a mock function with given fields: locker +func (_m *MockAccountObject) SetLocker(locker smartblock.Locker) { + _m.Called(locker) +} + +// MockAccountObject_SetLocker_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetLocker' +type MockAccountObject_SetLocker_Call struct { + *mock.Call +} + +// SetLocker is a helper method to define mock.On call +// - locker smartblock.Locker +func (_e *MockAccountObject_Expecter) SetLocker(locker interface{}) *MockAccountObject_SetLocker_Call { + return &MockAccountObject_SetLocker_Call{Call: _e.mock.On("SetLocker", locker)} +} + +func (_c *MockAccountObject_SetLocker_Call) Run(run func(locker smartblock.Locker)) *MockAccountObject_SetLocker_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(smartblock.Locker)) + }) + return _c +} + +func (_c *MockAccountObject_SetLocker_Call) Return() *MockAccountObject_SetLocker_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_SetLocker_Call) RunAndReturn(run func(smartblock.Locker)) *MockAccountObject_SetLocker_Call { + _c.Call.Return(run) + return _c +} + +// SetProfileDetails provides a mock function with given fields: details +func (_m *MockAccountObject) SetProfileDetails(details *types.Struct) error { + ret := _m.Called(details) + + if len(ret) == 0 { + panic("no return value specified for SetProfileDetails") + } + + var r0 error + if rf, ok := ret.Get(0).(func(*types.Struct) error); ok { + r0 = rf(details) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_SetProfileDetails_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetProfileDetails' +type MockAccountObject_SetProfileDetails_Call struct { + *mock.Call +} + +// SetProfileDetails is a helper method to define mock.On call +// - details *types.Struct +func (_e *MockAccountObject_Expecter) SetProfileDetails(details interface{}) *MockAccountObject_SetProfileDetails_Call { + return &MockAccountObject_SetProfileDetails_Call{Call: _e.mock.On("SetProfileDetails", details)} +} + +func (_c *MockAccountObject_SetProfileDetails_Call) Run(run func(details *types.Struct)) *MockAccountObject_SetProfileDetails_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(*types.Struct)) + }) + return _c +} + +func (_c *MockAccountObject_SetProfileDetails_Call) Return(err error) *MockAccountObject_SetProfileDetails_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_SetProfileDetails_Call) RunAndReturn(run func(*types.Struct) error) *MockAccountObject_SetProfileDetails_Call { + _c.Call.Return(run) + return _c +} + +// SetSharedSpacesLimit provides a mock function with given fields: limit +func (_m *MockAccountObject) SetSharedSpacesLimit(limit int) error { + ret := _m.Called(limit) + + if len(ret) == 0 { + panic("no return value specified for SetSharedSpacesLimit") + } + + var r0 error + if rf, ok := ret.Get(0).(func(int) error); ok { + r0 = rf(limit) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_SetSharedSpacesLimit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetSharedSpacesLimit' +type MockAccountObject_SetSharedSpacesLimit_Call struct { + *mock.Call +} + +// SetSharedSpacesLimit is a helper method to define mock.On call +// - limit int +func (_e *MockAccountObject_Expecter) SetSharedSpacesLimit(limit interface{}) *MockAccountObject_SetSharedSpacesLimit_Call { + return &MockAccountObject_SetSharedSpacesLimit_Call{Call: _e.mock.On("SetSharedSpacesLimit", limit)} +} + +func (_c *MockAccountObject_SetSharedSpacesLimit_Call) Run(run func(limit int)) *MockAccountObject_SetSharedSpacesLimit_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(int)) + }) + return _c +} + +func (_c *MockAccountObject_SetSharedSpacesLimit_Call) Return(err error) *MockAccountObject_SetSharedSpacesLimit_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockAccountObject_SetSharedSpacesLimit_Call) RunAndReturn(run func(int) error) *MockAccountObject_SetSharedSpacesLimit_Call { + _c.Call.Return(run) + return _c +} + +// SetVerticalAlign provides a mock function with given fields: ctx, align, ids +func (_m *MockAccountObject) SetVerticalAlign(ctx session.Context, align model.BlockVerticalAlign, ids ...string) error { + _va := make([]interface{}, len(ids)) + for _i := range ids { + _va[_i] = ids[_i] + } + var _ca []interface{} + _ca = append(_ca, ctx, align) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for SetVerticalAlign") + } + + var r0 error + if rf, ok := ret.Get(0).(func(session.Context, model.BlockVerticalAlign, ...string) error); ok { + r0 = rf(ctx, align, ids...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccountObject_SetVerticalAlign_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetVerticalAlign' +type MockAccountObject_SetVerticalAlign_Call struct { + *mock.Call +} + +// SetVerticalAlign is a helper method to define mock.On call +// - ctx session.Context +// - align model.BlockVerticalAlign +// - ids ...string +func (_e *MockAccountObject_Expecter) SetVerticalAlign(ctx interface{}, align interface{}, ids ...interface{}) *MockAccountObject_SetVerticalAlign_Call { + return &MockAccountObject_SetVerticalAlign_Call{Call: _e.mock.On("SetVerticalAlign", + append([]interface{}{ctx, align}, ids...)...)} +} + +func (_c *MockAccountObject_SetVerticalAlign_Call) Run(run func(ctx session.Context, align model.BlockVerticalAlign, ids ...string)) *MockAccountObject_SetVerticalAlign_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]string, len(args)-2) + for i, a := range args[2:] { + if a != nil { + variadicArgs[i] = a.(string) + } + } + run(args[0].(session.Context), args[1].(model.BlockVerticalAlign), variadicArgs...) + }) + return _c +} + +func (_c *MockAccountObject_SetVerticalAlign_Call) Return(_a0 error) *MockAccountObject_SetVerticalAlign_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_SetVerticalAlign_Call) RunAndReturn(run func(session.Context, model.BlockVerticalAlign, ...string) error) *MockAccountObject_SetVerticalAlign_Call { + _c.Call.Return(run) + return _c +} + +// Show provides a mock function with given fields: +func (_m *MockAccountObject) Show() (*model.ObjectView, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Show") + } + + var r0 *model.ObjectView + var r1 error + if rf, ok := ret.Get(0).(func() (*model.ObjectView, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() *model.ObjectView); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.ObjectView) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAccountObject_Show_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Show' +type MockAccountObject_Show_Call struct { + *mock.Call +} + +// Show is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Show() *MockAccountObject_Show_Call { + return &MockAccountObject_Show_Call{Call: _e.mock.On("Show")} +} + +func (_c *MockAccountObject_Show_Call) Run(run func()) *MockAccountObject_Show_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Show_Call) Return(obj *model.ObjectView, err error) *MockAccountObject_Show_Call { + _c.Call.Return(obj, err) + return _c +} + +func (_c *MockAccountObject_Show_Call) RunAndReturn(run func() (*model.ObjectView, error)) *MockAccountObject_Show_Call { + _c.Call.Return(run) + return _c +} + +// Snippet provides a mock function with given fields: +func (_m *MockAccountObject) Snippet() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Snippet") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_Snippet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Snippet' +type MockAccountObject_Snippet_Call struct { + *mock.Call +} + +// Snippet is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Snippet() *MockAccountObject_Snippet_Call { + return &MockAccountObject_Snippet_Call{Call: _e.mock.On("Snippet")} +} + +func (_c *MockAccountObject_Snippet_Call) Run(run func()) *MockAccountObject_Snippet_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Snippet_Call) Return(snippet string) *MockAccountObject_Snippet_Call { + _c.Call.Return(snippet) + return _c +} + +func (_c *MockAccountObject_Snippet_Call) RunAndReturn(run func() string) *MockAccountObject_Snippet_Call { + _c.Call.Return(run) + return _c +} + +// Space provides a mock function with given fields: +func (_m *MockAccountObject) Space() smartblock.Space { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Space") + } + + var r0 smartblock.Space + if rf, ok := ret.Get(0).(func() smartblock.Space); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(smartblock.Space) + } + } + + return r0 +} + +// MockAccountObject_Space_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Space' +type MockAccountObject_Space_Call struct { + *mock.Call +} + +// Space is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Space() *MockAccountObject_Space_Call { + return &MockAccountObject_Space_Call{Call: _e.mock.On("Space")} +} + +func (_c *MockAccountObject_Space_Call) Run(run func()) *MockAccountObject_Space_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Space_Call) Return(_a0 smartblock.Space) *MockAccountObject_Space_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Space_Call) RunAndReturn(run func() smartblock.Space) *MockAccountObject_Space_Call { + _c.Call.Return(run) + return _c +} + +// SpaceID provides a mock function with given fields: +func (_m *MockAccountObject) SpaceID() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for SpaceID") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_SpaceID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SpaceID' +type MockAccountObject_SpaceID_Call struct { + *mock.Call +} + +// SpaceID is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) SpaceID() *MockAccountObject_SpaceID_Call { + return &MockAccountObject_SpaceID_Call{Call: _e.mock.On("SpaceID")} +} + +func (_c *MockAccountObject_SpaceID_Call) Run(run func()) *MockAccountObject_SpaceID_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_SpaceID_Call) Return(_a0 string) *MockAccountObject_SpaceID_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_SpaceID_Call) RunAndReturn(run func() string) *MockAccountObject_SpaceID_Call { + _c.Call.Return(run) + return _c +} + +// Tree provides a mock function with given fields: +func (_m *MockAccountObject) Tree() objecttree.ObjectTree { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Tree") + } + + var r0 objecttree.ObjectTree + if rf, ok := ret.Get(0).(func() objecttree.ObjectTree); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(objecttree.ObjectTree) + } + } + + return r0 +} + +// MockAccountObject_Tree_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Tree' +type MockAccountObject_Tree_Call struct { + *mock.Call +} + +// Tree is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Tree() *MockAccountObject_Tree_Call { + return &MockAccountObject_Tree_Call{Call: _e.mock.On("Tree")} +} + +func (_c *MockAccountObject_Tree_Call) Run(run func()) *MockAccountObject_Tree_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Tree_Call) Return(_a0 objecttree.ObjectTree) *MockAccountObject_Tree_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Tree_Call) RunAndReturn(run func() objecttree.ObjectTree) *MockAccountObject_Tree_Call { + _c.Call.Return(run) + return _c +} + +// TryClose provides a mock function with given fields: objectTTL +func (_m *MockAccountObject) TryClose(objectTTL time.Duration) (bool, error) { + ret := _m.Called(objectTTL) + + if len(ret) == 0 { + panic("no return value specified for TryClose") + } + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(time.Duration) (bool, error)); ok { + return rf(objectTTL) + } + if rf, ok := ret.Get(0).(func(time.Duration) bool); ok { + r0 = rf(objectTTL) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(time.Duration) error); ok { + r1 = rf(objectTTL) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAccountObject_TryClose_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TryClose' +type MockAccountObject_TryClose_Call struct { + *mock.Call +} + +// TryClose is a helper method to define mock.On call +// - objectTTL time.Duration +func (_e *MockAccountObject_Expecter) TryClose(objectTTL interface{}) *MockAccountObject_TryClose_Call { + return &MockAccountObject_TryClose_Call{Call: _e.mock.On("TryClose", objectTTL)} +} + +func (_c *MockAccountObject_TryClose_Call) Run(run func(objectTTL time.Duration)) *MockAccountObject_TryClose_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(time.Duration)) + }) + return _c +} + +func (_c *MockAccountObject_TryClose_Call) Return(res bool, err error) *MockAccountObject_TryClose_Call { + _c.Call.Return(res, err) + return _c +} + +func (_c *MockAccountObject_TryClose_Call) RunAndReturn(run func(time.Duration) (bool, error)) *MockAccountObject_TryClose_Call { + _c.Call.Return(run) + return _c +} + +// Type provides a mock function with given fields: +func (_m *MockAccountObject) Type() coresmartblock.SmartBlockType { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Type") + } + + var r0 coresmartblock.SmartBlockType + if rf, ok := ret.Get(0).(func() coresmartblock.SmartBlockType); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(coresmartblock.SmartBlockType) + } + + return r0 +} + +// MockAccountObject_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type MockAccountObject_Type_Call struct { + *mock.Call +} + +// Type is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Type() *MockAccountObject_Type_Call { + return &MockAccountObject_Type_Call{Call: _e.mock.On("Type")} +} + +func (_c *MockAccountObject_Type_Call) Run(run func()) *MockAccountObject_Type_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Type_Call) Return(_a0 coresmartblock.SmartBlockType) *MockAccountObject_Type_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_Type_Call) RunAndReturn(run func() coresmartblock.SmartBlockType) *MockAccountObject_Type_Call { + _c.Call.Return(run) + return _c +} + +// UniqueKey provides a mock function with given fields: +func (_m *MockAccountObject) UniqueKey() domain.UniqueKey { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for UniqueKey") + } + + var r0 domain.UniqueKey + if rf, ok := ret.Get(0).(func() domain.UniqueKey); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(domain.UniqueKey) + } + } + + return r0 +} + +// MockAccountObject_UniqueKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UniqueKey' +type MockAccountObject_UniqueKey_Call struct { + *mock.Call +} + +// UniqueKey is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) UniqueKey() *MockAccountObject_UniqueKey_Call { + return &MockAccountObject_UniqueKey_Call{Call: _e.mock.On("UniqueKey")} +} + +func (_c *MockAccountObject_UniqueKey_Call) Run(run func()) *MockAccountObject_UniqueKey_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_UniqueKey_Call) Return(_a0 domain.UniqueKey) *MockAccountObject_UniqueKey_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_UniqueKey_Call) RunAndReturn(run func() domain.UniqueKey) *MockAccountObject_UniqueKey_Call { + _c.Call.Return(run) + return _c +} + +// UniqueKeyInternal provides a mock function with given fields: +func (_m *MockAccountObject) UniqueKeyInternal() string { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for UniqueKeyInternal") + } + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// MockAccountObject_UniqueKeyInternal_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UniqueKeyInternal' +type MockAccountObject_UniqueKeyInternal_Call struct { + *mock.Call +} + +// UniqueKeyInternal is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) UniqueKeyInternal() *MockAccountObject_UniqueKeyInternal_Call { + return &MockAccountObject_UniqueKeyInternal_Call{Call: _e.mock.On("UniqueKeyInternal")} +} + +func (_c *MockAccountObject_UniqueKeyInternal_Call) Run(run func()) *MockAccountObject_UniqueKeyInternal_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_UniqueKeyInternal_Call) Return(_a0 string) *MockAccountObject_UniqueKeyInternal_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccountObject_UniqueKeyInternal_Call) RunAndReturn(run func() string) *MockAccountObject_UniqueKeyInternal_Call { + _c.Call.Return(run) + return _c +} + +// Unlock provides a mock function with given fields: +func (_m *MockAccountObject) Unlock() { + _m.Called() +} + +// MockAccountObject_Unlock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unlock' +type MockAccountObject_Unlock_Call struct { + *mock.Call +} + +// Unlock is a helper method to define mock.On call +func (_e *MockAccountObject_Expecter) Unlock() *MockAccountObject_Unlock_Call { + return &MockAccountObject_Unlock_Call{Call: _e.mock.On("Unlock")} +} + +func (_c *MockAccountObject_Unlock_Call) Run(run func()) *MockAccountObject_Unlock_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockAccountObject_Unlock_Call) Return() *MockAccountObject_Unlock_Call { + _c.Call.Return() + return _c +} + +func (_c *MockAccountObject_Unlock_Call) RunAndReturn(run func()) *MockAccountObject_Unlock_Call { + _c.Call.Return(run) + return _c +} + +// NewMockAccountObject creates a new instance of MockAccountObject. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockAccountObject(t interface { + mock.TestingT + Cleanup(func()) +}) *MockAccountObject { + mock := &MockAccountObject{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/space/techspace/mock_techspace/mock_SpaceView.go b/space/techspace/mock_techspace/mock_SpaceView.go index f011e75d2a..273046a8a2 100644 --- a/space/techspace/mock_techspace/mock_SpaceView.go +++ b/space/techspace/mock_techspace/mock_SpaceView.go @@ -483,6 +483,53 @@ func (_c *MockSpaceView_SetInviteFileInfo_Call) RunAndReturn(run func(string, st return _c } +// SetOwner provides a mock function with given fields: ownerId, createdDate +func (_m *MockSpaceView) SetOwner(ownerId string, createdDate int64) error { + ret := _m.Called(ownerId, createdDate) + + if len(ret) == 0 { + panic("no return value specified for SetOwner") + } + + var r0 error + if rf, ok := ret.Get(0).(func(string, int64) error); ok { + r0 = rf(ownerId, createdDate) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockSpaceView_SetOwner_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetOwner' +type MockSpaceView_SetOwner_Call struct { + *mock.Call +} + +// SetOwner is a helper method to define mock.On call +// - ownerId string +// - createdDate int64 +func (_e *MockSpaceView_Expecter) SetOwner(ownerId interface{}, createdDate interface{}) *MockSpaceView_SetOwner_Call { + return &MockSpaceView_SetOwner_Call{Call: _e.mock.On("SetOwner", ownerId, createdDate)} +} + +func (_c *MockSpaceView_SetOwner_Call) Run(run func(ownerId string, createdDate int64)) *MockSpaceView_SetOwner_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(int64)) + }) + return _c +} + +func (_c *MockSpaceView_SetOwner_Call) Return(err error) *MockSpaceView_SetOwner_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockSpaceView_SetOwner_Call) RunAndReturn(run func(string, int64) error) *MockSpaceView_SetOwner_Call { + _c.Call.Return(run) + return _c +} + // SetSharedSpacesLimit provides a mock function with given fields: limits func (_m *MockSpaceView) SetSharedSpacesLimit(limits int) error { ret := _m.Called(limits) diff --git a/space/techspace/mock_techspace/mock_TechSpace.go b/space/techspace/mock_techspace/mock_TechSpace.go index 802683a4a5..829a5ae192 100644 --- a/space/techspace/mock_techspace/mock_TechSpace.go +++ b/space/techspace/mock_techspace/mock_TechSpace.go @@ -32,6 +32,61 @@ func (_m *MockTechSpace) EXPECT() *MockTechSpace_Expecter { return &MockTechSpace_Expecter{mock: &_m.Mock} } +// AccountObjectId provides a mock function with given fields: +func (_m *MockTechSpace) AccountObjectId() (string, error) { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for AccountObjectId") + } + + var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockTechSpace_AccountObjectId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AccountObjectId' +type MockTechSpace_AccountObjectId_Call struct { + *mock.Call +} + +// AccountObjectId is a helper method to define mock.On call +func (_e *MockTechSpace_Expecter) AccountObjectId() *MockTechSpace_AccountObjectId_Call { + return &MockTechSpace_AccountObjectId_Call{Call: _e.mock.On("AccountObjectId")} +} + +func (_c *MockTechSpace_AccountObjectId_Call) Run(run func()) *MockTechSpace_AccountObjectId_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockTechSpace_AccountObjectId_Call) Return(_a0 string, _a1 error) *MockTechSpace_AccountObjectId_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockTechSpace_AccountObjectId_Call) RunAndReturn(run func() (string, error)) *MockTechSpace_AccountObjectId_Call { + _c.Call.Return(run) + return _c +} + // Close provides a mock function with given fields: ctx func (_m *MockTechSpace) Close(ctx context.Context) error { ret := _m.Called(ctx) @@ -78,6 +133,53 @@ func (_c *MockTechSpace_Close_Call) RunAndReturn(run func(context.Context) error return _c } +// DoAccountObject provides a mock function with given fields: ctx, apply +func (_m *MockTechSpace) DoAccountObject(ctx context.Context, apply func(techspace.AccountObject) error) error { + ret := _m.Called(ctx, apply) + + if len(ret) == 0 { + panic("no return value specified for DoAccountObject") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, func(techspace.AccountObject) error) error); ok { + r0 = rf(ctx, apply) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockTechSpace_DoAccountObject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DoAccountObject' +type MockTechSpace_DoAccountObject_Call struct { + *mock.Call +} + +// DoAccountObject is a helper method to define mock.On call +// - ctx context.Context +// - apply func(techspace.AccountObject) error +func (_e *MockTechSpace_Expecter) DoAccountObject(ctx interface{}, apply interface{}) *MockTechSpace_DoAccountObject_Call { + return &MockTechSpace_DoAccountObject_Call{Call: _e.mock.On("DoAccountObject", ctx, apply)} +} + +func (_c *MockTechSpace_DoAccountObject_Call) Run(run func(ctx context.Context, apply func(techspace.AccountObject) error)) *MockTechSpace_DoAccountObject_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(func(techspace.AccountObject) error)) + }) + return _c +} + +func (_c *MockTechSpace_DoAccountObject_Call) Return(err error) *MockTechSpace_DoAccountObject_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockTechSpace_DoAccountObject_Call) RunAndReturn(run func(context.Context, func(techspace.AccountObject) error) error) *MockTechSpace_DoAccountObject_Call { + _c.Call.Return(run) + return _c +} + // DoSpaceView provides a mock function with given fields: ctx, spaceID, apply func (_m *MockTechSpace) DoSpaceView(ctx context.Context, spaceID string, apply func(techspace.SpaceView) error) error { ret := _m.Called(ctx, spaceID, apply) @@ -276,17 +378,17 @@ func (_c *MockTechSpace_Name_Call) RunAndReturn(run func() string) *MockTechSpac return _c } -// Run provides a mock function with given fields: techCoreSpace, objectCache -func (_m *MockTechSpace) Run(techCoreSpace commonspace.Space, objectCache objectcache.Cache) error { - ret := _m.Called(techCoreSpace, objectCache) +// Run provides a mock function with given fields: techCoreSpace, objectCache, create +func (_m *MockTechSpace) Run(techCoreSpace commonspace.Space, objectCache objectcache.Cache, create bool) error { + ret := _m.Called(techCoreSpace, objectCache, create) if len(ret) == 0 { panic("no return value specified for Run") } var r0 error - if rf, ok := ret.Get(0).(func(commonspace.Space, objectcache.Cache) error); ok { - r0 = rf(techCoreSpace, objectCache) + if rf, ok := ret.Get(0).(func(commonspace.Space, objectcache.Cache, bool) error); ok { + r0 = rf(techCoreSpace, objectCache, create) } else { r0 = ret.Error(0) } @@ -302,13 +404,14 @@ type MockTechSpace_Run_Call struct { // Run is a helper method to define mock.On call // - techCoreSpace commonspace.Space // - objectCache objectcache.Cache -func (_e *MockTechSpace_Expecter) Run(techCoreSpace interface{}, objectCache interface{}) *MockTechSpace_Run_Call { - return &MockTechSpace_Run_Call{Call: _e.mock.On("Run", techCoreSpace, objectCache)} +// - create bool +func (_e *MockTechSpace_Expecter) Run(techCoreSpace interface{}, objectCache interface{}, create interface{}) *MockTechSpace_Run_Call { + return &MockTechSpace_Run_Call{Call: _e.mock.On("Run", techCoreSpace, objectCache, create)} } -func (_c *MockTechSpace_Run_Call) Run(run func(techCoreSpace commonspace.Space, objectCache objectcache.Cache)) *MockTechSpace_Run_Call { +func (_c *MockTechSpace_Run_Call) Run(run func(techCoreSpace commonspace.Space, objectCache objectcache.Cache, create bool)) *MockTechSpace_Run_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(commonspace.Space), args[1].(objectcache.Cache)) + run(args[0].(commonspace.Space), args[1].(objectcache.Cache), args[2].(bool)) }) return _c } @@ -318,7 +421,7 @@ func (_c *MockTechSpace_Run_Call) Return(err error) *MockTechSpace_Run_Call { return _c } -func (_c *MockTechSpace_Run_Call) RunAndReturn(run func(commonspace.Space, objectcache.Cache) error) *MockTechSpace_Run_Call { +func (_c *MockTechSpace_Run_Call) RunAndReturn(run func(commonspace.Space, objectcache.Cache, bool) error) *MockTechSpace_Run_Call { _c.Call.Return(run) return _c } diff --git a/space/techspace/techspace.go b/space/techspace/techspace.go index 1400b78c3b..dfd1971285 100644 --- a/space/techspace/techspace.go +++ b/space/techspace/techspace.go @@ -9,6 +9,7 @@ import ( "github.com/anyproto/any-sync/app" "github.com/anyproto/any-sync/app/logger" "github.com/anyproto/any-sync/commonspace" + "github.com/anyproto/any-sync/commonspace/object/tree/treestorage" "github.com/anyproto/any-sync/net/peer" "github.com/gogo/protobuf/types" "go.uber.org/zap" @@ -35,15 +36,27 @@ var ( ErrNotStarted = errors.New("techspace not started") ) +type AccountObject interface { + editorsb.SmartBlock + SetSharedSpacesLimit(limit int) (err error) + SetProfileDetails(details *types.Struct) (err error) + MigrateIconImage(image string) (err error) + IsIconMigrated() (bool, error) + SetAnalyticsId(analyticsId string) (err error) + GetAnalyticsId() (string, error) + GetPrivateAnalyticsId() string +} + type TechSpace interface { app.Component - Run(techCoreSpace commonspace.Space, objectCache objectcache.Cache) (err error) + Run(techCoreSpace commonspace.Space, objectCache objectcache.Cache, create bool) (err error) Close(ctx context.Context) (err error) WakeUpViews() WaitViews() error TechSpaceId() string DoSpaceView(ctx context.Context, spaceID string, apply func(spaceView SpaceView) error) (err error) + DoAccountObject(ctx context.Context, apply func(accountObject AccountObject) error) (err error) SpaceViewCreate(ctx context.Context, spaceId string, force bool, info spaceinfo.SpacePersistentInfo) (err error) GetSpaceView(ctx context.Context, spaceId string) (SpaceView, error) SpaceViewExists(ctx context.Context, spaceId string) (exists bool, err error) @@ -51,6 +64,7 @@ type TechSpace interface { SetPersistentInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) (err error) SpaceViewSetData(ctx context.Context, spaceId string, details *types.Struct) (err error) SpaceViewId(id string) (string, error) + AccountObjectId() (string, error) } type SpaceView interface { @@ -62,6 +76,7 @@ type SpaceView interface { SetInviteFileInfo(fileCid string, fileKey string) (err error) SetAccessType(acc spaceinfo.AccessType) error SetAclIsEmpty(isEmpty bool) (err error) + SetOwner(ownerId string, createdDate int64) (err error) SetSpacePersistentInfo(info spaceinfo.SpacePersistentInfo) error RemoveExistingInviteInfo() (fileCid string, err error) GetSpaceDescription() (data spaceinfo.SpaceDescription) @@ -79,8 +94,9 @@ func New() TechSpace { } type techSpace struct { - techCore commonspace.Space - objectCache objectcache.Cache + techCore commonspace.Space + objectCache objectcache.Cache + accountObjectId string mu sync.Mutex @@ -99,10 +115,16 @@ func (s *techSpace) Name() (name string) { return CName } -func (s *techSpace) Run(techCoreSpace commonspace.Space, objectCache objectcache.Cache) (err error) { +func (s *techSpace) Run(techCoreSpace commonspace.Space, objectCache objectcache.Cache, create bool) (err error) { s.techCore = techCoreSpace s.objectCache = objectCache - return + if !create { + exists, err := s.accountObjectExists(s.ctx) + if err != nil || exists { + return err + } + } + return s.accountObjectCreate(s.ctx) } func (s *techSpace) WakeUpViews() { @@ -194,6 +216,18 @@ func (s *techSpace) SpaceViewExists(ctx context.Context, spaceId string) (exists return getErr == nil, nil } +func (s *techSpace) accountObjectExists(ctx context.Context) (exists bool, err error) { + objId, err := s.AccountObjectId() + if err != nil { + return + } + ctx, cancel := context.WithTimeout(ctx, spaceViewCheckTimeout) + defer cancel() + ctx = peer.CtxWithPeerId(ctx, peer.CtxResponsiblePeers) + _, getErr := s.objectCache.GetObject(ctx, objId) + return getErr == nil, nil +} + func (s *techSpace) GetSpaceView(ctx context.Context, spaceId string) (SpaceView, error) { viewId, err := s.getViewIdLocked(ctx, spaceId) if err != nil { @@ -240,6 +274,50 @@ func (s *techSpace) spaceViewCreate(ctx context.Context, spaceID string, info sp return } +func (s *techSpace) accountObjectCreate(ctx context.Context) (err error) { + uniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeAccountObject, s.techCore.Id()) + if err != nil { + return + } + initFunc := func(id string) *editorsb.InitContext { + st := state.NewDoc(id, nil).(*state.State) + return &editorsb.InitContext{Ctx: ctx, SpaceID: s.techCore.Id(), State: st} + } + _, err = s.objectCache.DeriveTreeObject(ctx, objectcache.TreeDerivationParams{ + Key: uniqueKey, + InitFunc: initFunc, + }) + if errors.Is(err, treestorage.ErrTreeExists) { + accId, err := s.AccountObjectId() + if err != nil { + return err + } + _, err = s.objectCache.GetObject(ctx, accId) + return err + } + return +} + +func (s *techSpace) AccountObjectId() (string, error) { + s.mu.Lock() + defer s.mu.Unlock() + if s.accountObjectId != "" { + return s.accountObjectId, nil + } + uniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeAccountObject, s.techCore.Id()) + if err != nil { + return "", err + } + payload, err := s.objectCache.DeriveTreePayload(context.Background(), payloadcreator.PayloadDerivationParams{ + Key: uniqueKey, + }) + if err != nil { + return "", err + } + s.accountObjectId = payload.RootRawChange.Id + return payload.RootRawChange.Id, nil +} + func (s *techSpace) deriveSpaceViewID(ctx context.Context, spaceID string) (string, error) { uniqueKey, err := domain.NewUniqueKey(smartblock.SmartBlockTypeSpaceView, spaceID) if err != nil { @@ -273,6 +351,26 @@ func (s *techSpace) DoSpaceView(ctx context.Context, spaceID string, apply func( return apply(spaceView) } +func (s *techSpace) DoAccountObject(ctx context.Context, apply func(accountObject AccountObject) error) (err error) { + id, err := s.AccountObjectId() + if err != nil { + return err + } + obj, err := s.objectCache.GetObject(ctx, id) + if err != nil { + // TODO: [PS] check specific error + return ErrSpaceViewNotExists + } + accountObject, ok := obj.(AccountObject) + if !ok { + return ErrNotASpaceView + } + + accountObject.Lock() + defer accountObject.Unlock() + return apply(accountObject) +} + func (s *techSpace) getViewIdLocked(ctx context.Context, spaceId string) (viewId string, err error) { s.mu.Lock() defer s.mu.Unlock() diff --git a/space/techspace/techspace_test.go b/space/techspace/techspace_test.go index 167d77b442..1092b36bee 100644 --- a/space/techspace/techspace_test.go +++ b/space/techspace/techspace_test.go @@ -31,9 +31,10 @@ var ctx = context.Background() const ( testTechSpaceId = "techspaceId" + accountObjectId = "accountObjectId" ) -func TestTechSpace_Init(t *testing.T) { +func TestTechSpace_Run(t *testing.T) { var initIDs = []string{"1", "2", "3"} fx := newFixture(t, initIDs) defer fx.finish(t) @@ -58,6 +59,10 @@ func (s *spaceViewStub) GetSharedSpacesLimit() (limits int) { return } +func (s *spaceViewStub) SetOwner(owner string, createdDate int64) (err error) { + return +} + func (s *spaceViewStub) GetPersistentInfo() spaceinfo.SpacePersistentInfo { return spaceinfo.NewSpacePersistentInfo("spaceId") } @@ -115,7 +120,7 @@ func TestTechSpace_SpaceViewCreate(t *testing.T) { defer fx.finish(t) fx.expectDeriveTreePayload(viewId) - fx.objectCache.EXPECT().GetObject(ctx, viewId).Return(nil, fmt.Errorf("not found")) + fx.objectCache.EXPECT().GetObject(ctx, viewId).Return(nil, fmt.Errorf("not found")).Times(1) fx.objectCache.EXPECT().DeriveTreeObject(ctx, mock.Anything).Return(view, nil) info := spaceinfo.NewSpacePersistentInfo(spaceId) info.SetAccountStatus(spaceinfo.AccountStatusUnknown) @@ -341,9 +346,20 @@ func newFixture(t *testing.T, storeIDs []string) *fixture { // expect wakeUpIds fx.techCore.EXPECT().Id().Return(testTechSpaceId).AnyTimes() + fx.objectCache.EXPECT().DeriveTreePayload(ctx, mock.Anything).Return(treestorage.TreeStorageCreatePayload{ + RootRawChange: &treechangeproto.RawTreeChangeWithId{ + Id: accountObjectId, + }, + }, nil).Times(1) + fx.objectCache.EXPECT().GetObject(mock.Anything, accountObjectId).RunAndReturn(func(ctx context.Context, id string) (smartblock.SmartBlock, error) { + peerId, err := peer.CtxPeerId(ctx) + require.NoError(t, err) + require.Equal(t, peer.CtxResponsiblePeers, peerId) + return nil, nil + }).Times(1) require.NoError(t, fx.a.Start(ctx)) - err := fx.TechSpace.Run(fx.techCore, fx.objectCache) + err := fx.TechSpace.Run(fx.techCore, fx.objectCache, false) require.NoError(t, err) // do not cancel wakeUpIds func @@ -357,7 +373,7 @@ func (fx *fixture) expectDeriveTreePayload(viewId string) { RootRawChange: &treechangeproto.RawTreeChangeWithId{ Id: viewId, }, - }, nil) + }, nil).Times(1) } func (fx *fixture) finish(t *testing.T) { diff --git a/tantivity_sha256.txt b/tantivity_sha256.txt index e7ab01e6f0..41995da24f 100644 --- a/tantivity_sha256.txt +++ b/tantivity_sha256.txt @@ -1,11 +1,11 @@ -7a472fd61b7c32b1aecc130a0d65a0b1e36f404c97144b2dc993c7bfe628ea6b deps/libs/android-386.tar.gz -7c3902588b98d6c4951124b8ded78b956448483a057c03e7ef85cb05182a7afd deps/libs/android-amd64.tar.gz -f12a6a9b2904a67a7cec36863a65dc128b8efd9c6968db29bb7904ca79040381 deps/libs/android-arm.tar.gz -d15a085afb2887a839697080101772525b614667924c5df98aa212ae3d72a825 deps/libs/android-arm64.tar.gz -dc6eca09d7946dbf0b0fd7615be555edfc6d6f1be9a47dd757d90626a6d05c09 deps/libs/darwin-amd64.tar.gz -216a751320edb4e5e737ebeb7eb3181fbdab71f2ec4d441621ce723056a5bc03 deps/libs/darwin-arm64.tar.gz -87d629216a127eb29064cb3d1dca63ef360d1920330bfcbecf0ca78e35f37756 deps/libs/ios-amd64.tar.gz -4a82c10a149f84073af08f2cf85dce680fd3301fc7cd19279227dddd60effbcc deps/libs/ios-arm64.tar.gz -b55ecde8d30fd38ab12ffe2d51415b2c7a74ff5af7b61cd35c401345a33a482d deps/libs/ios-arm64-sim.tar.gz -a514c9e61dd8e6fea7c5236cf359ffd14bc2fd5db52fc1ca8b0e3df10a00cbcd deps/libs/linux-amd64-musl.tar.gz -3bbab5b3a28cab4306b3ced4dd0c60f06a85e01592367ccf910f3a59c7db674b deps/libs/windows-amd64.tar.gz +29584474bc680356df77090a57f4268e8fa5e6797e9ba17ca9a718ac0efcfabc deps/libs/android-386.tar.gz +534e30ea899e2809ef9fb09e34d4f427f5f52c012da96ba97445f5c069fe7055 deps/libs/android-amd64.tar.gz +7604f462b242eb1e59b44ccf5a783d752debe5b183bd79a5f2a0328ccc7bdd62 deps/libs/android-arm.tar.gz +be507777dc121fa02b401596108a5d9b8631c635a95d7d118ad4a4382085eeea deps/libs/android-arm64.tar.gz +cc21b1df7d08bffdc7995ea77cffdb9df1401af3e8c2bcbe842ce4921cf1a3d1 deps/libs/darwin-amd64.tar.gz +e36998bfa4105f259371918af2f7f77da0e883f55da774eb4a05da6aea70ce9f deps/libs/darwin-arm64.tar.gz +40623f7e2c83b46cb8571b69749e95776b5a582562fec6a9cfc4b152394ecdeb deps/libs/ios-amd64.tar.gz +0600440e398f973805ff2204e502431451cb8e62b3c7243d19a8e5eb2cf5c765 deps/libs/ios-arm64.tar.gz +282753feadb97da0b4d43db23e66638d461d3e247b17ada869eb05a45f084d0c deps/libs/ios-arm64-sim.tar.gz +0d5fb12feedca0d6e94592be5c29a1164d556a2175005a565ae8dea4d55069bd deps/libs/linux-amd64-musl.tar.gz +2eb806b64a6eb2154ad69f3bdc65ee8f912da4b9405ec4f3f9eec097cd74b90a deps/libs/windows-amd64.tar.gz diff --git a/tests/blockbuilder/constructors.go b/tests/blockbuilder/constructors.go index 41665307cf..7c199f1036 100644 --- a/tests/blockbuilder/constructors.go +++ b/tests/blockbuilder/constructors.go @@ -7,6 +7,7 @@ import ( "github.com/globalsign/mgo/bson" "github.com/gogo/protobuf/types" + "github.com/anyproto/anytype-heart/core/block/simple" "github.com/anyproto/anytype-heart/pkg/lib/pb/model" "github.com/anyproto/anytype-heart/util/pbtypes" ) @@ -53,6 +54,15 @@ func (b *Block) Build() []*model.Block { }, descendants...) } +func (b *Block) BuildMap() map[string]simple.Block { + blocks := b.Build() + res := make(map[string]simple.Block, len(blocks)) + for _, bl := range blocks { + res[bl.Id] = simple.New(bl) + } + return res +} + func mkBlock(b *model.Block, opts ...Option) *Block { o := options{ // Init children for easier equality check in tests diff --git a/tests/integration/util_test.go b/tests/integration/util_test.go index 67e6523e0f..9975eb0eab 100644 --- a/tests/integration/util_test.go +++ b/tests/integration/util_test.go @@ -116,6 +116,7 @@ func newTestSubscription(t *testing.T, app *testApplication, keys []domain.Relat subscriptionId := bson.NewObjectId().Hex() subscriptionService := getService[subscription.Service](app) _, err := subscriptionService.Search(subscription.SubscribeRequest{ + SpaceId: app.account.Info.AccountSpaceId, SubId: subscriptionId, Keys: keysConverted, Filters: filters, diff --git a/util/bufferpool/buffer.go b/util/bufferpool/buffer.go index eeb34b0939..25e1919582 100644 --- a/util/bufferpool/buffer.go +++ b/util/bufferpool/buffer.go @@ -20,6 +20,16 @@ type buffer struct { closed bool } +func (b *buffer) Close() error { + b.m.Lock() + defer b.m.Unlock() + if !b.closed { + b.pool.Put(b.buf) + b.closed = true + } + return nil +} + // GetReadSeekCloser returns a ReadSeekCloser that reads from the buffer. // GetReadSeekCloser after Close will return EOF. // It's a responsibility of the caller to Close the ReadSeekCloser to put the buffer back into the pool. @@ -47,12 +57,3 @@ func (b *buffer) Write(p []byte) (n int, err error) { // Close puts the buffer back into the pool. // Close after GetReadSeekCloser does nothing. -func (b *buffer) Close() error { - b.m.Lock() - defer b.m.Unlock() - if !b.closed { - b.pool.Put(b.buf) - b.closed = true - } - return nil -} diff --git a/util/builtinobjects/builtinobjects.go b/util/builtinobjects/builtinobjects.go index bb8466f867..2162c954a3 100644 --- a/util/builtinobjects/builtinobjects.go +++ b/util/builtinobjects/builtinobjects.go @@ -102,11 +102,7 @@ var ( {model.BlockContentWidget_CompactList, widget.DefaultWidgetRecent, "", false}, }, pb.RpcObjectImportUseCaseRequest_GET_STARTED: { - {model.BlockContentWidget_Tree, "bafyreib54qrvlara5ickx4sk7mtdmeuwnyrmsdwrrrmvw7rhluwd3mwkg4", "", true}, - {model.BlockContentWidget_List, "bafyreifvmvqmlmrzzdd4db5gau4fcdhxbii4pkanjdvcjbofmmywhg3zni", "f984ddde-eb13-497e-809a-2b9a96fd3503", true}, - {model.BlockContentWidget_List, widget.DefaultWidgetFavorite, "", false}, - {model.BlockContentWidget_CompactList, widget.DefaultWidgetSet, "", false}, - {model.BlockContentWidget_CompactList, widget.DefaultWidgetRecent, "", false}, + {model.BlockContentWidget_Tree, "bafyreia4uol63iev5ywhiqdqf4trh44ep2j27rlrvmypd65adg4ntnihn4", "", true}, }, pb.RpcObjectImportUseCaseRequest_PERSONAL_PROJECTS: { {model.BlockContentWidget_CompactList, widget.DefaultWidgetFavorite, "", false}, @@ -458,7 +454,7 @@ func (b *builtinObjects) createWidgets(ctx session.Context, spaceId string, useC func (b *builtinObjects) getNewObjectID(spaceID string, oldID string) (id string, err error) { var ids []string - if ids, _, err = b.store.QueryObjectIDs(database.Query{ + if ids, _, err = b.store.SpaceIndex(spaceID).QueryObjectIds(database.Query{ Filters: []*model.BlockContentDataviewFilter{ { Condition: model.BlockContentDataviewFilter_Equal, diff --git a/util/builtinobjects/data/get_started.zip b/util/builtinobjects/data/get_started.zip index e9fde2a531..19f3e4362f 100644 Binary files a/util/builtinobjects/data/get_started.zip and b/util/builtinobjects/data/get_started.zip differ diff --git a/util/builtintemplate/builtintemplate.go b/util/builtintemplate/builtintemplate.go index 3118ce7118..cb295cb995 100644 --- a/util/builtintemplate/builtintemplate.go +++ b/util/builtintemplate/builtintemplate.go @@ -114,7 +114,7 @@ func (b *builtinTemplate) registerBuiltin(space clientspace.Space, rd io.ReadClo st.SetLocalDetail(bundle.RelationKeySpaceId.String(), pbtypes.String(addr.AnytypeMarketplaceWorkspace)) st.SetDetail(bundle.RelationKeyOrigin.String(), pbtypes.Int64(int64(model.ObjectOrigin_builtin))) - err = b.setObjectTypes(st) + err = b.setObjectTypes(st, "TODO") if err != nil { return fmt.Errorf("set object types: %w", err) } @@ -151,14 +151,14 @@ func (b *builtinTemplate) registerBuiltin(space clientspace.Space, rd io.ReadClo }) } -func (b *builtinTemplate) setObjectTypes(st *state.State) error { +func (b *builtinTemplate) setObjectTypes(st *state.State, spaceId string) error { targetObjectTypeID := pbtypes.GetString(st.Details(), bundle.RelationKeyTargetObjectType.String()) var targetObjectTypeKey domain.TypeKey if strings.HasPrefix(targetObjectTypeID, addr.BundledObjectTypeURLPrefix) { // todo: remove this hack after fixing bundled templates targetObjectTypeKey = domain.TypeKey(strings.TrimPrefix(targetObjectTypeID, addr.BundledObjectTypeURLPrefix)) } else { - targetObjectType, err := b.objectStore.GetObjectType(targetObjectTypeID) + targetObjectType, err := b.objectStore.SpaceIndex(spaceId).GetObjectType(targetObjectTypeID) if err != nil { return fmt.Errorf("get object type %s: %w", targetObjectTypeID, err) } diff --git a/util/builtintemplate/builtintemplate_test.go b/util/builtintemplate/builtintemplate_test.go index 9ecfcdc20c..9c7a4f5ee5 100644 --- a/util/builtintemplate/builtintemplate_test.go +++ b/util/builtintemplate/builtintemplate_test.go @@ -10,26 +10,26 @@ import ( "go.uber.org/mock/gomock" "github.com/anyproto/anytype-heart/core/anytype/config" + "github.com/anyproto/anytype-heart/core/block/source/mock_source" "github.com/anyproto/anytype-heart/pkg/lib/localstore/addr" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore/mock_objectstore" - mock_space "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" + "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" + "github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace" "github.com/anyproto/anytype-heart/tests/testutil" - "github.com/anyproto/anytype-heart/util/testMock/mockSource" ) func Test_registerBuiltin(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() - sourceService := mockSource.NewMockService(ctrl) - sourceService.EXPECT().NewStaticSource(gomock.Any()).AnyTimes() - sourceService.EXPECT().RegisterStaticSource(gomock.Any()).AnyTimes() + sourceService := mock_source.NewMockService(t) + sourceService.EXPECT().NewStaticSource(mock.Anything).Return(nil).Maybe() + sourceService.EXPECT().RegisterStaticSource(mock.Anything).Return(nil).Maybe() - marketplaceSpace := mock_space.NewMockSpace(t) + marketplaceSpace := mock_clientspace.NewMockSpace(t) marketplaceSpace.EXPECT().Id().Return(addr.AnytypeMarketplaceWorkspace) marketplaceSpace.EXPECT().Do(mock.Anything, mock.Anything).Return(nil) - objectStore := mock_objectstore.NewMockObjectStore(t) + objectStore := objectstore.NewStoreFixture(t) builtInTemplates := New() @@ -38,7 +38,7 @@ func Test_registerBuiltin(t *testing.T) { a.Register(testutil.PrepareMock(ctx, a, sourceService)) a.Register(builtInTemplates) a.Register(config.New()) - a.Register(testutil.PrepareMock(ctx, a, objectStore)) + a.Register(objectStore) err := builtInTemplates.Init(a) assert.NoError(t, err) diff --git a/util/contexthelper/context.go b/util/contexthelper/context.go new file mode 100644 index 0000000000..8778dfabb3 --- /dev/null +++ b/util/contexthelper/context.go @@ -0,0 +1,24 @@ +package contexthelper + +import "context" + +// ContextWithCloseChan returns a context that is canceled when either the parent context +// is canceled or when the provided close channel is closed. +func ContextWithCloseChan(ctx context.Context, closeChan <-chan struct{}) (context.Context, context.CancelFunc) { + // Create a new context that can be canceled + newCtx, cancel := context.WithCancel(ctx) + + // Start a goroutine that waits for either the closeChan to be closed or + // the new context to be canceled + go func() { + select { + case <-closeChan: + cancel() + case <-newCtx.Done(): + // newCtx is canceled, goroutine exits + } + }() + + // Return the cancel function + return newCtx, cancel +} diff --git a/util/contexthelper/context_test.go b/util/contexthelper/context_test.go new file mode 100644 index 0000000000..614bc419dd --- /dev/null +++ b/util/contexthelper/context_test.go @@ -0,0 +1,126 @@ +package contexthelper + +import ( + "context" + "sync" + "testing" + "time" +) + +func TestContextWithCloseChan_CloseChanCancellation(t *testing.T) { + parentCtx := context.Background() + closeChan := make(chan struct{}) + ctx, cancelFunc := ContextWithCloseChan(parentCtx, closeChan) + defer cancelFunc() // Ensure resources are released + + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + select { + case <-ctx.Done(): + // Expected to be canceled when closeChan is closed + case <-time.After(1 * time.Second): + t.Error("context was not canceled when closeChan was closed") + } + }() + + // Close the closeChan to trigger cancellation + close(closeChan) + + wg.Wait() + + // Verify that the context was canceled + if ctx.Err() == nil { + t.Error("context error is nil, expected cancellation error") + } +} + +func TestContextWithCloseChan_ParentContextCancellation(t *testing.T) { + parentCtx, parentCancel := context.WithCancel(context.Background()) + closeChan := make(chan struct{}) + ctx, cancelFunc := ContextWithCloseChan(parentCtx, closeChan) + defer cancelFunc() // Ensure resources are released + + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + select { + case <-ctx.Done(): + // Expected to be canceled when parentCtx is canceled + case <-time.After(1 * time.Second): + t.Error("context was not canceled when parent context was canceled") + } + }() + + // Cancel the parent context + parentCancel() + + wg.Wait() + + // Verify that the context was canceled + if ctx.Err() == nil { + t.Error("context error is nil, expected cancellation error") + } +} + +func TestContextWithCloseChan_NoCancellation(t *testing.T) { + parentCtx := context.Background() + closeChan := make(chan struct{}) + ctx, cancelFunc := ContextWithCloseChan(parentCtx, closeChan) + defer cancelFunc() // Ensure resources are released + + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + select { + case <-ctx.Done(): + t.Error("context was canceled unexpectedly") + case <-time.After(50 * time.Millisecond): + // Expected to timeout here as neither context nor closeChan is canceled + } + }() + + wg.Wait() + + // Verify that the context is still active + if ctx.Err() != nil { + t.Errorf("context error is %v, expected nil", ctx.Err()) + } +} + +func TestContextWithCloseChan_BothCancellation(t *testing.T) { + parentCtx, parentCancel := context.WithCancel(context.Background()) + closeChan := make(chan struct{}) + ctx, cancelFunc := ContextWithCloseChan(parentCtx, closeChan) + defer cancelFunc() // Ensure resources are released + + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + select { + case <-ctx.Done(): + // Expected to be canceled + case <-time.After(1 * time.Second): + t.Error("context was not canceled when both parent context and closeChan were canceled") + } + }() + + // Cancel both parent context and closeChan + parentCancel() + close(closeChan) + + wg.Wait() + + // Verify that the context was canceled + if ctx.Err() == nil { + t.Error("context error is nil, expected cancellation error") + } +} diff --git a/util/pbtypes/json.go b/util/pbtypes/anyenc.go similarity index 71% rename from util/pbtypes/json.go rename to util/pbtypes/anyenc.go index 3bb06d818d..394719a507 100644 --- a/util/pbtypes/json.go +++ b/util/pbtypes/anyenc.go @@ -4,11 +4,11 @@ import ( "bytes" "fmt" + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" - "github.com/valyala/fastjson" ) -func JsonToProto(v *fastjson.Value) (*types.Struct, error) { +func AnyEncToProto(v *anyenc.Value) (*types.Struct, error) { obj, err := v.Object() if err != nil { return nil, fmt.Errorf("is object: %w", err) @@ -17,12 +17,12 @@ func JsonToProto(v *fastjson.Value) (*types.Struct, error) { Fields: make(map[string]*types.Value, obj.Len()), } var visitErr error - obj.Visit(func(k []byte, v *fastjson.Value) { + obj.Visit(func(k []byte, v *anyenc.Value) { if visitErr != nil { return } // key is copied - val, err := JsonValueToProto(v) + val, err := AnyEncValueToProto(v) if err != nil { visitErr = err } @@ -31,32 +31,32 @@ func JsonToProto(v *fastjson.Value) (*types.Struct, error) { return res, visitErr } -func JsonValueToProto(val *fastjson.Value) (*types.Value, error) { +func AnyEncValueToProto(val *anyenc.Value) (*types.Value, error) { switch val.Type() { - case fastjson.TypeNumber: + case anyenc.TypeNumber: v, err := val.Float64() if err != nil { return nil, fmt.Errorf("float64: %w", err) } return Float64(v), nil - case fastjson.TypeString: + case anyenc.TypeString: v, err := val.StringBytes() if err != nil { return nil, fmt.Errorf("string: %w", err) } return String(string(v)), nil - case fastjson.TypeTrue: + case anyenc.TypeTrue: return Bool(true), nil - case fastjson.TypeFalse: + case anyenc.TypeFalse: return Bool(false), nil - case fastjson.TypeArray: + case anyenc.TypeArray: vals, err := val.Array() if err != nil { return nil, fmt.Errorf("array: %w", err) } lst := make([]*types.Value, 0, len(vals)) for i, v := range vals { - val, err := JsonValueToProto(v) + val, err := AnyEncValueToProto(v) if err != nil { return nil, fmt.Errorf("array item %d: %w", i, err) } @@ -73,15 +73,15 @@ func JsonValueToProto(val *fastjson.Value) (*types.Value, error) { return Null(), nil } -func ProtoToJson(arena *fastjson.Arena, details *types.Struct) *fastjson.Value { +func ProtoToAnyEnc(arena *anyenc.Arena, details *types.Struct) *anyenc.Value { obj := arena.NewObject() for k, v := range details.Fields { - obj.Set(k, ProtoValueToJson(arena, v)) + obj.Set(k, ProtoValueToAnyEnc(arena, v)) } return obj } -func ProtoValueToJson(arena *fastjson.Arena, v *types.Value) *fastjson.Value { +func ProtoValueToAnyEnc(arena *anyenc.Arena, v *types.Value) *anyenc.Value { if v == nil { return arena.NewNull() } @@ -99,7 +99,7 @@ func ProtoValueToJson(arena *fastjson.Arena, v *types.Value) *fastjson.Value { case *types.Value_ListValue: lst := arena.NewArray() for i, v := range v.GetListValue().Values { - lst.SetArrayItem(i, ProtoValueToJson(arena, v)) + lst.SetArrayItem(i, ProtoValueToAnyEnc(arena, v)) } return lst default: @@ -107,21 +107,21 @@ func ProtoValueToJson(arena *fastjson.Arena, v *types.Value) *fastjson.Value { } } -type JsonDiffType int +type AnyEncDiffType int const ( - JsonDiffTypeAdd JsonDiffType = iota - JsonDiffTypeRemove - JsonDiffTypeUpdate + AnyEncDiffTypeAdd AnyEncDiffType = iota + AnyEncDiffTypeRemove + AnyEncDiffTypeUpdate ) -type JsonDiff struct { - Type JsonDiffType +type AnyEncDiff struct { + Type AnyEncDiffType Key string - Value *fastjson.Value + Value *anyenc.Value } -func DiffJson(a *fastjson.Value, b *fastjson.Value) ([]JsonDiff, error) { +func AnyEncJson(a *anyenc.Value, b *anyenc.Value) ([]AnyEncDiff, error) { objA, err := a.Object() if err != nil { return nil, fmt.Errorf("param a is not an object: %w", err) @@ -131,10 +131,10 @@ func DiffJson(a *fastjson.Value, b *fastjson.Value) ([]JsonDiff, error) { return nil, fmt.Errorf("param b is not an object: %w", err) } - var diffs []JsonDiff + var diffs []AnyEncDiff existsA := make(map[string]struct{}, objA.Len()) - objA.Visit(func(key []byte, v *fastjson.Value) { + objA.Visit(func(key []byte, v *anyenc.Value) { existsA[string(key)] = struct{}{} }) @@ -142,29 +142,29 @@ func DiffJson(a *fastjson.Value, b *fastjson.Value) ([]JsonDiff, error) { stop bool visitErr error ) - objB.Visit(func(key []byte, v *fastjson.Value) { + objB.Visit(func(key []byte, v *anyenc.Value) { if stop { return } - strKey := string(key) - if _, ok := existsA[strKey]; ok { - eq, err := compareValue(a.Get(strKey), v) + sKey := string(key) + if _, ok := existsA[sKey]; ok { + eq, err := compareValue(a.Get(sKey), v) if err != nil { visitErr = err stop = true } if !eq { - diffs = append(diffs, JsonDiff{ - Type: JsonDiffTypeUpdate, - Key: strKey, + diffs = append(diffs, AnyEncDiff{ + Type: AnyEncDiffTypeUpdate, + Key: sKey, Value: v, // Holden value, be cautious }) } - delete(existsA, strKey) + delete(existsA, sKey) } else { - diffs = append(diffs, JsonDiff{ - Type: JsonDiffTypeAdd, - Key: strKey, + diffs = append(diffs, AnyEncDiff{ + Type: AnyEncDiffTypeAdd, + Key: sKey, Value: v, // Holden value, be cautious }) } @@ -174,23 +174,23 @@ func DiffJson(a *fastjson.Value, b *fastjson.Value) ([]JsonDiff, error) { } for key := range existsA { - diffs = append(diffs, JsonDiff{ - Type: JsonDiffTypeRemove, + diffs = append(diffs, AnyEncDiff{ + Type: AnyEncDiffTypeRemove, Key: key, }) } return diffs, nil } -func compareValue(a *fastjson.Value, b *fastjson.Value) (bool, error) { +func compareValue(a *anyenc.Value, b *anyenc.Value) (bool, error) { if a.Type() != b.Type() { // Return true, as we have checked that types are equal return false, nil } switch a.Type() { - case fastjson.TypeNull: + case anyenc.TypeNull: return true, nil - case fastjson.TypeNumber: + case anyenc.TypeNumber: af, err := a.Float64() if err != nil { return false, fmt.Errorf("a: get float64: %w", err) @@ -200,7 +200,7 @@ func compareValue(a *fastjson.Value, b *fastjson.Value) (bool, error) { return false, fmt.Errorf("b: get float64: %w", err) } return af == bf, nil - case fastjson.TypeString: + case anyenc.TypeString: as, err := a.StringBytes() if err != nil { return false, fmt.Errorf("a: get string: %w", err) @@ -210,10 +210,10 @@ func compareValue(a *fastjson.Value, b *fastjson.Value) (bool, error) { return false, fmt.Errorf("b: get string: %w", err) } return bytes.Compare(as, bs) == 0, nil - case fastjson.TypeTrue, fastjson.TypeFalse: + case anyenc.TypeTrue, anyenc.TypeFalse: // Return true, as we have checked that types are equal return true, nil - case fastjson.TypeArray: + case anyenc.TypeArray: aa, err := a.Array() if err != nil { return false, fmt.Errorf("a: get array: %w", err) @@ -235,7 +235,7 @@ func compareValue(a *fastjson.Value, b *fastjson.Value) (bool, error) { } } return true, nil - case fastjson.TypeObject: + case anyenc.TypeObject: ao, err := a.Object() if err != nil { return false, fmt.Errorf("a: get object: %w", err) @@ -252,7 +252,7 @@ func compareValue(a *fastjson.Value, b *fastjson.Value) (bool, error) { stop bool visitErr error ) - ao.Visit(func(k []byte, va *fastjson.Value) { + ao.Visit(func(k []byte, va *anyenc.Value) { if stop { return } @@ -280,7 +280,7 @@ func compareValue(a *fastjson.Value, b *fastjson.Value) (bool, error) { return false, nil } -func JsonArrayToStrings(arr []*fastjson.Value) []string { +func AnyEncArrayToStrings(arr []*anyenc.Value) []string { res := make([]string, 0, len(arr)) for _, v := range arr { res = append(res, string(v.GetStringBytes())) @@ -288,7 +288,7 @@ func JsonArrayToStrings(arr []*fastjson.Value) []string { return res } -func StringsToJsonArray(arena *fastjson.Arena, arr []string) *fastjson.Value { +func StringsToAnyEnc(arena *anyenc.Arena, arr []string) *anyenc.Value { res := arena.NewArray() for i, v := range arr { res.SetArrayItem(i, arena.NewString(v)) diff --git a/util/pbtypes/json_test.go b/util/pbtypes/anyenc_test.go similarity index 79% rename from util/pbtypes/json_test.go rename to util/pbtypes/anyenc_test.go index c716d3d727..c9d9f0bc05 100644 --- a/util/pbtypes/json_test.go +++ b/util/pbtypes/anyenc_test.go @@ -3,19 +3,19 @@ package pbtypes import ( "testing" + "github.com/anyproto/any-store/anyenc" "github.com/gogo/protobuf/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/valyala/fastjson" ) func TestJsonToProto(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("empty", func(t *testing.T) { - val := fastjson.MustParse(`{}`) + val := anyenc.MustParseJson(`{}`) - got, err := JsonToProto(val) + got, err := AnyEncToProto(val) require.NoError(t, err) want := &types.Struct{ @@ -23,14 +23,14 @@ func TestJsonToProto(t *testing.T) { } assert.Equal(t, want, got) - gotJson := ProtoToJson(arena, got) - diff, err := DiffJson(val, gotJson) + gotJson := ProtoToAnyEnc(arena, got) + diff, err := AnyEncJson(val, gotJson) require.NoError(t, err) assert.Empty(t, diff) }) t.Run("all types", func(t *testing.T) { - val := fastjson.MustParse(` + val := anyenc.MustParseJson(` { "key1": "value1", "key2": 123, @@ -43,7 +43,7 @@ func TestJsonToProto(t *testing.T) { "key9": {"nestedKey1": "value1", "nestedKey2": 123} }`) - got, err := JsonToProto(val) + got, err := AnyEncToProto(val) require.NoError(t, err) want := &types.Struct{ @@ -61,14 +61,14 @@ func TestJsonToProto(t *testing.T) { } assert.Equal(t, want, got) - gotJson := ProtoToJson(arena, got) - diff, err := DiffJson(val, gotJson) + gotJson := ProtoToAnyEnc(arena, got) + diff, err := AnyEncJson(val, gotJson) require.NoError(t, err) // We don't yet support converting nested objects from JSON to proto - assert.Equal(t, []JsonDiff{ + assert.Equal(t, []AnyEncDiff{ { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key9", Value: arena.NewNull(), }, @@ -78,14 +78,14 @@ func TestJsonToProto(t *testing.T) { } func TestDiffJson(t *testing.T) { - arena := &fastjson.Arena{} + arena := &anyenc.Arena{} t.Run("empty objects -- no changes", func(t *testing.T) { - diff, err := DiffJson(arena.NewObject(), arena.NewObject()) + diff, err := AnyEncJson(arena.NewObject(), arena.NewObject()) require.NoError(t, err) assert.Empty(t, diff) }) t.Run("equal objects", func(t *testing.T) { - fillObject := func(obj *fastjson.Value) { + fillObject := func(obj *anyenc.Value) { obj.Set("key1", arena.NewString("value1")) obj.Set("key2", arena.NewNumberFloat64(42)) obj.Set("key3", arena.NewTrue()) @@ -106,7 +106,7 @@ func TestDiffJson(t *testing.T) { b := arena.NewObject() fillObject(b) - diff, err := DiffJson(a, b) + diff, err := AnyEncJson(a, b) require.NoError(t, err) assert.Empty(t, diff) }) @@ -143,42 +143,42 @@ func TestDiffJson(t *testing.T) { objB.Set("nestedKey2", arena.NewNumberFloat64(123)) b.Set("key7", objB) - diff, err := DiffJson(a, b) + diff, err := AnyEncJson(a, b) require.NoError(t, err) - want := []JsonDiff{ + want := []AnyEncDiff{ { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key1", Value: arena.NewString("value2"), }, { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key2", Value: arena.NewNumberFloat64(43), }, { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key3", Value: arena.NewFalse(), }, { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key4", Value: arena.NewTrue(), }, { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key5", Value: arena.NewFalse(), }, { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key6", Value: arrB, }, { - Type: JsonDiffTypeUpdate, + Type: AnyEncDiffTypeUpdate, Key: "key7", Value: objB, }, @@ -195,11 +195,11 @@ func TestDiffJson(t *testing.T) { b := arena.NewObject() b.Set("key1", arena.NewString("value1")) - diff, err := DiffJson(a, b) + diff, err := AnyEncJson(a, b) require.NoError(t, err) - assert.Equal(t, []JsonDiff{ + assert.Equal(t, []AnyEncDiff{ { - Type: JsonDiffTypeAdd, + Type: AnyEncDiffTypeAdd, Key: "key1", Value: arena.NewString("value1"), }, @@ -210,11 +210,11 @@ func TestDiffJson(t *testing.T) { a.Set("key1", arena.NewString("value1")) b := arena.NewObject() - diff, err := DiffJson(a, b) + diff, err := AnyEncJson(a, b) require.NoError(t, err) - assert.Equal(t, []JsonDiff{ + assert.Equal(t, []AnyEncDiff{ { - Type: JsonDiffTypeRemove, + Type: AnyEncDiffTypeRemove, Key: "key1", }, }, diff) diff --git a/util/pbtypes/pbtypes.go b/util/pbtypes/pbtypes.go index b5d0a1a7b5..66d1ebb853 100644 --- a/util/pbtypes/pbtypes.go +++ b/util/pbtypes/pbtypes.go @@ -398,6 +398,85 @@ func ValueToInterface(v *types.Value) interface{} { } } +func InterfaceToValue(i any) *types.Value { + switch v := i.(type) { + case nil: + return Null() + case float64: + return Float64(v) + case float32: + return Float64(float64(v)) + case int: + return Int64(int64(v)) + case int64: + return Int64(v) + case int32: + return Int64(int64(v)) + case uint: + return Int64(int64(v)) + case uint64: + return Int64(int64(v)) + case uint32: + return Int64(int64(v)) + case string: + return String(v) + case bool: + return Bool(v) + case map[string]any: + fields := make(map[string]*types.Value) + for k, val := range v { + fields[k] = InterfaceToValue(val) + } + return &types.Value{ + Kind: &types.Value_StructValue{StructValue: &types.Struct{Fields: fields}}, + } + case []string: + return StringList(v) + case []int: + vals := make([]*types.Value, len(v)) + for i, val := range v { + vals[i] = Int64(int64(val)) + } + return &types.Value{ + Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: vals}}, + } + case []int64: + vals := make([]*types.Value, len(v)) + for i, val := range v { + vals[i] = Int64(val) + } + return &types.Value{ + Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: vals}}, + } + case []float64: + vals := make([]*types.Value, len(v)) + for i, val := range v { + vals[i] = Float64(val) + } + return &types.Value{ + Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: vals}}, + } + case []bool: + vals := make([]*types.Value, len(v)) + for i, val := range v { + vals[i] = Bool(val) + } + return &types.Value{ + Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: vals}}, + } + case []any: + vals := make([]*types.Value, len(v)) + for i, val := range v { + vals[i] = InterfaceToValue(val) + } + return &types.Value{ + Kind: &types.Value_ListValue{ListValue: &types.ListValue{Values: vals}}, + } + default: + panic(fmt.Sprintf("InterfaceToValue: unsupported type %T", v)) + } +} + // deprecated func BundledRelationIdToKey(id string) (string, error) { if strings.HasPrefix(id, addr.BundledRelationURLPrefix) { diff --git a/util/testMock/anytype.go b/util/testMock/anytype.go deleted file mode 100644 index e10fd1b897..0000000000 --- a/util/testMock/anytype.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:generate mockgen -package testMock -destination anytype_mock.go github.com/anyproto/anytype-heart/pkg/lib/core Service -//go:generate mockgen -package testMock -destination objectstore_mock.go github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore ObjectStore -//go:generate mockgen -package testMock -destination history_mock.go github.com/anyproto/anytype-heart/core/block/undo History -//go:generate mockgen -package testMock -destination sbt_provider_mock.go github.com/anyproto/anytype-heart/space/spacecore/typeprovider SmartBlockTypeProvider -//go:generate mockgen -package testMock -destination file_service_mock.go -mock_names Service=MockFileService github.com/anyproto/anytype-heart/core/files Service,Image,File -package testMock - -import ( - "context" - - "github.com/anyproto/any-sync/app" - "go.uber.org/mock/gomock" - - "github.com/anyproto/anytype-heart/core/kanban" - "github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore" - "github.com/anyproto/anytype-heart/util/testMock/mockKanban" -) - -type App interface { - Register(component app.Component) *app.App -} - -func RegisterMockObjectStore(ctrl *gomock.Controller, ta App) *MockObjectStore { - ms := NewMockObjectStore(ctrl) - ms.EXPECT().Name().AnyTimes().Return(objectstore.CName) - ms.EXPECT().Init(gomock.Any()).AnyTimes() - ms.EXPECT().Run(context.Background()).AnyTimes() - ms.EXPECT().Close(context.Background()).AnyTimes() - ta.Register(ms) - return ms -} - -func RegisterMockKanban(ctrl *gomock.Controller, ta App) *mockKanban.MockService { - ms := mockKanban.NewMockService(ctrl) - ms.EXPECT().Name().AnyTimes().Return(kanban.CName) - ms.EXPECT().Init(gomock.Any()).AnyTimes() - ta.Register(ms) - return ms -} diff --git a/util/testMock/anytype_mock.go b/util/testMock/anytype_mock.go deleted file mode 100644 index 89ba8b397f..0000000000 --- a/util/testMock/anytype_mock.go +++ /dev/null @@ -1,125 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/pkg/lib/core (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package testMock -destination anytype_mock.go github.com/anyproto/anytype-heart/pkg/lib/core Service -// - -// Package testMock is a generated GoMock package. -package testMock - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - gomock "go.uber.org/mock/gomock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockService) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// IsStarted mocks base method. -func (m *MockService) IsStarted() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsStarted") - ret0, _ := ret[0].(bool) - return ret0 -} - -// IsStarted indicates an expected call of IsStarted. -func (mr *MockServiceMockRecorder) IsStarted() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsStarted", reflect.TypeOf((*MockService)(nil).IsStarted)) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} - -// Run mocks base method. -func (m *MockService) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) -} - -// Stop mocks base method. -func (m *MockService) Stop() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Stop") - ret0, _ := ret[0].(error) - return ret0 -} - -// Stop indicates an expected call of Stop. -func (mr *MockServiceMockRecorder) Stop() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockService)(nil).Stop)) -} diff --git a/util/testMock/file_service_mock.go b/util/testMock/file_service_mock.go deleted file mode 100644 index a8924eecfb..0000000000 --- a/util/testMock/file_service_mock.go +++ /dev/null @@ -1,368 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/files (interfaces: Service,Image,File) -// -// Generated by this command: -// -// mockgen -package testMock -destination file_service_mock.go -mock_names Service=MockFileService github.com/anyproto/anytype-heart/core/files Service,Image,File -// - -// Package testMock is a generated GoMock package. -package testMock - -import ( - context "context" - io "io" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - domain "github.com/anyproto/anytype-heart/core/domain" - files "github.com/anyproto/anytype-heart/core/files" - pb "github.com/anyproto/anytype-heart/pb" - storage "github.com/anyproto/anytype-heart/pkg/lib/pb/storage" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" -) - -// MockFileService is a mock of Service interface. -type MockFileService struct { - ctrl *gomock.Controller - recorder *MockFileServiceMockRecorder -} - -// MockFileServiceMockRecorder is the mock recorder for MockFileService. -type MockFileServiceMockRecorder struct { - mock *MockFileService -} - -// NewMockFileService creates a new mock instance. -func NewMockFileService(ctrl *gomock.Controller) *MockFileService { - mock := &MockFileService{ctrl: ctrl} - mock.recorder = &MockFileServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockFileService) EXPECT() *MockFileServiceMockRecorder { - return m.recorder -} - -// FileAdd mocks base method. -func (m *MockFileService) FileAdd(arg0 context.Context, arg1 string, arg2 ...files.AddOption) (*files.AddResult, error) { - m.ctrl.T.Helper() - varargs := []any{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "FileAdd", varargs...) - ret0, _ := ret[0].(*files.AddResult) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FileAdd indicates an expected call of FileAdd. -func (mr *MockFileServiceMockRecorder) FileAdd(arg0, arg1 any, arg2 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileAdd", reflect.TypeOf((*MockFileService)(nil).FileAdd), varargs...) -} - -// FileByHash mocks base method. -func (m *MockFileService) FileByHash(arg0 context.Context, arg1 domain.FullFileId) (files.File, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileByHash", arg0, arg1) - ret0, _ := ret[0].(files.File) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FileByHash indicates an expected call of FileByHash. -func (mr *MockFileServiceMockRecorder) FileByHash(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileByHash", reflect.TypeOf((*MockFileService)(nil).FileByHash), arg0, arg1) -} - -// FileGetKeys mocks base method. -func (m *MockFileService) FileGetKeys(arg0 domain.FileId) (*domain.FileEncryptionKeys, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileGetKeys", arg0) - ret0, _ := ret[0].(*domain.FileEncryptionKeys) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FileGetKeys indicates an expected call of FileGetKeys. -func (mr *MockFileServiceMockRecorder) FileGetKeys(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileGetKeys", reflect.TypeOf((*MockFileService)(nil).FileGetKeys), arg0) -} - -// GetNodeUsage mocks base method. -func (m *MockFileService) GetNodeUsage(arg0 context.Context) (*files.NodeUsageResponse, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNodeUsage", arg0) - ret0, _ := ret[0].(*files.NodeUsageResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetNodeUsage indicates an expected call of GetNodeUsage. -func (mr *MockFileServiceMockRecorder) GetNodeUsage(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNodeUsage", reflect.TypeOf((*MockFileService)(nil).GetNodeUsage), arg0) -} - -// GetSpaceUsage mocks base method. -func (m *MockFileService) GetSpaceUsage(arg0 context.Context, arg1 string) (*pb.RpcFileSpaceUsageResponseUsage, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSpaceUsage", arg0, arg1) - ret0, _ := ret[0].(*pb.RpcFileSpaceUsageResponseUsage) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSpaceUsage indicates an expected call of GetSpaceUsage. -func (mr *MockFileServiceMockRecorder) GetSpaceUsage(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpaceUsage", reflect.TypeOf((*MockFileService)(nil).GetSpaceUsage), arg0, arg1) -} - -// ImageAdd mocks base method. -func (m *MockFileService) ImageAdd(arg0 context.Context, arg1 string, arg2 ...files.AddOption) (*files.AddResult, error) { - m.ctrl.T.Helper() - varargs := []any{arg0, arg1} - for _, a := range arg2 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "ImageAdd", varargs...) - ret0, _ := ret[0].(*files.AddResult) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ImageAdd indicates an expected call of ImageAdd. -func (mr *MockFileServiceMockRecorder) ImageAdd(arg0, arg1 any, arg2 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0, arg1}, arg2...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageAdd", reflect.TypeOf((*MockFileService)(nil).ImageAdd), varargs...) -} - -// ImageByHash mocks base method. -func (m *MockFileService) ImageByHash(arg0 context.Context, arg1 domain.FullFileId) (files.Image, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ImageByHash", arg0, arg1) - ret0, _ := ret[0].(files.Image) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ImageByHash indicates an expected call of ImageByHash. -func (mr *MockFileServiceMockRecorder) ImageByHash(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageByHash", reflect.TypeOf((*MockFileService)(nil).ImageByHash), arg0, arg1) -} - -// Init mocks base method. -func (m *MockFileService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockFileServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockFileService)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockFileService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockFileServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockFileService)(nil).Name)) -} - -// MockImage is a mock of Image interface. -type MockImage struct { - ctrl *gomock.Controller - recorder *MockImageMockRecorder -} - -// MockImageMockRecorder is the mock recorder for MockImage. -type MockImageMockRecorder struct { - mock *MockImage -} - -// NewMockImage creates a new mock instance. -func NewMockImage(ctrl *gomock.Controller) *MockImage { - mock := &MockImage{ctrl: ctrl} - mock.recorder = &MockImageMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockImage) EXPECT() *MockImageMockRecorder { - return m.recorder -} - -// Details mocks base method. -func (m *MockImage) Details(arg0 context.Context) (*types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Details", arg0) - ret0, _ := ret[0].(*types.Struct) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Details indicates an expected call of Details. -func (mr *MockImageMockRecorder) Details(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Details", reflect.TypeOf((*MockImage)(nil).Details), arg0) -} - -// FileId mocks base method. -func (m *MockImage) FileId() domain.FileId { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileId") - ret0, _ := ret[0].(domain.FileId) - return ret0 -} - -// FileId indicates an expected call of FileId. -func (mr *MockImageMockRecorder) FileId() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileId", reflect.TypeOf((*MockImage)(nil).FileId)) -} - -// GetFileForWidth mocks base method. -func (m *MockImage) GetFileForWidth(arg0 int) (files.File, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFileForWidth", arg0) - ret0, _ := ret[0].(files.File) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetFileForWidth indicates an expected call of GetFileForWidth. -func (mr *MockImageMockRecorder) GetFileForWidth(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFileForWidth", reflect.TypeOf((*MockImage)(nil).GetFileForWidth), arg0) -} - -// GetOriginalFile mocks base method. -func (m *MockImage) GetOriginalFile() (files.File, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOriginalFile") - ret0, _ := ret[0].(files.File) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOriginalFile indicates an expected call of GetOriginalFile. -func (mr *MockImageMockRecorder) GetOriginalFile() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOriginalFile", reflect.TypeOf((*MockImage)(nil).GetOriginalFile)) -} - -// MockFile is a mock of File interface. -type MockFile struct { - ctrl *gomock.Controller - recorder *MockFileMockRecorder -} - -// MockFileMockRecorder is the mock recorder for MockFile. -type MockFileMockRecorder struct { - mock *MockFile -} - -// NewMockFile creates a new mock instance. -func NewMockFile(ctrl *gomock.Controller) *MockFile { - mock := &MockFile{ctrl: ctrl} - mock.recorder = &MockFileMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockFile) EXPECT() *MockFileMockRecorder { - return m.recorder -} - -// Details mocks base method. -func (m *MockFile) Details(arg0 context.Context) (*types.Struct, domain.TypeKey, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Details", arg0) - ret0, _ := ret[0].(*types.Struct) - ret1, _ := ret[1].(domain.TypeKey) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// Details indicates an expected call of Details. -func (mr *MockFileMockRecorder) Details(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Details", reflect.TypeOf((*MockFile)(nil).Details), arg0) -} - -// FileId mocks base method. -func (m *MockFile) FileId() domain.FileId { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FileId") - ret0, _ := ret[0].(domain.FileId) - return ret0 -} - -// FileId indicates an expected call of FileId. -func (mr *MockFileMockRecorder) FileId() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FileId", reflect.TypeOf((*MockFile)(nil).FileId)) -} - -// Info mocks base method. -func (m *MockFile) Info() *storage.FileInfo { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Info") - ret0, _ := ret[0].(*storage.FileInfo) - return ret0 -} - -// Info indicates an expected call of Info. -func (mr *MockFileMockRecorder) Info() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockFile)(nil).Info)) -} - -// Meta mocks base method. -func (m *MockFile) Meta() *files.FileMeta { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Meta") - ret0, _ := ret[0].(*files.FileMeta) - return ret0 -} - -// Meta indicates an expected call of Meta. -func (mr *MockFileMockRecorder) Meta() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Meta", reflect.TypeOf((*MockFile)(nil).Meta)) -} - -// Reader mocks base method. -func (m *MockFile) Reader(arg0 context.Context) (io.ReadSeeker, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Reader", arg0) - ret0, _ := ret[0].(io.ReadSeeker) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Reader indicates an expected call of Reader. -func (mr *MockFileMockRecorder) Reader(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reader", reflect.TypeOf((*MockFile)(nil).Reader), arg0) -} diff --git a/util/testMock/history_mock.go b/util/testMock/history_mock.go deleted file mode 100644 index d84515f88e..0000000000 --- a/util/testMock/history_mock.go +++ /dev/null @@ -1,147 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/block/undo (interfaces: History) -// -// Generated by this command: -// -// mockgen -package testMock -destination history_mock.go github.com/anyproto/anytype-heart/core/block/undo History -// - -// Package testMock is a generated GoMock package. -package testMock - -import ( - reflect "reflect" - - undo "github.com/anyproto/anytype-heart/core/block/undo" - gomock "go.uber.org/mock/gomock" -) - -// MockHistory is a mock of History interface. -type MockHistory struct { - ctrl *gomock.Controller - recorder *MockHistoryMockRecorder -} - -// MockHistoryMockRecorder is the mock recorder for MockHistory. -type MockHistoryMockRecorder struct { - mock *MockHistory -} - -// NewMockHistory creates a new mock instance. -func NewMockHistory(ctrl *gomock.Controller) *MockHistory { - mock := &MockHistory{ctrl: ctrl} - mock.recorder = &MockHistoryMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockHistory) EXPECT() *MockHistoryMockRecorder { - return m.recorder -} - -// Add mocks base method. -func (m *MockHistory) Add(arg0 undo.Action) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Add", arg0) -} - -// Add indicates an expected call of Add. -func (mr *MockHistoryMockRecorder) Add(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockHistory)(nil).Add), arg0) -} - -// Counters mocks base method. -func (m *MockHistory) Counters() (int32, int32) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Counters") - ret0, _ := ret[0].(int32) - ret1, _ := ret[1].(int32) - return ret0, ret1 -} - -// Counters indicates an expected call of Counters. -func (mr *MockHistoryMockRecorder) Counters() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Counters", reflect.TypeOf((*MockHistory)(nil).Counters)) -} - -// Len mocks base method. -func (m *MockHistory) Len() int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Len") - ret0, _ := ret[0].(int) - return ret0 -} - -// Len indicates an expected call of Len. -func (mr *MockHistoryMockRecorder) Len() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Len", reflect.TypeOf((*MockHistory)(nil).Len)) -} - -// Next mocks base method. -func (m *MockHistory) Next() (undo.Action, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Next") - ret0, _ := ret[0].(undo.Action) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Next indicates an expected call of Next. -func (mr *MockHistoryMockRecorder) Next() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Next", reflect.TypeOf((*MockHistory)(nil).Next)) -} - -// Previous mocks base method. -func (m *MockHistory) Previous() (undo.Action, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Previous") - ret0, _ := ret[0].(undo.Action) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Previous indicates an expected call of Previous. -func (mr *MockHistoryMockRecorder) Previous() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Previous", reflect.TypeOf((*MockHistory)(nil).Previous)) -} - -// Reset mocks base method. -func (m *MockHistory) Reset() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Reset") -} - -// Reset indicates an expected call of Reset. -func (mr *MockHistoryMockRecorder) Reset() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockHistory)(nil).Reset)) -} - -// SetCarriageBeforeState mocks base method. -func (m *MockHistory) SetCarriageBeforeState(arg0 undo.CarriageState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCarriageBeforeState", arg0) -} - -// SetCarriageBeforeState indicates an expected call of SetCarriageBeforeState. -func (mr *MockHistoryMockRecorder) SetCarriageBeforeState(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCarriageBeforeState", reflect.TypeOf((*MockHistory)(nil).SetCarriageBeforeState), arg0) -} - -// SetCarriageState mocks base method. -func (m *MockHistory) SetCarriageState(arg0 undo.CarriageState) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetCarriageState", arg0) -} - -// SetCarriageState indicates an expected call of SetCarriageState. -func (mr *MockHistoryMockRecorder) SetCarriageState(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetCarriageState", reflect.TypeOf((*MockHistory)(nil).SetCarriageState), arg0) -} diff --git a/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go b/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go deleted file mode 100644 index b82119fe22..0000000000 --- a/util/testMock/mockBuiltinTemplate/builtintemplate_mock.go +++ /dev/null @@ -1,110 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/util/builtintemplate (interfaces: BuiltinTemplate) -// -// Generated by this command: -// -// mockgen -package mockBuiltinTemplate -destination builtintemplate_mock.go github.com/anyproto/anytype-heart/util/builtintemplate BuiltinTemplate -// -// Package mockBuiltinTemplate is a generated GoMock package. -package mockBuiltinTemplate - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - gomock "go.uber.org/mock/gomock" -) - -// MockBuiltinTemplate is a mock of BuiltinTemplate interface. -type MockBuiltinTemplate struct { - ctrl *gomock.Controller - recorder *MockBuiltinTemplateMockRecorder -} - -// MockBuiltinTemplateMockRecorder is the mock recorder for MockBuiltinTemplate. -type MockBuiltinTemplateMockRecorder struct { - mock *MockBuiltinTemplate -} - -// NewMockBuiltinTemplate creates a new mock instance. -func NewMockBuiltinTemplate(ctrl *gomock.Controller) *MockBuiltinTemplate { - mock := &MockBuiltinTemplate{ctrl: ctrl} - mock.recorder = &MockBuiltinTemplateMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBuiltinTemplate) EXPECT() *MockBuiltinTemplateMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockBuiltinTemplate) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockBuiltinTemplateMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockBuiltinTemplate)(nil).Close), arg0) -} - -// Hash mocks base method. -func (m *MockBuiltinTemplate) Hash() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Hash") - ret0, _ := ret[0].(string) - return ret0 -} - -// Hash indicates an expected call of Hash. -func (mr *MockBuiltinTemplateMockRecorder) Hash() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Hash", reflect.TypeOf((*MockBuiltinTemplate)(nil).Hash)) -} - -// Init mocks base method. -func (m *MockBuiltinTemplate) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockBuiltinTemplateMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockBuiltinTemplate)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockBuiltinTemplate) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockBuiltinTemplateMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockBuiltinTemplate)(nil).Name)) -} - -// Run mocks base method. -func (m *MockBuiltinTemplate) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockBuiltinTemplateMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockBuiltinTemplate)(nil).Run), arg0) -} diff --git a/util/testMock/mockCreator/creator_mock.go b/util/testMock/mockCreator/creator_mock.go deleted file mode 100644 index e7a89b09ab..0000000000 --- a/util/testMock/mockCreator/creator_mock.go +++ /dev/null @@ -1,153 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/block/object/objectcreator (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package mockCreator -destination creator_mock.go github.com/anyproto/anytype-heart/core/block/object/objectcreator Service -// -// Package mockCreator is a generated GoMock package. -package mockCreator - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" - - state "github.com/anyproto/anytype-heart/core/block/editor/state" - pb "github.com/anyproto/anytype-heart/pb" - smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// CreateSet mocks base method. -func (m *MockService) CreateSet(arg0 *pb.RpcObjectCreateSetRequest) (string, *types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSet", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(*types.Struct) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// CreateSet indicates an expected call of CreateSet. -func (mr *MockServiceMockRecorder) CreateSet(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSet", reflect.TypeOf((*MockService)(nil).CreateSet), arg0) -} - -// CreateSmartBlockFromState mocks base method. -func (m *MockService) CreateSmartBlockFromState(arg0 context.Context, arg1 smartblock.SmartBlockType, arg2 *types.Struct, arg3 *state.State) (string, *types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSmartBlockFromState", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(*types.Struct) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// CreateSmartBlockFromState indicates an expected call of CreateSmartBlockFromState. -func (mr *MockServiceMockRecorder) CreateSmartBlockFromState(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSmartBlockFromState", reflect.TypeOf((*MockService)(nil).CreateSmartBlockFromState), arg0, arg1, arg2, arg3) -} - -// CreateSmartBlockFromTemplate mocks base method. -func (m *MockService) CreateSmartBlockFromTemplate(arg0 context.Context, arg1 smartblock.SmartBlockType, arg2 *types.Struct, arg3 string) (string, *types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSmartBlockFromTemplate", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(*types.Struct) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// CreateSmartBlockFromTemplate indicates an expected call of CreateSmartBlockFromTemplate. -func (mr *MockServiceMockRecorder) CreateSmartBlockFromTemplate(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSmartBlockFromTemplate", reflect.TypeOf((*MockService)(nil).CreateSmartBlockFromTemplate), arg0, arg1, arg2, arg3) -} - -// CreateSubObjectInWorkspace mocks base method. -func (m *MockService) CreateSubObjectInWorkspace(arg0 *types.Struct, arg1 string) (string, *types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSubObjectInWorkspace", arg0, arg1) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(*types.Struct) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// CreateSubObjectInWorkspace indicates an expected call of CreateSubObjectInWorkspace. -func (mr *MockServiceMockRecorder) CreateSubObjectInWorkspace(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSubObjectInWorkspace", reflect.TypeOf((*MockService)(nil).CreateSubObjectInWorkspace), arg0, arg1) -} - -// CreateSubObjectsInWorkspace mocks base method. -func (m *MockService) CreateSubObjectsInWorkspace(arg0 []*types.Struct) ([]string, []*types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSubObjectsInWorkspace", arg0) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].([]*types.Struct) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// CreateSubObjectsInWorkspace indicates an expected call of CreateSubObjectsInWorkspace. -func (mr *MockServiceMockRecorder) CreateSubObjectsInWorkspace(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSubObjectsInWorkspace", reflect.TypeOf((*MockService)(nil).CreateSubObjectsInWorkspace), arg0) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} diff --git a/util/testMock/mockKanban/kanban.go b/util/testMock/mockKanban/kanban.go deleted file mode 100644 index 95783a9304..0000000000 --- a/util/testMock/mockKanban/kanban.go +++ /dev/null @@ -1,2 +0,0 @@ -//go:generate mockgen -package mockKanban -destination kanban_mock.go github.com/anyproto/anytype-heart/core/kanban Service -package mockKanban diff --git a/util/testMock/mockKanban/kanban_mock.go b/util/testMock/mockKanban/kanban_mock.go deleted file mode 100644 index 5e5aa6a6ff..0000000000 --- a/util/testMock/mockKanban/kanban_mock.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/kanban (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package mockKanban -destination kanban_mock.go github.com/anyproto/anytype-heart/core/kanban Service -// - -// Package mockKanban is a generated GoMock package. -package mockKanban - -import ( - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - kanban "github.com/anyproto/anytype-heart/core/kanban" - gomock "go.uber.org/mock/gomock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// Grouper mocks base method. -func (m *MockService) Grouper(arg0, arg1 string) (kanban.Grouper, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Grouper", arg0, arg1) - ret0, _ := ret[0].(kanban.Grouper) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Grouper indicates an expected call of Grouper. -func (mr *MockServiceMockRecorder) Grouper(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Grouper", reflect.TypeOf((*MockService)(nil).Grouper), arg0, arg1) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} diff --git a/util/testMock/mockSource/source.go b/util/testMock/mockSource/source.go deleted file mode 100644 index 9e5fd6bdc8..0000000000 --- a/util/testMock/mockSource/source.go +++ /dev/null @@ -1,2 +0,0 @@ -//go:generate mockgen -package mockSource -destination source_mock.go github.com/anyproto/anytype-heart/core/block/source Service,Source -package mockSource diff --git a/util/testMock/mockSource/source_mock.go b/util/testMock/mockSource/source_mock.go deleted file mode 100644 index 3004705088..0000000000 --- a/util/testMock/mockSource/source_mock.go +++ /dev/null @@ -1,314 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/block/source (interfaces: Service,Source) -// -// Generated by this command: -// -// mockgen -package mockSource -destination source_mock.go github.com/anyproto/anytype-heart/core/block/source Service,Source -// - -// Package mockSource is a generated GoMock package. -package mockSource - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - state "github.com/anyproto/anytype-heart/core/block/editor/state" - source "github.com/anyproto/anytype-heart/core/block/source" - pb "github.com/anyproto/anytype-heart/pb" - smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// DetailsFromIdBasedSource mocks base method. -func (m *MockService) DetailsFromIdBasedSource(arg0 string) (*types.Struct, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DetailsFromIdBasedSource", arg0) - ret0, _ := ret[0].(*types.Struct) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DetailsFromIdBasedSource indicates an expected call of DetailsFromIdBasedSource. -func (mr *MockServiceMockRecorder) DetailsFromIdBasedSource(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetailsFromIdBasedSource", reflect.TypeOf((*MockService)(nil).DetailsFromIdBasedSource), arg0) -} - -// IDsListerBySmartblockType mocks base method. -func (m *MockService) IDsListerBySmartblockType(arg0 source.Space, arg1 smartblock.SmartBlockType) (source.IDsLister, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IDsListerBySmartblockType", arg0, arg1) - ret0, _ := ret[0].(source.IDsLister) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// IDsListerBySmartblockType indicates an expected call of IDsListerBySmartblockType. -func (mr *MockServiceMockRecorder) IDsListerBySmartblockType(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDsListerBySmartblockType", reflect.TypeOf((*MockService)(nil).IDsListerBySmartblockType), arg0, arg1) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} - -// NewSource mocks base method. -func (m *MockService) NewSource(arg0 context.Context, arg1 source.Space, arg2 string, arg3 source.BuildOptions) (source.Source, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewSource", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].(source.Source) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// NewSource indicates an expected call of NewSource. -func (mr *MockServiceMockRecorder) NewSource(arg0, arg1, arg2, arg3 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewSource", reflect.TypeOf((*MockService)(nil).NewSource), arg0, arg1, arg2, arg3) -} - -// NewStaticSource mocks base method. -func (m *MockService) NewStaticSource(arg0 source.StaticSourceParams) source.SourceWithType { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewStaticSource", arg0) - ret0, _ := ret[0].(source.SourceWithType) - return ret0 -} - -// NewStaticSource indicates an expected call of NewStaticSource. -func (mr *MockServiceMockRecorder) NewStaticSource(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStaticSource", reflect.TypeOf((*MockService)(nil).NewStaticSource), arg0) -} - -// RegisterStaticSource mocks base method. -func (m *MockService) RegisterStaticSource(arg0 source.Source) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RegisterStaticSource", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RegisterStaticSource indicates an expected call of RegisterStaticSource. -func (mr *MockServiceMockRecorder) RegisterStaticSource(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterStaticSource", reflect.TypeOf((*MockService)(nil).RegisterStaticSource), arg0) -} - -// MockSource is a mock of Source interface. -type MockSource struct { - ctrl *gomock.Controller - recorder *MockSourceMockRecorder -} - -// MockSourceMockRecorder is the mock recorder for MockSource. -type MockSourceMockRecorder struct { - mock *MockSource -} - -// NewMockSource creates a new mock instance. -func NewMockSource(ctrl *gomock.Controller) *MockSource { - mock := &MockSource{ctrl: ctrl} - mock.recorder = &MockSourceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSource) EXPECT() *MockSourceMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockSource) Close() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockSourceMockRecorder) Close() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockSource)(nil).Close)) -} - -// GetCreationInfo mocks base method. -func (m *MockSource) GetCreationInfo() (string, int64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCreationInfo") - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(int64) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetCreationInfo indicates an expected call of GetCreationInfo. -func (mr *MockSourceMockRecorder) GetCreationInfo() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCreationInfo", reflect.TypeOf((*MockSource)(nil).GetCreationInfo)) -} - -// GetFileKeysSnapshot mocks base method. -func (m *MockSource) GetFileKeysSnapshot() []*pb.ChangeFileKeys { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetFileKeysSnapshot") - ret0, _ := ret[0].([]*pb.ChangeFileKeys) - return ret0 -} - -// GetFileKeysSnapshot indicates an expected call of GetFileKeysSnapshot. -func (mr *MockSourceMockRecorder) GetFileKeysSnapshot() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFileKeysSnapshot", reflect.TypeOf((*MockSource)(nil).GetFileKeysSnapshot)) -} - -// Heads mocks base method. -func (m *MockSource) Heads() []string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Heads") - ret0, _ := ret[0].([]string) - return ret0 -} - -// Heads indicates an expected call of Heads. -func (mr *MockSourceMockRecorder) Heads() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Heads", reflect.TypeOf((*MockSource)(nil).Heads)) -} - -// Id mocks base method. -func (m *MockSource) Id() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Id") - ret0, _ := ret[0].(string) - return ret0 -} - -// Id indicates an expected call of Id. -func (mr *MockSourceMockRecorder) Id() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Id", reflect.TypeOf((*MockSource)(nil).Id)) -} - -// PushChange mocks base method. -func (m *MockSource) PushChange(arg0 source.PushChangeParams) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PushChange", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PushChange indicates an expected call of PushChange. -func (mr *MockSourceMockRecorder) PushChange(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushChange", reflect.TypeOf((*MockSource)(nil).PushChange), arg0) -} - -// ReadDoc mocks base method. -func (m *MockSource) ReadDoc(arg0 context.Context, arg1 source.ChangeReceiver, arg2 bool) (state.Doc, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadDoc", arg0, arg1, arg2) - ret0, _ := ret[0].(state.Doc) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ReadDoc indicates an expected call of ReadDoc. -func (mr *MockSourceMockRecorder) ReadDoc(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadDoc", reflect.TypeOf((*MockSource)(nil).ReadDoc), arg0, arg1, arg2) -} - -// ReadOnly mocks base method. -func (m *MockSource) ReadOnly() bool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadOnly") - ret0, _ := ret[0].(bool) - return ret0 -} - -// ReadOnly indicates an expected call of ReadOnly. -func (mr *MockSourceMockRecorder) ReadOnly() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadOnly", reflect.TypeOf((*MockSource)(nil).ReadOnly)) -} - -// SpaceID mocks base method. -func (m *MockSource) SpaceID() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SpaceID") - ret0, _ := ret[0].(string) - return ret0 -} - -// SpaceID indicates an expected call of SpaceID. -func (mr *MockSourceMockRecorder) SpaceID() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpaceID", reflect.TypeOf((*MockSource)(nil).SpaceID)) -} - -// Type mocks base method. -func (m *MockSource) Type() smartblock.SmartBlockType { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Type") - ret0, _ := ret[0].(smartblock.SmartBlockType) - return ret0 -} - -// Type indicates an expected call of Type. -func (mr *MockSourceMockRecorder) Type() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockSource)(nil).Type)) -} diff --git a/util/testMock/mockSpace/space_mock.go b/util/testMock/mockSpace/space_mock.go deleted file mode 100644 index 8c76503194..0000000000 --- a/util/testMock/mockSpace/space_mock.go +++ /dev/null @@ -1,218 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/space (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package mockSpace -destination space_mock.go github.com/anyproto/anytype-heart/space Service -// -// Package mockSpace is a generated GoMock package. -package mockSpace - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - commonspace "github.com/anyproto/any-sync/commonspace" - streampool "github.com/anyproto/any-sync/net/streampool" - gomock "go.uber.org/mock/gomock" - - space "github.com/anyproto/anytype-heart/space/spacecore" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// AccountId mocks base method. -func (m *MockService) AccountId() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AccountId") - ret0, _ := ret[0].(string) - return ret0 -} - -// AccountId indicates an expected call of AccountId. -func (mr *MockServiceMockRecorder) AccountId() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountId", reflect.TypeOf((*MockService)(nil).AccountId)) -} - -// AccountSpace mocks base method. -func (m *MockService) AccountSpace(arg0 context.Context) (commonspace.Space, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AccountSpace", arg0) - ret0, _ := ret[0].(commonspace.Space) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// AccountSpace indicates an expected call of AccountSpace. -func (mr *MockServiceMockRecorder) AccountSpace(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountSpace", reflect.TypeOf((*MockService)(nil).AccountSpace), arg0) -} - -// Close mocks base method. -func (m *MockService) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) -} - -// CreateSpace mocks base method. -func (m *MockService) CreateSpace(arg0 context.Context) (commonspace.Space, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateSpace", arg0) - ret0, _ := ret[0].(commonspace.Space) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CreateSpace indicates an expected call of CreateSpace. -func (mr *MockServiceMockRecorder) CreateSpace(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSpace", reflect.TypeOf((*MockService)(nil).CreateSpace), arg0) -} - -// DeleteAccount mocks base method. -func (m *MockService) DeleteAccount(arg0 context.Context, arg1 bool) (space.NetworkStatus, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteAccount", arg0, arg1) - ret0, _ := ret[0].(space.NetworkStatus) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeleteAccount indicates an expected call of DeleteAccount. -func (mr *MockServiceMockRecorder) DeleteAccount(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAccount", reflect.TypeOf((*MockService)(nil).DeleteAccount), arg0, arg1) -} - -// DeleteSpace mocks base method. -func (m *MockService) DeleteSpace(arg0 context.Context, arg1 string, arg2 bool) (space.NetworkStatus, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteSpace", arg0, arg1, arg2) - ret0, _ := ret[0].(space.NetworkStatus) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeleteSpace indicates an expected call of DeleteSpace. -func (mr *MockServiceMockRecorder) DeleteSpace(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSpace", reflect.TypeOf((*MockService)(nil).DeleteSpace), arg0, arg1, arg2) -} - -// DeriveSpace mocks base method. -func (m *MockService) DeriveSpace(arg0 context.Context, arg1 commonspace.SpaceDerivePayload) (commonspace.Space, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeriveSpace", arg0, arg1) - ret0, _ := ret[0].(commonspace.Space) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// DeriveSpace indicates an expected call of DeriveSpace. -func (mr *MockServiceMockRecorder) DeriveSpace(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeriveSpace", reflect.TypeOf((*MockService)(nil).DeriveSpace), arg0, arg1) -} - -// GetSpace mocks base method. -func (m *MockService) GetSpace(arg0 context.Context, arg1 string) (commonspace.Space, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSpace", arg0, arg1) - ret0, _ := ret[0].(commonspace.Space) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetSpace indicates an expected call of GetSpace. -func (mr *MockServiceMockRecorder) GetSpace(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpace", reflect.TypeOf((*MockService)(nil).GetSpace), arg0, arg1) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} - -// Run mocks base method. -func (m *MockService) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) -} - -// StreamPool mocks base method. -func (m *MockService) StreamPool() streampool.StreamPool { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StreamPool") - ret0, _ := ret[0].(streampool.StreamPool) - return ret0 -} - -// StreamPool indicates an expected call of StreamPool. -func (mr *MockServiceMockRecorder) StreamPool() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamPool", reflect.TypeOf((*MockService)(nil).StreamPool)) -} diff --git a/util/testMock/mockStatus/status_mock.go b/util/testMock/mockStatus/status_mock.go deleted file mode 100644 index 55f7223035..0000000000 --- a/util/testMock/mockStatus/status_mock.go +++ /dev/null @@ -1,137 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/core/syncstatus (interfaces: Service) -// -// Generated by this command: -// -// mockgen -package mockStatus -destination status_mock.go github.com/anyproto/anytype-heart/core/syncstatus Service -// -// Package mockStatus is a generated GoMock package. -package mockStatus - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - gomock "go.uber.org/mock/gomock" -) - -// MockService is a mock of Service interface. -type MockService struct { - ctrl *gomock.Controller - recorder *MockServiceMockRecorder -} - -// MockServiceMockRecorder is the mock recorder for MockService. -type MockServiceMockRecorder struct { - mock *MockService -} - -// NewMockService creates a new mock instance. -func NewMockService(ctrl *gomock.Controller) *MockService { - mock := &MockService{ctrl: ctrl} - mock.recorder = &MockServiceMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockService) EXPECT() *MockServiceMockRecorder { - return m.recorder -} - -// Close mocks base method. -func (m *MockService) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockServiceMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockService)(nil).Close), arg0) -} - -// Init mocks base method. -func (m *MockService) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockServiceMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockService)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockService) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockServiceMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockService)(nil).Name)) -} - -// OnFileUpload mocks base method. -func (m *MockService) OnFileUpload(arg0, arg1 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OnFileUpload", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// OnFileUpload indicates an expected call of OnFileUpload. -func (mr *MockServiceMockRecorder) OnFileUpload(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnFileUpload", reflect.TypeOf((*MockService)(nil).OnFileUpload), arg0, arg1) -} - -// Run mocks base method. -func (m *MockService) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockServiceMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockService)(nil).Run), arg0) -} - -// Unwatch mocks base method. -func (m *MockService) Unwatch(arg0 string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Unwatch", arg0) -} - -// Unwatch indicates an expected call of Unwatch. -func (mr *MockServiceMockRecorder) Unwatch(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unwatch", reflect.TypeOf((*MockService)(nil).Unwatch), arg0) -} - -// Watch mocks base method. -func (m *MockService) Watch(arg0 string, arg1 func() []string) (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Watch", arg0, arg1) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Watch indicates an expected call of Watch. -func (mr *MockServiceMockRecorder) Watch(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockService)(nil).Watch), arg0, arg1) -} diff --git a/util/testMock/objectstore_mock.go b/util/testMock/objectstore_mock.go deleted file mode 100644 index 1032052c13..0000000000 --- a/util/testMock/objectstore_mock.go +++ /dev/null @@ -1,896 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore (interfaces: ObjectStore) -// -// Generated by this command: -// -// mockgen -package testMock -destination objectstore_mock.go github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore ObjectStore -// - -// Package testMock is a generated GoMock package. -package testMock - -import ( - context "context" - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - coordinatorproto "github.com/anyproto/any-sync/coordinator/coordinatorproto" - domain "github.com/anyproto/anytype-heart/core/domain" - relationutils "github.com/anyproto/anytype-heart/core/relationutils" - database "github.com/anyproto/anytype-heart/pkg/lib/database" - ftsearch "github.com/anyproto/anytype-heart/pkg/lib/localstore/ftsearch" - model "github.com/anyproto/anytype-heart/pkg/lib/pb/model" - pbtypes "github.com/anyproto/anytype-heart/util/pbtypes" - types "github.com/gogo/protobuf/types" - gomock "go.uber.org/mock/gomock" -) - -// MockObjectStore is a mock of ObjectStore interface. -type MockObjectStore struct { - ctrl *gomock.Controller - recorder *MockObjectStoreMockRecorder -} - -// MockObjectStoreMockRecorder is the mock recorder for MockObjectStore. -type MockObjectStoreMockRecorder struct { - mock *MockObjectStore -} - -// NewMockObjectStore creates a new mock instance. -func NewMockObjectStore(ctrl *gomock.Controller) *MockObjectStore { - mock := &MockObjectStore{ctrl: ctrl} - mock.recorder = &MockObjectStoreMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockObjectStore) EXPECT() *MockObjectStoreMockRecorder { - return m.recorder -} - -// AddToIndexQueue mocks base method. -func (m *MockObjectStore) AddToIndexQueue(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddToIndexQueue", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// AddToIndexQueue indicates an expected call of AddToIndexQueue. -func (mr *MockObjectStoreMockRecorder) AddToIndexQueue(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddToIndexQueue", reflect.TypeOf((*MockObjectStore)(nil).AddToIndexQueue), arg0) -} - -// BatchProcessFullTextQueue mocks base method. -func (m *MockObjectStore) BatchProcessFullTextQueue(arg0 context.Context, arg1 int, arg2 func([]string) error) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BatchProcessFullTextQueue", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// BatchProcessFullTextQueue indicates an expected call of BatchProcessFullTextQueue. -func (mr *MockObjectStoreMockRecorder) BatchProcessFullTextQueue(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BatchProcessFullTextQueue", reflect.TypeOf((*MockObjectStore)(nil).BatchProcessFullTextQueue), arg0, arg1, arg2) -} - -// Close mocks base method. -func (m *MockObjectStore) Close(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Close indicates an expected call of Close. -func (mr *MockObjectStoreMockRecorder) Close(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockObjectStore)(nil).Close), arg0) -} - -// DeleteDetails mocks base method. -func (m *MockObjectStore) DeleteDetails(arg0 ...string) error { - m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "DeleteDetails", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteDetails indicates an expected call of DeleteDetails. -func (mr *MockObjectStoreMockRecorder) DeleteDetails(arg0 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDetails", reflect.TypeOf((*MockObjectStore)(nil).DeleteDetails), arg0...) -} - -// DeleteLinks mocks base method. -func (m *MockObjectStore) DeleteLinks(arg0 ...string) error { - m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "DeleteLinks", varargs...) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteLinks indicates an expected call of DeleteLinks. -func (mr *MockObjectStoreMockRecorder) DeleteLinks(arg0 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteLinks", reflect.TypeOf((*MockObjectStore)(nil).DeleteLinks), arg0...) -} - -// DeleteObject mocks base method. -func (m *MockObjectStore) DeleteObject(arg0 domain.FullID) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteObject", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteObject indicates an expected call of DeleteObject. -func (mr *MockObjectStoreMockRecorder) DeleteObject(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteObject", reflect.TypeOf((*MockObjectStore)(nil).DeleteObject), arg0) -} - -// DeleteVirtualSpace mocks base method. -func (m *MockObjectStore) DeleteVirtualSpace(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteVirtualSpace", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// DeleteVirtualSpace indicates an expected call of DeleteVirtualSpace. -func (mr *MockObjectStoreMockRecorder) DeleteVirtualSpace(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteVirtualSpace", reflect.TypeOf((*MockObjectStore)(nil).DeleteVirtualSpace), arg0) -} - -// FTSearch mocks base method. -func (m *MockObjectStore) FTSearch() ftsearch.FTSearch { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FTSearch") - ret0, _ := ret[0].(ftsearch.FTSearch) - return ret0 -} - -// FTSearch indicates an expected call of FTSearch. -func (mr *MockObjectStoreMockRecorder) FTSearch() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FTSearch", reflect.TypeOf((*MockObjectStore)(nil).FTSearch)) -} - -// FetchRelationByKey mocks base method. -func (m *MockObjectStore) FetchRelationByKey(arg0, arg1 string) (*relationutils.Relation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchRelationByKey", arg0, arg1) - ret0, _ := ret[0].(*relationutils.Relation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchRelationByKey indicates an expected call of FetchRelationByKey. -func (mr *MockObjectStoreMockRecorder) FetchRelationByKey(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchRelationByKey", reflect.TypeOf((*MockObjectStore)(nil).FetchRelationByKey), arg0, arg1) -} - -// FetchRelationByKeys mocks base method. -func (m *MockObjectStore) FetchRelationByKeys(arg0 string, arg1 ...string) (relationutils.Relations, error) { - m.ctrl.T.Helper() - varargs := []any{arg0} - for _, a := range arg1 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "FetchRelationByKeys", varargs...) - ret0, _ := ret[0].(relationutils.Relations) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchRelationByKeys indicates an expected call of FetchRelationByKeys. -func (mr *MockObjectStoreMockRecorder) FetchRelationByKeys(arg0 any, arg1 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0}, arg1...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchRelationByKeys", reflect.TypeOf((*MockObjectStore)(nil).FetchRelationByKeys), varargs...) -} - -// FetchRelationByLinks mocks base method. -func (m *MockObjectStore) FetchRelationByLinks(arg0 string, arg1 pbtypes.RelationLinks) (relationutils.Relations, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FetchRelationByLinks", arg0, arg1) - ret0, _ := ret[0].(relationutils.Relations) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// FetchRelationByLinks indicates an expected call of FetchRelationByLinks. -func (mr *MockObjectStoreMockRecorder) FetchRelationByLinks(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchRelationByLinks", reflect.TypeOf((*MockObjectStore)(nil).FetchRelationByLinks), arg0, arg1) -} - -// GetAccountStatus mocks base method. -func (m *MockObjectStore) GetAccountStatus() (*coordinatorproto.SpaceStatusPayload, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAccountStatus") - ret0, _ := ret[0].(*coordinatorproto.SpaceStatusPayload) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAccountStatus indicates an expected call of GetAccountStatus. -func (mr *MockObjectStoreMockRecorder) GetAccountStatus() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccountStatus", reflect.TypeOf((*MockObjectStore)(nil).GetAccountStatus)) -} - -// GetActiveViews mocks base method. -func (m *MockObjectStore) GetActiveViews(arg0 string) (map[string]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetActiveViews", arg0) - ret0, _ := ret[0].(map[string]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetActiveViews indicates an expected call of GetActiveViews. -func (mr *MockObjectStoreMockRecorder) GetActiveViews(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveViews", reflect.TypeOf((*MockObjectStore)(nil).GetActiveViews), arg0) -} - -// GetByIDs mocks base method. -func (m *MockObjectStore) GetByIDs(arg0 string, arg1 []string) ([]*model.ObjectInfo, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByIDs", arg0, arg1) - ret0, _ := ret[0].([]*model.ObjectInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetByIDs indicates an expected call of GetByIDs. -func (mr *MockObjectStoreMockRecorder) GetByIDs(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockObjectStore)(nil).GetByIDs), arg0, arg1) -} - -// GetChecksums mocks base method. -func (m *MockObjectStore) GetChecksums(arg0 string) (*model.ObjectStoreChecksums, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChecksums", arg0) - ret0, _ := ret[0].(*model.ObjectStoreChecksums) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetChecksums indicates an expected call of GetChecksums. -func (mr *MockObjectStoreMockRecorder) GetChecksums(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChecksums", reflect.TypeOf((*MockObjectStore)(nil).GetChecksums), arg0) -} - -// GetDetails mocks base method. -func (m *MockObjectStore) GetDetails(arg0 string) (*model.ObjectDetails, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDetails", arg0) - ret0, _ := ret[0].(*model.ObjectDetails) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetDetails indicates an expected call of GetDetails. -func (mr *MockObjectStoreMockRecorder) GetDetails(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDetails", reflect.TypeOf((*MockObjectStore)(nil).GetDetails), arg0) -} - -// GetGlobalChecksums mocks base method. -func (m *MockObjectStore) GetGlobalChecksums() (*model.ObjectStoreChecksums, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetGlobalChecksums") - ret0, _ := ret[0].(*model.ObjectStoreChecksums) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetGlobalChecksums indicates an expected call of GetGlobalChecksums. -func (mr *MockObjectStoreMockRecorder) GetGlobalChecksums() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGlobalChecksums", reflect.TypeOf((*MockObjectStore)(nil).GetGlobalChecksums)) -} - -// GetInboundLinksByID mocks base method. -func (m *MockObjectStore) GetInboundLinksByID(arg0 string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetInboundLinksByID", arg0) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetInboundLinksByID indicates an expected call of GetInboundLinksByID. -func (mr *MockObjectStoreMockRecorder) GetInboundLinksByID(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInboundLinksByID", reflect.TypeOf((*MockObjectStore)(nil).GetInboundLinksByID), arg0) -} - -// GetLastIndexedHeadsHash mocks base method. -func (m *MockObjectStore) GetLastIndexedHeadsHash(arg0 string) (string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLastIndexedHeadsHash", arg0) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetLastIndexedHeadsHash indicates an expected call of GetLastIndexedHeadsHash. -func (mr *MockObjectStoreMockRecorder) GetLastIndexedHeadsHash(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).GetLastIndexedHeadsHash), arg0) -} - -// GetObjectByUniqueKey mocks base method. -func (m *MockObjectStore) GetObjectByUniqueKey(arg0 string, arg1 domain.UniqueKey) (*model.ObjectDetails, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetObjectByUniqueKey", arg0, arg1) - ret0, _ := ret[0].(*model.ObjectDetails) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetObjectByUniqueKey indicates an expected call of GetObjectByUniqueKey. -func (mr *MockObjectStoreMockRecorder) GetObjectByUniqueKey(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectByUniqueKey", reflect.TypeOf((*MockObjectStore)(nil).GetObjectByUniqueKey), arg0, arg1) -} - -// GetObjectType mocks base method. -func (m *MockObjectStore) GetObjectType(arg0 string) (*model.ObjectType, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetObjectType", arg0) - ret0, _ := ret[0].(*model.ObjectType) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetObjectType indicates an expected call of GetObjectType. -func (mr *MockObjectStoreMockRecorder) GetObjectType(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectType", reflect.TypeOf((*MockObjectStore)(nil).GetObjectType), arg0) -} - -// GetOutboundLinksByID mocks base method. -func (m *MockObjectStore) GetOutboundLinksByID(arg0 string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetOutboundLinksByID", arg0) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetOutboundLinksByID indicates an expected call of GetOutboundLinksByID. -func (mr *MockObjectStoreMockRecorder) GetOutboundLinksByID(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOutboundLinksByID", reflect.TypeOf((*MockObjectStore)(nil).GetOutboundLinksByID), arg0) -} - -// GetRelationByID mocks base method. -func (m *MockObjectStore) GetRelationByID(arg0 string) (*model.Relation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationByID", arg0) - ret0, _ := ret[0].(*model.Relation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRelationByID indicates an expected call of GetRelationByID. -func (mr *MockObjectStoreMockRecorder) GetRelationByID(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByID", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByID), arg0) -} - -// GetRelationByKey mocks base method. -func (m *MockObjectStore) GetRelationByKey(arg0, arg1 string) (*model.Relation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationByKey", arg0, arg1) - ret0, _ := ret[0].(*model.Relation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRelationByKey indicates an expected call of GetRelationByKey. -func (mr *MockObjectStoreMockRecorder) GetRelationByKey(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationByKey), arg0, arg1) -} - -// GetRelationFormatByKey mocks base method. -func (m *MockObjectStore) GetRelationFormatByKey(arg0 string) (model.RelationFormat, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationFormatByKey", arg0) - ret0, _ := ret[0].(model.RelationFormat) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRelationFormatByKey indicates an expected call of GetRelationFormatByKey. -func (mr *MockObjectStoreMockRecorder) GetRelationFormatByKey(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationFormatByKey", reflect.TypeOf((*MockObjectStore)(nil).GetRelationFormatByKey), arg0) -} - -// GetRelationLink mocks base method. -func (m *MockObjectStore) GetRelationLink(arg0, arg1 string) (*model.RelationLink, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRelationLink", arg0, arg1) - ret0, _ := ret[0].(*model.RelationLink) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRelationLink indicates an expected call of GetRelationLink. -func (mr *MockObjectStoreMockRecorder) GetRelationLink(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRelationLink", reflect.TypeOf((*MockObjectStore)(nil).GetRelationLink), arg0, arg1) -} - -// GetSpaceName mocks base method. -func (m *MockObjectStore) GetSpaceName(arg0 string) string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSpaceName", arg0) - ret0, _ := ret[0].(string) - return ret0 -} - -// GetSpaceName indicates an expected call of GetSpaceName. -func (mr *MockObjectStoreMockRecorder) GetSpaceName(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSpaceName", reflect.TypeOf((*MockObjectStore)(nil).GetSpaceName), arg0) -} - -// GetUniqueKeyById mocks base method. -func (m *MockObjectStore) GetUniqueKeyById(arg0 string) (domain.UniqueKey, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUniqueKeyById", arg0) - ret0, _ := ret[0].(domain.UniqueKey) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetUniqueKeyById indicates an expected call of GetUniqueKeyById. -func (mr *MockObjectStoreMockRecorder) GetUniqueKeyById(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUniqueKeyById", reflect.TypeOf((*MockObjectStore)(nil).GetUniqueKeyById), arg0) -} - -// GetWithLinksInfoByID mocks base method. -func (m *MockObjectStore) GetWithLinksInfoByID(arg0, arg1 string) (*model.ObjectInfoWithLinks, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetWithLinksInfoByID", arg0, arg1) - ret0, _ := ret[0].(*model.ObjectInfoWithLinks) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetWithLinksInfoByID indicates an expected call of GetWithLinksInfoByID. -func (mr *MockObjectStoreMockRecorder) GetWithLinksInfoByID(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWithLinksInfoByID", reflect.TypeOf((*MockObjectStore)(nil).GetWithLinksInfoByID), arg0, arg1) -} - -// HasIDs mocks base method. -func (m *MockObjectStore) HasIDs(arg0 ...string) ([]string, error) { - m.ctrl.T.Helper() - varargs := []any{} - for _, a := range arg0 { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "HasIDs", varargs...) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// HasIDs indicates an expected call of HasIDs. -func (mr *MockObjectStoreMockRecorder) HasIDs(arg0 ...any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasIDs", reflect.TypeOf((*MockObjectStore)(nil).HasIDs), arg0...) -} - -// Init mocks base method. -func (m *MockObjectStore) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockObjectStoreMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockObjectStore)(nil).Init), arg0) -} - -// List mocks base method. -func (m *MockObjectStore) List(arg0 string, arg1 bool) ([]*model.ObjectInfo, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", arg0, arg1) - ret0, _ := ret[0].([]*model.ObjectInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// List indicates an expected call of List. -func (mr *MockObjectStoreMockRecorder) List(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockObjectStore)(nil).List), arg0, arg1) -} - -// ListAllRelations mocks base method. -func (m *MockObjectStore) ListAllRelations(arg0 string) (relationutils.Relations, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListAllRelations", arg0) - ret0, _ := ret[0].(relationutils.Relations) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListAllRelations indicates an expected call of ListAllRelations. -func (mr *MockObjectStoreMockRecorder) ListAllRelations(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAllRelations", reflect.TypeOf((*MockObjectStore)(nil).ListAllRelations), arg0) -} - -// ListIDsFromFullTextQueue mocks base method. -func (m *MockObjectStore) ListIDsFromFullTextQueue(arg0 int) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListIDsFromFullTextQueue", arg0) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListIDsFromFullTextQueue indicates an expected call of ListIDsFromFullTextQueue. -func (mr *MockObjectStoreMockRecorder) ListIDsFromFullTextQueue(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListIDsFromFullTextQueue", reflect.TypeOf((*MockObjectStore)(nil).ListIDsFromFullTextQueue), arg0) -} - -// ListIds mocks base method. -func (m *MockObjectStore) ListIds() ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListIds") - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListIds indicates an expected call of ListIds. -func (mr *MockObjectStoreMockRecorder) ListIds() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListIds", reflect.TypeOf((*MockObjectStore)(nil).ListIds)) -} - -// ListIdsBySpace mocks base method. -func (m *MockObjectStore) ListIdsBySpace(arg0 string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListIdsBySpace", arg0) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListIdsBySpace indicates an expected call of ListIdsBySpace. -func (mr *MockObjectStoreMockRecorder) ListIdsBySpace(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListIdsBySpace", reflect.TypeOf((*MockObjectStore)(nil).ListIdsBySpace), arg0) -} - -// ListVirtualSpaces mocks base method. -func (m *MockObjectStore) ListVirtualSpaces() ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListVirtualSpaces") - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ListVirtualSpaces indicates an expected call of ListVirtualSpaces. -func (mr *MockObjectStoreMockRecorder) ListVirtualSpaces() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListVirtualSpaces", reflect.TypeOf((*MockObjectStore)(nil).ListVirtualSpaces)) -} - -// ModifyObjectDetails mocks base method. -func (m *MockObjectStore) ModifyObjectDetails(arg0 string, arg1 func(*types.Struct) (*types.Struct, bool, error)) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ModifyObjectDetails", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// ModifyObjectDetails indicates an expected call of ModifyObjectDetails. -func (mr *MockObjectStoreMockRecorder) ModifyObjectDetails(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ModifyObjectDetails", reflect.TypeOf((*MockObjectStore)(nil).ModifyObjectDetails), arg0, arg1) -} - -// Name mocks base method. -func (m *MockObjectStore) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockObjectStoreMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockObjectStore)(nil).Name)) -} - -// Query mocks base method. -func (m *MockObjectStore) Query(arg0 database.Query) ([]database.Record, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Query", arg0) - ret0, _ := ret[0].([]database.Record) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Query indicates an expected call of Query. -func (mr *MockObjectStoreMockRecorder) Query(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Query", reflect.TypeOf((*MockObjectStore)(nil).Query), arg0) -} - -// QueryByID mocks base method. -func (m *MockObjectStore) QueryByID(arg0 []string) ([]database.Record, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryByID", arg0) - ret0, _ := ret[0].([]database.Record) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryByID indicates an expected call of QueryByID. -func (mr *MockObjectStoreMockRecorder) QueryByID(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryByID", reflect.TypeOf((*MockObjectStore)(nil).QueryByID), arg0) -} - -// QueryByIDAndSubscribeForChanges mocks base method. -func (m *MockObjectStore) QueryByIDAndSubscribeForChanges(arg0 []string, arg1 database.Subscription) ([]database.Record, func(), error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryByIDAndSubscribeForChanges", arg0, arg1) - ret0, _ := ret[0].([]database.Record) - ret1, _ := ret[1].(func()) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// QueryByIDAndSubscribeForChanges indicates an expected call of QueryByIDAndSubscribeForChanges. -func (mr *MockObjectStoreMockRecorder) QueryByIDAndSubscribeForChanges(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryByIDAndSubscribeForChanges", reflect.TypeOf((*MockObjectStore)(nil).QueryByIDAndSubscribeForChanges), arg0, arg1) -} - -// QueryIterate mocks base method. -func (m *MockObjectStore) QueryIterate(arg0 database.Query, arg1 func(*types.Struct)) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryIterate", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// QueryIterate indicates an expected call of QueryIterate. -func (mr *MockObjectStoreMockRecorder) QueryIterate(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryIterate", reflect.TypeOf((*MockObjectStore)(nil).QueryIterate), arg0, arg1) -} - -// QueryObjectIDs mocks base method. -func (m *MockObjectStore) QueryObjectIDs(arg0 database.Query) ([]string, int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryObjectIDs", arg0) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(int) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// QueryObjectIDs indicates an expected call of QueryObjectIDs. -func (mr *MockObjectStoreMockRecorder) QueryObjectIDs(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryObjectIDs", reflect.TypeOf((*MockObjectStore)(nil).QueryObjectIDs), arg0) -} - -// QueryRaw mocks base method. -func (m *MockObjectStore) QueryRaw(arg0 *database.Filters, arg1, arg2 int) ([]database.Record, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "QueryRaw", arg0, arg1, arg2) - ret0, _ := ret[0].([]database.Record) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// QueryRaw indicates an expected call of QueryRaw. -func (mr *MockObjectStoreMockRecorder) QueryRaw(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryRaw", reflect.TypeOf((*MockObjectStore)(nil).QueryRaw), arg0, arg1, arg2) -} - -// RemoveIDsFromFullTextQueue mocks base method. -func (m *MockObjectStore) RemoveIDsFromFullTextQueue(arg0 []string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RemoveIDsFromFullTextQueue", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// RemoveIDsFromFullTextQueue indicates an expected call of RemoveIDsFromFullTextQueue. -func (mr *MockObjectStoreMockRecorder) RemoveIDsFromFullTextQueue(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveIDsFromFullTextQueue", reflect.TypeOf((*MockObjectStore)(nil).RemoveIDsFromFullTextQueue), arg0) -} - -// Run mocks base method. -func (m *MockObjectStore) Run(arg0 context.Context) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Run", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Run indicates an expected call of Run. -func (mr *MockObjectStoreMockRecorder) Run(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockObjectStore)(nil).Run), arg0) -} - -// SaveAccountStatus mocks base method. -func (m *MockObjectStore) SaveAccountStatus(arg0 *coordinatorproto.SpaceStatusPayload) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveAccountStatus", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveAccountStatus indicates an expected call of SaveAccountStatus. -func (mr *MockObjectStoreMockRecorder) SaveAccountStatus(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveAccountStatus", reflect.TypeOf((*MockObjectStore)(nil).SaveAccountStatus), arg0) -} - -// SaveChecksums mocks base method. -func (m *MockObjectStore) SaveChecksums(arg0 string, arg1 *model.ObjectStoreChecksums) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveChecksums", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveChecksums indicates an expected call of SaveChecksums. -func (mr *MockObjectStoreMockRecorder) SaveChecksums(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveChecksums", reflect.TypeOf((*MockObjectStore)(nil).SaveChecksums), arg0, arg1) -} - -// SaveLastIndexedHeadsHash mocks base method. -func (m *MockObjectStore) SaveLastIndexedHeadsHash(arg0, arg1 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveLastIndexedHeadsHash", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveLastIndexedHeadsHash indicates an expected call of SaveLastIndexedHeadsHash. -func (mr *MockObjectStoreMockRecorder) SaveLastIndexedHeadsHash(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveLastIndexedHeadsHash", reflect.TypeOf((*MockObjectStore)(nil).SaveLastIndexedHeadsHash), arg0, arg1) -} - -// SaveVirtualSpace mocks base method. -func (m *MockObjectStore) SaveVirtualSpace(arg0 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SaveVirtualSpace", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// SaveVirtualSpace indicates an expected call of SaveVirtualSpace. -func (mr *MockObjectStoreMockRecorder) SaveVirtualSpace(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveVirtualSpace", reflect.TypeOf((*MockObjectStore)(nil).SaveVirtualSpace), arg0) -} - -// SetActiveView mocks base method. -func (m *MockObjectStore) SetActiveView(arg0, arg1, arg2 string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetActiveView", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetActiveView indicates an expected call of SetActiveView. -func (mr *MockObjectStoreMockRecorder) SetActiveView(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetActiveView", reflect.TypeOf((*MockObjectStore)(nil).SetActiveView), arg0, arg1, arg2) -} - -// SetActiveViews mocks base method. -func (m *MockObjectStore) SetActiveViews(arg0 string, arg1 map[string]string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetActiveViews", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// SetActiveViews indicates an expected call of SetActiveViews. -func (mr *MockObjectStoreMockRecorder) SetActiveViews(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetActiveViews", reflect.TypeOf((*MockObjectStore)(nil).SetActiveViews), arg0, arg1) -} - -// SubscribeForAll mocks base method. -func (m *MockObjectStore) SubscribeForAll(arg0 func(database.Record)) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SubscribeForAll", arg0) -} - -// SubscribeForAll indicates an expected call of SubscribeForAll. -func (mr *MockObjectStoreMockRecorder) SubscribeForAll(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeForAll", reflect.TypeOf((*MockObjectStore)(nil).SubscribeForAll), arg0) -} - -// UpdateObjectDetails mocks base method. -func (m *MockObjectStore) UpdateObjectDetails(arg0 context.Context, arg1 string, arg2 *types.Struct) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateObjectDetails", arg0, arg1, arg2) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateObjectDetails indicates an expected call of UpdateObjectDetails. -func (mr *MockObjectStoreMockRecorder) UpdateObjectDetails(arg0, arg1, arg2 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectDetails", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectDetails), arg0, arg1, arg2) -} - -// UpdateObjectLinks mocks base method. -func (m *MockObjectStore) UpdateObjectLinks(arg0 string, arg1 []string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateObjectLinks", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateObjectLinks indicates an expected call of UpdateObjectLinks. -func (mr *MockObjectStoreMockRecorder) UpdateObjectLinks(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateObjectLinks", reflect.TypeOf((*MockObjectStore)(nil).UpdateObjectLinks), arg0, arg1) -} - -// UpdatePendingLocalDetails mocks base method. -func (m *MockObjectStore) UpdatePendingLocalDetails(arg0 string, arg1 func(*types.Struct) (*types.Struct, error)) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdatePendingLocalDetails", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdatePendingLocalDetails indicates an expected call of UpdatePendingLocalDetails. -func (mr *MockObjectStoreMockRecorder) UpdatePendingLocalDetails(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatePendingLocalDetails", reflect.TypeOf((*MockObjectStore)(nil).UpdatePendingLocalDetails), arg0, arg1) -} diff --git a/util/testMock/sbt_provider_mock.go b/util/testMock/sbt_provider_mock.go deleted file mode 100644 index b1858d5469..0000000000 --- a/util/testMock/sbt_provider_mock.go +++ /dev/null @@ -1,111 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anyproto/anytype-heart/space/spacecore/typeprovider (interfaces: SmartBlockTypeProvider) -// -// Generated by this command: -// -// mockgen -package testMock -destination sbt_provider_mock.go github.com/anyproto/anytype-heart/space/spacecore/typeprovider SmartBlockTypeProvider -// - -// Package testMock is a generated GoMock package. -package testMock - -import ( - reflect "reflect" - - app "github.com/anyproto/any-sync/app" - smartblock "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock" - gomock "go.uber.org/mock/gomock" -) - -// MockSmartBlockTypeProvider is a mock of SmartBlockTypeProvider interface. -type MockSmartBlockTypeProvider struct { - ctrl *gomock.Controller - recorder *MockSmartBlockTypeProviderMockRecorder -} - -// MockSmartBlockTypeProviderMockRecorder is the mock recorder for MockSmartBlockTypeProvider. -type MockSmartBlockTypeProviderMockRecorder struct { - mock *MockSmartBlockTypeProvider -} - -// NewMockSmartBlockTypeProvider creates a new mock instance. -func NewMockSmartBlockTypeProvider(ctrl *gomock.Controller) *MockSmartBlockTypeProvider { - mock := &MockSmartBlockTypeProvider{ctrl: ctrl} - mock.recorder = &MockSmartBlockTypeProviderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockSmartBlockTypeProvider) EXPECT() *MockSmartBlockTypeProviderMockRecorder { - return m.recorder -} - -// Init mocks base method. -func (m *MockSmartBlockTypeProvider) Init(arg0 *app.App) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Init", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// Init indicates an expected call of Init. -func (mr *MockSmartBlockTypeProviderMockRecorder) Init(arg0 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Init), arg0) -} - -// Name mocks base method. -func (m *MockSmartBlockTypeProvider) Name() string { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Name") - ret0, _ := ret[0].(string) - return ret0 -} - -// Name indicates an expected call of Name. -func (mr *MockSmartBlockTypeProviderMockRecorder) Name() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Name)) -} - -// PartitionIDsByType mocks base method. -func (m *MockSmartBlockTypeProvider) PartitionIDsByType(arg0 string, arg1 []string) (map[smartblock.SmartBlockType][]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PartitionIDsByType", arg0, arg1) - ret0, _ := ret[0].(map[smartblock.SmartBlockType][]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// PartitionIDsByType indicates an expected call of PartitionIDsByType. -func (mr *MockSmartBlockTypeProviderMockRecorder) PartitionIDsByType(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PartitionIDsByType", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).PartitionIDsByType), arg0, arg1) -} - -// RegisterStaticType mocks base method. -func (m *MockSmartBlockTypeProvider) RegisterStaticType(arg0 string, arg1 smartblock.SmartBlockType) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "RegisterStaticType", arg0, arg1) -} - -// RegisterStaticType indicates an expected call of RegisterStaticType. -func (mr *MockSmartBlockTypeProviderMockRecorder) RegisterStaticType(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterStaticType", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).RegisterStaticType), arg0, arg1) -} - -// Type mocks base method. -func (m *MockSmartBlockTypeProvider) Type(arg0, arg1 string) (smartblock.SmartBlockType, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Type", arg0, arg1) - ret0, _ := ret[0].(smartblock.SmartBlockType) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Type indicates an expected call of Type. -func (mr *MockSmartBlockTypeProviderMockRecorder) Type(arg0, arg1 any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Type", reflect.TypeOf((*MockSmartBlockTypeProvider)(nil).Type), arg0, arg1) -} diff --git a/util/text/text.go b/util/text/text.go index 507ec63b87..5c6a92322c 100644 --- a/util/text/text.go +++ b/util/text/text.go @@ -7,8 +7,12 @@ import ( const TruncateEllipsis = " …" -func Truncate(text string, length int) string { - length = length - UTF16RuneCountString(TruncateEllipsis) +func TruncateEllipsized(text string, length int) string { + return Truncate(text, length, TruncateEllipsis) +} + +func Truncate(text string, length int, ending string) string { + length -= UTF16RuneCountString(ending) if UTF16RuneCountString(text) <= length { return text } @@ -30,14 +34,21 @@ func Truncate(text string, length int) string { endTextPos = lastWordIndex } out := utf16Text[0:endTextPos] - return UTF16ToStr(out) + TruncateEllipsis + return UTF16ToStr(out) + ending } } return UTF16ToStr(utf16Text) } func UTF16RuneCountString(str string) int { - return len(utf16.Encode([]rune(str))) + buf := make([]uint16, 0, 2) + var n int + for _, s := range str { + buf = utf16.AppendRune(buf, s) + n += len(buf) + buf = buf[:0] + } + return n } func UTF16RuneCount(bStr []byte) int { diff --git a/util/text/text_test.go b/util/text/text_test.go index d2efd1b27b..e0ddf14a7d 100644 --- a/util/text/text_test.go +++ b/util/text/text_test.go @@ -65,7 +65,7 @@ func TestTruncate(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - actual := Truncate(test.text, test.length) + actual := TruncateEllipsized(test.text, test.length) assert.Equal(t, test.expected, actual) }) }