1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-10 18:10:49 +09:00

GO-4270 Merge branch 'main' into go-4270-add-virtual-file-blocks

This commit is contained in:
kirillston 2024-12-11 10:28:04 +01:00
commit 3a238c267c
No known key found for this signature in database
GPG key ID: BE4BF014F0ECDFE8
103 changed files with 6309 additions and 3145 deletions

View file

@ -59,7 +59,7 @@ jobs:
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install --ignore-dependencies ./swift-protobuf.rb
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install mingw-w64
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew install grpcurl
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew tap messense/macos-cross-toolchains && brew install x86_64-unknown-linux-musl
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 brew tap messense/macos-cross-toolchains && brew install x86_64-unknown-linux-musl && brew install aarch64-unknown-linux-musl
npm i -g node-gyp
if: runner.name != 'mac-mini-org-heart'
- name: Checkout
@ -115,6 +115,7 @@ jobs:
GOOS="darwin" CGO_CFLAGS="-mmacosx-version-min=11" MACOSX_DEPLOYMENT_TARGET=11.0 GOARCH="arm64" CGO_ENABLED="1" go build -tags="envproduction nographviz nowatchdog nosigar nomutexdeadlockdetector" -ldflags="$FLAGS" -o darwin-arm64 github.com/anyproto/anytype-heart/cmd/grpcserver
GOOS="windows" GOARCH="amd64" CGO_ENABLED="1" CC="x86_64-w64-mingw32-gcc" CXX="x86_64-w64-mingw32-g++" go build -tags="envproduction nographviz nowatchdog nosigar nomutexdeadlockdetector noheic" -ldflags="$FLAGS -linkmode external -extldflags=-static" -o windows-amd64 github.com/anyproto/anytype-heart/cmd/grpcserver
GOOS="linux" GOARCH="amd64" CGO_ENABLED="1" CC="x86_64-linux-musl-gcc" go build -tags="envproduction nographviz nowatchdog nosigar nomutexdeadlockdetector noheic" -ldflags="$FLAGS -linkmode external -extldflags '-static -Wl,-z stack-size=1000000'" -o linux-amd64 github.com/anyproto/anytype-heart/cmd/grpcserver
GOOS="linux" GOARCH="arm64" CGO_ENABLED="1" CC="aarch64-linux-musl-gcc" go build -tags="envproduction nographviz nowatchdog nosigar nomutexdeadlockdetector noheic" -ldflags="$FLAGS -linkmode external" -o linux-arm64 github.com/anyproto/anytype-heart/cmd/grpcserver
ls -lha .
- name: run perf tests
run: |
@ -185,7 +186,7 @@ jobs:
mv js_${VERSION}_${OSARCH}.tar.gz .release/
done
if: github.event_name == 'push'
- name: Pack server unix
- name: Pack server unix amd64
run: |
declare -a arr=("linux-amd64")
for i in "${arr[@]}"
@ -196,6 +197,17 @@ jobs:
mv js_${VERSION}_${OSARCH}.tar.gz .release/
done
if: github.event_name == 'push'
- name: Pack server unix arm64
run: |
declare -a arr=("linux-arm64")
for i in "${arr[@]}"
do
OSARCH=${i%.*}
cp ./${i}* ./grpc-server
tar -czf js_${VERSION}_${OSARCH}.tar.gz grpc-server protobuf json
mv js_${VERSION}_${OSARCH}.tar.gz .release/
done
if: github.event_name == 'push'
- name: Make swift protos
run: |
mkdir -p .release

View file

@ -353,6 +353,7 @@ TANTIVY_LIBS := android-386.tar.gz \
ios-arm64.tar.gz \
ios-arm64-sim.tar.gz \
linux-amd64-musl.tar.gz \
linux-arm64-musl.tar.gz \
windows-amd64.tar.gz
define download_tantivy_lib

View file

@ -25,335 +25,337 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
var fileDescriptor_93a29dc403579097 = []byte{
// 5246 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0xdf, 0x6f, 0x1d, 0x49,
0x56, 0xf8, 0xc7, 0x2f, 0xdf, 0xf9, 0xd2, 0xcb, 0x0e, 0x70, 0x07, 0x86, 0xd9, 0x61, 0x37, 0xc9,
0x64, 0x92, 0x38, 0x89, 0xe3, 0xeb, 0x4c, 0x32, 0x3f, 0x56, 0xbb, 0x48, 0xc8, 0xb1, 0x63, 0x8f,
0x59, 0xdb, 0x31, 0xbe, 0xd7, 0x89, 0x34, 0x12, 0x12, 0xe5, 0x7b, 0xcb, 0xd7, 0x8d, 0xfb, 0x76,
0xf5, 0x76, 0xd7, 0xbd, 0xce, 0x5d, 0x04, 0x02, 0x81, 0x40, 0x20, 0x10, 0x2b, 0x7e, 0xbd, 0x22,
0xf1, 0xc2, 0xbf, 0xc2, 0xe3, 0x3e, 0xf2, 0x88, 0x66, 0x5e, 0xf8, 0x33, 0x50, 0x57, 0x55, 0xd7,
0x8f, 0xd3, 0xe7, 0x54, 0xb7, 0xf7, 0x29, 0xd1, 0x3d, 0x9f, 0x73, 0x4e, 0xfd, 0x3c, 0x75, 0xaa,
0xba, 0xba, 0x9d, 0xdc, 0x2e, 0xce, 0xb7, 0x8a, 0x52, 0x48, 0x51, 0x6d, 0x55, 0xbc, 0x5c, 0xa6,
0x13, 0xde, 0xfc, 0x3b, 0x54, 0x3f, 0x0f, 0xde, 0x65, 0xf9, 0x4a, 0xae, 0x0a, 0xfe, 0xd1, 0x87,
0x8e, 0x9c, 0x88, 0xf9, 0x9c, 0xe5, 0xd3, 0x4a, 0x23, 0x1f, 0x7d, 0xe0, 0x24, 0x7c, 0xc9, 0x73,
0x69, 0x7e, 0x7f, 0xf6, 0x9f, 0xff, 0xbb, 0x96, 0xbc, 0xb7, 0x93, 0xa5, 0x3c, 0x97, 0x3b, 0x46,
0x63, 0xf0, 0x75, 0xf2, 0xdd, 0xed, 0xa2, 0xd8, 0xe7, 0xf2, 0x35, 0x2f, 0xab, 0x54, 0xe4, 0x83,
0x4f, 0x86, 0xc6, 0xc1, 0xf0, 0xb4, 0x98, 0x0c, 0xb7, 0x8b, 0x62, 0xe8, 0x84, 0xc3, 0x53, 0xfe,
0xd3, 0x05, 0xaf, 0xe4, 0x47, 0xf7, 0xe2, 0x50, 0x55, 0x88, 0xbc, 0xe2, 0x83, 0x8b, 0xe4, 0x37,
0xb6, 0x8b, 0x62, 0xc4, 0xe5, 0x2e, 0xaf, 0x2b, 0x30, 0x92, 0x4c, 0xf2, 0xc1, 0x7a, 0x4b, 0x35,
0x04, 0xac, 0x8f, 0x87, 0xdd, 0xa0, 0xf1, 0x33, 0x4e, 0xbe, 0x53, 0xfb, 0xb9, 0x5c, 0xc8, 0xa9,
0xb8, 0xce, 0x07, 0x1f, 0xb7, 0x15, 0x8d, 0xc8, 0xda, 0xbe, 0x1b, 0x43, 0x8c, 0xd5, 0x37, 0xc9,
0xaf, 0xbe, 0x61, 0x59, 0xc6, 0xe5, 0x4e, 0xc9, 0xeb, 0x82, 0x87, 0x3a, 0x5a, 0x34, 0xd4, 0x32,
0x6b, 0xf7, 0x93, 0x28, 0x63, 0x0c, 0x7f, 0x9d, 0x7c, 0x57, 0x4b, 0x4e, 0xf9, 0x44, 0x2c, 0x79,
0x39, 0x40, 0xb5, 0x8c, 0x90, 0x68, 0xf2, 0x16, 0x04, 0x6d, 0xef, 0x88, 0x7c, 0xc9, 0x4b, 0x89,
0xdb, 0x36, 0xc2, 0xb8, 0x6d, 0x07, 0x19, 0xdb, 0x7f, 0xbb, 0x96, 0x7c, 0x7f, 0x7b, 0x32, 0x11,
0x8b, 0x5c, 0x1e, 0x8a, 0x09, 0xcb, 0x0e, 0xd3, 0xfc, 0xea, 0x98, 0x5f, 0xef, 0x5c, 0xd6, 0x7c,
0x3e, 0xe3, 0x83, 0xe7, 0x61, 0xab, 0x6a, 0x74, 0x68, 0xd9, 0xa1, 0x0f, 0x5b, 0xdf, 0x9f, 0xdd,
0x4c, 0xc9, 0x94, 0xe5, 0x1f, 0xd7, 0x92, 0x5b, 0xb0, 0x2c, 0x23, 0x91, 0x2d, 0xb9, 0x2b, 0xcd,
0xe7, 0x1d, 0x86, 0x43, 0xdc, 0x96, 0xe7, 0x8b, 0x9b, 0xaa, 0x99, 0x12, 0x65, 0xc9, 0xfb, 0xfe,
0x70, 0x19, 0xf1, 0x4a, 0x4d, 0xa7, 0x47, 0xf4, 0x88, 0x30, 0x88, 0xf5, 0xfc, 0xb8, 0x0f, 0x6a,
0xbc, 0xa5, 0xc9, 0xc0, 0x78, 0xcb, 0x44, 0x65, 0x9d, 0x3d, 0x44, 0x2d, 0x78, 0x84, 0xf5, 0xf5,
0xa8, 0x07, 0x69, 0x5c, 0xfd, 0x51, 0xf2, 0x6b, 0x6f, 0x44, 0x79, 0x55, 0x15, 0x6c, 0xc2, 0xcd,
0x54, 0xb8, 0x1f, 0x6a, 0x37, 0x52, 0x38, 0x1b, 0x1e, 0x74, 0x61, 0xde, 0xa0, 0x6d, 0x84, 0xaf,
0x0a, 0x0e, 0x63, 0x90, 0x53, 0xac, 0x85, 0xd4, 0xa0, 0x85, 0x90, 0xb1, 0x7d, 0x95, 0x0c, 0x9c,
0xed, 0xf3, 0x3f, 0xe6, 0x13, 0xb9, 0x3d, 0x9d, 0xc2, 0x5e, 0x71, 0xba, 0x8a, 0x18, 0x6e, 0x4f,
0xa7, 0x54, 0xaf, 0xe0, 0xa8, 0x71, 0x76, 0x9d, 0x7c, 0x00, 0x9c, 0x1d, 0xa6, 0x95, 0x72, 0xb8,
0x19, 0xb7, 0x62, 0x30, 0xeb, 0x74, 0xd8, 0x17, 0x37, 0x8e, 0xff, 0x7c, 0x2d, 0xf9, 0x1e, 0xe2,
0xf9, 0x94, 0xcf, 0xc5, 0x92, 0x0f, 0x9e, 0x76, 0x5b, 0xd3, 0xa4, 0xf5, 0xff, 0xe9, 0x0d, 0x34,
0x90, 0x61, 0x32, 0xe2, 0x19, 0x9f, 0x48, 0x72, 0x98, 0x68, 0x71, 0xe7, 0x30, 0xb1, 0x98, 0x37,
0xc3, 0x1a, 0xe1, 0x3e, 0x97, 0x3b, 0x8b, 0xb2, 0xe4, 0xb9, 0x24, 0xfb, 0xd2, 0x21, 0x9d, 0x7d,
0x19, 0xa0, 0x48, 0x7d, 0xf6, 0xb9, 0xdc, 0xce, 0x32, 0xb2, 0x3e, 0x5a, 0xdc, 0x59, 0x1f, 0x8b,
0x19, 0x0f, 0x93, 0xe4, 0xd7, 0xbd, 0x16, 0x93, 0x07, 0xf9, 0x85, 0x18, 0xd0, 0x6d, 0xa1, 0xe4,
0xd6, 0xc7, 0x7a, 0x27, 0x87, 0x54, 0xe3, 0xe5, 0xdb, 0x42, 0x94, 0x74, 0xb7, 0x68, 0x71, 0x67,
0x35, 0x2c, 0x66, 0x3c, 0xfc, 0x61, 0xf2, 0x9e, 0x89, 0x92, 0xcd, 0x7a, 0x76, 0x0f, 0x0d, 0xa1,
0x70, 0x41, 0xbb, 0xdf, 0x41, 0xb9, 0xe0, 0x60, 0x64, 0x26, 0xf8, 0x7c, 0x82, 0xea, 0x81, 0xd0,
0x73, 0x2f, 0x0e, 0xb5, 0x6c, 0xef, 0xf2, 0x8c, 0x93, 0xb6, 0xb5, 0xb0, 0xc3, 0xb6, 0x85, 0x8c,
0xed, 0x32, 0xf9, 0x2d, 0xdb, 0x2c, 0xf5, 0x3a, 0xaa, 0xe4, 0x75, 0x90, 0xde, 0x20, 0xea, 0xed,
0x43, 0xd6, 0xd7, 0x93, 0x7e, 0x70, 0xab, 0x3e, 0x66, 0x06, 0xe2, 0xf5, 0x01, 0xf3, 0xef, 0x5e,
0x1c, 0x32, 0xb6, 0xff, 0x6e, 0x2d, 0xf9, 0x81, 0x91, 0xbd, 0xcc, 0xd9, 0x79, 0xc6, 0xd5, 0x92,
0x78, 0xcc, 0xe5, 0xb5, 0x28, 0xaf, 0x46, 0xab, 0x7c, 0x42, 0x2c, 0xff, 0x38, 0xdc, 0xb1, 0xfc,
0x93, 0x4a, 0x5e, 0xc6, 0x67, 0x2a, 0x2a, 0x45, 0x01, 0x33, 0xbe, 0xa6, 0x06, 0x52, 0x14, 0x54,
0xc6, 0x17, 0x22, 0x2d, 0xab, 0x47, 0x75, 0xd8, 0xc4, 0xad, 0x1e, 0xf9, 0x71, 0xf2, 0x6e, 0x0c,
0x71, 0x61, 0xab, 0x19, 0xc0, 0x22, 0xbf, 0x48, 0x67, 0x67, 0xc5, 0xb4, 0x1e, 0xc6, 0x8f, 0xf0,
0x11, 0xea, 0x21, 0x44, 0xd8, 0x22, 0x50, 0xe3, 0xed, 0x1f, 0x5c, 0x62, 0x64, 0xa6, 0xd2, 0x5e,
0x29, 0xe6, 0x87, 0x7c, 0xc6, 0x26, 0x2b, 0x33, 0xff, 0x3f, 0x8b, 0x4d, 0x3c, 0x48, 0xdb, 0x42,
0x7c, 0x7e, 0x43, 0x2d, 0x53, 0x9e, 0x7f, 0x5f, 0x4b, 0xee, 0x35, 0xd5, 0xbf, 0x64, 0xf9, 0x8c,
0x9b, 0xfe, 0xd4, 0xa5, 0xdf, 0xce, 0xa7, 0xa7, 0xbc, 0x92, 0xac, 0x94, 0x83, 0x1f, 0xe1, 0x95,
0x8c, 0xe9, 0xd8, 0xb2, 0xfd, 0xf8, 0x97, 0xd2, 0x75, 0xbd, 0x3e, 0xaa, 0x03, 0x9b, 0x09, 0x01,
0x61, 0xaf, 0x2b, 0x09, 0x0c, 0x00, 0x77, 0x63, 0x88, 0xeb, 0x75, 0x25, 0x38, 0xc8, 0x97, 0xa9,
0xe4, 0xfb, 0x3c, 0xe7, 0x65, 0xbb, 0xd7, 0xb5, 0x6a, 0x88, 0x10, 0xbd, 0x4e, 0xa0, 0x2e, 0xd8,
0x04, 0xde, 0xec, 0xe2, 0xb8, 0x11, 0x31, 0xd2, 0x5a, 0x1e, 0x9f, 0xf4, 0x83, 0xdd, 0xee, 0xce,
0xf3, 0x79, 0xca, 0x97, 0xe2, 0x0a, 0xee, 0xee, 0x7c, 0x13, 0x1a, 0x20, 0x76, 0x77, 0x28, 0xe8,
0x56, 0x30, 0xcf, 0xcf, 0xeb, 0x94, 0x5f, 0x83, 0x15, 0xcc, 0x57, 0xae, 0xc5, 0xc4, 0x0a, 0x86,
0x60, 0xc6, 0xc3, 0x71, 0xf2, 0x2b, 0x4a, 0xf8, 0xfb, 0x22, 0xcd, 0x07, 0xb7, 0x11, 0xa5, 0x5a,
0x60, 0xad, 0xde, 0xa1, 0x01, 0x50, 0xe2, 0xfa, 0xd7, 0x1d, 0x96, 0x4f, 0x78, 0x86, 0x96, 0xd8,
0x89, 0xa3, 0x25, 0x0e, 0x30, 0x97, 0x3a, 0x28, 0x61, 0x1d, 0xbf, 0x46, 0x97, 0xac, 0x4c, 0xf3,
0xd9, 0x00, 0xd3, 0xf5, 0xe4, 0x44, 0xea, 0x80, 0x71, 0x60, 0x08, 0x1b, 0xc5, 0xed, 0xa2, 0x28,
0xeb, 0xb0, 0x88, 0x0d, 0xe1, 0x10, 0x89, 0x0e, 0xe1, 0x16, 0x8a, 0x7b, 0xdb, 0xe5, 0x93, 0x2c,
0xcd, 0xa3, 0xde, 0x0c, 0xd2, 0xc7, 0x9b, 0x43, 0xc1, 0xe0, 0x3d, 0xe4, 0x6c, 0xc9, 0x9b, 0x9a,
0x61, 0x2d, 0xe3, 0x03, 0xd1, 0xc1, 0x0b, 0x40, 0xb7, 0x4f, 0x53, 0xe2, 0x23, 0x76, 0xc5, 0xeb,
0x06, 0xe6, 0xf5, 0xba, 0x36, 0xc0, 0xf4, 0x03, 0x82, 0xd8, 0xa7, 0xe1, 0xa4, 0x71, 0xb5, 0x48,
0x3e, 0x50, 0xf2, 0x13, 0x56, 0xca, 0x74, 0x92, 0x16, 0x2c, 0x6f, 0xf2, 0x7f, 0x6c, 0x5e, 0xb7,
0x28, 0xeb, 0x72, 0xb3, 0x27, 0x6d, 0xdc, 0xfe, 0xdb, 0x5a, 0xf2, 0x31, 0xf4, 0x7b, 0xc2, 0xcb,
0x79, 0xaa, 0xb6, 0x91, 0x95, 0x0e, 0xc2, 0x83, 0x2f, 0xe3, 0x46, 0x5b, 0x0a, 0xb6, 0x34, 0x3f,
0xbc, 0xb9, 0xa2, 0x29, 0xd8, 0x1f, 0x24, 0x89, 0xde, 0xae, 0xa8, 0x2d, 0x65, 0x38, 0x6b, 0xcd,
0x3e, 0x26, 0xd8, 0x4f, 0x7e, 0x1c, 0x21, 0xdc, 0x52, 0xa1, 0x7f, 0x57, 0x3b, 0xe5, 0x01, 0xaa,
0xa1, 0x44, 0xc4, 0x52, 0x01, 0x10, 0x58, 0xd0, 0xd1, 0xa5, 0xb8, 0xc6, 0x0b, 0x5a, 0x4b, 0xe2,
0x05, 0x35, 0x84, 0x3b, 0xbb, 0x32, 0x05, 0xc5, 0xce, 0xae, 0x9a, 0x62, 0xc4, 0xce, 0xae, 0x20,
0x63, 0x0c, 0x8b, 0xe4, 0x37, 0x7d, 0xc3, 0x2f, 0x84, 0xb8, 0x9a, 0xb3, 0xf2, 0x6a, 0xf0, 0x98,
0x56, 0x6e, 0x18, 0xeb, 0x68, 0xa3, 0x17, 0xeb, 0xc2, 0x82, 0xef, 0xb0, 0x4e, 0x34, 0xce, 0xca,
0x0c, 0x84, 0x85, 0xc0, 0x86, 0x41, 0x88, 0xb0, 0x40, 0xa0, 0x2e, 0x72, 0xfb, 0xde, 0x46, 0x1c,
0xee, 0x96, 0x02, 0xf5, 0x11, 0xa7, 0x76, 0x4b, 0x08, 0x06, 0x87, 0xd0, 0x7e, 0xc9, 0x8a, 0x4b,
0x7c, 0x08, 0x29, 0x51, 0x7c, 0x08, 0x35, 0x08, 0xec, 0xef, 0x11, 0x67, 0xe5, 0xe4, 0x12, 0xef,
0x6f, 0x2d, 0x8b, 0xf7, 0xb7, 0x65, 0x60, 0x7f, 0x6b, 0xc1, 0x9b, 0x54, 0x5e, 0x1e, 0x71, 0xc9,
0xf0, 0xfe, 0x0e, 0x99, 0x78, 0x7f, 0xb7, 0x58, 0x97, 0xc9, 0xf8, 0x0e, 0x47, 0x8b, 0xf3, 0x6a,
0x52, 0xa6, 0xe7, 0x7c, 0x10, 0xb1, 0x62, 0x21, 0x22, 0x93, 0x21, 0x61, 0xe3, 0xf3, 0xe7, 0x6b,
0xc9, 0xed, 0xa6, 0xdb, 0x45, 0x55, 0xe9, 0x95, 0x15, 0xb8, 0xff, 0x1c, 0xef, 0x5f, 0x02, 0x27,
0x4e, 0x13, 0x7b, 0xa8, 0x79, 0x51, 0x15, 0x2f, 0xd2, 0x59, 0x5e, 0xd9, 0x42, 0x7d, 0xd9, 0xc7,
0xba, 0xa7, 0x40, 0x44, 0xd5, 0x5e, 0x8a, 0x6e, 0x41, 0x33, 0xfd, 0xd3, 0xc8, 0x0e, 0xa6, 0x15,
0x58, 0xd0, 0x9a, 0xf6, 0xf6, 0x08, 0x62, 0x41, 0xc3, 0x49, 0x38, 0x14, 0xf6, 0x4b, 0xb1, 0x28,
0xaa, 0x8e, 0xa1, 0x00, 0xa0, 0xf8, 0x50, 0x68, 0xc3, 0xc6, 0xe7, 0xdb, 0xe4, 0xb7, 0xfd, 0xe1,
0xe7, 0x37, 0xf6, 0x26, 0x3d, 0xa6, 0xb0, 0x26, 0x1e, 0xf6, 0xc5, 0x5d, 0x4a, 0xd7, 0x78, 0x96,
0xbb, 0x5c, 0xb2, 0x34, 0xab, 0x06, 0x0f, 0x70, 0x1b, 0x8d, 0x9c, 0x48, 0xe9, 0x30, 0x0e, 0xc6,
0xb7, 0xdd, 0x45, 0x91, 0xa5, 0x93, 0xf6, 0x59, 0xae, 0xd1, 0xb5, 0xe2, 0x78, 0x7c, 0xf3, 0x31,
0x18, 0xaf, 0x47, 0x5c, 0xea, 0xff, 0x8c, 0x57, 0x05, 0xc7, 0xe3, 0x75, 0x80, 0xc4, 0xe3, 0x35,
0x44, 0x61, 0x7d, 0x46, 0x5c, 0x1e, 0xb2, 0x95, 0x58, 0x10, 0xf1, 0xda, 0x8a, 0xe3, 0xf5, 0xf1,
0x31, 0x97, 0x55, 0x59, 0x0f, 0x07, 0xb9, 0xe4, 0x65, 0xce, 0xb2, 0xbd, 0x8c, 0xcd, 0xaa, 0x01,
0x11, 0x63, 0x42, 0x8a, 0xc8, 0xaa, 0x68, 0x1a, 0x69, 0xc6, 0x83, 0x6a, 0x8f, 0x2d, 0x45, 0x99,
0x4a, 0xba, 0x19, 0x1d, 0xd2, 0xd9, 0x8c, 0x01, 0x8a, 0x7a, 0xdb, 0x2e, 0x27, 0x97, 0xe9, 0x92,
0x4f, 0x23, 0xde, 0x1a, 0xa4, 0x87, 0x37, 0x0f, 0x45, 0x3a, 0x6d, 0x24, 0x16, 0xe5, 0x84, 0x93,
0x9d, 0xa6, 0xc5, 0x9d, 0x9d, 0x66, 0x31, 0xe3, 0xe1, 0xaf, 0xd6, 0x92, 0xdf, 0xd1, 0x52, 0xff,
0x80, 0x75, 0x97, 0x55, 0x97, 0xe7, 0x82, 0x95, 0xd3, 0xc1, 0xa7, 0x98, 0x1d, 0x14, 0xb5, 0xae,
0x9f, 0xdd, 0x44, 0x05, 0x36, 0xeb, 0x61, 0x5a, 0x79, 0x33, 0x0e, 0x6d, 0xd6, 0x00, 0x89, 0x37,
0x2b, 0x44, 0x61, 0x00, 0x51, 0x72, 0x7d, 0x98, 0xf1, 0x80, 0xd4, 0x0f, 0x4f, 0x34, 0xd6, 0x3b,
0x39, 0x18, 0x1f, 0x6b, 0x61, 0x38, 0x5a, 0x36, 0x29, 0x1b, 0xf8, 0x88, 0x19, 0xf6, 0xc5, 0x49,
0xcf, 0x76, 0x56, 0xc4, 0x3d, 0xb7, 0x66, 0xc6, 0xb0, 0x2f, 0x4e, 0x78, 0xf6, 0xc2, 0x5a, 0xcc,
0x33, 0x12, 0xda, 0x86, 0x7d, 0x71, 0x98, 0x7d, 0x19, 0xa6, 0x59, 0x17, 0x1e, 0x47, 0xec, 0xc0,
0xb5, 0x61, 0xa3, 0x17, 0x6b, 0x1c, 0xfe, 0xcd, 0x5a, 0xf2, 0x7d, 0xe7, 0xf1, 0x48, 0x4c, 0xd3,
0x8b, 0x95, 0x86, 0x5e, 0xb3, 0x6c, 0xc1, 0xab, 0xc1, 0x33, 0xca, 0x5a, 0x9b, 0xb5, 0x25, 0x78,
0x7e, 0x23, 0x1d, 0x38, 0x77, 0xb6, 0x8b, 0x22, 0x5b, 0x8d, 0xf9, 0xbc, 0xc8, 0xc8, 0xb9, 0x13,
0x20, 0xf1, 0xb9, 0x03, 0x51, 0x98, 0x95, 0x8f, 0x45, 0x9d, 0xf3, 0xa3, 0x59, 0xb9, 0x12, 0xc5,
0xb3, 0xf2, 0x06, 0x81, 0xb9, 0xd2, 0x58, 0xec, 0x88, 0x2c, 0xe3, 0x13, 0xd9, 0x7e, 0x48, 0x6b,
0x35, 0x1d, 0x11, 0xcf, 0x95, 0x00, 0xe9, 0xce, 0x33, 0x9a, 0x3d, 0x24, 0x2b, 0xf9, 0x8b, 0xd5,
0x61, 0x9a, 0x5f, 0x0d, 0xf0, 0xb4, 0xc0, 0x01, 0xc4, 0x79, 0x06, 0x0a, 0xc2, 0xbd, 0xea, 0x59,
0x3e, 0x15, 0xf8, 0x5e, 0xb5, 0x96, 0xc4, 0xf7, 0xaa, 0x86, 0x80, 0x26, 0x4f, 0x39, 0x65, 0xb2,
0x96, 0xc4, 0x4d, 0x1a, 0x02, 0x0b, 0x85, 0xe6, 0xd4, 0x9b, 0x0c, 0x85, 0xe0, 0x9c, 0x7b, 0xbd,
0x93, 0x83, 0x23, 0xb4, 0xd9, 0xb4, 0xee, 0x71, 0x39, 0xb9, 0xc4, 0x47, 0x68, 0x80, 0xc4, 0x47,
0x28, 0x44, 0x61, 0x95, 0xc6, 0xc2, 0x6e, 0xba, 0x1f, 0xe0, 0xe3, 0xa3, 0xb5, 0xe1, 0x5e, 0xef,
0xe4, 0xe0, 0x36, 0xf2, 0x60, 0xae, 0xda, 0x0c, 0x1d, 0xe4, 0x5a, 0x16, 0xdf, 0x46, 0x5a, 0x06,
0x96, 0x5e, 0x0b, 0xea, 0xe6, 0xc4, 0x4b, 0xef, 0xe4, 0xf1, 0xd2, 0x07, 0x9c, 0x71, 0xf2, 0x2f,
0x76, 0x1b, 0xa7, 0xa5, 0xc7, 0xa2, 0x9e, 0x23, 0xaf, 0x59, 0x96, 0x4e, 0x99, 0xe4, 0x63, 0x71,
0xc5, 0x73, 0x7c, 0xc7, 0x64, 0x4a, 0xab, 0xf9, 0x61, 0xa0, 0x10, 0xdf, 0x31, 0xc5, 0x15, 0xe1,
0x38, 0xd1, 0xf4, 0x59, 0xc5, 0x77, 0x58, 0x45, 0x44, 0xb2, 0x00, 0x89, 0x8f, 0x13, 0x88, 0xc2,
0x7c, 0x55, 0xcb, 0x5f, 0xbe, 0x2d, 0x78, 0x99, 0xf2, 0x7c, 0xc2, 0xf1, 0x7c, 0x15, 0x52, 0xf1,
0x7c, 0x15, 0xa1, 0xe1, 0x5e, 0x6d, 0x97, 0x49, 0xfe, 0x62, 0x35, 0x4e, 0xe7, 0xbc, 0x92, 0x6c,
0x5e, 0xe0, 0x7b, 0x35, 0x00, 0xc5, 0xf7, 0x6a, 0x6d, 0xb8, 0x75, 0x34, 0x64, 0x03, 0x62, 0xfb,
0x6e, 0x07, 0x24, 0x22, 0x77, 0x3b, 0x08, 0x14, 0x36, 0xac, 0x03, 0xd0, 0xe3, 0xd5, 0x96, 0x95,
0xe8, 0xf1, 0x2a, 0x4d, 0xb7, 0x0e, 0xdc, 0x2c, 0x33, 0xaa, 0xa7, 0x66, 0x47, 0xd1, 0x47, 0xfe,
0x14, 0xdd, 0xe8, 0xc5, 0xe2, 0x27, 0x7c, 0xa7, 0x3c, 0x63, 0x6a, 0xd9, 0x8a, 0x1c, 0xa3, 0x35,
0x4c, 0x9f, 0x13, 0x3e, 0x8f, 0x35, 0x0e, 0xff, 0x62, 0x2d, 0xf9, 0x08, 0xf3, 0xf8, 0xaa, 0x50,
0x7e, 0x9f, 0x76, 0xdb, 0xd2, 0x24, 0x71, 0x79, 0x25, 0xae, 0x61, 0xca, 0xf0, 0x27, 0xc9, 0x87,
0x8d, 0xc8, 0xdd, 0x6d, 0x31, 0x05, 0x08, 0x93, 0x36, 0x5b, 0x7e, 0xc8, 0x59, 0xf7, 0x5b, 0xbd,
0x79, 0xb7, 0x1f, 0x0a, 0xcb, 0x55, 0x81, 0xfd, 0x90, 0xb5, 0x61, 0xc4, 0xc4, 0x7e, 0x08, 0xc1,
0xdc, 0xec, 0xf4, 0xab, 0xf7, 0x26, 0x95, 0x97, 0x2a, 0xdf, 0x02, 0xb3, 0x33, 0x28, 0xab, 0x85,
0x88, 0xd9, 0x49, 0xc2, 0x30, 0x23, 0x69, 0xc0, 0x7a, 0x6e, 0x62, 0xb1, 0xdc, 0x1a, 0xf2, 0x67,
0xe6, 0xc3, 0x6e, 0x10, 0x8e, 0xd7, 0x46, 0x6c, 0xb6, 0x3e, 0x8f, 0x63, 0x16, 0xc0, 0xf6, 0x67,
0xa3, 0x17, 0x6b, 0x1c, 0xfe, 0x59, 0xf2, 0xbd, 0x56, 0xc5, 0xf6, 0x38, 0x93, 0x8b, 0x92, 0x4f,
0x07, 0x5b, 0x1d, 0xe5, 0x6e, 0x40, 0xeb, 0xfa, 0x69, 0x7f, 0x85, 0x56, 0x8e, 0xde, 0x70, 0x7a,
0x58, 0xd9, 0x32, 0x3c, 0x8b, 0x99, 0x0c, 0xd9, 0x68, 0x8e, 0x4e, 0xeb, 0xb4, 0xb6, 0xd9, 0xfe,
0xe8, 0xda, 0x5e, 0xb2, 0x34, 0x53, 0x8f, 0xb9, 0x3e, 0x8d, 0x19, 0x0d, 0xd0, 0xe8, 0x36, 0x9b,
0x54, 0x69, 0x45, 0x66, 0x35, 0xc7, 0xbd, 0xed, 0xd9, 0x13, 0x3a, 0x12, 0x20, 0xbb, 0xb3, 0xcd,
0x9e, 0xb4, 0x71, 0x2b, 0x9b, 0x25, 0xaf, 0xfe, 0xd9, 0x1f, 0xe4, 0x98, 0x57, 0xa3, 0x8a, 0x8c,
0xf4, 0xcd, 0x9e, 0xb4, 0xf1, 0xfa, 0xa7, 0xc9, 0x87, 0x6d, 0xaf, 0x66, 0x21, 0xda, 0xea, 0x34,
0x05, 0xd6, 0xa2, 0xa7, 0xfd, 0x15, 0xdc, 0x96, 0xe6, 0xab, 0xb4, 0x92, 0xa2, 0x5c, 0x8d, 0x2e,
0xc5, 0x75, 0x73, 0x67, 0x3c, 0x9c, 0xad, 0x06, 0x18, 0x7a, 0x04, 0xb1, 0xa5, 0xc1, 0xc9, 0x96,
0x2b, 0x77, 0xb7, 0xbc, 0x22, 0x5c, 0x79, 0x44, 0x87, 0xab, 0x90, 0x74, 0xb1, 0xaa, 0xa9, 0x95,
0xbb, 0x08, 0xbf, 0x8e, 0x17, 0xb5, 0x7d, 0x19, 0xfe, 0x61, 0x37, 0xe8, 0x32, 0x16, 0x23, 0xde,
0x4d, 0x2f, 0x2e, 0x6c, 0x9d, 0xf0, 0x92, 0xfa, 0x08, 0x91, 0xb1, 0x10, 0xa8, 0x4b, 0xba, 0xf7,
0xd2, 0x8c, 0xab, 0x13, 0xfd, 0x57, 0x17, 0x17, 0x99, 0x60, 0x53, 0x90, 0x74, 0xd7, 0xe2, 0xa1,
0x2f, 0x27, 0x92, 0x6e, 0x8c, 0x73, 0x57, 0xce, 0x6a, 0xe9, 0x29, 0x9f, 0x88, 0x7c, 0x92, 0x66,
0xf0, 0x0a, 0x9d, 0xd2, 0xb4, 0x42, 0xe2, 0xca, 0x59, 0x0b, 0x72, 0x0b, 0x63, 0x2d, 0xaa, 0xa7,
0x7d, 0x53, 0xfe, 0xfb, 0x6d, 0x45, 0x4f, 0x4c, 0x2c, 0x8c, 0x08, 0xe6, 0xf6, 0x9e, 0xb5, 0xf0,
0xac, 0x50, 0xc6, 0xef, 0xb4, 0xb5, 0xb4, 0x84, 0xd8, 0x7b, 0x86, 0x84, 0xdb, 0x43, 0xd5, 0xbf,
0xef, 0x8a, 0xeb, 0x5c, 0x19, 0xbd, 0xdb, 0x56, 0x69, 0x64, 0xc4, 0x1e, 0x0a, 0x32, 0xc6, 0xf0,
0x4f, 0x92, 0xff, 0xaf, 0x0c, 0x97, 0xa2, 0x18, 0xdc, 0x42, 0x14, 0x4a, 0xef, 0xb6, 0xdb, 0x6d,
0x52, 0xee, 0x2e, 0x6d, 0xda, 0xb1, 0x71, 0x56, 0xb1, 0x19, 0x1f, 0xdc, 0x23, 0x7a, 0x5c, 0x49,
0x89, 0x4b, 0x9b, 0x6d, 0x2a, 0x1c, 0x15, 0xc7, 0x62, 0x6a, 0xac, 0x23, 0x35, 0xb4, 0xc2, 0xd8,
0xa8, 0xf0, 0x21, 0x97, 0xcc, 0x1c, 0xb3, 0x65, 0x3a, 0xb3, 0x0b, 0x8e, 0x8e, 0x5b, 0x15, 0x48,
0x66, 0x1c, 0x33, 0xf4, 0x20, 0x22, 0x99, 0x21, 0x61, 0xe3, 0xf3, 0x9f, 0xd7, 0x92, 0x3b, 0x8e,
0xd9, 0x6f, 0x4e, 0xeb, 0x0e, 0xf2, 0x0b, 0x51, 0xa7, 0x3e, 0x87, 0x69, 0x7e, 0x55, 0x0d, 0xbe,
0xa0, 0x4c, 0xe2, 0xbc, 0x2d, 0xca, 0x97, 0x37, 0xd6, 0x73, 0x59, 0x6b, 0x73, 0x94, 0xe5, 0x9e,
0x67, 0x6b, 0x0d, 0x90, 0xb5, 0xda, 0x13, 0x2f, 0xc8, 0x11, 0x59, 0x6b, 0x8c, 0x77, 0x5d, 0x6c,
0x9d, 0x67, 0x22, 0x87, 0x5d, 0xec, 0x2c, 0xd4, 0x42, 0xa2, 0x8b, 0x5b, 0x90, 0x8b, 0xc7, 0x8d,
0x48, 0x9f, 0xba, 0x6c, 0x67, 0x19, 0x88, 0xc7, 0x56, 0xd5, 0x02, 0x44, 0x3c, 0x46, 0x41, 0xe3,
0xe7, 0x34, 0xf9, 0x4e, 0xdd, 0xa4, 0x27, 0x25, 0x5f, 0xa6, 0x1c, 0x5e, 0xbd, 0xf0, 0x24, 0xc4,
0xfc, 0x0f, 0x09, 0x37, 0xb3, 0xce, 0xf2, 0xaa, 0xc8, 0x58, 0x75, 0x69, 0x1e, 0xc6, 0x87, 0x75,
0x6e, 0x84, 0xf0, 0x71, 0xfc, 0xfd, 0x0e, 0xca, 0x05, 0xf5, 0x46, 0x66, 0x43, 0xcc, 0x03, 0x5c,
0xb5, 0x15, 0x66, 0xd6, 0x3b, 0x39, 0x77, 0xe2, 0xbd, 0xcf, 0xb2, 0x8c, 0x97, 0xab, 0x46, 0x76,
0xc4, 0xf2, 0xf4, 0x82, 0x57, 0x12, 0x9c, 0x78, 0x1b, 0x6a, 0x08, 0x31, 0xe2, 0xc4, 0x3b, 0x82,
0xbb, 0x6c, 0x1e, 0x78, 0x3e, 0xc8, 0xa7, 0xfc, 0x2d, 0xc8, 0xe6, 0xa1, 0x1d, 0xc5, 0x10, 0xd9,
0x3c, 0xc5, 0xba, 0x93, 0xdf, 0x17, 0x99, 0x98, 0x5c, 0x99, 0x25, 0x20, 0xec, 0x60, 0x25, 0x81,
0x6b, 0xc0, 0xdd, 0x18, 0xe2, 0x16, 0x01, 0x25, 0x38, 0xe5, 0x45, 0xc6, 0x26, 0xf0, 0xfe, 0x8d,
0xd6, 0x31, 0x32, 0x62, 0x11, 0x80, 0x0c, 0x28, 0xae, 0xb9, 0xd7, 0x83, 0x15, 0x17, 0x5c, 0xeb,
0xb9, 0x1b, 0x43, 0xdc, 0x32, 0xa8, 0x04, 0xa3, 0x22, 0x4b, 0x25, 0x98, 0x06, 0x5a, 0x43, 0x49,
0x88, 0x69, 0x10, 0x12, 0xc0, 0xe4, 0x11, 0x2f, 0x67, 0x1c, 0x35, 0xa9, 0x24, 0x51, 0x93, 0x0d,
0xe1, 0xae, 0x69, 0xea, 0xba, 0x8b, 0x62, 0x05, 0xae, 0x69, 0x9a, 0x6a, 0x89, 0x62, 0x45, 0x5c,
0xd3, 0x0c, 0x00, 0x50, 0xc4, 0x13, 0x56, 0x49, 0xbc, 0x88, 0x4a, 0x12, 0x2d, 0x62, 0x43, 0xb8,
0x35, 0x5a, 0x17, 0x71, 0x21, 0xc1, 0x1a, 0x6d, 0x0a, 0xe0, 0x3d, 0x81, 0xbe, 0x4d, 0xca, 0x5d,
0x24, 0xd1, 0xbd, 0xc2, 0xe5, 0x5e, 0xca, 0xb3, 0x69, 0x05, 0x22, 0x89, 0x69, 0xf7, 0x46, 0x4a,
0x44, 0x92, 0x36, 0x05, 0x86, 0x92, 0x39, 0x1f, 0xc7, 0x6a, 0x07, 0x8e, 0xc6, 0xef, 0xc6, 0x10,
0x17, 0x9f, 0x9a, 0x42, 0xef, 0xb0, 0xb2, 0x4c, 0xeb, 0xc5, 0xff, 0x01, 0x5e, 0xa0, 0x46, 0x4e,
0xc4, 0x27, 0x8c, 0x03, 0xd3, 0xab, 0x09, 0xdc, 0x58, 0xc1, 0x60, 0xe8, 0xfe, 0x24, 0xca, 0xb8,
0x8c, 0x53, 0x49, 0xbc, 0x47, 0xa8, 0x58, 0x6b, 0x22, 0x4f, 0x50, 0x1f, 0x74, 0x61, 0xde, 0x6b,
0x14, 0xd6, 0xc5, 0x91, 0x58, 0xf2, 0xb1, 0x78, 0xf9, 0x36, 0xad, 0x64, 0x9a, 0xcf, 0xcc, 0xca,
0xfd, 0x9c, 0xb0, 0x84, 0xc1, 0xc4, 0x6b, 0x14, 0x9d, 0x4a, 0x2e, 0x81, 0x00, 0x65, 0x39, 0xe6,
0xd7, 0x68, 0x02, 0x01, 0x2d, 0x5a, 0x8e, 0x48, 0x20, 0x62, 0xbc, 0x3b, 0x47, 0xb1, 0xce, 0xcd,
0xbb, 0xa6, 0x63, 0xd1, 0xe4, 0x72, 0x94, 0x35, 0x08, 0x12, 0x5b, 0xd9, 0xa8, 0x82, 0xdb, 0x5f,
0x5a, 0xff, 0x6e, 0x8a, 0x3d, 0x24, 0xec, 0xb4, 0xa7, 0xd9, 0xa3, 0x1e, 0x24, 0xe2, 0xca, 0xdd,
0x03, 0xa0, 0x5c, 0xb5, 0xaf, 0x01, 0x3c, 0xea, 0x41, 0x7a, 0x67, 0x32, 0x7e, 0xb5, 0x5e, 0xb0,
0xc9, 0xd5, 0xac, 0x14, 0x8b, 0x7c, 0xba, 0x23, 0x32, 0x51, 0x82, 0x33, 0x99, 0xa0, 0xd4, 0x00,
0x25, 0xce, 0x64, 0x3a, 0x54, 0x5c, 0x06, 0xe7, 0x97, 0x62, 0x3b, 0x4b, 0x67, 0x70, 0x47, 0x1d,
0x18, 0x52, 0x00, 0x91, 0xc1, 0xa1, 0x20, 0x32, 0x88, 0xf4, 0x8e, 0x5b, 0xa6, 0x13, 0x96, 0x69,
0x7f, 0x5b, 0xb4, 0x99, 0x00, 0xec, 0x1c, 0x44, 0x88, 0x02, 0x52, 0xcf, 0xf1, 0xa2, 0xcc, 0x0f,
0x72, 0x29, 0xc8, 0x7a, 0x36, 0x40, 0x67, 0x3d, 0x3d, 0x10, 0x84, 0xd5, 0x31, 0x7f, 0x5b, 0x97,
0xa6, 0xfe, 0x07, 0x0b, 0xab, 0xf5, 0xef, 0x43, 0x23, 0x8f, 0x85, 0x55, 0xc0, 0x81, 0xca, 0x18,
0x27, 0x7a, 0xc0, 0x44, 0xb4, 0xc3, 0x61, 0xf2, 0xb0, 0x1b, 0xc4, 0xfd, 0x8c, 0xe4, 0x2a, 0xe3,
0x31, 0x3f, 0x0a, 0xe8, 0xe3, 0xa7, 0x01, 0xdd, 0x71, 0x4b, 0x50, 0x9f, 0x4b, 0x3e, 0xb9, 0x6a,
0x5d, 0x6b, 0x0a, 0x0b, 0xaa, 0x11, 0xe2, 0xb8, 0x85, 0x40, 0xf1, 0x2e, 0x3a, 0x98, 0x88, 0x3c,
0xd6, 0x45, 0xb5, 0xbc, 0x4f, 0x17, 0x19, 0xce, 0x6d, 0x7e, 0xad, 0xd4, 0x8c, 0x4c, 0xdd, 0x4d,
0x1b, 0x84, 0x05, 0x1f, 0x22, 0x36, 0xbf, 0x24, 0xec, 0x72, 0x72, 0xe8, 0xf3, 0xa8, 0x7d, 0xe7,
0xbb, 0x65, 0xe5, 0x88, 0xbe, 0xf3, 0x4d, 0xb1, 0x74, 0x25, 0xf5, 0x18, 0xe9, 0xb0, 0x12, 0x8e,
0x93, 0x27, 0xfd, 0x60, 0xb7, 0xe5, 0x09, 0x7c, 0xee, 0x64, 0x9c, 0x95, 0xda, 0xeb, 0x66, 0xc4,
0x90, 0xc3, 0x88, 0x2d, 0x4f, 0x04, 0x07, 0x21, 0x2c, 0xf0, 0xbc, 0x23, 0x72, 0xc9, 0x73, 0x89,
0x85, 0xb0, 0xd0, 0x98, 0x01, 0x63, 0x21, 0x8c, 0x52, 0x00, 0xe3, 0x56, 0x9d, 0x07, 0x71, 0x79,
0xcc, 0xe6, 0x68, 0xc6, 0xa6, 0xcf, 0x7a, 0xb4, 0x3c, 0x36, 0x6e, 0x01, 0xe7, 0x3d, 0xe4, 0xf3,
0xbd, 0x8c, 0x59, 0x39, 0xb3, 0xa7, 0x1b, 0xd3, 0xc1, 0x53, 0xda, 0x4e, 0x48, 0x12, 0x0f, 0xf9,
0xe2, 0x1a, 0x20, 0xec, 0x1c, 0xcc, 0xd9, 0xcc, 0xd6, 0x14, 0xa9, 0x81, 0x92, 0xb7, 0xaa, 0xfa,
0xb0, 0x1b, 0x04, 0x7e, 0x5e, 0xa7, 0x53, 0x2e, 0x22, 0x7e, 0x94, 0xbc, 0x8f, 0x1f, 0x08, 0x82,
0xec, 0xad, 0xae, 0xb7, 0xde, 0xd1, 0x6d, 0xe7, 0x53, 0xb3, 0x8f, 0x1d, 0x12, 0xcd, 0x03, 0xb8,
0x58, 0xf6, 0x46, 0xf0, 0x60, 0x8e, 0x36, 0x07, 0xb4, 0xb1, 0x39, 0x6a, 0xcf, 0x5f, 0xfb, 0xcc,
0x51, 0x0c, 0x36, 0x3e, 0x7f, 0x66, 0xe6, 0xe8, 0x2e, 0x93, 0xac, 0xce, 0xdb, 0x5f, 0xa7, 0xfc,
0xda, 0x6c, 0x84, 0x91, 0xfa, 0x36, 0xd4, 0x50, 0xbd, 0xec, 0x07, 0x76, 0xc5, 0x5b, 0xbd, 0xf9,
0x88, 0x6f, 0xb3, 0x43, 0xe8, 0xf4, 0x0d, 0xb6, 0x0a, 0x5b, 0xbd, 0xf9, 0x88, 0x6f, 0xf3, 0x16,
0x71, 0xa7, 0x6f, 0xf0, 0x2a, 0xf1, 0x56, 0x6f, 0xde, 0xf8, 0xfe, 0xcb, 0x66, 0xe2, 0xfa, 0xce,
0xeb, 0x3c, 0x6c, 0x22, 0xd3, 0x25, 0xc7, 0xd2, 0xc9, 0xd0, 0x9e, 0x45, 0x63, 0xe9, 0x24, 0xad,
0xe2, 0x7d, 0x7a, 0x06, 0x2b, 0xc5, 0x89, 0xa8, 0x52, 0xf5, 0x90, 0xfe, 0x79, 0x0f, 0xa3, 0x0d,
0x1c, 0xdb, 0x34, 0xc5, 0x94, 0xdc, 0xe3, 0xc6, 0x00, 0x75, 0xb7, 0x98, 0x9f, 0x44, 0xec, 0xb5,
0x2f, 0x33, 0x6f, 0xf6, 0xa4, 0xdd, 0x83, 0xbf, 0x80, 0xf1, 0x9f, 0x38, 0xc6, 0x7a, 0x15, 0x7d,
0xe8, 0xf8, 0xb4, 0xbf, 0x82, 0x71, 0xff, 0xd7, 0xcd, 0xbe, 0x02, 0xfa, 0x37, 0x93, 0xe0, 0x59,
0x1f, 0x8b, 0x60, 0x22, 0x3c, 0xbf, 0x91, 0x8e, 0x29, 0xc8, 0xdf, 0x37, 0x1b, 0xe8, 0x06, 0x55,
0xef, 0x72, 0xbc, 0x2a, 0xa7, 0xbc, 0x34, 0x73, 0x22, 0xd6, 0xad, 0x0e, 0x86, 0x33, 0xe3, 0xf3,
0x1b, 0x6a, 0x79, 0x1f, 0x22, 0x0a, 0x60, 0xf3, 0xce, 0xa1, 0x57, 0x9e, 0x98, 0x65, 0x8f, 0x86,
0x05, 0xfa, 0xe2, 0xa6, 0x6a, 0xd4, 0x5c, 0xf1, 0x60, 0xf5, 0x5d, 0x83, 0xe7, 0x3d, 0x0d, 0x07,
0x5f, 0x3a, 0xf8, 0xec, 0x66, 0x4a, 0xa6, 0x2c, 0xff, 0xb1, 0x96, 0xdc, 0x0f, 0x58, 0xf7, 0x3c,
0x01, 0x9c, 0x7a, 0xfc, 0x38, 0x62, 0x9f, 0x52, 0xb2, 0x85, 0xfb, 0xdd, 0x5f, 0x4e, 0xd9, 0x7d,
0xb5, 0x27, 0x50, 0xd9, 0x4b, 0x33, 0xc9, 0xcb, 0xf6, 0x57, 0x7b, 0x42, 0xbb, 0x9a, 0x1a, 0xd2,
0x5f, 0xed, 0x89, 0xe0, 0xde, 0x57, 0x7b, 0x10, 0xcf, 0xe8, 0x57, 0x7b, 0x50, 0x6b, 0xd1, 0xaf,
0xf6, 0xc4, 0x35, 0xa8, 0xf0, 0xde, 0x14, 0x41, 0x9f, 0x5b, 0xf7, 0xb2, 0x18, 0x1e, 0x63, 0x3f,
0xbb, 0x89, 0x0a, 0xb1, 0xc0, 0x69, 0x4e, 0xdd, 0x73, 0xeb, 0xd1, 0xa6, 0xc1, 0x5d, 0xb7, 0xad,
0xde, 0xbc, 0xf1, 0xfd, 0x53, 0xb3, 0xbb, 0xb1, 0xe1, 0x5c, 0x94, 0xea, 0x8b, 0x4d, 0x1b, 0xb1,
0xf0, 0x5c, 0x5b, 0xf0, 0x7b, 0xfe, 0x49, 0x3f, 0x98, 0xa8, 0x6e, 0x4d, 0x98, 0x4e, 0x1f, 0x76,
0x19, 0x02, 0x5d, 0xbe, 0xd5, 0x9b, 0x27, 0x96, 0x11, 0xed, 0x5b, 0xf7, 0x76, 0x0f, 0x63, 0x61,
0x5f, 0x3f, 0xed, 0xaf, 0x60, 0xdc, 0x2f, 0x4d, 0xda, 0xe8, 0xbb, 0x57, 0xfd, 0xbc, 0xd9, 0x65,
0x6a, 0x14, 0x74, 0xf3, 0xb0, 0x2f, 0x1e, 0x4b, 0x20, 0xfc, 0x25, 0xb4, 0x2b, 0x81, 0x40, 0x97,
0xd1, 0xcf, 0x6e, 0xa6, 0x64, 0xca, 0xf2, 0x4f, 0x6b, 0xc9, 0x6d, 0xb2, 0x2c, 0x66, 0x1c, 0x7c,
0xd1, 0xd7, 0x32, 0x18, 0x0f, 0x5f, 0xde, 0x58, 0xcf, 0x14, 0xea, 0x5f, 0xd7, 0x92, 0x3b, 0x91,
0x42, 0xe9, 0x01, 0x72, 0x03, 0xeb, 0xe1, 0x40, 0xf9, 0xe1, 0xcd, 0x15, 0xa9, 0xe5, 0xde, 0xc7,
0x47, 0xed, 0xcf, 0xd9, 0x44, 0x6c, 0x8f, 0xe8, 0xcf, 0xd9, 0x74, 0x6b, 0xc1, 0x43, 0x1e, 0x76,
0xde, 0x6c, 0xba, 0xd0, 0x43, 0x1e, 0x75, 0x43, 0x0d, 0xec, 0x39, 0xd6, 0x3b, 0x39, 0xcc, 0xc9,
0xcb, 0xb7, 0x05, 0xcb, 0xa7, 0xb4, 0x13, 0x2d, 0xef, 0x76, 0x62, 0x39, 0x78, 0x38, 0x56, 0x4b,
0x4f, 0x45, 0xb3, 0x91, 0x7a, 0x44, 0xe9, 0x5b, 0x24, 0x7a, 0x38, 0xd6, 0x42, 0x09, 0x6f, 0x26,
0x6b, 0x8c, 0x79, 0x03, 0xc9, 0xe2, 0xe3, 0x3e, 0x28, 0x48, 0xd1, 0xad, 0x37, 0x7b, 0xe6, 0xfe,
0x24, 0x66, 0xa5, 0x75, 0xee, 0xbe, 0xd9, 0x93, 0x26, 0xdc, 0x8e, 0xb8, 0xfc, 0x8a, 0xb3, 0x29,
0x2f, 0xa3, 0x6e, 0x2d, 0xd5, 0xcb, 0xad, 0x4f, 0x63, 0x6e, 0x77, 0x44, 0xb6, 0x98, 0xe7, 0xa6,
0x33, 0x49, 0xb7, 0x3e, 0xd5, 0xed, 0x16, 0xd0, 0xf0, 0x58, 0xd0, 0xb9, 0x55, 0xe9, 0xe5, 0xe3,
0xb8, 0x99, 0x20, 0xab, 0xdc, 0xe8, 0xc5, 0xd2, 0xf5, 0x34, 0xc3, 0xa8, 0xa3, 0x9e, 0x60, 0x24,
0x6d, 0xf6, 0xa4, 0xe1, 0xf9, 0x9c, 0xe7, 0xd6, 0x8e, 0xa7, 0xad, 0x0e, 0x5b, 0xad, 0x21, 0xf5,
0xb4, 0xbf, 0x02, 0x3c, 0x0d, 0x35, 0xa3, 0xea, 0x30, 0xad, 0xe4, 0x5e, 0x9a, 0x65, 0x83, 0x8d,
0xc8, 0x30, 0x69, 0xa0, 0xe8, 0x69, 0x28, 0x02, 0x13, 0x23, 0xb9, 0x39, 0x3d, 0xcc, 0x07, 0x5d,
0x76, 0x14, 0xd5, 0x6b, 0x24, 0xfb, 0x34, 0x38, 0xd1, 0xf2, 0x9a, 0xda, 0xd6, 0x76, 0x18, 0x6f,
0xb8, 0x56, 0x85, 0xb7, 0x7a, 0xf3, 0xe0, 0x71, 0xbb, 0xa2, 0xd4, 0xca, 0x72, 0x8f, 0x32, 0x11,
0xac, 0x24, 0xf7, 0x3b, 0x28, 0x70, 0x2a, 0xa8, 0xa7, 0xd1, 0x9b, 0x74, 0x3a, 0xe3, 0x12, 0x7d,
0x52, 0xe4, 0x03, 0xd1, 0x27, 0x45, 0x00, 0x04, 0x5d, 0xa7, 0x7f, 0xb7, 0xc7, 0xa1, 0x07, 0x53,
0xac, 0xeb, 0x8c, 0xb2, 0x47, 0xc5, 0xba, 0x0e, 0xa5, 0x41, 0x34, 0xb0, 0x6e, 0xcd, 0xeb, 0xf8,
0x8f, 0x63, 0x66, 0xc0, 0x3b, 0xf9, 0x1b, 0xbd, 0x58, 0xb0, 0xa2, 0x38, 0x87, 0xe9, 0x3c, 0x95,
0xd8, 0x8a, 0xe2, 0xd9, 0xa8, 0x91, 0xd8, 0x8a, 0xd2, 0x46, 0xa9, 0xea, 0xd5, 0x39, 0xc2, 0xc1,
0x34, 0x5e, 0x3d, 0xcd, 0xf4, 0xab, 0x9e, 0x65, 0x5b, 0x0f, 0x36, 0x73, 0x3b, 0x64, 0xe4, 0xa5,
0xd9, 0x2c, 0x23, 0x63, 0x5b, 0xbd, 0xa6, 0x09, 0xc1, 0x58, 0xd4, 0xa1, 0x14, 0xe0, 0x81, 0x7d,
0xcd, 0x35, 0xcf, 0x5e, 0x8b, 0x82, 0xb3, 0x92, 0xe5, 0x13, 0x74, 0x73, 0xaa, 0x0c, 0xb6, 0xc8,
0xd8, 0xe6, 0x94, 0xd4, 0x00, 0x8f, 0xcd, 0xc3, 0x17, 0x2c, 0x91, 0xa9, 0x60, 0xdf, 0x64, 0x0c,
0xdf, 0xaf, 0x7c, 0xd4, 0x83, 0x84, 0x8f, 0xcd, 0x1b, 0xc0, 0x1e, 0x7c, 0x6b, 0xa7, 0x9f, 0x46,
0x4c, 0x85, 0x68, 0x6c, 0x23, 0x4c, 0xab, 0x80, 0x41, 0x6d, 0x13, 0x5c, 0x2e, 0x7f, 0xc2, 0x57,
0xd8, 0xa0, 0x76, 0xf9, 0xa9, 0x42, 0x62, 0x83, 0xba, 0x8d, 0x82, 0x3c, 0xd3, 0xdf, 0x07, 0x3d,
0x88, 0xe8, 0xfb, 0x5b, 0x9f, 0xf5, 0x4e, 0x0e, 0xcc, 0x9c, 0xdd, 0x74, 0x19, 0x3c, 0x27, 0x40,
0x0a, 0xba, 0x9b, 0x2e, 0xf1, 0xc7, 0x04, 0x1b, 0xbd, 0x58, 0xf8, 0x48, 0x9e, 0x49, 0xfe, 0xb6,
0x79, 0x56, 0x8e, 0x14, 0x57, 0xc9, 0x5b, 0x0f, 0xcb, 0x1f, 0x76, 0x83, 0xee, 0x02, 0xec, 0x49,
0x29, 0x26, 0xbc, 0xaa, 0xcc, 0x37, 0xfe, 0xc2, 0x1b, 0x46, 0x46, 0x36, 0x04, 0x5f, 0xf8, 0xbb,
0x17, 0x87, 0x5c, 0xcf, 0x18, 0x91, 0xfb, 0xea, 0xcd, 0x03, 0x54, 0xb3, 0xfd, 0xc1, 0x9b, 0xf5,
0x4e, 0xce, 0x4d, 0x2f, 0x23, 0xf5, 0x3f, 0x73, 0xf3, 0x10, 0x55, 0xc7, 0xbe, 0x70, 0xf3, 0xa8,
0x07, 0x69, 0x5c, 0x7d, 0x95, 0xbc, 0x7b, 0x28, 0x66, 0x23, 0x9e, 0x4f, 0x07, 0x3f, 0x08, 0xaf,
0xd0, 0x8a, 0xd9, 0xb0, 0xfe, 0xd9, 0x1a, 0xbd, 0x45, 0x89, 0xdd, 0x25, 0xc0, 0x5d, 0x7e, 0xbe,
0x98, 0x8d, 0x24, 0x93, 0xe0, 0x12, 0xa0, 0xfa, 0x7d, 0x58, 0x0b, 0x88, 0x4b, 0x80, 0x01, 0x00,
0xec, 0x8d, 0x4b, 0xce, 0x51, 0x7b, 0xb5, 0x20, 0x6a, 0xcf, 0x00, 0x2e, 0x8b, 0xb0, 0xf6, 0xea,
0x44, 0x1d, 0x5e, 0xda, 0x73, 0x3a, 0x4a, 0x4a, 0x64, 0x11, 0x6d, 0xca, 0x0d, 0x6e, 0x5d, 0x7d,
0xf5, 0xd5, 0x91, 0xc5, 0x7c, 0xce, 0xca, 0x15, 0x18, 0xdc, 0xa6, 0x96, 0x1e, 0x40, 0x0c, 0x6e,
0x14, 0x74, 0xb3, 0xb6, 0x69, 0xe6, 0xc9, 0xd5, 0xbe, 0x28, 0xc5, 0x42, 0xa6, 0x39, 0x87, 0x5f,
0x9e, 0xb0, 0x0d, 0xea, 0x33, 0xc4, 0xac, 0xa5, 0x58, 0x97, 0xe5, 0x2a, 0x42, 0xdf, 0x27, 0x54,
0x5f, 0xfe, 0xad, 0xa4, 0x28, 0xe1, 0xf3, 0x44, 0x6d, 0x05, 0x42, 0x44, 0x96, 0x4b, 0xc2, 0xa0,
0xef, 0x4f, 0xd2, 0x7c, 0x86, 0xf6, 0xfd, 0x89, 0xff, 0xdd, 0xcc, 0x3b, 0x34, 0xe0, 0x26, 0x94,
0x6e, 0x34, 0x3d, 0x01, 0xcc, 0xbb, 0x9c, 0x68, 0xa3, 0xfb, 0x04, 0x31, 0xa1, 0x70, 0x12, 0xb8,
0x7a, 0x55, 0xf0, 0x9c, 0x4f, 0x9b, 0x5b, 0x73, 0x98, 0xab, 0x80, 0x88, 0xba, 0x82, 0xa4, 0x8b,
0x45, 0x4a, 0x7e, 0xba, 0xc8, 0x4f, 0x4a, 0x71, 0x91, 0x66, 0xbc, 0x04, 0xb1, 0x48, 0xab, 0x7b,
0x72, 0x22, 0x16, 0x61, 0x9c, 0xbb, 0x7e, 0xa1, 0xa4, 0xc1, 0xe7, 0xab, 0xc7, 0x25, 0x9b, 0xc0,
0xeb, 0x17, 0xda, 0x46, 0x1b, 0x23, 0x4e, 0x06, 0x23, 0xb8, 0x97, 0xe8, 0x68, 0xd7, 0xf9, 0x4a,
0x8d, 0x0f, 0xf3, 0x2e, 0xa1, 0xfa, 0x9a, 0x64, 0x05, 0x12, 0x1d, 0x63, 0x0e, 0x23, 0x89, 0x44,
0x27, 0xae, 0xe1, 0x96, 0x12, 0xc5, 0x1d, 0x9b, 0x6b, 0x45, 0x60, 0x29, 0xd1, 0x36, 0x1a, 0x21,
0xb1, 0x94, 0xb4, 0x20, 0x10, 0x90, 0x9a, 0x69, 0x30, 0x43, 0x03, 0x92, 0x95, 0x46, 0x03, 0x92,
0x4f, 0xb9, 0x40, 0x71, 0x90, 0xa7, 0x32, 0x65, 0xd9, 0x88, 0xcb, 0x13, 0x56, 0xb2, 0x39, 0x97,
0xbc, 0x84, 0x81, 0xc2, 0x20, 0xc3, 0x80, 0x21, 0x02, 0x05, 0xc5, 0x1a, 0x87, 0xbf, 0x97, 0xbc,
0x5f, 0xaf, 0xfb, 0x3c, 0x37, 0x7f, 0xa8, 0xe2, 0xa5, 0xfa, 0x0b, 0x37, 0x83, 0x0f, 0xac, 0x8d,
0x91, 0x2c, 0x39, 0x9b, 0x37, 0xb6, 0xdf, 0xb3, 0xbf, 0x2b, 0xf0, 0xe9, 0x5a, 0x3d, 0x9e, 0x8f,
0x85, 0x4c, 0x2f, 0xea, 0x6d, 0xb6, 0x79, 0x83, 0x08, 0x8c, 0x67, 0x5f, 0x3c, 0x8c, 0x7c, 0x8b,
0x02, 0xe3, 0x5c, 0x9c, 0xf6, 0xa5, 0xa7, 0xbc, 0xc8, 0x60, 0x9c, 0x0e, 0xb4, 0x15, 0x40, 0xc4,
0x69, 0x14, 0x74, 0x93, 0xd3, 0x17, 0x8f, 0x79, 0xbc, 0x32, 0x63, 0xde, 0xaf, 0x32, 0xe3, 0xe0,
0xa5, 0x8c, 0x2c, 0x79, 0xff, 0x88, 0xcf, 0xcf, 0x79, 0x59, 0x5d, 0xa6, 0xc5, 0x7e, 0x9d, 0x70,
0x31, 0xb9, 0x80, 0xaf, 0x2d, 0x3a, 0x62, 0x68, 0x11, 0x22, 0x2b, 0x25, 0x50, 0xb7, 0x12, 0x38,
0xe0, 0xa0, 0x3a, 0x66, 0x73, 0xae, 0xbe, 0xac, 0x01, 0x56, 0x02, 0xcf, 0x88, 0x07, 0x11, 0x2b,
0x01, 0x09, 0x7b, 0xef, 0x77, 0x39, 0xe6, 0x94, 0xcf, 0xea, 0x11, 0x56, 0x9e, 0xb0, 0xd5, 0x9c,
0xe7, 0xd2, 0x98, 0x04, 0x67, 0xf2, 0x9e, 0x49, 0x9c, 0x27, 0xce, 0xe4, 0xfb, 0xe8, 0x79, 0xa1,
0x29, 0x68, 0xf8, 0x13, 0x51, 0x4a, 0xfd, 0x67, 0x68, 0xce, 0xca, 0x0c, 0x84, 0xa6, 0xb0, 0x51,
0x03, 0x92, 0x08, 0x4d, 0x71, 0x0d, 0xef, 0xfb, 0xed, 0x41, 0x19, 0x5e, 0xf3, 0xd2, 0x8e, 0x93,
0x97, 0x73, 0x96, 0x66, 0x66, 0x34, 0xfc, 0x28, 0x62, 0x9b, 0xd0, 0x21, 0xbe, 0xdf, 0xde, 0x57,
0xd7, 0xfb, 0xe2, 0x7d, 0xbc, 0x84, 0xe0, 0x11, 0x41, 0x87, 0x7d, 0xe2, 0x11, 0x41, 0xb7, 0x96,
0xdb, 0xb9, 0x3b, 0x56, 0x71, 0x2b, 0x45, 0xec, 0x88, 0x29, 0x3c, 0x2f, 0xf4, 0x6c, 0x02, 0x90,
0xd8, 0xb9, 0x47, 0x15, 0x5c, 0x6a, 0xe0, 0xb0, 0xbd, 0x34, 0x67, 0x59, 0xfa, 0x33, 0x98, 0xd6,
0x7b, 0x76, 0x1a, 0x82, 0x48, 0x0d, 0x70, 0x12, 0x73, 0xb5, 0xcf, 0xe5, 0x38, 0xad, 0x43, 0xff,
0xc3, 0x48, 0xbb, 0x29, 0xa2, 0xdb, 0x95, 0x47, 0x7a, 0xdf, 0x68, 0x85, 0xcd, 0xba, 0x5d, 0x14,
0xa3, 0x7a, 0x55, 0x3d, 0xe5, 0x13, 0x9e, 0x16, 0x72, 0xf0, 0x79, 0xbc, 0xad, 0x00, 0x4e, 0x5c,
0xb4, 0xe8, 0xa1, 0xe6, 0x3d, 0xbe, 0xaf, 0x63, 0xc9, 0x48, 0xff, 0x7d, 0xb6, 0xb3, 0x8a, 0x97,
0x26, 0xd1, 0xd8, 0xe7, 0x12, 0xcc, 0x4e, 0x8f, 0x1b, 0x7a, 0x60, 0x5d, 0x51, 0x62, 0x76, 0xc6,
0x35, 0xdc, 0x61, 0x9f, 0xc7, 0x9d, 0xf2, 0x4a, 0x64, 0x4b, 0xae, 0xee, 0x1b, 0x3e, 0x21, 0x8d,
0x79, 0x14, 0x71, 0xd8, 0x47, 0xd3, 0x2e, 0x5b, 0x6b, 0xbb, 0xdd, 0xce, 0x57, 0x07, 0xf0, 0xca,
0x04, 0x62, 0x49, 0x61, 0x44, 0xb6, 0x16, 0xc1, 0xbd, 0xc3, 0xf0, 0x52, 0xb0, 0xe9, 0x84, 0x55,
0xf2, 0x84, 0xad, 0x32, 0xc1, 0xa6, 0x6a, 0x5d, 0x87, 0x87, 0xe1, 0x0d, 0x33, 0xf4, 0x21, 0xea,
0x30, 0x9c, 0x82, 0xfd, 0xec, 0x4c, 0xfd, 0xd9, 0x39, 0x73, 0x97, 0x13, 0x66, 0x67, 0xaa, 0xbc,
0xf0, 0x1e, 0xe7, 0xbd, 0x38, 0xe4, 0xde, 0x41, 0xd3, 0x22, 0x95, 0x86, 0xdc, 0xc1, 0x74, 0x82,
0x04, 0xe4, 0xe3, 0x08, 0xe1, 0xbe, 0x4b, 0xa1, 0x7f, 0x6f, 0xfe, 0x72, 0x8a, 0x34, 0x5f, 0xb2,
0x7e, 0x82, 0xe9, 0xfa, 0xd0, 0xd0, 0xff, 0xc0, 0xdd, 0x66, 0x4f, 0xda, 0xa5, 0x99, 0x3b, 0x97,
0x4c, 0x6e, 0x4f, 0xa7, 0x47, 0xbc, 0x42, 0x5e, 0x28, 0xaf, 0x85, 0x43, 0x27, 0x25, 0xd2, 0xcc,
0x36, 0xe5, 0x06, 0x7a, 0x2d, 0x7b, 0x39, 0x4d, 0xa5, 0x91, 0x35, 0x37, 0xa4, 0x9f, 0xb4, 0x0d,
0xb4, 0x29, 0xa2, 0x56, 0x34, 0xed, 0x62, 0x79, 0xcd, 0x8c, 0xc5, 0x6c, 0x96, 0x71, 0x03, 0x9d,
0x72, 0xa6, 0x3f, 0xe4, 0xb7, 0xd5, 0xb6, 0x85, 0x82, 0x44, 0x2c, 0x8f, 0x2a, 0xb8, 0x34, 0xb2,
0xc6, 0xf4, 0x23, 0xa9, 0xa6, 0x61, 0xd7, 0xdb, 0x66, 0x02, 0x80, 0x48, 0x23, 0x51, 0xd0, 0xbd,
0xf7, 0x56, 0x8b, 0xf7, 0x79, 0xd3, 0x12, 0xf0, 0x13, 0x44, 0x4a, 0xd9, 0x13, 0x13, 0xef, 0xbd,
0x21, 0x98, 0xdb, 0x27, 0x00, 0x0f, 0x2f, 0x56, 0x07, 0x53, 0xb8, 0x4f, 0x80, 0xfa, 0x8a, 0x21,
0xf6, 0x09, 0x14, 0x1b, 0x76, 0x9d, 0x3d, 0xf7, 0x3a, 0x64, 0x95, 0xab, 0x1c, 0xd2, 0x75, 0x28,
0x18, 0xeb, 0x3a, 0x4a, 0x21, 0x6c, 0x52, 0xff, 0x68, 0x0d, 0x69, 0x52, 0xec, 0x5c, 0xed, 0x41,
0x17, 0xe6, 0xe2, 0x92, 0xdd, 0x4f, 0xaa, 0x2b, 0x4b, 0xf8, 0x17, 0xfc, 0xb5, 0x90, 0x88, 0x4b,
0x2d, 0x48, 0xdb, 0x7e, 0xf1, 0xf1, 0x7f, 0x7d, 0x73, 0x6b, 0xed, 0x17, 0xdf, 0xdc, 0x5a, 0xfb,
0x9f, 0x6f, 0x6e, 0xad, 0xfd, 0xfc, 0xdb, 0x5b, 0xef, 0xfc, 0xe2, 0xdb, 0x5b, 0xef, 0xfc, 0xf7,
0xb7, 0xb7, 0xde, 0xf9, 0xfa, 0x5d, 0xf3, 0xe7, 0x48, 0xcf, 0xff, 0x9f, 0xfa, 0xa3, 0xa2, 0xcf,
0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x51, 0x19, 0x1a, 0x8e, 0xb2, 0x74, 0x00, 0x00,
// 5279 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0x5b, 0x6f, 0x24, 0x49,
0x56, 0xf8, 0xc7, 0x2f, 0xff, 0xf9, 0x93, 0xcb, 0x0e, 0x50, 0x03, 0xc3, 0xec, 0xb0, 0xdb, 0xb7,
0xe9, 0xb6, 0xdd, 0x6d, 0xbb, 0xdc, 0xd3, 0x3d, 0x3d, 0xb3, 0xda, 0x45, 0x42, 0x6e, 0xbb, 0xed,
0x31, 0x6b, 0xbb, 0x8d, 0xab, 0xdc, 0x2d, 0x8d, 0x84, 0x44, 0x38, 0x2b, 0x5c, 0x4e, 0x9c, 0x95,
0x91, 0x9b, 0x19, 0x55, 0xee, 0x5a, 0x04, 0x02, 0x81, 0x40, 0x20, 0x10, 0x2b, 0x6e, 0xaf, 0x48,
0x7c, 0x1a, 0x1e, 0xf7, 0x91, 0x47, 0x34, 0x23, 0x1e, 0xf8, 0x16, 0x28, 0x23, 0x23, 0xe3, 0x72,
0xf2, 0x9c, 0xc8, 0xf4, 0x3e, 0x75, 0xab, 0xce, 0xef, 0x9c, 0x13, 0xd7, 0x13, 0x27, 0x22, 0x23,
0xd3, 0xd1, 0xdd, 0xfc, 0x62, 0x3b, 0x2f, 0x84, 0x14, 0xe5, 0x76, 0xc9, 0x8b, 0x45, 0x12, 0xf3,
0xe6, 0xdf, 0xa1, 0xfa, 0x79, 0xf0, 0x3e, 0xcb, 0x96, 0x72, 0x99, 0xf3, 0x4f, 0x3e, 0xb6, 0x64,
0x2c, 0x66, 0x33, 0x96, 0x4d, 0xca, 0x1a, 0xf9, 0xe4, 0x23, 0x2b, 0xe1, 0x0b, 0x9e, 0x49, 0xfd,
0xfb, 0xb3, 0xff, 0xf9, 0xdf, 0x95, 0xe8, 0x83, 0xdd, 0x34, 0xe1, 0x99, 0xdc, 0xd5, 0x1a, 0x83,
0xaf, 0xa3, 0xef, 0xee, 0xe4, 0xf9, 0x01, 0x97, 0x6f, 0x78, 0x51, 0x26, 0x22, 0x1b, 0x7c, 0x3a,
0xd4, 0x0e, 0x86, 0x67, 0x79, 0x3c, 0xdc, 0xc9, 0xf3, 0xa1, 0x15, 0x0e, 0xcf, 0xf8, 0x4f, 0xe7,
0xbc, 0x94, 0x9f, 0x3c, 0x0c, 0x43, 0x65, 0x2e, 0xb2, 0x92, 0x0f, 0x2e, 0xa3, 0xdf, 0xd8, 0xc9,
0xf3, 0x11, 0x97, 0x7b, 0xbc, 0xaa, 0xc0, 0x48, 0x32, 0xc9, 0x07, 0x6b, 0x2d, 0x55, 0x1f, 0x30,
0x3e, 0xd6, 0xbb, 0x41, 0xed, 0x67, 0x1c, 0x7d, 0xa7, 0xf2, 0x73, 0x35, 0x97, 0x13, 0x71, 0x93,
0x0d, 0xee, 0xb7, 0x15, 0xb5, 0xc8, 0xd8, 0x7e, 0x10, 0x42, 0xb4, 0xd5, 0xb7, 0xd1, 0xaf, 0xbe,
0x65, 0x69, 0xca, 0xe5, 0x6e, 0xc1, 0xab, 0x82, 0xfb, 0x3a, 0xb5, 0x68, 0x58, 0xcb, 0x8c, 0xdd,
0x4f, 0x83, 0x8c, 0x36, 0xfc, 0x75, 0xf4, 0xdd, 0x5a, 0x72, 0xc6, 0x63, 0xb1, 0xe0, 0xc5, 0x00,
0xd5, 0xd2, 0x42, 0xa2, 0xc9, 0x5b, 0x10, 0xb4, 0xbd, 0x2b, 0xb2, 0x05, 0x2f, 0x24, 0x6e, 0x5b,
0x0b, 0xc3, 0xb6, 0x2d, 0xa4, 0x6d, 0xff, 0xed, 0x4a, 0xf4, 0xfd, 0x9d, 0x38, 0x16, 0xf3, 0x4c,
0x1e, 0x89, 0x98, 0xa5, 0x47, 0x49, 0x76, 0x7d, 0xc2, 0x6f, 0x76, 0xaf, 0x2a, 0x3e, 0x9b, 0xf2,
0xc1, 0x73, 0xbf, 0x55, 0x6b, 0x74, 0x68, 0xd8, 0xa1, 0x0b, 0x1b, 0xdf, 0x9f, 0xdf, 0x4e, 0x49,
0x97, 0xe5, 0x1f, 0x57, 0xa2, 0x3b, 0xb0, 0x2c, 0x23, 0x91, 0x2e, 0xb8, 0x2d, 0xcd, 0x8b, 0x0e,
0xc3, 0x3e, 0x6e, 0xca, 0xf3, 0xc5, 0x6d, 0xd5, 0x74, 0x89, 0xd2, 0xe8, 0x43, 0x77, 0xb8, 0x8c,
0x78, 0xa9, 0xa6, 0xd3, 0x63, 0x7a, 0x44, 0x68, 0xc4, 0x78, 0x7e, 0xd2, 0x07, 0xd5, 0xde, 0x92,
0x68, 0xa0, 0xbd, 0xa5, 0xa2, 0x34, 0xce, 0xd6, 0x51, 0x0b, 0x0e, 0x61, 0x7c, 0x3d, 0xee, 0x41,
0x6a, 0x57, 0x7f, 0x14, 0xfd, 0xda, 0x5b, 0x51, 0x5c, 0x97, 0x39, 0x8b, 0xb9, 0x9e, 0x0a, 0x8f,
0x7c, 0xed, 0x46, 0x0a, 0x67, 0xc3, 0x6a, 0x17, 0xe6, 0x0c, 0xda, 0x46, 0xf8, 0x3a, 0xe7, 0x30,
0x06, 0x59, 0xc5, 0x4a, 0x48, 0x0d, 0x5a, 0x08, 0x69, 0xdb, 0xd7, 0xd1, 0xc0, 0xda, 0xbe, 0xf8,
0x63, 0x1e, 0xcb, 0x9d, 0xc9, 0x04, 0xf6, 0x8a, 0xd5, 0x55, 0xc4, 0x70, 0x67, 0x32, 0xa1, 0x7a,
0x05, 0x47, 0xb5, 0xb3, 0x9b, 0xe8, 0x23, 0xe0, 0xec, 0x28, 0x29, 0x95, 0xc3, 0xad, 0xb0, 0x15,
0x8d, 0x19, 0xa7, 0xc3, 0xbe, 0xb8, 0x76, 0xfc, 0xe7, 0x2b, 0xd1, 0xf7, 0x10, 0xcf, 0x67, 0x7c,
0x26, 0x16, 0x7c, 0xf0, 0xb4, 0xdb, 0x5a, 0x4d, 0x1a, 0xff, 0x9f, 0xdd, 0x42, 0x03, 0x19, 0x26,
0x23, 0x9e, 0xf2, 0x58, 0x92, 0xc3, 0xa4, 0x16, 0x77, 0x0e, 0x13, 0x83, 0x39, 0x33, 0xac, 0x11,
0x1e, 0x70, 0xb9, 0x3b, 0x2f, 0x0a, 0x9e, 0x49, 0xb2, 0x2f, 0x2d, 0xd2, 0xd9, 0x97, 0x1e, 0x8a,
0xd4, 0xe7, 0x80, 0xcb, 0x9d, 0x34, 0x25, 0xeb, 0x53, 0x8b, 0x3b, 0xeb, 0x63, 0x30, 0xed, 0x21,
0x8e, 0x7e, 0xdd, 0x69, 0x31, 0x79, 0x98, 0x5d, 0x8a, 0x01, 0xdd, 0x16, 0x4a, 0x6e, 0x7c, 0xac,
0x75, 0x72, 0x48, 0x35, 0x5e, 0xbd, 0xcb, 0x45, 0x41, 0x77, 0x4b, 0x2d, 0xee, 0xac, 0x86, 0xc1,
0xb4, 0x87, 0x3f, 0x8c, 0x3e, 0xd0, 0x51, 0xb2, 0x59, 0xcf, 0x1e, 0xa2, 0x21, 0x14, 0x2e, 0x68,
0x8f, 0x3a, 0x28, 0x1b, 0x1c, 0xb4, 0x4c, 0x07, 0x9f, 0x4f, 0x51, 0x3d, 0x10, 0x7a, 0x1e, 0x86,
0xa1, 0x96, 0xed, 0x3d, 0x9e, 0x72, 0xd2, 0x76, 0x2d, 0xec, 0xb0, 0x6d, 0x20, 0x6d, 0xbb, 0x88,
0x7e, 0xcb, 0x34, 0x4b, 0xb5, 0x8e, 0x2a, 0x79, 0x15, 0xa4, 0x37, 0x88, 0x7a, 0xbb, 0x90, 0xf1,
0xb5, 0xd9, 0x0f, 0x6e, 0xd5, 0x47, 0xcf, 0x40, 0xbc, 0x3e, 0x60, 0xfe, 0x3d, 0x0c, 0x43, 0xda,
0xf6, 0xdf, 0xad, 0x44, 0x3f, 0xd0, 0xb2, 0x57, 0x19, 0xbb, 0x48, 0xb9, 0x5a, 0x12, 0x4f, 0xb8,
0xbc, 0x11, 0xc5, 0xf5, 0x68, 0x99, 0xc5, 0xc4, 0xf2, 0x8f, 0xc3, 0x1d, 0xcb, 0x3f, 0xa9, 0xe4,
0x64, 0x7c, 0xba, 0xa2, 0x52, 0xe4, 0x30, 0xe3, 0x6b, 0x6a, 0x20, 0x45, 0x4e, 0x65, 0x7c, 0x3e,
0xd2, 0xb2, 0x7a, 0x5c, 0x85, 0x4d, 0xdc, 0xea, 0xb1, 0x1b, 0x27, 0x1f, 0x84, 0x10, 0x1b, 0xb6,
0x9a, 0x01, 0x2c, 0xb2, 0xcb, 0x64, 0x7a, 0x9e, 0x4f, 0xaa, 0x61, 0xfc, 0x18, 0x1f, 0xa1, 0x0e,
0x42, 0x84, 0x2d, 0x02, 0xd5, 0xde, 0xfe, 0xc1, 0x26, 0x46, 0x7a, 0x2a, 0xed, 0x17, 0x62, 0x76,
0xc4, 0xa7, 0x2c, 0x5e, 0xea, 0xf9, 0xff, 0x79, 0x68, 0xe2, 0x41, 0xda, 0x14, 0xe2, 0xc5, 0x2d,
0xb5, 0x74, 0x79, 0xfe, 0x7d, 0x25, 0x7a, 0xd8, 0x54, 0xff, 0x8a, 0x65, 0x53, 0xae, 0xfb, 0xb3,
0x2e, 0xfd, 0x4e, 0x36, 0x39, 0xe3, 0xa5, 0x64, 0x85, 0x1c, 0xfc, 0x08, 0xaf, 0x64, 0x48, 0xc7,
0x94, 0xed, 0xc7, 0xbf, 0x94, 0xae, 0xed, 0xf5, 0x51, 0x15, 0xd8, 0x74, 0x08, 0xf0, 0x7b, 0x5d,
0x49, 0x60, 0x00, 0x78, 0x10, 0x42, 0x6c, 0xaf, 0x2b, 0xc1, 0x61, 0xb6, 0x48, 0x24, 0x3f, 0xe0,
0x19, 0x2f, 0xda, 0xbd, 0x5e, 0xab, 0xfa, 0x08, 0xd1, 0xeb, 0x04, 0x6a, 0x83, 0x8d, 0xe7, 0xcd,
0x2c, 0x8e, 0x1b, 0x01, 0x23, 0xad, 0xe5, 0x71, 0xb3, 0x1f, 0x6c, 0x77, 0x77, 0x8e, 0xcf, 0x33,
0xbe, 0x10, 0xd7, 0x70, 0x77, 0xe7, 0x9a, 0xa8, 0x01, 0x62, 0x77, 0x87, 0x82, 0x76, 0x05, 0x73,
0xfc, 0xbc, 0x49, 0xf8, 0x0d, 0x58, 0xc1, 0x5c, 0xe5, 0x4a, 0x4c, 0xac, 0x60, 0x08, 0xa6, 0x3d,
0x9c, 0x44, 0xbf, 0xa2, 0x84, 0xbf, 0x2f, 0x92, 0x6c, 0x70, 0x17, 0x51, 0xaa, 0x04, 0xc6, 0xea,
0x3d, 0x1a, 0x00, 0x25, 0xae, 0x7e, 0xdd, 0x65, 0x59, 0xcc, 0x53, 0xb4, 0xc4, 0x56, 0x1c, 0x2c,
0xb1, 0x87, 0xd9, 0xd4, 0x41, 0x09, 0xab, 0xf8, 0x35, 0xba, 0x62, 0x45, 0x92, 0x4d, 0x07, 0x98,
0xae, 0x23, 0x27, 0x52, 0x07, 0x8c, 0x03, 0x43, 0x58, 0x2b, 0xee, 0xe4, 0x79, 0x51, 0x85, 0x45,
0x6c, 0x08, 0xfb, 0x48, 0x70, 0x08, 0xb7, 0x50, 0xdc, 0xdb, 0x1e, 0x8f, 0xd3, 0x24, 0x0b, 0x7a,
0xd3, 0x48, 0x1f, 0x6f, 0x16, 0x05, 0x83, 0xf7, 0x88, 0xb3, 0x05, 0x6f, 0x6a, 0x86, 0xb5, 0x8c,
0x0b, 0x04, 0x07, 0x2f, 0x00, 0xed, 0x3e, 0x4d, 0x89, 0x8f, 0xd9, 0x35, 0xaf, 0x1a, 0x98, 0x57,
0xeb, 0xda, 0x00, 0xd3, 0xf7, 0x08, 0x62, 0x9f, 0x86, 0x93, 0xda, 0xd5, 0x3c, 0xfa, 0x48, 0xc9,
0x4f, 0x59, 0x21, 0x93, 0x38, 0xc9, 0x59, 0xd6, 0xe4, 0xff, 0xd8, 0xbc, 0x6e, 0x51, 0xc6, 0xe5,
0x56, 0x4f, 0x5a, 0xbb, 0xfd, 0xb7, 0x95, 0xe8, 0x3e, 0xf4, 0x7b, 0xca, 0x8b, 0x59, 0xa2, 0xb6,
0x91, 0x65, 0x1d, 0x84, 0x07, 0x5f, 0x86, 0x8d, 0xb6, 0x14, 0x4c, 0x69, 0x7e, 0x78, 0x7b, 0x45,
0x9b, 0x0c, 0x8d, 0x74, 0x6a, 0xfd, 0xba, 0x98, 0xb4, 0x8e, 0x59, 0x46, 0x4d, 0xbe, 0xac, 0x84,
0x44, 0x32, 0xd4, 0x82, 0xc0, 0x0c, 0x3f, 0xcf, 0xca, 0xc6, 0x3a, 0x36, 0xc3, 0xad, 0x38, 0x38,
0xc3, 0x3d, 0x4c, 0x7b, 0xf8, 0x83, 0x28, 0xaa, 0x37, 0x5b, 0x6a, 0x43, 0xec, 0xc7, 0x1c, 0xbd,
0x0b, 0xf3, 0x76, 0xc3, 0xf7, 0x03, 0x84, 0x5d, 0xe8, 0xea, 0xdf, 0xd5, 0x3e, 0x7f, 0x80, 0x6a,
0x28, 0x11, 0xb1, 0xd0, 0x01, 0x04, 0x16, 0x74, 0x74, 0x25, 0x6e, 0xf0, 0x82, 0x56, 0x92, 0x70,
0x41, 0x35, 0x61, 0x4f, 0xde, 0x74, 0x41, 0xb1, 0x93, 0xb7, 0xa6, 0x18, 0xa1, 0x93, 0x37, 0xc8,
0x68, 0xc3, 0x22, 0xfa, 0x4d, 0xd7, 0xf0, 0x4b, 0x21, 0xae, 0x67, 0xac, 0xb8, 0x1e, 0x3c, 0xa1,
0x95, 0x1b, 0xc6, 0x38, 0xda, 0xe8, 0xc5, 0xda, 0xa0, 0xe6, 0x3a, 0xac, 0xd2, 0xa4, 0xf3, 0x22,
0x05, 0x41, 0xcd, 0xb3, 0xa1, 0x11, 0x22, 0xa8, 0x11, 0xa8, 0x1d, 0x95, 0xae, 0xb7, 0x11, 0x87,
0x7b, 0x3d, 0x4f, 0x7d, 0xc4, 0xa9, 0xbd, 0x1e, 0x82, 0xc1, 0x21, 0x74, 0x50, 0xb0, 0xfc, 0x0a,
0x1f, 0x42, 0x4a, 0x14, 0x1e, 0x42, 0x0d, 0x02, 0xfb, 0x7b, 0xc4, 0x59, 0x11, 0x5f, 0xe1, 0xfd,
0x5d, 0xcb, 0xc2, 0xfd, 0x6d, 0x18, 0xd8, 0xdf, 0xb5, 0xe0, 0x6d, 0x22, 0xaf, 0x8e, 0xb9, 0x64,
0x78, 0x7f, 0xfb, 0x4c, 0xb8, 0xbf, 0x5b, 0xac, 0xcd, 0xc3, 0x5c, 0x87, 0xa3, 0xf9, 0x45, 0x19,
0x17, 0xc9, 0x05, 0x1f, 0x04, 0xac, 0x18, 0x88, 0xc8, 0xc3, 0x48, 0x58, 0xfb, 0xfc, 0xf9, 0x4a,
0x74, 0xb7, 0xe9, 0x76, 0x51, 0x96, 0x3a, 0xe6, 0xf9, 0xee, 0x5f, 0xe0, 0xfd, 0x4b, 0xe0, 0xc4,
0x59, 0x68, 0x0f, 0x35, 0x67, 0x4d, 0xc0, 0x8b, 0x74, 0x9e, 0x95, 0xa6, 0x50, 0x5f, 0xf6, 0xb1,
0xee, 0x28, 0x10, 0x6b, 0x42, 0x2f, 0x45, 0xbb, 0x1c, 0xeb, 0xfe, 0x69, 0x64, 0x87, 0x93, 0x12,
0x2c, 0xc7, 0x4d, 0x7b, 0x3b, 0x04, 0xb1, 0x1c, 0xe3, 0x24, 0x1c, 0x0a, 0x07, 0x85, 0x98, 0xe7,
0x65, 0xc7, 0x50, 0x00, 0x50, 0x78, 0x28, 0xb4, 0x61, 0xed, 0xf3, 0x5d, 0xf4, 0xdb, 0xee, 0xf0,
0x73, 0x1b, 0x7b, 0x8b, 0x1e, 0x53, 0x58, 0x13, 0x0f, 0xfb, 0xe2, 0x36, 0x21, 0x6d, 0x3c, 0xcb,
0x3d, 0x2e, 0x59, 0x92, 0x96, 0x83, 0x55, 0xdc, 0x46, 0x23, 0x27, 0x12, 0x52, 0x8c, 0x83, 0xf1,
0x6d, 0x6f, 0x9e, 0xa7, 0x49, 0xdc, 0x3e, 0x89, 0xd6, 0xba, 0x46, 0x1c, 0x8e, 0x6f, 0x2e, 0x06,
0xe3, 0x75, 0xb5, 0xe4, 0xab, 0xff, 0x8c, 0x97, 0x39, 0xc7, 0xe3, 0xb5, 0x87, 0x84, 0xe3, 0x35,
0x44, 0x61, 0x7d, 0x46, 0x5c, 0x1e, 0xb1, 0xa5, 0x98, 0x13, 0xf1, 0xda, 0x88, 0xc3, 0xf5, 0x71,
0x31, 0x9b, 0x13, 0x1a, 0x0f, 0x87, 0x99, 0xe4, 0x45, 0xc6, 0xd2, 0xfd, 0x94, 0x4d, 0xcb, 0x01,
0x11, 0x63, 0x7c, 0x8a, 0xc8, 0x09, 0x69, 0x1a, 0x69, 0xc6, 0xc3, 0x72, 0x9f, 0x2d, 0x44, 0x91,
0x48, 0xba, 0x19, 0x2d, 0xd2, 0xd9, 0x8c, 0x1e, 0x8a, 0x7a, 0xdb, 0x29, 0xe2, 0xab, 0x64, 0xc1,
0x27, 0x01, 0x6f, 0x0d, 0xd2, 0xc3, 0x9b, 0x83, 0x22, 0x9d, 0x36, 0x12, 0xf3, 0x22, 0xe6, 0x64,
0xa7, 0xd5, 0xe2, 0xce, 0x4e, 0x33, 0x98, 0xf6, 0xf0, 0x57, 0x2b, 0xd1, 0xef, 0xd4, 0x52, 0xf7,
0x78, 0x78, 0x8f, 0x95, 0x57, 0x17, 0x82, 0x15, 0x93, 0xc1, 0x67, 0x98, 0x1d, 0x14, 0x35, 0xae,
0x9f, 0xdd, 0x46, 0x05, 0x36, 0xeb, 0x51, 0x52, 0x3a, 0x33, 0x0e, 0x6d, 0x56, 0x0f, 0x09, 0x37,
0x2b, 0x44, 0x61, 0x00, 0x51, 0xf2, 0xfa, 0x28, 0x66, 0x95, 0xd4, 0xf7, 0xcf, 0x63, 0xd6, 0x3a,
0x39, 0x18, 0x1f, 0x2b, 0xa1, 0x3f, 0x5a, 0xb6, 0x28, 0x1b, 0xf8, 0x88, 0x19, 0xf6, 0xc5, 0x49,
0xcf, 0x66, 0x56, 0x84, 0x3d, 0xb7, 0x66, 0xc6, 0xb0, 0x2f, 0x4e, 0x78, 0x76, 0xc2, 0x5a, 0xc8,
0x33, 0x12, 0xda, 0x86, 0x7d, 0x71, 0x98, 0x7d, 0x69, 0xa6, 0x59, 0x17, 0x9e, 0x04, 0xec, 0xc0,
0xb5, 0x61, 0xa3, 0x17, 0xab, 0x1d, 0xfe, 0xcd, 0x4a, 0xf4, 0x7d, 0xeb, 0xf1, 0x58, 0x4c, 0x92,
0xcb, 0x65, 0x0d, 0xbd, 0x61, 0xe9, 0x9c, 0x97, 0x83, 0x67, 0x94, 0xb5, 0x36, 0x6b, 0x4a, 0xf0,
0xfc, 0x56, 0x3a, 0x70, 0xee, 0xec, 0xe4, 0x79, 0xba, 0x1c, 0xf3, 0x59, 0x9e, 0x92, 0x73, 0xc7,
0x43, 0xc2, 0x73, 0x07, 0xa2, 0x30, 0x2b, 0x1f, 0x8b, 0x2a, 0xe7, 0x47, 0xb3, 0x72, 0x25, 0x0a,
0x67, 0xe5, 0x0d, 0x02, 0x73, 0xa5, 0xb1, 0xd8, 0x15, 0x69, 0xca, 0x63, 0xd9, 0x7e, 0xc4, 0x6c,
0x34, 0x2d, 0x11, 0xce, 0x95, 0x00, 0x69, 0x4f, 0x63, 0x9a, 0x3d, 0x24, 0x2b, 0xf8, 0xcb, 0xe5,
0x51, 0x92, 0x5d, 0x0f, 0xf0, 0xb4, 0xc0, 0x02, 0xc4, 0x69, 0x0c, 0x0a, 0xc2, 0xbd, 0xea, 0x79,
0x36, 0x11, 0xf8, 0x5e, 0xb5, 0x92, 0x84, 0xf7, 0xaa, 0x9a, 0x80, 0x26, 0xcf, 0x38, 0x65, 0xb2,
0x92, 0x84, 0x4d, 0x6a, 0x02, 0x0b, 0x85, 0xfa, 0xcc, 0x9e, 0x0c, 0x85, 0xe0, 0x94, 0x7e, 0xad,
0x93, 0x83, 0x23, 0xb4, 0xd9, 0xb4, 0xee, 0x73, 0x19, 0x5f, 0xe1, 0x23, 0xd4, 0x43, 0xc2, 0x23,
0x14, 0xa2, 0xb0, 0x4a, 0x63, 0x61, 0x36, 0xdd, 0xab, 0xf8, 0xf8, 0x68, 0x6d, 0xb8, 0xd7, 0x3a,
0x39, 0xb8, 0x8d, 0x3c, 0x9c, 0xa9, 0x36, 0x43, 0x07, 0x79, 0x2d, 0x0b, 0x6f, 0x23, 0x0d, 0x03,
0x4b, 0x5f, 0x0b, 0xaa, 0xe6, 0xc4, 0x4b, 0x6f, 0xe5, 0xe1, 0xd2, 0x7b, 0x9c, 0x76, 0xf2, 0x2f,
0x66, 0x1b, 0x57, 0x4b, 0x4f, 0x44, 0x35, 0x47, 0xde, 0xb0, 0x34, 0x99, 0x30, 0xc9, 0xc7, 0xe2,
0x9a, 0x67, 0xf8, 0x8e, 0x49, 0x97, 0xb6, 0xe6, 0x87, 0x9e, 0x42, 0x78, 0xc7, 0x14, 0x56, 0x84,
0xe3, 0xa4, 0xa6, 0xcf, 0x4b, 0xbe, 0xcb, 0x4a, 0x22, 0x92, 0x79, 0x48, 0x78, 0x9c, 0x40, 0x14,
0xe6, 0xab, 0xb5, 0xfc, 0xd5, 0xbb, 0x9c, 0x17, 0x09, 0xcf, 0x62, 0x8e, 0xe7, 0xab, 0x90, 0x0a,
0xe7, 0xab, 0x08, 0x0d, 0xf7, 0x6a, 0x7b, 0x4c, 0xf2, 0x97, 0xcb, 0x71, 0x32, 0xe3, 0xa5, 0x64,
0xb3, 0x1c, 0xdf, 0xab, 0x01, 0x28, 0xbc, 0x57, 0x6b, 0xc3, 0xad, 0xa3, 0x21, 0x13, 0x10, 0xdb,
0x37, 0x53, 0x20, 0x11, 0xb8, 0x99, 0x42, 0xa0, 0xb0, 0x61, 0x2d, 0x80, 0x1e, 0x0e, 0xb7, 0xac,
0x04, 0x0f, 0x87, 0x69, 0xba, 0x75, 0xe0, 0x66, 0x98, 0x51, 0x35, 0x35, 0x3b, 0x8a, 0x3e, 0x72,
0xa7, 0xe8, 0x46, 0x2f, 0x16, 0x3f, 0xe1, 0x3b, 0xe3, 0x29, 0x53, 0xcb, 0x56, 0xe0, 0x18, 0xad,
0x61, 0xfa, 0x9c, 0xf0, 0x39, 0xac, 0x76, 0xf8, 0x17, 0x2b, 0xd1, 0x27, 0x98, 0xc7, 0xd7, 0xb9,
0xf2, 0xfb, 0xb4, 0xdb, 0x56, 0x4d, 0x12, 0x57, 0x6f, 0xc2, 0x1a, 0xba, 0x0c, 0x7f, 0x12, 0x7d,
0xdc, 0x88, 0xec, 0xcd, 0x1c, 0x5d, 0x00, 0x3f, 0x69, 0x33, 0xe5, 0x87, 0x9c, 0x71, 0xbf, 0xdd,
0x9b, 0xb7, 0xfb, 0x21, 0xbf, 0x5c, 0x25, 0xd8, 0x0f, 0x19, 0x1b, 0x5a, 0x4c, 0xec, 0x87, 0x10,
0xcc, 0xce, 0x4e, 0xb7, 0x7a, 0x6f, 0x13, 0x79, 0xa5, 0xf2, 0x2d, 0x30, 0x3b, 0xbd, 0xb2, 0x1a,
0x88, 0x98, 0x9d, 0x24, 0x0c, 0x33, 0x92, 0x06, 0xac, 0xe6, 0x26, 0x16, 0xcb, 0x8d, 0x21, 0x77,
0x66, 0xae, 0x77, 0x83, 0x70, 0xbc, 0x36, 0x62, 0xbd, 0xf5, 0x79, 0x12, 0xb2, 0x00, 0xb6, 0x3f,
0x1b, 0xbd, 0x58, 0xed, 0xf0, 0xcf, 0xa2, 0xef, 0xb5, 0x2a, 0xb6, 0xcf, 0x99, 0x9c, 0x17, 0x7c,
0x32, 0xd8, 0xee, 0x28, 0x77, 0x03, 0x1a, 0xd7, 0x4f, 0xfb, 0x2b, 0xb4, 0x72, 0xf4, 0x86, 0xab,
0x87, 0x95, 0x29, 0xc3, 0xb3, 0x90, 0x49, 0x9f, 0x0d, 0xe6, 0xe8, 0xb4, 0x4e, 0x6b, 0x9b, 0xed,
0x8e, 0xae, 0x9d, 0x05, 0x4b, 0x52, 0xf5, 0x90, 0xee, 0xb3, 0x90, 0x51, 0x0f, 0x0d, 0x6e, 0xb3,
0x49, 0x95, 0x56, 0x64, 0x56, 0x73, 0xdc, 0xd9, 0x9e, 0x6d, 0xd2, 0x91, 0x00, 0xd9, 0x9d, 0x6d,
0xf5, 0xa4, 0xb5, 0x5b, 0xd9, 0x2c, 0x79, 0xd5, 0xcf, 0xee, 0x20, 0xc7, 0xbc, 0x6a, 0x55, 0x64,
0xa4, 0x6f, 0xf5, 0xa4, 0xb5, 0xd7, 0x3f, 0x8d, 0x3e, 0x6e, 0x7b, 0xd5, 0x0b, 0xd1, 0x76, 0xa7,
0x29, 0xb0, 0x16, 0x3d, 0xed, 0xaf, 0x60, 0xb7, 0x34, 0x5f, 0x25, 0xa5, 0x14, 0xc5, 0x72, 0x74,
0x25, 0x6e, 0x9a, 0x1b, 0xef, 0xfe, 0x6c, 0xd5, 0xc0, 0xd0, 0x21, 0x88, 0x2d, 0x0d, 0x4e, 0xb6,
0x5c, 0xd9, 0x9b, 0xf1, 0x25, 0xe1, 0xca, 0x21, 0x3a, 0x5c, 0xf9, 0xa4, 0x8d, 0x55, 0x4d, 0xad,
0xec, 0x35, 0xfe, 0x35, 0xbc, 0xa8, 0xed, 0xab, 0xfc, 0xeb, 0xdd, 0xa0, 0xcd, 0x58, 0xb4, 0x78,
0x2f, 0xb9, 0xbc, 0x34, 0x75, 0xc2, 0x4b, 0xea, 0x22, 0x44, 0xc6, 0x42, 0xa0, 0x36, 0xe9, 0xde,
0x4f, 0x52, 0xae, 0x4e, 0xf4, 0x5f, 0x5f, 0x5e, 0xa6, 0x82, 0x4d, 0x40, 0xd2, 0x5d, 0x89, 0x87,
0xae, 0x9c, 0x48, 0xba, 0x31, 0xce, 0x3e, 0x23, 0xae, 0xa4, 0x67, 0x3c, 0x16, 0x59, 0x9c, 0xa4,
0xf0, 0x02, 0xa0, 0xd2, 0x34, 0x42, 0xe2, 0x19, 0x71, 0x0b, 0xb2, 0x0b, 0x63, 0x25, 0xaa, 0xa6,
0x7d, 0x53, 0xfe, 0x47, 0x6d, 0x45, 0x47, 0x4c, 0x2c, 0x8c, 0x08, 0x66, 0xf7, 0x9e, 0x95, 0xf0,
0x3c, 0x57, 0xc6, 0xef, 0xb5, 0xb5, 0x6a, 0x09, 0xb1, 0xf7, 0xf4, 0x09, 0xbb, 0x87, 0xaa, 0x7e,
0xdf, 0x13, 0x37, 0x99, 0x32, 0xfa, 0xa0, 0xad, 0xd2, 0xc8, 0x88, 0x3d, 0x14, 0x64, 0xb4, 0xe1,
0x9f, 0x44, 0xff, 0x5f, 0x19, 0x2e, 0x44, 0x3e, 0xb8, 0x83, 0x28, 0x14, 0xce, 0x5d, 0xbd, 0xbb,
0xa4, 0xdc, 0x5e, 0x39, 0x35, 0x63, 0xe3, 0xbc, 0x64, 0x53, 0x3e, 0x78, 0x48, 0xf4, 0xb8, 0x92,
0x12, 0x57, 0x4e, 0xdb, 0x94, 0x3f, 0x2a, 0x4e, 0xc4, 0x44, 0x5b, 0x47, 0x6a, 0x68, 0x84, 0xa1,
0x51, 0xe1, 0x42, 0x36, 0x99, 0x39, 0x61, 0x8b, 0x64, 0x6a, 0x16, 0x9c, 0x3a, 0x6e, 0x95, 0x20,
0x99, 0xb1, 0xcc, 0xd0, 0x81, 0x88, 0x64, 0x86, 0x84, 0xb5, 0xcf, 0x7f, 0x5e, 0x89, 0xee, 0x59,
0xe6, 0xa0, 0x39, 0xad, 0x3b, 0xcc, 0x2e, 0x45, 0x95, 0xfa, 0x1c, 0x25, 0xd9, 0x75, 0x39, 0xf8,
0x82, 0x32, 0x89, 0xf3, 0xa6, 0x28, 0x5f, 0xde, 0x5a, 0xcf, 0x66, 0xad, 0xcd, 0x51, 0x96, 0x7d,
0x9e, 0x5d, 0x6b, 0x80, 0xac, 0xd5, 0x9c, 0x78, 0x41, 0x8e, 0xc8, 0x5a, 0x43, 0xbc, 0xed, 0x62,
0xe3, 0x3c, 0x15, 0x19, 0xec, 0x62, 0x6b, 0xa1, 0x12, 0x12, 0x5d, 0xdc, 0x82, 0x6c, 0x3c, 0x6e,
0x44, 0xf5, 0xa9, 0xcb, 0x4e, 0x9a, 0x82, 0x78, 0x6c, 0x54, 0x0d, 0x40, 0xc4, 0x63, 0x14, 0xd4,
0x7e, 0xce, 0xa2, 0xef, 0x54, 0x4d, 0x7a, 0x5a, 0xf0, 0x45, 0xc2, 0xe1, 0xd5, 0x0b, 0x47, 0x42,
0xcc, 0x7f, 0x9f, 0xb0, 0x33, 0xeb, 0x3c, 0x2b, 0xf3, 0x94, 0x95, 0x57, 0xfa, 0x61, 0xbc, 0x5f,
0xe7, 0x46, 0x08, 0x1f, 0xc7, 0x3f, 0xea, 0xa0, 0x6c, 0x50, 0x6f, 0x64, 0x26, 0xc4, 0xac, 0xe2,
0xaa, 0xad, 0x30, 0xb3, 0xd6, 0xc9, 0xd9, 0x13, 0xef, 0x03, 0x96, 0xa6, 0xbc, 0x58, 0x36, 0xb2,
0x63, 0x96, 0x25, 0x97, 0xbc, 0x94, 0xe0, 0xc4, 0x5b, 0x53, 0x43, 0x88, 0x11, 0x27, 0xde, 0x01,
0xdc, 0x66, 0xf3, 0xc0, 0xf3, 0x61, 0x36, 0xe1, 0xef, 0x40, 0x36, 0x0f, 0xed, 0x28, 0x86, 0xc8,
0xe6, 0x29, 0xd6, 0x9e, 0xfc, 0xbe, 0x4c, 0x45, 0x7c, 0xad, 0x97, 0x00, 0xbf, 0x83, 0x95, 0x04,
0xae, 0x01, 0x0f, 0x42, 0x88, 0x5d, 0x04, 0x94, 0xe0, 0x8c, 0xe7, 0x29, 0x8b, 0xe1, 0xfd, 0x9b,
0x5a, 0x47, 0xcb, 0x88, 0x45, 0x00, 0x32, 0xa0, 0xb8, 0xfa, 0x5e, 0x0f, 0x56, 0x5c, 0x70, 0xad,
0xe7, 0x41, 0x08, 0xb1, 0xcb, 0xa0, 0x12, 0x8c, 0xf2, 0x34, 0x91, 0x60, 0x1a, 0xd4, 0x1a, 0x4a,
0x42, 0x4c, 0x03, 0x9f, 0x00, 0x26, 0x8f, 0x79, 0x31, 0xe5, 0xa8, 0x49, 0x25, 0x09, 0x9a, 0x6c,
0x08, 0x7b, 0xc9, 0xb4, 0xae, 0xbb, 0xc8, 0x97, 0xe0, 0x92, 0xa9, 0xae, 0x96, 0xc8, 0x97, 0xc4,
0x25, 0x53, 0x0f, 0x00, 0x45, 0x3c, 0x65, 0xa5, 0xc4, 0x8b, 0xa8, 0x24, 0xc1, 0x22, 0x36, 0x84,
0x5d, 0xa3, 0xeb, 0x22, 0xce, 0x25, 0x58, 0xa3, 0x75, 0x01, 0x9c, 0x27, 0xd0, 0x77, 0x49, 0xb9,
0x8d, 0x24, 0x75, 0xaf, 0x70, 0xb9, 0x9f, 0xf0, 0x74, 0x52, 0x82, 0x48, 0xa2, 0xdb, 0xbd, 0x91,
0x12, 0x91, 0xa4, 0x4d, 0x81, 0xa1, 0xa4, 0xcf, 0xc7, 0xb1, 0xda, 0x81, 0xa3, 0xf1, 0x07, 0x21,
0xc4, 0xc6, 0xa7, 0xa6, 0xd0, 0xbb, 0xac, 0x28, 0x92, 0x6a, 0xf1, 0x5f, 0xc5, 0x0b, 0xd4, 0xc8,
0x89, 0xf8, 0x84, 0x71, 0x60, 0x7a, 0x35, 0x81, 0x1b, 0x2b, 0x18, 0x0c, 0xdd, 0x9f, 0x06, 0x19,
0x9b, 0x71, 0x2a, 0x89, 0xf3, 0x08, 0x15, 0x6b, 0x4d, 0xe4, 0x09, 0xea, 0x6a, 0x17, 0xe6, 0xbc,
0x04, 0x62, 0x5c, 0x1c, 0x8b, 0x05, 0x1f, 0x8b, 0x57, 0xef, 0x92, 0x52, 0x26, 0xd9, 0x54, 0xaf,
0xdc, 0xcf, 0x09, 0x4b, 0x18, 0x4c, 0xbc, 0x04, 0xd2, 0xa9, 0x64, 0x13, 0x08, 0x50, 0x96, 0x13,
0x7e, 0x83, 0x26, 0x10, 0xd0, 0xa2, 0xe1, 0x88, 0x04, 0x22, 0xc4, 0xdb, 0x73, 0x14, 0xe3, 0x5c,
0xbf, 0x29, 0x3b, 0x16, 0x4d, 0x2e, 0x47, 0x59, 0x83, 0x20, 0xb1, 0x95, 0x0d, 0x2a, 0xd8, 0xfd,
0xa5, 0xf1, 0x6f, 0xa7, 0xd8, 0x3a, 0x61, 0xa7, 0x3d, 0xcd, 0x1e, 0xf7, 0x20, 0x11, 0x57, 0xf6,
0x1e, 0x00, 0xe5, 0xaa, 0x7d, 0x0d, 0xe0, 0x71, 0x0f, 0xd2, 0x39, 0x93, 0x71, 0xab, 0xf5, 0x92,
0xc5, 0xd7, 0xd3, 0x42, 0xcc, 0xb3, 0xc9, 0xae, 0x48, 0x45, 0x01, 0xce, 0x64, 0xbc, 0x52, 0x03,
0x94, 0x38, 0x93, 0xe9, 0x50, 0xb1, 0x19, 0x9c, 0x5b, 0x8a, 0x9d, 0x34, 0x99, 0xc2, 0x1d, 0xb5,
0x67, 0x48, 0x01, 0x44, 0x06, 0x87, 0x82, 0xc8, 0x20, 0xaa, 0x77, 0xdc, 0x32, 0x89, 0x59, 0x5a,
0xfb, 0xdb, 0xa6, 0xcd, 0x78, 0x60, 0xe7, 0x20, 0x42, 0x14, 0x90, 0x7a, 0x8e, 0xe7, 0x45, 0x76,
0x98, 0x49, 0x41, 0xd6, 0xb3, 0x01, 0x3a, 0xeb, 0xe9, 0x80, 0x20, 0xac, 0x8e, 0xf9, 0xbb, 0xaa,
0x34, 0xd5, 0x3f, 0x58, 0x58, 0xad, 0x7e, 0x1f, 0x6a, 0x79, 0x28, 0xac, 0x02, 0x0e, 0x54, 0x46,
0x3b, 0xa9, 0x07, 0x4c, 0x40, 0xdb, 0x1f, 0x26, 0xeb, 0xdd, 0x20, 0xee, 0x67, 0x24, 0x97, 0x29,
0x0f, 0xf9, 0x51, 0x40, 0x1f, 0x3f, 0x0d, 0x68, 0x8f, 0x5b, 0xbc, 0xfa, 0x5c, 0xf1, 0xf8, 0xba,
0x75, 0xad, 0xc9, 0x2f, 0x68, 0x8d, 0x10, 0xc7, 0x2d, 0x04, 0x8a, 0x77, 0xd1, 0x61, 0x2c, 0xb2,
0x50, 0x17, 0x55, 0xf2, 0x3e, 0x5d, 0xa4, 0x39, 0xbb, 0xf9, 0x35, 0x52, 0x3d, 0x32, 0xeb, 0x6e,
0xda, 0x20, 0x2c, 0xb8, 0x10, 0xb1, 0xf9, 0x25, 0x61, 0x9b, 0x93, 0x43, 0x9f, 0xc7, 0xed, 0x3b,
0xdf, 0x2d, 0x2b, 0xc7, 0xf4, 0x9d, 0x6f, 0x8a, 0xa5, 0x2b, 0x59, 0x8f, 0x91, 0x0e, 0x2b, 0xfe,
0x38, 0xd9, 0xec, 0x07, 0xdb, 0x2d, 0x8f, 0xe7, 0x73, 0x37, 0xe5, 0xac, 0xa8, 0xbd, 0x6e, 0x05,
0x0c, 0x59, 0x8c, 0xd8, 0xf2, 0x04, 0x70, 0x10, 0xc2, 0x3c, 0xcf, 0xbb, 0x22, 0x93, 0x3c, 0x93,
0x58, 0x08, 0xf3, 0x8d, 0x69, 0x30, 0x14, 0xc2, 0x28, 0x05, 0x30, 0x6e, 0xd5, 0x79, 0x10, 0x97,
0x27, 0x6c, 0x86, 0x66, 0x6c, 0xf5, 0x59, 0x4f, 0x2d, 0x0f, 0x8d, 0x5b, 0xc0, 0x39, 0x0f, 0xf9,
0x5c, 0x2f, 0x63, 0x56, 0x4c, 0xcd, 0xe9, 0xc6, 0x64, 0xf0, 0x94, 0xb6, 0xe3, 0x93, 0xc4, 0x43,
0xbe, 0xb0, 0x06, 0x08, 0x3b, 0x87, 0x33, 0x36, 0x35, 0x35, 0x45, 0x6a, 0xa0, 0xe4, 0xad, 0xaa,
0xae, 0x77, 0x83, 0xc0, 0xcf, 0x9b, 0x64, 0xc2, 0x45, 0xc0, 0x8f, 0x92, 0xf7, 0xf1, 0x03, 0x41,
0x90, 0xbd, 0x55, 0xf5, 0xae, 0x77, 0x74, 0x3b, 0xd9, 0x44, 0xef, 0x63, 0x87, 0x44, 0xf3, 0x00,
0x2e, 0x94, 0xbd, 0x11, 0x3c, 0x98, 0xa3, 0xcd, 0x01, 0x6d, 0x68, 0x8e, 0x9a, 0xf3, 0xd7, 0x3e,
0x73, 0x14, 0x83, 0xb5, 0xcf, 0x9f, 0xe9, 0x39, 0xba, 0xc7, 0x24, 0xab, 0xf2, 0xf6, 0x37, 0x09,
0xbf, 0xd1, 0x1b, 0x61, 0xa4, 0xbe, 0x0d, 0x35, 0x54, 0xaf, 0x2a, 0x82, 0x5d, 0xf1, 0x76, 0x6f,
0x3e, 0xe0, 0x5b, 0xef, 0x10, 0x3a, 0x7d, 0x83, 0xad, 0xc2, 0x76, 0x6f, 0x3e, 0xe0, 0x5b, 0xbf,
0x03, 0xdd, 0xe9, 0x1b, 0xbc, 0x08, 0xbd, 0xdd, 0x9b, 0xd7, 0xbe, 0xff, 0xb2, 0x99, 0xb8, 0xae,
0xf3, 0x2a, 0x0f, 0x8b, 0x65, 0xb2, 0xe0, 0x58, 0x3a, 0xe9, 0xdb, 0x33, 0x68, 0x28, 0x9d, 0xa4,
0x55, 0x9c, 0x0f, 0xe7, 0x60, 0xa5, 0x38, 0x15, 0x65, 0xa2, 0x1e, 0xd2, 0x3f, 0xef, 0x61, 0xb4,
0x81, 0x43, 0x9b, 0xa6, 0x90, 0x92, 0x7d, 0xdc, 0xe8, 0xa1, 0xf6, 0x16, 0xf3, 0x66, 0xc0, 0x5e,
0xfb, 0x32, 0xf3, 0x56, 0x4f, 0xda, 0x3e, 0xf8, 0xf3, 0x18, 0xf7, 0x89, 0x63, 0xa8, 0x57, 0xd1,
0x87, 0x8e, 0x4f, 0xfb, 0x2b, 0x68, 0xf7, 0x7f, 0xdd, 0xec, 0x2b, 0xa0, 0x7f, 0x3d, 0x09, 0x9e,
0xf5, 0xb1, 0x08, 0x26, 0xc2, 0xf3, 0x5b, 0xe9, 0xe8, 0x82, 0xfc, 0x7d, 0xb3, 0x81, 0x6e, 0x50,
0xf5, 0x2e, 0x87, 0x7a, 0xf7, 0x4f, 0xcf, 0x89, 0x50, 0xb7, 0x5a, 0x18, 0xce, 0x8c, 0x17, 0xb7,
0xd4, 0x72, 0x3e, 0xa3, 0xe4, 0xc1, 0xfa, 0x9d, 0x43, 0xa7, 0x3c, 0x21, 0xcb, 0x0e, 0x0d, 0x0b,
0xf4, 0xc5, 0x6d, 0xd5, 0xa8, 0xb9, 0xe2, 0xc0, 0xea, 0xab, 0x0c, 0xcf, 0x7b, 0x1a, 0xf6, 0xbe,
0xd3, 0xf0, 0xf9, 0xed, 0x94, 0x74, 0x59, 0xfe, 0x63, 0x25, 0x7a, 0xe4, 0xb1, 0xf6, 0x79, 0x02,
0x38, 0xf5, 0xf8, 0x71, 0xc0, 0x3e, 0xa5, 0x64, 0x0a, 0xf7, 0xbb, 0xbf, 0x9c, 0xb2, 0xfd, 0xe6,
0x90, 0xa7, 0xb2, 0x9f, 0xa4, 0x92, 0x17, 0xed, 0x6f, 0x0e, 0xf9, 0x76, 0x6b, 0x6a, 0x48, 0x7f,
0x73, 0x28, 0x80, 0x3b, 0xdf, 0x1c, 0x42, 0x3c, 0xa3, 0xdf, 0x1c, 0x42, 0xad, 0x05, 0xbf, 0x39,
0x14, 0xd6, 0xa0, 0xc2, 0x7b, 0x53, 0x84, 0xfa, 0xdc, 0xba, 0x97, 0x45, 0xff, 0x18, 0xfb, 0xd9,
0x6d, 0x54, 0x88, 0x05, 0xae, 0xe6, 0xd4, 0x3d, 0xb7, 0x1e, 0x6d, 0xea, 0xdd, 0x75, 0xdb, 0xee,
0xcd, 0x6b, 0xdf, 0x3f, 0xd5, 0xbb, 0x1b, 0x13, 0xce, 0x45, 0xa1, 0xbe, 0x37, 0xb5, 0x11, 0x0a,
0xcf, 0x95, 0x05, 0xb7, 0xe7, 0x37, 0xfb, 0xc1, 0x44, 0x75, 0x2b, 0x42, 0x77, 0xfa, 0xb0, 0xcb,
0x10, 0xe8, 0xf2, 0xed, 0xde, 0x3c, 0xb1, 0x8c, 0xd4, 0xbe, 0xeb, 0xde, 0xee, 0x61, 0xcc, 0xef,
0xeb, 0xa7, 0xfd, 0x15, 0xb4, 0xfb, 0x85, 0x4e, 0x1b, 0x5d, 0xf7, 0xaa, 0x9f, 0xb7, 0xba, 0x4c,
0x8d, 0xbc, 0x6e, 0x1e, 0xf6, 0xc5, 0x43, 0x09, 0x84, 0xbb, 0x84, 0x76, 0x25, 0x10, 0xe8, 0x32,
0xfa, 0xf9, 0xed, 0x94, 0x74, 0x59, 0xfe, 0x69, 0x25, 0xba, 0x4b, 0x96, 0x45, 0x8f, 0x83, 0x2f,
0xfa, 0x5a, 0x06, 0xe3, 0xe1, 0xcb, 0x5b, 0xeb, 0xe9, 0x42, 0xfd, 0xeb, 0x4a, 0x74, 0x2f, 0x50,
0xa8, 0x7a, 0x80, 0xdc, 0xc2, 0xba, 0x3f, 0x50, 0x7e, 0x78, 0x7b, 0x45, 0x6a, 0xb9, 0x77, 0xf1,
0x51, 0xfb, 0x63, 0x3c, 0x01, 0xdb, 0x23, 0xfa, 0x63, 0x3c, 0xdd, 0x5a, 0xf0, 0x90, 0x87, 0x5d,
0x34, 0x9b, 0x2e, 0xf4, 0x90, 0x47, 0xdd, 0x50, 0x03, 0x7b, 0x8e, 0xb5, 0x4e, 0x0e, 0x73, 0xf2,
0xea, 0x5d, 0xce, 0xb2, 0x09, 0xed, 0xa4, 0x96, 0x77, 0x3b, 0x31, 0x1c, 0x3c, 0x1c, 0xab, 0xa4,
0x67, 0xa2, 0xd9, 0x48, 0x3d, 0xa6, 0xf4, 0x0d, 0x12, 0x3c, 0x1c, 0x6b, 0xa1, 0x84, 0x37, 0x9d,
0x35, 0x86, 0xbc, 0x81, 0x64, 0xf1, 0x49, 0x1f, 0x14, 0xa4, 0xe8, 0xc6, 0x9b, 0x39, 0x73, 0xdf,
0x0c, 0x59, 0x69, 0x9d, 0xbb, 0x6f, 0xf5, 0xa4, 0x09, 0xb7, 0x23, 0x2e, 0xbf, 0xe2, 0x6c, 0xc2,
0x8b, 0xa0, 0x5b, 0x43, 0xf5, 0x72, 0xeb, 0xd2, 0x98, 0xdb, 0x5d, 0x91, 0xce, 0x67, 0x99, 0xee,
0x4c, 0xd2, 0xad, 0x4b, 0x75, 0xbb, 0x05, 0x34, 0x3c, 0x16, 0xb4, 0x6e, 0x55, 0x7a, 0xf9, 0x24,
0x6c, 0xc6, 0xcb, 0x2a, 0x37, 0x7a, 0xb1, 0x74, 0x3d, 0xf5, 0x30, 0xea, 0xa8, 0x27, 0x18, 0x49,
0x5b, 0x3d, 0x69, 0x78, 0x3e, 0xe7, 0xb8, 0x35, 0xe3, 0x69, 0xbb, 0xc3, 0x56, 0x6b, 0x48, 0x3d,
0xed, 0xaf, 0x00, 0x4f, 0x43, 0xf5, 0xa8, 0x3a, 0x4a, 0x4a, 0xb9, 0x9f, 0xa4, 0xe9, 0x60, 0x23,
0x30, 0x4c, 0x1a, 0x28, 0x78, 0x1a, 0x8a, 0xc0, 0xc4, 0x48, 0x6e, 0x4e, 0x0f, 0xb3, 0x41, 0x97,
0x1d, 0x45, 0xf5, 0x1a, 0xc9, 0x2e, 0x0d, 0x4e, 0xb4, 0x9c, 0xa6, 0x36, 0xb5, 0x1d, 0x86, 0x1b,
0xae, 0x55, 0xe1, 0xed, 0xde, 0x3c, 0x78, 0xdc, 0xae, 0x28, 0xb5, 0xb2, 0x3c, 0xa4, 0x4c, 0x78,
0x2b, 0xc9, 0xa3, 0x0e, 0x0a, 0x9c, 0x0a, 0xd6, 0xd3, 0xe8, 0x6d, 0x32, 0x99, 0x72, 0x89, 0x3e,
0x29, 0x72, 0x81, 0xe0, 0x93, 0x22, 0x00, 0x82, 0xae, 0xab, 0x7f, 0x37, 0xc7, 0xa1, 0x87, 0x13,
0xac, 0xeb, 0xb4, 0xb2, 0x43, 0x85, 0xba, 0x0e, 0xa5, 0x41, 0x34, 0x30, 0x6e, 0xf5, 0xeb, 0xf8,
0x4f, 0x42, 0x66, 0xc0, 0x3b, 0xf9, 0x1b, 0xbd, 0x58, 0xb0, 0xa2, 0x58, 0x87, 0xc9, 0x2c, 0x91,
0xd8, 0x8a, 0xe2, 0xd8, 0xa8, 0x90, 0xd0, 0x8a, 0xd2, 0x46, 0xa9, 0xea, 0x55, 0x39, 0xc2, 0xe1,
0x24, 0x5c, 0xbd, 0x9a, 0xe9, 0x57, 0x3d, 0xc3, 0xb6, 0x1e, 0x6c, 0x66, 0x66, 0xc8, 0xc8, 0x2b,
0xbd, 0x59, 0x46, 0xc6, 0xb6, 0x7a, 0x4d, 0x13, 0x82, 0xa1, 0xa8, 0x43, 0x29, 0xc0, 0x03, 0xfb,
0x8a, 0x6b, 0x9e, 0xbd, 0xe6, 0x39, 0x67, 0x05, 0xcb, 0x62, 0x74, 0x73, 0xaa, 0x0c, 0xb6, 0xc8,
0xd0, 0xe6, 0x94, 0xd4, 0x00, 0x8f, 0xcd, 0xfd, 0x17, 0x2c, 0x91, 0xa9, 0x60, 0xde, 0x64, 0xf4,
0xdf, 0xaf, 0x7c, 0xdc, 0x83, 0x84, 0x8f, 0xcd, 0x1b, 0xc0, 0x1c, 0x7c, 0xd7, 0x4e, 0x3f, 0x0b,
0x98, 0xf2, 0xd1, 0xd0, 0x46, 0x98, 0x56, 0x01, 0x83, 0xda, 0x24, 0xb8, 0x5c, 0xfe, 0x84, 0x2f,
0xb1, 0x41, 0x6d, 0xf3, 0x53, 0x85, 0x84, 0x06, 0x75, 0x1b, 0x05, 0x79, 0xa6, 0xbb, 0x0f, 0x5a,
0x0d, 0xe8, 0xbb, 0x5b, 0x9f, 0xb5, 0x4e, 0x0e, 0xcc, 0x9c, 0xbd, 0x64, 0xe1, 0x3d, 0x27, 0x40,
0x0a, 0xba, 0x97, 0x2c, 0xf0, 0xc7, 0x04, 0x1b, 0xbd, 0x58, 0xf8, 0x48, 0x9e, 0x49, 0xfe, 0xae,
0x79, 0x56, 0x8e, 0x14, 0x57, 0xc9, 0x5b, 0x0f, 0xcb, 0xd7, 0xbb, 0x41, 0x7b, 0x01, 0xf6, 0xb4,
0x10, 0x31, 0x2f, 0x4b, 0xfd, 0x85, 0x42, 0xff, 0x86, 0x91, 0x96, 0x0d, 0xc1, 0xf7, 0x09, 0x1f,
0x86, 0x21, 0xdb, 0x33, 0x5a, 0x64, 0xbf, 0x7a, 0xb3, 0x8a, 0x6a, 0xb6, 0x3f, 0x78, 0xb3, 0xd6,
0xc9, 0xd9, 0xe9, 0xa5, 0xa5, 0xee, 0x67, 0x6e, 0xd6, 0x51, 0x75, 0xec, 0x0b, 0x37, 0x8f, 0x7b,
0x90, 0xda, 0xd5, 0x57, 0xd1, 0xfb, 0x47, 0x62, 0x3a, 0xe2, 0xd9, 0x64, 0xf0, 0x03, 0xff, 0x0a,
0xad, 0x98, 0x0e, 0xab, 0x9f, 0x8d, 0xd1, 0x3b, 0x94, 0xd8, 0x5e, 0x02, 0xdc, 0xe3, 0x17, 0xf3,
0xe9, 0x48, 0x32, 0x09, 0x2e, 0x01, 0xaa, 0xdf, 0x87, 0x95, 0x80, 0xb8, 0x04, 0xe8, 0x01, 0xc0,
0xde, 0xb8, 0xe0, 0x1c, 0xb5, 0x57, 0x09, 0x82, 0xf6, 0x34, 0x60, 0xb3, 0x08, 0x63, 0xaf, 0x4a,
0xd4, 0xe1, 0xa5, 0x3d, 0xab, 0xa3, 0xa4, 0x44, 0x16, 0xd1, 0xa6, 0xec, 0xe0, 0xae, 0xab, 0xaf,
0xbe, 0x3a, 0x32, 0x9f, 0xcd, 0x58, 0xb1, 0x04, 0x83, 0x5b, 0xd7, 0xd2, 0x01, 0x88, 0xc1, 0x8d,
0x82, 0x76, 0xd6, 0x36, 0xcd, 0x1c, 0x5f, 0x1f, 0x88, 0x42, 0xcc, 0x65, 0x92, 0x71, 0xf8, 0xe5,
0x09, 0xd3, 0xa0, 0x2e, 0x43, 0xcc, 0x5a, 0x8a, 0xb5, 0x59, 0xae, 0x22, 0xea, 0xfb, 0x84, 0xea,
0xbb, 0xc5, 0xa5, 0x14, 0x05, 0x7c, 0x9e, 0x58, 0x5b, 0x81, 0x10, 0x91, 0xe5, 0x92, 0x30, 0xe8,
0xfb, 0xd3, 0x24, 0x9b, 0xa2, 0x7d, 0x7f, 0xea, 0x7e, 0xf5, 0xf3, 0x1e, 0x0d, 0xd8, 0x09, 0x55,
0x37, 0x5a, 0x3d, 0x01, 0xf4, 0xbb, 0x9c, 0x68, 0xa3, 0xbb, 0x04, 0x31, 0xa1, 0x70, 0x12, 0xb8,
0x7a, 0x9d, 0xf3, 0x8c, 0x4f, 0x9a, 0x5b, 0x73, 0x98, 0x2b, 0x8f, 0x08, 0xba, 0x82, 0xa4, 0x8d,
0x45, 0x4a, 0x7e, 0x36, 0xcf, 0x4e, 0x0b, 0x71, 0x99, 0xa4, 0xbc, 0x00, 0xb1, 0xa8, 0x56, 0x77,
0xe4, 0x44, 0x2c, 0xc2, 0x38, 0x7b, 0xfd, 0x42, 0x49, 0xbd, 0x8f, 0x6f, 0x8f, 0x0b, 0x16, 0xc3,
0xeb, 0x17, 0xb5, 0x8d, 0x36, 0x46, 0x9c, 0x0c, 0x06, 0x70, 0x27, 0xd1, 0xa9, 0x5d, 0x67, 0x4b,
0x35, 0x3e, 0xf4, 0xbb, 0x84, 0xea, 0x5b, 0x98, 0x25, 0x48, 0x74, 0xb4, 0x39, 0x8c, 0x24, 0x12,
0x9d, 0xb0, 0x86, 0x5d, 0x4a, 0x14, 0x77, 0xa2, 0xaf, 0x15, 0x81, 0xa5, 0xa4, 0xb6, 0xd1, 0x08,
0x89, 0xa5, 0xa4, 0x05, 0x81, 0x80, 0xd4, 0x4c, 0x83, 0x29, 0x1a, 0x90, 0x8c, 0x34, 0x18, 0x90,
0x5c, 0xca, 0x06, 0x8a, 0xc3, 0x2c, 0x91, 0x09, 0x4b, 0x47, 0x5c, 0x9e, 0xb2, 0x82, 0xcd, 0xb8,
0xe4, 0x05, 0x0c, 0x14, 0x1a, 0x19, 0x7a, 0x0c, 0x11, 0x28, 0x28, 0x56, 0x3b, 0xfc, 0xbd, 0xe8,
0xc3, 0x6a, 0xdd, 0xe7, 0x99, 0xfe, 0x33, 0x1b, 0xaf, 0xd4, 0xdf, 0xe7, 0x19, 0x7c, 0x64, 0x6c,
0x8c, 0x64, 0xc1, 0xd9, 0xac, 0xb1, 0xfd, 0x81, 0xf9, 0x5d, 0x81, 0x4f, 0x57, 0xaa, 0xf1, 0x7c,
0x22, 0x64, 0x72, 0x59, 0x6d, 0xb3, 0xf5, 0x1b, 0x44, 0x60, 0x3c, 0xbb, 0xe2, 0x61, 0xe0, 0x5b,
0x14, 0x18, 0x67, 0xe3, 0xb4, 0x2b, 0x3d, 0xe3, 0x79, 0x0a, 0xe3, 0xb4, 0xa7, 0xad, 0x00, 0x22,
0x4e, 0xa3, 0xa0, 0x9d, 0x9c, 0xae, 0x78, 0xcc, 0xc3, 0x95, 0x19, 0xf3, 0x7e, 0x95, 0x19, 0x7b,
0x2f, 0x65, 0xa4, 0xd1, 0x87, 0xc7, 0x7c, 0x76, 0xc1, 0x8b, 0xf2, 0x2a, 0xc9, 0x0f, 0xaa, 0x84,
0x8b, 0xc9, 0x39, 0x7c, 0x6d, 0xd1, 0x12, 0x43, 0x83, 0x10, 0x59, 0x29, 0x81, 0xda, 0x95, 0xc0,
0x02, 0x87, 0xe5, 0x09, 0x9b, 0x71, 0xf5, 0x65, 0x0d, 0xb0, 0x12, 0x38, 0x46, 0x1c, 0x88, 0x58,
0x09, 0x48, 0xd8, 0x79, 0xbf, 0xcb, 0x32, 0x67, 0x7c, 0x5a, 0x8d, 0xb0, 0xe2, 0x94, 0x2d, 0x67,
0x3c, 0x93, 0xda, 0x24, 0x38, 0x93, 0x77, 0x4c, 0xe2, 0x3c, 0x71, 0x26, 0xdf, 0x47, 0xcf, 0x09,
0x4d, 0x5e, 0xc3, 0x9f, 0x8a, 0x42, 0xd6, 0x7f, 0x44, 0xe7, 0xbc, 0x48, 0x41, 0x68, 0xf2, 0x1b,
0xd5, 0x23, 0x89, 0xd0, 0x14, 0xd6, 0x70, 0xbe, 0x3e, 0xef, 0x95, 0xe1, 0x0d, 0x2f, 0xcc, 0x38,
0x79, 0x35, 0x63, 0x49, 0xaa, 0x47, 0xc3, 0x8f, 0x02, 0xb6, 0x09, 0x1d, 0xe2, 0xeb, 0xf3, 0x7d,
0x75, 0x9d, 0xef, 0xf5, 0x87, 0x4b, 0x08, 0x1e, 0x11, 0x74, 0xd8, 0x27, 0x1e, 0x11, 0x74, 0x6b,
0xd9, 0x9d, 0xbb, 0x65, 0x15, 0xb7, 0x54, 0xc4, 0xae, 0x98, 0xc0, 0xf3, 0x42, 0xc7, 0x26, 0x00,
0x89, 0x9d, 0x7b, 0x50, 0xc1, 0xa6, 0x06, 0x16, 0xdb, 0x4f, 0x32, 0x96, 0x26, 0x3f, 0x83, 0x69,
0xbd, 0x63, 0xa7, 0x21, 0x88, 0xd4, 0x00, 0x27, 0x31, 0x57, 0x07, 0x5c, 0x8e, 0x93, 0x2a, 0xf4,
0xaf, 0x07, 0xda, 0x4d, 0x11, 0xdd, 0xae, 0x1c, 0xd2, 0xf9, 0x46, 0x2b, 0x6c, 0xd6, 0x9d, 0x3c,
0x1f, 0x55, 0xab, 0xea, 0x19, 0x8f, 0x79, 0x92, 0xcb, 0xc1, 0x8b, 0x70, 0x5b, 0x01, 0x9c, 0xb8,
0x68, 0xd1, 0x43, 0xcd, 0x79, 0x7c, 0x5f, 0xc5, 0x92, 0x51, 0xfd, 0xd7, 0xe5, 0xce, 0x4b, 0x5e,
0xe8, 0x44, 0xe3, 0x80, 0x4b, 0x30, 0x3b, 0x1d, 0x6e, 0xe8, 0x80, 0x55, 0x45, 0x89, 0xd9, 0x19,
0xd6, 0xb0, 0x87, 0x7d, 0x0e, 0x77, 0xc6, 0x4b, 0x91, 0x2e, 0xb8, 0xba, 0x6f, 0xb8, 0x49, 0x1a,
0x73, 0x28, 0xe2, 0xb0, 0x8f, 0xa6, 0x6d, 0xb6, 0xd6, 0x76, 0xbb, 0x93, 0x2d, 0x0f, 0xe1, 0x95,
0x09, 0xc4, 0x92, 0xc2, 0x88, 0x6c, 0x2d, 0x80, 0x3b, 0x87, 0xe1, 0x85, 0x60, 0x93, 0x98, 0x95,
0xf2, 0x94, 0x2d, 0x53, 0xc1, 0x26, 0x6a, 0x5d, 0x87, 0x87, 0xe1, 0x0d, 0x33, 0x74, 0x21, 0xea,
0x30, 0x9c, 0x82, 0xdd, 0xec, 0x4c, 0xfd, 0xd1, 0x3c, 0x7d, 0x97, 0x13, 0x66, 0x67, 0xaa, 0xbc,
0xf0, 0x1e, 0xe7, 0xc3, 0x30, 0x64, 0xdf, 0x41, 0xab, 0x45, 0x2a, 0x0d, 0xb9, 0x87, 0xe9, 0x78,
0x09, 0xc8, 0xfd, 0x00, 0x61, 0xbf, 0x4b, 0x51, 0xff, 0xde, 0xfc, 0xdd, 0x17, 0xa9, 0xbf, 0x64,
0xbd, 0x89, 0xe9, 0xba, 0xd0, 0xd0, 0xfd, 0xc0, 0xdd, 0x56, 0x4f, 0xda, 0xa6, 0x99, 0xbb, 0x57,
0x4c, 0xee, 0x4c, 0x26, 0xc7, 0xbc, 0x44, 0x5e, 0x28, 0xaf, 0x84, 0x43, 0x2b, 0x25, 0xd2, 0xcc,
0x36, 0x65, 0x07, 0x7a, 0x25, 0x7b, 0x35, 0x49, 0xa4, 0x96, 0x35, 0x37, 0xa4, 0x37, 0xdb, 0x06,
0xda, 0x14, 0x51, 0x2b, 0x9a, 0xb6, 0xb1, 0xbc, 0x62, 0xc6, 0x62, 0x3a, 0x4d, 0xb9, 0x86, 0xce,
0x38, 0xab, 0x3f, 0xe4, 0xb7, 0xdd, 0xb6, 0x85, 0x82, 0x44, 0x2c, 0x0f, 0x2a, 0xd8, 0x34, 0xb2,
0xc2, 0xea, 0x47, 0x52, 0x4d, 0xc3, 0xae, 0xb5, 0xcd, 0x78, 0x00, 0x91, 0x46, 0xa2, 0xa0, 0x7d,
0xef, 0xad, 0x12, 0x1f, 0xf0, 0xa6, 0x25, 0xe0, 0x27, 0x88, 0x94, 0xb2, 0x23, 0x26, 0xde, 0x7b,
0x43, 0x30, 0xbb, 0x4f, 0x00, 0x1e, 0x5e, 0x2e, 0x0f, 0x27, 0x70, 0x9f, 0x00, 0xf5, 0x15, 0x43,
0xec, 0x13, 0x28, 0xd6, 0xef, 0x3a, 0x73, 0xee, 0x75, 0xc4, 0x4a, 0x5b, 0x39, 0xa4, 0xeb, 0x50,
0x30, 0xd4, 0x75, 0x94, 0x82, 0xdf, 0xa4, 0xee, 0xd1, 0x1a, 0xd2, 0xa4, 0xd8, 0xb9, 0xda, 0x6a,
0x17, 0x66, 0xe3, 0x92, 0xd9, 0x4f, 0xaa, 0x2b, 0x4b, 0xf8, 0x17, 0xfc, 0x6b, 0x21, 0x11, 0x97,
0x5a, 0x50, 0x6d, 0xfb, 0xe5, 0xfd, 0xff, 0xfc, 0xe6, 0xce, 0xca, 0x2f, 0xbe, 0xb9, 0xb3, 0xf2,
0xdf, 0xdf, 0xdc, 0x59, 0xf9, 0xf9, 0xb7, 0x77, 0xde, 0xfb, 0xc5, 0xb7, 0x77, 0xde, 0xfb, 0xaf,
0x6f, 0xef, 0xbc, 0xf7, 0xf5, 0xfb, 0xfa, 0x8f, 0xa9, 0x5e, 0xfc, 0x3f, 0xf5, 0x27, 0x51, 0x9f,
0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0xd6, 0xda, 0x85, 0x70, 0x75, 0x00, 0x00,
}
// This is a compile-time assertion to ensure that this generated file
@ -416,6 +418,8 @@ type ClientCommandsHandler interface {
SpaceMakeShareable(context.Context, *pb.RpcSpaceMakeShareableRequest) *pb.RpcSpaceMakeShareableResponse
SpaceParticipantRemove(context.Context, *pb.RpcSpaceParticipantRemoveRequest) *pb.RpcSpaceParticipantRemoveResponse
SpaceParticipantPermissionsChange(context.Context, *pb.RpcSpaceParticipantPermissionsChangeRequest) *pb.RpcSpaceParticipantPermissionsChangeResponse
SpaceSetOrder(context.Context, *pb.RpcSpaceSetOrderRequest) *pb.RpcSpaceSetOrderResponse
SpaceUnsetOrder(context.Context, *pb.RpcSpaceUnsetOrderRequest) *pb.RpcSpaceUnsetOrderResponse
// Object
// ***
ObjectOpen(context.Context, *pb.RpcObjectOpenRequest) *pb.RpcObjectOpenResponse
@ -1598,6 +1602,46 @@ func SpaceParticipantPermissionsChange(b []byte) (resp []byte) {
return resp
}
func SpaceSetOrder(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
if r := recover(); r != nil {
resp, _ = (&pb.RpcSpaceSetOrderResponse{Error: &pb.RpcSpaceSetOrderResponseError{Code: pb.RpcSpaceSetOrderResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
PanicHandler(r)
}
}
}()
in := new(pb.RpcSpaceSetOrderRequest)
if err := in.Unmarshal(b); err != nil {
resp, _ = (&pb.RpcSpaceSetOrderResponse{Error: &pb.RpcSpaceSetOrderResponseError{Code: pb.RpcSpaceSetOrderResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
return resp
}
resp, _ = clientCommandsHandler.SpaceSetOrder(context.Background(), in).Marshal()
return resp
}
func SpaceUnsetOrder(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
if r := recover(); r != nil {
resp, _ = (&pb.RpcSpaceUnsetOrderResponse{Error: &pb.RpcSpaceUnsetOrderResponseError{Code: pb.RpcSpaceUnsetOrderResponseError_UNKNOWN_ERROR, Description: "panic recovered"}}).Marshal()
PanicHandler(r)
}
}
}()
in := new(pb.RpcSpaceUnsetOrderRequest)
if err := in.Unmarshal(b); err != nil {
resp, _ = (&pb.RpcSpaceUnsetOrderResponse{Error: &pb.RpcSpaceUnsetOrderResponseError{Code: pb.RpcSpaceUnsetOrderResponseError_BAD_INPUT, Description: err.Error()}}).Marshal()
return resp
}
resp, _ = clientCommandsHandler.SpaceUnsetOrder(context.Background(), in).Marshal()
return resp
}
func ObjectOpen(b []byte) (resp []byte) {
defer func() {
if PanicHandler != nil {
@ -6134,6 +6178,10 @@ func CommandAsync(cmd string, data []byte, callback func(data []byte)) {
cd = SpaceParticipantRemove(data)
case "SpaceParticipantPermissionsChange":
cd = SpaceParticipantPermissionsChange(data)
case "SpaceSetOrder":
cd = SpaceSetOrder(data)
case "SpaceUnsetOrder":
cd = SpaceUnsetOrder(data)
case "ObjectOpen":
cd = ObjectOpen(data)
case "ObjectClose":
@ -7230,6 +7278,34 @@ func (h *ClientCommandsHandlerProxy) SpaceParticipantPermissionsChange(ctx conte
call, _ := actualCall(ctx, req)
return call.(*pb.RpcSpaceParticipantPermissionsChangeResponse)
}
func (h *ClientCommandsHandlerProxy) SpaceSetOrder(ctx context.Context, req *pb.RpcSpaceSetOrderRequest) *pb.RpcSpaceSetOrderResponse {
actualCall := func(ctx context.Context, req any) (any, error) {
return h.client.SpaceSetOrder(ctx, req.(*pb.RpcSpaceSetOrderRequest)), nil
}
for _, interceptor := range h.interceptors {
toCall := actualCall
currentInterceptor := interceptor
actualCall = func(ctx context.Context, req any) (any, error) {
return currentInterceptor(ctx, req, "SpaceSetOrder", toCall)
}
}
call, _ := actualCall(ctx, req)
return call.(*pb.RpcSpaceSetOrderResponse)
}
func (h *ClientCommandsHandlerProxy) SpaceUnsetOrder(ctx context.Context, req *pb.RpcSpaceUnsetOrderRequest) *pb.RpcSpaceUnsetOrderResponse {
actualCall := func(ctx context.Context, req any) (any, error) {
return h.client.SpaceUnsetOrder(ctx, req.(*pb.RpcSpaceUnsetOrderRequest)), nil
}
for _, interceptor := range h.interceptors {
toCall := actualCall
currentInterceptor := interceptor
actualCall = func(ctx context.Context, req any) (any, error) {
return currentInterceptor(ctx, req, "SpaceUnsetOrder", toCall)
}
}
call, _ := actualCall(ctx, req)
return call.(*pb.RpcSpaceUnsetOrderResponse)
}
func (h *ClientCommandsHandlerProxy) ObjectOpen(ctx context.Context, req *pb.RpcObjectOpenRequest) *pb.RpcObjectOpenResponse {
actualCall := func(ctx context.Context, req any) (any, error) {
return h.client.ObjectOpen(ctx, req.(*pb.RpcObjectOpenRequest)), nil

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"path/filepath"
"time"
"github.com/anyproto/any-sync/accountservice"
"github.com/anyproto/any-sync/app"
@ -23,9 +24,14 @@ import (
"github.com/anyproto/anytype-heart/space"
"github.com/anyproto/anytype-heart/space/spacecore"
"github.com/anyproto/anytype-heart/space/techspace"
"github.com/anyproto/anytype-heart/util/metricsid"
)
const CName = "account"
const (
CName = "account"
analyticsWaitTimeout = time.Second * 30
)
var log = logging.Logger(CName)
@ -171,29 +177,37 @@ func (s *service) GetSpaceInfo(ctx context.Context, spaceId string) (*model.Acco
}
func (s *service) getAnalyticsId(ctx context.Context, techSpace techspace.TechSpace) (analyticsId string, err error) {
if s.config.AnalyticsId != "" {
return s.config.AnalyticsId, nil
}
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
})
if analyticsId == "" {
err = s.spaceService.WaitPersonalSpaceMigration(ctx)
start := time.Now()
for {
err = techSpace.DoAccountObject(ctx, func(accountObject techspace.AccountObject) error {
var innerErr error
analyticsId, innerErr = accountObject.GetAnalyticsId()
if innerErr != nil {
log.Debug("failed to get analytics id: %s", innerErr)
}
return nil
})
if err != nil {
return
}
} else {
return analyticsId, nil
if analyticsId != "" {
return analyticsId, nil
}
if time.Since(start) > analyticsWaitTimeout {
metricsId, err := metricsid.DeriveMetricsId(s.keyProvider.Account().SignKey)
if err != nil {
return "", err
}
err = techSpace.DoAccountObject(ctx, func(accountObject techspace.AccountObject) error {
return accountObject.SetAnalyticsId(metricsId)
})
if err != nil {
return "", err
}
return metricsId, nil
}
time.Sleep(time.Second)
}
err = techSpace.DoAccountObject(ctx, func(accountObject techspace.AccountObject) error {
analyticsId, err = accountObject.GetAnalyticsId()
return err
})
return
}
func (s *service) getNetworkId() string {

View file

@ -82,6 +82,7 @@ import (
"github.com/anyproto/anytype-heart/core/peerstatus"
"github.com/anyproto/anytype-heart/core/recordsbatcher"
"github.com/anyproto/anytype-heart/core/session"
"github.com/anyproto/anytype-heart/core/spaceview"
"github.com/anyproto/anytype-heart/core/subscription"
"github.com/anyproto/anytype-heart/core/subscription/crossspacesub"
"github.com/anyproto/anytype-heart/core/syncstatus"
@ -316,7 +317,8 @@ func Bootstrap(a *app.App, components ...app.Component) {
Register(payments.New()).
Register(paymentscache.New()).
Register(peerstatus.New()).
Register(lastused.New())
Register(lastused.New()).
Register(spaceview.New())
}
func MiddlewareVersion() string {

View file

@ -106,14 +106,13 @@ func (s *Service) handleCustomStorageLocation(req *pb.RpcAccountCreateRequest, a
func (s *Service) setAccountAndProfileDetails(ctx context.Context, req *pb.RpcAccountCreateRequest, newAcc *model.Account) error {
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)
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
newAcc.Info.AccountSpaceId = spaceService.FirstCreatedSpaceId()
bs := s.app.MustComponent(block.CName).(*block.Service)
commonDetails := []*model.Detail{

View file

@ -26,6 +26,7 @@ import (
"github.com/anyproto/anytype-heart/util/anyerror"
"github.com/anyproto/anytype-heart/util/builtinobjects"
"github.com/anyproto/anytype-heart/util/constant"
"github.com/anyproto/anytype-heart/util/metricsid"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
@ -104,7 +105,10 @@ func (s *Service) RecoverFromLegacy(req *pb.RpcAccountRecoverFromLegacyExportReq
if profile.AnalyticsId != "" {
cfg.AnalyticsId = profile.AnalyticsId
} else {
cfg.AnalyticsId = metrics.GenerateAnalyticsId()
cfg.AnalyticsId, err = metricsid.DeriveMetricsId(res.Identity)
if err != nil {
return RecoverFromLegacyResponse{}, err
}
}
err = s.startApp(cfg, res)

View file

@ -99,6 +99,11 @@ func (s *Service) start(ctx context.Context, id string, rootPath string, disable
}
}
defer func() {
if repoWasMissing && err != nil {
os.RemoveAll(filepath.Join(s.rootPath, id))
}
}()
cfg := anytype.BootstrapConfig(false, os.Getenv("ANYTYPE_STAGING") == "1")
if disableLocalNetworkSync {
cfg.DontStartLocalNetworkSyncAutomatically = true

View file

@ -0,0 +1,45 @@
package application
import (
"context"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/anyproto/anytype-heart/core/event/mock_event"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/core"
)
func TestService_AccountSelect(t *testing.T) {
t.Run("account select finish with error", func(t *testing.T) {
// given
s := New()
dir := t.TempDir()
s.SetClientVersion("platform", "1")
mnemonic, err := core.WalletGenerateMnemonic(wordCount)
assert.NoError(t, err)
err = s.setMnemonic(mnemonic)
assert.NoError(t, err)
account, err := core.WalletAccountAt(mnemonic, 0)
assert.NoError(t, err)
expectedDir := filepath.Join(dir, account.Identity.GetPublic().Account())
sender := mock_event.NewMockSender(t)
sender.EXPECT().Name().Return("service")
ctx := context.Background()
sender.EXPECT().Init(mock.Anything).Return(ErrFailedToStartApplication)
s.eventSender = sender
// when
_, err = s.AccountSelect(ctx, &pb.RpcAccountSelectRequest{Id: account.Identity.GetPublic().Account(), RootPath: dir})
// then
assert.NotNil(t, err)
_, err = os.Stat(expectedDir)
assert.True(t, os.IsNotExist(err))
})
}

View file

@ -18,7 +18,7 @@ type Service interface {
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)
GetMessages(ctx context.Context, chatObjectId string, req chatobject.GetMessagesRequest) ([]*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
@ -74,10 +74,10 @@ func (s *service) DeleteMessage(ctx context.Context, chatObjectId string, messag
})
}
func (s *service) GetMessages(ctx context.Context, chatObjectId string, beforeOrderId string, limit int) ([]*model.ChatMessage, error) {
func (s *service) GetMessages(ctx context.Context, chatObjectId string, req chatobject.GetMessagesRequest) ([]*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)
msgs, err := sb.GetMessages(ctx, req)
if err != nil {
return err
}

View file

@ -137,7 +137,7 @@ func (s *service) ModifyDetailsList(req *pb.RpcObjectListModifyDetailValuesReque
}
err := modifyDetailsFunc(objectId, func(current *types.Struct) (*types.Struct, error) {
for _, op := range req.Operations {
if !pbtypes.IsEmptyValue(op.Set) {
if !pbtypes.IsNullValue(op.Set) {
// Set operation has higher priority than Add and Remove, because it modifies full value
current.Fields[op.RelationKey] = op.Set
continue

View file

@ -217,6 +217,31 @@ func TestService_ModifyDetailsList(t *testing.T) {
// then
assert.Error(t, err)
})
t.Run("set false value", func(t *testing.T) {
// given
fx := newFixture(t)
object := smarttest.New("obj1")
err := object.SetDetails(nil, []*model.Detail{{Key: bundle.RelationKeyDone.String(), Value: pbtypes.Bool(true)}}, false)
require.NoError(t, err)
fx.getter.EXPECT().GetObject(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, objectId string) (smartblock.SmartBlock, error) {
return object, nil
})
doneSet := []*pb.RpcObjectListModifyDetailValuesRequestOperation{{
RelationKey: bundle.RelationKeyDone.String(),
Set: pbtypes.Bool(false),
}}
// when
err = fx.ModifyDetailsList(&pb.RpcObjectListModifyDetailValuesRequest{
ObjectIds: []string{"obj1"},
Operations: doneSet,
})
// then
assert.NoError(t, err)
assert.False(t, pbtypes.GetBool(object.Details(), bundle.RelationKeyDone.String()))
})
}
func TestService_SetSpaceInfo(t *testing.T) {

View file

@ -10,6 +10,7 @@ import (
anystore "github.com/anyproto/any-store"
"github.com/anyproto/any-store/anyenc"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/util/crypto"
"github.com/gogo/protobuf/types"
"go.uber.org/zap"
@ -32,18 +33,18 @@ import (
"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/metricsid"
"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"
collectionName = "account"
accountDocumentId = "accountObject"
idKey = "id"
analyticsKey = "analyticsId"
iconMigrationKey = "iconMigration"
)
type ProfileDetails struct {
@ -63,7 +64,6 @@ type AccountObject interface {
IsIconMigrated() (bool, error)
SetAnalyticsId(analyticsId string) (err error)
GetAnalyticsId() (string, error)
GetPrivateAnalyticsId() string
}
type StoreDbProvider interface {
@ -75,6 +75,7 @@ var _ AccountObject = (*accountObject)(nil)
type accountObject struct {
anystoredebug.AnystoreDebug
smartblock.SmartBlock
keys *accountdata.AccountKeys
bs basic.DetailsSettable
state *storestate.StoreState
storeSource source.Store
@ -95,6 +96,7 @@ func (a *accountObject) SetDetailsAndUpdateLastUsed(ctx session.Context, details
func New(
sb smartblock.SmartBlock,
keys *accountdata.AccountKeys,
spaceObjects spaceindex.Store,
layoutConverter converter.LayoutConverter,
fileObjectService fileobject.Service,
@ -103,6 +105,7 @@ func New(
cfg *config.Config) AccountObject {
return &accountObject{
crdtDb: crdtDb,
keys: keys,
bs: basic.NewBasic(sb, spaceObjects, layoutConverter, fileObjectService, lastUsedUpdater),
SmartBlock: sb,
cfg: cfg,
@ -127,7 +130,6 @@ func (a *accountObject) Init(ctx *smartblock.InitContext) error {
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")
@ -148,12 +150,21 @@ func (a *accountObject) Init(ctx *smartblock.InitContext) error {
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)
var builder *storestate.Builder
if a.cfg.IsNewAccount() {
builder, err = a.genInitialDoc()
if err != nil {
return fmt.Errorf("generate initial doc: %w", err)
}
_, err = a.storeSource.PushStoreChange(ctx.Ctx, source.PushStoreChangeParams{
Changes: builder.ChangeSet,
State: a.state,
Time: time.Now(),
})
} else {
docToInsert := fmt.Sprintf(`{"%s":"%s"}`, idKey, accountDocumentId)
err = coll.Insert(ctx.Ctx, anyenc.MustParseJson(docToInsert))
}
err = coll.Insert(ctx.Ctx, anyenc.MustParseJson(docToInsert))
if err != nil {
return fmt.Errorf("insert account document: %w", err)
}
@ -170,30 +181,25 @@ func (a *accountObject) Init(ctx *smartblock.InitContext) error {
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()
func (a *accountObject) genInitialDoc() (builder *storestate.Builder, err error) {
builder = &storestate.Builder{}
analyticsId, err := metricsid.DeriveMetricsId(a.keys.SignKey)
if err != nil {
return ""
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)
newDocument := map[string]any{
idKey: accountDocumentId,
analyticsKey: analyticsId,
iconMigrationKey: "true",
}
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)
for key, val := range newDocument {
if str, ok := val.(string); ok {
val = fmt.Sprintf(`"%s"`, str)
}
err = builder.Modify(collectionName, accountDocumentId, []string{key}, pb.ModifyOp_Set, val)
if err != nil {
return
}
}
return
}
@ -262,14 +268,6 @@ func (a *accountObject) SetAnalyticsId(id string) error {
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,
@ -381,7 +379,8 @@ func (a *accountObject) update(ctx context.Context, st *state.State) (err error)
if err != nil {
return fmt.Errorf("get collection: %w", err)
}
obj, err := coll.FindId(ctx, accountDocumentId)
accId := accountDocumentId
obj, err := coll.FindId(ctx, accId)
if err != nil {
return fmt.Errorf("find id: %w", err)
}

View file

@ -9,6 +9,7 @@ import (
anystore "github.com/anyproto/any-store"
"github.com/anyproto/any-store/anyenc"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/globalsign/mgo/bson"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/mock"
@ -24,6 +25,7 @@ import (
"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/metricsid"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
@ -40,7 +42,6 @@ type fixture struct {
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 {
@ -52,8 +53,9 @@ func newFixture(t *testing.T, isNewAccount bool, prepareDb func(db anystore.DB))
})
sb := smarttest.New("accountId1")
indexStore := objectstore.NewStoreFixture(t).SpaceIndex("spaceId")
object := New(sb, indexStore, nil, nil, nil, db, cfg)
keys, err := accountdata.NewRandom()
require.NoError(t, err)
object := New(sb, keys, indexStore, nil, nil, nil, db, cfg)
fx := &fixture{
storeFx: objectstore.NewStoreFixture(t),
db: db,
@ -137,6 +139,8 @@ func (fx *fixture) assertStateValue(t *testing.T, val any, extract func(str *typ
func TestAccountNew(t *testing.T) {
fx := newFixture(t, true, nil)
expectedId, err := metricsid.DeriveMetricsId(fx.keys.SignKey)
require.NoError(t, err)
st := fx.SmartBlock.NewState()
assertBlock(t, st, "accountId1")
assertBlock(t, st, "title")
@ -147,14 +151,14 @@ func TestAccountNew(t *testing.T) {
require.True(t, res)
id, err := fx.GetAnalyticsId()
require.NoError(t, err)
require.Equal(t, "analyticsId", id)
fmt.Println(id)
require.Equal(t, expectedId, 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)
coll, err := db.CreateCollection(tx.Context(), "accountId1"+collectionName)
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)
@ -211,21 +215,6 @@ func TestSetSharedSpacesLimit(t *testing.T) {
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")

View file

@ -25,6 +25,7 @@ import (
const (
collectionName = "chats"
descOrder = "-_o.id"
ascOrder = "_o.id"
)
type StoreObject interface {
@ -32,7 +33,7 @@ type StoreObject interface {
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)
GetMessages(ctx context.Context, req GetMessagesRequest) ([]*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
@ -41,6 +42,12 @@ type StoreObject interface {
Unsubscribe() error
}
type GetMessagesRequest struct {
AfterOrderId string
BeforeOrderId string
Limit int
}
type AccountService interface {
AccountID() string
}
@ -129,24 +136,22 @@ func (s *storeObject) GetMessagesByIds(ctx context.Context, messageIds []string)
return messages, txn.Commit()
}
func (s *storeObject) GetMessages(ctx context.Context, beforeOrderId string, limit int) ([]*model.ChatMessage, error) {
func (s *storeObject) GetMessages(ctx context.Context, req GetMessagesRequest) ([]*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)
}
var qry anystore.Query
if req.AfterOrderId != "" {
qry = coll.Find(query.Key{Path: []string{orderKey, "id"}, Filter: query.NewComp(query.CompOpGt, req.AfterOrderId)}).Sort(ascOrder).Limit(uint(req.Limit))
} else if req.BeforeOrderId != "" {
qry = coll.Find(query.Key{Path: []string{orderKey, "id"}, Filter: query.NewComp(query.CompOpLt, req.BeforeOrderId)}).Sort(descOrder).Limit(uint(req.Limit))
} 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)
}
qry = coll.Find(nil).Sort(descOrder).Limit(uint(req.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

View file

@ -96,7 +96,7 @@ func TestAddMessage(t *testing.T) {
assert.NotEmpty(t, messageId)
assert.NotEmpty(t, sessionCtx.GetMessages())
messages, err := fx.GetMessages(ctx, "", 0)
messages, err := fx.GetMessages(ctx, GetMessagesRequest{})
require.NoError(t, err)
require.Len(t, messages, 1)
@ -121,20 +121,32 @@ func TestGetMessages(t *testing.T) {
assert.NotEmpty(t, messageId)
}
messages, err := fx.GetMessages(ctx, "", 5)
messages, err := fx.GetMessages(ctx, GetMessagesRequest{Limit: 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)
}
t.Run("with requested BeforeOrderId", func(t *testing.T) {
lastOrderId := messages[0].OrderId // text 6
gotMessages, err := fx.GetMessages(ctx, GetMessagesRequest{BeforeOrderId: lastOrderId, Limit: 5})
require.NoError(t, err)
wantTexts = []string{"text 1", "text 2", "text 3", "text 4", "text 5"}
for i, msg := range gotMessages {
assert.Equal(t, wantTexts[i], msg.Message.Text)
}
})
t.Run("with requested AfterOrderId", func(t *testing.T) {
lastOrderId := messages[0].OrderId // text 6
gotMessages, err := fx.GetMessages(ctx, GetMessagesRequest{AfterOrderId: lastOrderId, Limit: 2})
require.NoError(t, err)
wantTexts = []string{"text 7", "text 8"}
for i, msg := range gotMessages {
assert.Equal(t, wantTexts[i], msg.Message.Text)
}
})
}
func TestGetMessagesByIds(t *testing.T) {
@ -177,7 +189,7 @@ func TestEditMessage(t *testing.T) {
err = fx.EditMessage(ctx, messageId, editedMessage)
require.NoError(t, err)
messages, err := fx.GetMessages(ctx, "", 0)
messages, err := fx.GetMessages(ctx, GetMessagesRequest{})
require.NoError(t, err)
require.Len(t, messages, 1)
@ -212,7 +224,7 @@ func TestEditMessage(t *testing.T) {
require.Error(t, err)
// Check that nothing is changed
messages, err := fx.GetMessages(ctx, "", 0)
messages, err := fx.GetMessages(ctx, GetMessagesRequest{})
require.NoError(t, err)
require.Len(t, messages, 1)
@ -268,7 +280,7 @@ func TestToggleReaction(t *testing.T) {
require.NoError(t, err)
})
messages, err := fx.GetMessages(ctx, "", 0)
messages, err := fx.GetMessages(ctx, GetMessagesRequest{})
require.NoError(t, err)
require.Len(t, messages, 1)

View file

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/anytype-heart/core/anytype/config"
@ -44,6 +45,7 @@ type accountService interface {
AccountID() string
PersonalSpaceID() string
MyParticipantId(spaceId string) string
Keys() *accountdata.AccountKeys
}
type deviceService interface {
@ -213,7 +215,7 @@ func (f *ObjectFactory) New(space smartblock.Space, sbType coresb.SmartBlockType
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
return accountobject.New(sb, f.accountService.Keys(), 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)
}

View file

@ -32,6 +32,7 @@ var pageRequiredRelations = []domain.RelationKey{
bundle.RelationKeySnippet,
bundle.RelationKeyFeaturedRelations,
bundle.RelationKeyLinks,
bundle.RelationKeyBacklinks,
bundle.RelationKeyLayoutAlign,
}

View file

@ -301,6 +301,8 @@ func (st *SmartTest) UpdateDetailsAndLastUsed(update func(current *types.Struct)
return nil
}
st.Doc.(*state.State).SetDetails(newDetails)
for key := range diff.Fields {
st.Results.LastUsedUpdates = append(st.Results.LastUsedUpdates, key)
}

View file

@ -5,6 +5,7 @@ import (
"fmt"
"time"
"github.com/anyproto/lexid"
"github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/types"
"golang.org/x/exp/slices"
@ -26,6 +27,8 @@ var spaceViewLog = logging.Logger("core.block.editor.spaceview")
var ErrIncorrectSpaceInfo = errors.New("space info is incorrect")
var lx = lexid.Must(lexid.CharsBase64, 4, 1000)
// required relations for spaceview beside the bundle.RequiredInternalRelations
var spaceViewRequiredRelations = []domain.RelationKey{
bundle.RelationKeySpaceLocalStatus,
@ -313,6 +316,34 @@ func (s *SpaceView) UpdateLastOpenedDate() error {
return s.Apply(st, smartblock.NoHistory, smartblock.NoEvent, smartblock.SkipIfNoChanges, smartblock.KeepInternalFlags)
}
func (s *SpaceView) SetOrder(prevViewOrderId string) (string, error) {
st := s.NewState()
spaceOrderId := lx.Next(prevViewOrderId)
st.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String(spaceOrderId))
return spaceOrderId, s.Apply(st)
}
func (s *SpaceView) SetAfterGivenView(viewOrderId string) error {
st := s.NewState()
spaceOrderId := pbtypes.GetString(st.Details(), bundle.RelationKeySpaceOrder.String())
if viewOrderId > spaceOrderId {
spaceOrderId = lx.Next(viewOrderId)
st.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String(spaceOrderId))
return s.Apply(st)
}
return nil
}
func (s *SpaceView) SetBetweenViews(prevViewOrderId, afterViewOrderId string) error {
st := s.NewState()
before, err := lx.NextBefore(prevViewOrderId, afterViewOrderId)
if err != nil {
return fmt.Errorf("failed to get before lexid, %w", err)
}
st.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String(before))
return s.Apply(st)
}
func stateSetAccessType(st *state.State, accessType spaceinfo.AccessType) {
st.SetDetailAndBundledRelation(bundle.RelationKeySpaceAccessType, pbtypes.Int64(int64(accessType)))
}

View file

@ -6,6 +6,7 @@ import (
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
@ -128,6 +129,129 @@ func TestSpaceView_SetOwner(t *testing.T) {
require.Equal(t, int64(125), pbtypes.GetInt64(fx.CombinedDetails(), bundle.RelationKeyCreatedDate.String()))
}
func TestSpaceView_SetAfterGivenView(t *testing.T) {
t.Run("set view after given id", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
// when
err := fx.SetAfterGivenView("viewOrderId")
// then
require.NoError(t, err)
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
})
t.Run("set view after given id, order exist", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
state := fx.NewState()
state.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String("spaceViewOrderId"))
err := fx.Apply(state)
require.NoError(t, err)
// when
err = fx.SetAfterGivenView("viewOrderId")
// then
require.NoError(t, err)
assert.NotEqual(t, "spaceViewOrderId", pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > "viewOrderId")
})
t.Run("set view after given id, order exist, but already less than given view", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
state := fx.NewState()
state.SetDetail(bundle.RelationKeySpaceOrder.String(), pbtypes.String("viewOrderId"))
err := fx.Apply(state)
require.NoError(t, err)
// when
err = fx.SetAfterGivenView("spaceViewOrderId")
// then
require.NoError(t, err)
assert.Equal(t, "viewOrderId", pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > "spaceViewOrderId")
})
}
func TestSpaceView_SetBetweenViews(t *testing.T) {
t.Run("set view in the beginning", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
// when
err := fx.SetBetweenViews("", "afterId")
// then
require.NoError(t, err)
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
})
t.Run("set view between", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
firstSpaceView := lx.Next("")
secondSpaceView := lx.Next(firstSpaceView)
thirdSpaceView := lx.Next(secondSpaceView)
// when
err := fx.SetBetweenViews(secondSpaceView, thirdSpaceView)
// then
require.NoError(t, err)
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
})
t.Run("after id is empty", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
// when
err := fx.SetBetweenViews("afterId", "")
// then
require.Error(t, err)
})
}
func TestSpaceView_SetOrder(t *testing.T) {
t.Run("set order", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
// when
prevViewOrderId := ""
order, err := fx.SetOrder(prevViewOrderId)
// then
require.NoError(t, err)
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
assert.Equal(t, order, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > prevViewOrderId)
})
t.Run("set order, previous id not empty", func(t *testing.T) {
// given
fx := newSpaceViewFixture(t)
defer fx.finish()
// when
prevViewOrderId := "previous"
order, err := fx.SetOrder(prevViewOrderId)
// then
require.NoError(t, err)
assert.NotEmpty(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
assert.Equal(t, order, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()))
assert.True(t, pbtypes.GetString(fx.Details(), bundle.RelationKeySpaceOrder.String()) > prevViewOrderId)
})
}
type spaceServiceStub struct {
}

View file

@ -15,6 +15,7 @@ const (
DefaultWidgetSet = "set"
DefaultWidgetRecent = "recent"
DefaultWidgetCollection = "collection"
DefaultWidgetRecentOpen = "recentOpen"
)
type Widget interface {

View file

@ -12,13 +12,18 @@ import (
"github.com/anyproto/anytype-heart/util/anyerror"
)
type OriginalFileNameGetter interface {
GetFileOriginalName(filename string) string
}
type Zip struct {
archiveReader *zip.ReadCloser
fileReaders map[string]*zip.File
archiveReader *zip.ReadCloser
fileReaders map[string]*zip.File
originalToNormalizedNames map[string]string
}
func NewZip() *Zip {
return &Zip{fileReaders: make(map[string]*zip.File, 0)}
return &Zip{fileReaders: make(map[string]*zip.File), originalToNormalizedNames: make(map[string]string)}
}
func (z *Zip) Initialize(importPath string) error {
@ -32,7 +37,11 @@ func (z *Zip) Initialize(importPath string) error {
if strings.HasPrefix(f.Name, "__MACOSX/") {
continue
}
fileReaders[normalizeName(f, i)] = f
normalizedName := normalizeName(f, i)
fileReaders[normalizedName] = f
if normalizedName != f.Name {
z.originalToNormalizedNames[f.Name] = normalizedName
}
}
z.fileReaders = fileReaders
return nil
@ -94,3 +103,10 @@ func (z *Zip) Close() {
func (z *Zip) IsRootFile(fileName string) bool {
return filepath.Dir(fileName) == "."
}
func (z *Zip) GetFileOriginalName(fileName string) string {
if originalName, ok := z.originalToNormalizedNames[fileName]; ok {
return originalName
}
return fileName
}

View file

@ -2,18 +2,27 @@ package test
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func CreateEmptyZip(t *testing.T, zipFileName string) error {
func CreateEmptyZip(t *testing.T, zipFileName string) {
zipFile, err := os.Create(zipFileName)
if err != nil {
return fmt.Errorf("Failed to create zip file: %w\n", err)
}
assert.NoError(t, err)
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
err = zipWriter.Close()
assert.NoError(t, err)
}
func CreateZipWithFiles(t *testing.T, zipFileName, testDataDir string, files []*zip.FileHeader) {
zipFile, err := os.Create(zipFileName)
assert.NoError(t, err)
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
@ -21,5 +30,13 @@ func CreateEmptyZip(t *testing.T, zipFileName string) error {
err = zipWriter.Close()
assert.NoError(t, err)
}()
return nil
for _, file := range files {
writer, err := zipWriter.CreateHeader(file)
assert.NoError(t, err)
fileReader, err := os.Open(filepath.Join(testDataDir, file.Name))
assert.NoError(t, err)
_, err = io.Copy(writer, fileReader)
assert.NoError(t, err)
}
}

View file

@ -819,8 +819,7 @@ func TestCSV_GetSnapshots(t *testing.T) {
// given
dir := t.TempDir()
zipPath := filepath.Join(dir, "empty.zip")
err := test.CreateEmptyZip(t, zipPath)
assert.Nil(t, err)
test.CreateEmptyZip(t, zipPath)
csv := CSV{}
p := process.NewProgress(&pb.ModelProcessMessageOfImport{Import: &pb.ModelProcessImport{}})

View file

@ -61,8 +61,7 @@ func TestHTML_GetSnapshots(t *testing.T) {
// given
dir := t.TempDir()
zipPath := filepath.Join(dir, "empty.zip")
err := test.CreateEmptyZip(t, zipPath)
assert.Nil(t, err)
test.CreateEmptyZip(t, zipPath)
html := HTML{}
p := process.NewProgress(&pb.ModelProcessMessageOfImport{Import: &pb.ModelProcessImport{}})

View file

@ -56,7 +56,7 @@ func (m *mdConverter) processFiles(importPath string, allErrors *common.ConvertE
}
fileInfo := m.getFileInfo(importSource, allErrors)
for name, file := range fileInfo {
m.processBlocks(name, file, fileInfo)
m.processBlocks(name, file, fileInfo, importSource)
for _, b := range file.ParsedBlocks {
m.processFileBlock(b, importSource, importPath)
}
@ -89,72 +89,76 @@ func (m *mdConverter) fillFilesInfo(importSource source.Source, fileInfo map[str
return nil
}
func (m *mdConverter) processBlocks(shortPath string, file *FileInfo, files map[string]*FileInfo) {
func (m *mdConverter) processBlocks(shortPath string, file *FileInfo, files map[string]*FileInfo, importSource source.Source) {
for _, block := range file.ParsedBlocks {
m.processTextBlock(block, files)
m.processTextBlock(block, files, importSource)
}
m.processLinkBlock(shortPath, file, files)
}
func (m *mdConverter) processTextBlock(block *model.Block, files map[string]*FileInfo) {
func (m *mdConverter) processTextBlock(block *model.Block, files map[string]*FileInfo, importSource source.Source) {
txt := block.GetText()
if txt != nil && txt.Marks != nil {
if len(txt.Marks.Marks) == 1 && txt.Marks.Marks[0].Type == model.BlockContentTextMark_Link {
m.handleSingleMark(block, files)
m.handleSingleMark(block, files, importSource)
} else {
m.handleMultipleMarks(block, files)
m.handleMultipleMarks(block, files, importSource)
}
}
}
func (m *mdConverter) handleSingleMark(block *model.Block, files map[string]*FileInfo) {
func (m *mdConverter) handleSingleMark(block *model.Block, files map[string]*FileInfo, importSource source.Source) {
txt := block.GetText()
link := txt.Marks.Marks[0].Param
wholeLineLink := m.isWholeLineLink(txt.Text, txt.Marks.Marks[0])
ext := filepath.Ext(link)
ext := filepath.Ext(txt.Marks.Marks[0].Param)
link := m.getOriginalName(txt.Marks.Marks[0].Param, importSource)
if file := files[link]; file != nil {
if strings.EqualFold(ext, ".csv") {
txt.Marks.Marks[0].Param = link
m.processCSVFileLink(block, files, link, wholeLineLink)
return
}
if strings.EqualFold(ext, ".md") {
// only convert if this is the only link in the row
txt.Marks.Marks[0].Param = link
m.convertToAnytypeLinkBlock(block, wholeLineLink)
} else {
block.Content = anymark.ConvertTextToFile(txt.Marks.Marks[0].Param)
}
file.HasInboundLinks = true
} else if wholeLineLink {
block.Content = m.convertTextToBookmark(txt.Marks.Marks[0].Param)
m.convertTextToBookmark(txt.Marks.Marks[0].Param, block)
}
}
func (m *mdConverter) handleMultipleMarks(block *model.Block, files map[string]*FileInfo) {
func (m *mdConverter) handleMultipleMarks(block *model.Block, files map[string]*FileInfo, importSource source.Source) {
txt := block.GetText()
for _, mark := range txt.Marks.Marks {
if mark.Type == model.BlockContentTextMark_Link {
if stop := m.handleSingleLinkMark(block, files, mark, txt); stop {
if stop := m.handleSingleLinkMark(block, files, mark, txt, importSource); stop {
return
}
}
}
}
func (m *mdConverter) handleSingleLinkMark(block *model.Block, files map[string]*FileInfo, mark *model.BlockContentTextMark, txt *model.BlockContentText) bool {
link := mark.Param
func (m *mdConverter) handleSingleLinkMark(block *model.Block, files map[string]*FileInfo, mark *model.BlockContentTextMark, txt *model.BlockContentText, importSource source.Source) bool {
isWholeLink := m.isWholeLineLink(txt.Text, mark)
link := m.getOriginalName(mark.Param, importSource)
ext := filepath.Ext(link)
if file := files[link]; file != nil {
file.HasInboundLinks = true
if strings.EqualFold(ext, ".md") || strings.EqualFold(ext, ".csv") {
mark.Type = model.BlockContentTextMark_Mention
mark.Param = link
return false
}
if m.isWholeLineLink(txt.Text, mark) {
if isWholeLink {
block.Content = anymark.ConvertTextToFile(mark.Param)
return true
}
} else if m.isWholeLineLink(txt.Text, mark) {
block.Content = m.convertTextToBookmark(mark.Param)
} else if isWholeLink {
m.convertTextToBookmark(mark.Param, block)
return true
}
return false
@ -238,12 +242,12 @@ func (m *mdConverter) convertTextToPageLink(block *model.Block) {
}
}
func (m *mdConverter) convertTextToBookmark(url string) *model.BlockContentOfBookmark {
func (m *mdConverter) convertTextToBookmark(url string, block *model.Block) {
if err := uri.ValidateURI(url); err != nil {
return nil
return
}
return &model.BlockContentOfBookmark{
block.Content = &model.BlockContentOfBookmark{
Bookmark: &model.BlockContentBookmark{
Url: url,
},
@ -275,3 +279,10 @@ func (m *mdConverter) createBlocksFromFile(importSource source.Source, filePath
}
return nil
}
func (m *mdConverter) getOriginalName(link string, importSource source.Source) string {
if originalFileNameGetter, ok := importSource.(source.OriginalFileNameGetter); ok {
return originalFileNameGetter.GetFileOriginalName(link)
}
return link
}

View file

@ -42,7 +42,7 @@ func Test_processFiles(t *testing.T) {
files := converter.processFiles(absolutePath, common.NewError(pb.RpcObjectImportRequest_IGNORE_ERRORS), source)
// then
assert.Len(t, files, 6)
assert.Len(t, files, 9)
pdfFilePath := filepath.Join(absolutePath, "test.pdf")
assert.Contains(t, files, pdfFilePath)
@ -74,7 +74,7 @@ func Test_processFiles(t *testing.T) {
files := converter.processFiles(absolutePath, common.NewError(pb.RpcObjectImportRequest_IGNORE_ERRORS), source)
// then
assert.Len(t, files, 4)
assert.Len(t, files, 7)
pdfFilePath := filepath.Join(absolutePath, "test.pdf")
assert.NotContains(t, files, pdfFilePath)

View file

@ -1,6 +1,7 @@
package markdown
import (
"archive/zip"
"context"
"errors"
"os"
@ -97,7 +98,7 @@ func TestMarkdown_GetSnapshots(t *testing.T) {
// then
assert.Nil(t, err)
assert.NotNil(t, sn)
assert.Len(t, sn.Snapshots, 4)
assert.Len(t, sn.Snapshots, 7)
fileNameToObjectId := make(map[string]string, len(sn.Snapshots))
for _, snapshot := range sn.Snapshots {
@ -119,8 +120,7 @@ func TestMarkdown_GetSnapshots(t *testing.T) {
// given
testDirectory := t.TempDir()
zipPath := filepath.Join(testDirectory, "empty.zip")
err := test.CreateEmptyZip(t, zipPath)
assert.Nil(t, err)
test.CreateEmptyZip(t, zipPath)
h := &Markdown{}
p := process.NewProgress(&pb.ModelProcessMessageOfImport{Import: &pb.ModelProcessImport{}})
@ -139,6 +139,132 @@ func TestMarkdown_GetSnapshots(t *testing.T) {
assert.Nil(t, sn)
assert.True(t, errors.Is(ce.GetResultError(model.Import_Markdown), common.ErrFileImportNoObjectsInZipArchive))
})
t.Run("import non utf files", func(t *testing.T) {
// given
testDirectory := t.TempDir()
zipPath := filepath.Join(testDirectory, "nonutf.zip")
fileMdName := "こんにちは.md"
fileCsvName := "你好.csv"
fileWithLinksName := "nonutflinks.md"
test.CreateZipWithFiles(t, zipPath, "testdata", []*zip.FileHeader{
{
Name: fileWithLinksName,
Method: zip.Deflate,
},
{
Name: fileMdName,
Method: zip.Deflate,
NonUTF8: true,
},
{
Name: fileCsvName,
Method: zip.Deflate,
NonUTF8: true,
},
})
h := &Markdown{}
p := process.NewProgress(&pb.ModelProcessMessageOfImport{Import: &pb.ModelProcessImport{}})
// when
sn, ce := h.GetSnapshots(context.Background(), &pb.RpcObjectImportRequest{
Params: &pb.RpcObjectImportRequestParamsOfMarkdownParams{
MarkdownParams: &pb.RpcObjectImportRequestMarkdownParams{Path: []string{zipPath}},
},
Type: model.Import_Markdown,
Mode: pb.RpcObjectImportRequest_IGNORE_ERRORS,
}, p)
// then
assert.Nil(t, ce)
assert.NotNil(t, sn)
assert.Len(t, sn.Snapshots, 4)
fileNameToObjectId := make(map[string]string, len(sn.Snapshots))
for _, snapshot := range sn.Snapshots {
fileNameToObjectId[snapshot.FileName] = snapshot.Id
}
var found bool
rootId := fileNameToObjectId[fileWithLinksName]
want := buildTreeWithNonUtfLinks(fileNameToObjectId, rootId)
for _, snapshot := range sn.Snapshots {
if snapshot.FileName == fileWithLinksName {
found = true
blockbuilder.AssertTreesEqual(t, want.Build(), snapshot.Snapshot.Data.Blocks)
}
}
assert.True(t, found)
})
}
func buildTreeWithNonUtfLinks(fileNameToObjectId map[string]string, rootId string) *blockbuilder.Block {
testMdPath := fileNameToObjectId["import file 2.md"]
testCsvPath := fileNameToObjectId["import file 3.csv"]
want := blockbuilder.Root(
blockbuilder.ID(rootId),
blockbuilder.Children(
blockbuilder.Text("NonUtf 1 test6", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 9, To: 14},
Type: model.BlockContentTextMark_Mention,
Param: testMdPath,
},
}})),
blockbuilder.Text("NonUtf 2 test7", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 9, To: 14},
Type: model.BlockContentTextMark_Mention,
Param: testCsvPath,
},
}})),
blockbuilder.Text("NonUtf 1 test6", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 9, To: 14},
Type: model.BlockContentTextMark_Mention,
Param: testMdPath,
},
{
Range: &model.Range{From: 9, To: 14},
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Text("NonUtf 2 test7", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 9, To: 14},
Type: model.BlockContentTextMark_Mention,
Param: testCsvPath,
},
{
Range: &model.Range{From: 9, To: 14},
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Text("test6", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 0, To: 5},
Type: model.BlockContentTextMark_Mention,
Param: testMdPath,
},
{
Range: &model.Range{From: 0, To: 5},
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Text("test7", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 0, To: 5},
Type: model.BlockContentTextMark_Mention,
Param: testCsvPath,
},
{
Range: &model.Range{From: 0, To: 5},
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Link(rootId),
))
return want
}
func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempDir, rootId string) *blockbuilder.Block {
@ -146,6 +272,7 @@ func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempD
testMdPath := filepath.Join("testdata", "test.md")
testCsvPath := filepath.Join("testdata", "test.csv")
testTxtPath := filepath.Join("testdata", "test.txt")
url := "http://example.com/%zz"
want := blockbuilder.Root(
blockbuilder.ID(rootId),
blockbuilder.Children(
@ -171,6 +298,13 @@ func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempD
Param: fileNameToObjectId[testCsvPath],
},
}})),
blockbuilder.Text("Should not panic test5", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 17, To: 22},
Type: model.BlockContentTextMark_Link,
Param: url,
},
}})),
blockbuilder.Text("File does not exist with bold mark test1", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 35, To: 40},
@ -215,6 +349,17 @@ func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempD
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Text("Should not panic test5", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 17, To: 22},
Type: model.BlockContentTextMark_Link,
Param: url,
},
{
Range: &model.Range{From: 17, To: 22},
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Bookmark(fileMdPath),
blockbuilder.Text("test2", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
@ -239,6 +384,17 @@ func buildExpectedTree(fileNameToObjectId map[string]string, provider *MockTempD
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Text("test5", blockbuilder.TextMarks(model.BlockContentTextMarks{Marks: []*model.BlockContentTextMark{
{
Range: &model.Range{From: 0, To: 5},
Type: model.BlockContentTextMark_Link,
Param: url,
},
{
Range: &model.Range{From: 0, To: 5},
Type: model.BlockContentTextMark_Bold,
},
}})),
blockbuilder.Link(rootId),
))
return want

View file

@ -6,6 +6,8 @@ Test file block [test3](test.txt)
Test link to csv [test4](test.csv)
Should not panic [test5](http://example.com/%zz)
File does not exist with bold mark **[test1](file.md)**
Test link to page with bold mark **[test2](test.md)**
@ -14,6 +16,8 @@ Test file block with bold mark **[test3](test.txt)**
Test link to csv with bold mark **[test4](test.csv)**
Should not panic **[test5](http://example.com/%zz)**
**[test1](file.md)**
**[test2](test.md)**
@ -21,3 +25,5 @@ Test link to csv with bold mark **[test4](test.csv)**
**[test3](test.txt)**
**[test4](test.csv)**
**[test5](http://example.com/%zz)**

View file

@ -0,0 +1,11 @@
NonUtf 1 [test6](こんにちは.md)
NonUtf 2 [test7](你好.csv)
NonUtf 1 **[test6](こんにちは.md)**
NonUtf 2 **[test7](你好.csv)**
**[test6](こんにちは.md)**
**[test7](你好.csv)**

View file

View file

View file

@ -243,8 +243,7 @@ func TestPb_GetSnapshots(t *testing.T) {
dir := t.TempDir()
p := &Pb{}
zipPath := filepath.Join(dir, "empty.zip")
err := test.CreateEmptyZip(t, zipPath)
assert.Nil(t, err)
test.CreateEmptyZip(t, zipPath)
// when
_, ce := p.GetSnapshots(context.Background(), &pb.RpcObjectImportRequest{

View file

@ -78,8 +78,7 @@ func TestTXT_GetSnapshots(t *testing.T) {
// given
dir := t.TempDir()
zipPath := filepath.Join(dir, "empty.zip")
err := test.CreateEmptyZip(t, zipPath)
assert.Nil(t, err)
test.CreateEmptyZip(t, zipPath)
h := &TXT{}
p := process.NewProgress(&pb.ModelProcessMessageOfImport{Import: &pb.ModelProcessImport{}})

View file

@ -74,12 +74,12 @@ func (c *objectCache) DeriveTreePayload(ctx context.Context, params payloadcreat
return treestorage.TreeStorageCreatePayload{}, err
}
accountKeys := c.accountService.Account()
if c.space.TreeBuilder() == nil {
return treestorage.TreeStorageCreatePayload{}, fmt.Errorf("can't derive in virtual space")
}
// we have to derive ids differently for personal space
if c.personalSpaceId == c.space.Id() || params.UseAccountSignature {
treePayload := derivePersonalPayload(c.space.Id(), accountKeys.SignKey, changePayload)
if c.space.TreeBuilder() == nil {
return treestorage.TreeStorageCreatePayload{}, fmt.Errorf("can't derive in virtual space")
}
create, err := c.space.TreeBuilder().CreateTree(context.Background(), treePayload)
if err != nil {
return storagePayload, err

View file

@ -2,11 +2,13 @@ package objectlink
import (
"context"
"errors"
"time"
"github.com/gogo/protobuf/types"
"github.com/ipfs/go-cid"
"github.com/samber/lo"
"go.uber.org/zap"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/editor/template"
@ -21,15 +23,21 @@ import (
var log = logging.Logger("objectlink")
type KeyToIDConverter interface {
GetRelationIdByKey(ctx context.Context, key domain.RelationKey) (id string, err error)
GetTypeIdByKey(ctx context.Context, key domain.TypeKey) (id string, err error)
}
type (
KeyToIDConverter interface {
GetRelationIdByKey(ctx context.Context, key domain.RelationKey) (id string, err error)
GetTypeIdByKey(ctx context.Context, key domain.TypeKey) (id string, err error)
}
type linkSource interface {
FillSmartIds(ids []string) []string
HasSmartIds() bool
}
linkSource interface {
FillSmartIds(ids []string) []string
HasSmartIds() bool
}
spaceIdResolver interface {
ResolveSpaceID(id string) (spaceId string, err error)
}
)
type Flags struct {
Blocks,
@ -88,6 +96,31 @@ func DependentObjectIDs(s *state.State, converter KeyToIDConverter, flags Flags)
return
}
func DependentObjectIDsPerSpace(rootSpaceId string, s *state.State, converter KeyToIDConverter, resolver spaceIdResolver, flags Flags) map[string][]string {
ids := DependentObjectIDs(s, converter, flags)
perSpace := map[string][]string{}
for _, id := range ids {
if dateObject, parseErr := dateutil.BuildDateObjectFromId(id); parseErr == nil {
perSpace[rootSpaceId] = append(perSpace[rootSpaceId], dateObject.Id())
continue
}
spaceId, err := resolver.ResolveSpaceID(id)
if errors.Is(err, domain.ErrObjectNotFound) {
perSpace[rootSpaceId] = append(perSpace[rootSpaceId], id)
continue
}
if err != nil {
perSpace[rootSpaceId] = append(perSpace[rootSpaceId], id)
log.With("id", id).Warn("resolve space id", zap.Error(err))
continue
}
perSpace[spaceId] = append(perSpace[spaceId], id)
}
return perSpace
}
func collectIdsFromBlocks(s *state.State, flags Flags) (ids []string) {
err := s.Iterate(func(b simple.Block) (isContinue bool) {
if flags.DataviewBlockOnlyTarget {

View file

@ -7,6 +7,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/core/block/simple"
@ -32,6 +33,18 @@ func fakeDerivedID(key string) string {
return fmt.Sprintf("derivedFrom(%s)", key)
}
type fakeSpaceIdResolver struct {
idsToSpaceIds map[string]string
}
func (r *fakeSpaceIdResolver) ResolveSpaceID(id string) (string, error) {
spaceId, found := r.idsToSpaceIds[id]
if !found {
return "", fmt.Errorf("not found")
}
return spaceId, nil
}
func TestState_DepSmartIdsLinks(t *testing.T) {
// given
stateWithLinks := state.NewDoc("root", map[string]simple.Block{
@ -218,8 +231,7 @@ func TestState_DepSmartIdsLinksAndRelations(t *testing.T) {
})
}
func TestState_DepSmartIdsLinksDetailsAndRelations(t *testing.T) {
// given
func buildStateWithLinks() *state.State {
stateWithLinks := state.NewDoc("root", map[string]simple.Block{
"root": simple.New(&model.Block{
Id: "root",
@ -261,7 +273,6 @@ func TestState_DepSmartIdsLinksDetailsAndRelations(t *testing.T) {
},
}}),
}).(*state.State)
converter := &fakeConverter{}
relations := []*model.RelationLink{
{
@ -292,6 +303,14 @@ func TestState_DepSmartIdsLinksDetailsAndRelations(t *testing.T) {
stateWithLinks.SetDetail("relation4", pbtypes.String("option3"))
stateWithLinks.SetDetail("relation5", pbtypes.Int64(time.Now().Unix()))
return stateWithLinks
}
func TestState_DepSmartIdsLinksDetailsAndRelations(t *testing.T) {
// given
stateWithLinks := buildStateWithLinks()
converter := &fakeConverter{}
t.Run("blocks option is turned on: get ids from blocks", func(t *testing.T) {
objectIDs := DependentObjectIDs(stateWithLinks, converter, Flags{Blocks: true})
assert.Len(t, objectIDs, 4) // links
@ -362,3 +381,39 @@ func TestState_DepSmartIdsObjectTypes(t *testing.T) {
}, objectIDs)
})
}
func TestDependentObjectIDsPerSpace(t *testing.T) {
// given
const (
spc1 = "space1"
spc2 = "space2"
spc3 = "space3"
)
st := buildStateWithLinks()
converter := &fakeConverter{}
resolver := &fakeSpaceIdResolver{idsToSpaceIds: map[string]string{
"objectID": spc1,
"objectID2": spc2,
"objectID3": spc3,
"objectID4": spc1,
"relation1": spc1,
"relation2": spc1,
"relation3": spc1,
"relation4": spc1,
"relation5": spc1,
"file": spc2,
// "option1": ???,
"option2": spc2,
"option3": spc3,
dateutil.NewDateObject(time.Now(), false).Id(): spc1,
}}
// when
ids := DependentObjectIDsPerSpace(spc1, st, converter, resolver, Flags{Blocks: true, Relations: true, Details: true})
// then
require.Len(t, ids, 3)
assert.Len(t, ids[spc1], 9)
assert.Len(t, ids[spc2], 3)
assert.Len(t, ids[spc3], 2)
}

View file

@ -150,7 +150,14 @@ func extractTargetDetails(originDetails *types.Struct, templateDetails *types.St
func (s *service) createCustomTemplateState(templateId string) (targetState *state.State, err error) {
err = cache.Do(s.picker, templateId, func(sb smartblock.SmartBlock) (innerErr error) {
targetState, innerErr = s.buildState(sb)
return
if innerErr != nil {
return innerErr
}
details := targetState.Details()
if pbtypes.GetBool(details, bundle.RelationKeyIsDeleted.String()) || pbtypes.GetBool(details, bundle.RelationKeyIsUninstalled.String()) {
return spacestorage.ErrTreeStorageAlreadyDeleted
}
return nil
})
if errors.Is(err, spacestorage.ErrTreeStorageAlreadyDeleted) {
return s.createBlankTemplateState(model.ObjectType_basic), nil

View file

@ -4,6 +4,7 @@ import (
"context"
"github.com/anyproto/anytype-heart/core/block/chats"
"github.com/anyproto/anytype-heart/core/block/editor/chatobject"
"github.com/anyproto/anytype-heart/pb"
)
@ -65,7 +66,11 @@ func (mw *Middleware) ChatDeleteMessage(cctx context.Context, req *pb.RpcChatDel
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))
messages, err := chatService.GetMessages(cctx, req.ChatObjectId, chatobject.GetMessagesRequest{
AfterOrderId: req.AfterOrderId,
BeforeOrderId: req.BeforeOrderId,
Limit: int(req.Limit),
})
code := mapErrorCode[pb.RpcChatGetMessagesResponseErrorCode](err)
return &pb.RpcChatGetMessagesResponse{
Messages: messages,

View file

@ -12,28 +12,43 @@ import (
"github.com/anyproto/anytype-heart/core/block/source"
"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/database"
"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/util/dateutil"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
var literals []string
func init() {
literals = []string{"today", "now", "yesterday", "tomorrow"}
for i := 0; i < 7; i++ {
literals = append(literals, strings.ToLower(time.Weekday(i).String()))
}
for i := 0; i < 12; i++ {
literals = append(literals, strings.ToLower(time.Month(i+1).String()))
}
}
func EnrichRecordsWithDateSuggestions(
ctx context.Context,
spaceId, fullText string,
records []database.Record,
req *pb.RpcObjectSearchRequest,
filters []*model.BlockContentDataviewFilter,
store objectstore.ObjectStore,
spaceService space.Service,
) ([]database.Record, error) {
ids := suggestDateObjectIds(req)
ids := suggestDateObjectIds(fullText, filters)
if len(ids) == 0 {
return records, nil
}
spc, err := spaceService.Get(ctx, req.SpaceId)
spc, err := spaceService.Get(ctx, spaceId)
if err != nil {
return nil, fmt.Errorf("get space: %w", err)
}
@ -48,7 +63,7 @@ func EnrichRecordsWithDateSuggestions(
return nil, fmt.Errorf("make date record: %w", err)
}
f, _ := database.MakeFilters(req.Filters, store.SpaceIndex(req.SpaceId)) //nolint:errcheck
f, _ := database.MakeFilters(filters, store.SpaceIndex(spaceId)) //nolint:errcheck
if f.FilterObject(rec.Details) {
records = append([]database.Record{rec}, records...)
}
@ -60,8 +75,8 @@ func EnrichRecordsWithDateSuggestions(
// suggestDateObjectIds suggests date object ids based on two fields:
// - fullText - if naturalDate successfully parses text into date, resulting date object id is returned
// - filter with key id
func suggestDateObjectIds(req *pb.RpcObjectSearchRequest) []string {
dt := suggestDateForSearch(time.Now(), req.FullText)
func suggestDateObjectIds(fullText string, filters []*model.BlockContentDataviewFilter) []string {
dt := suggestDateForSearch(time.Now(), fullText)
if !dt.IsZero() {
// TODO: GO-4097 Uncomment it when we will be able to support dates with seconds precision
// isDay := dt.Hour() == 0 && dt.Minute() == 0 && dt.Second() == 0
@ -69,7 +84,7 @@ func suggestDateObjectIds(req *pb.RpcObjectSearchRequest) []string {
return []string{dateutil.NewDateObject(dt, !isDay).Id()}
}
for _, filter := range req.Filters {
for _, filter := range filters {
if filter.RelationKey == bundle.RelationKeyId.String() {
list := pbtypes.GetStringListValue(filter.Value)
var dateObjectIds []string
@ -91,10 +106,19 @@ func suggestDateForSearch(now time.Time, raw string) time.Time {
return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
}
if len(raw) > 1 {
for _, variant := range literals {
if strings.Contains(variant, strings.ToLower(raw)) {
raw = variant
break
}
}
}
suggesters := []func() time.Time{
func() time.Time {
var exprType naturaldate.ExprType
t, exprType, err := naturaldate.Parse(raw, now)
t, exprType, err := naturaldate.Parse(raw, now, naturaldate.WithDirection(naturaldate.Future))
if err != nil {
return time.Time{}
}

View file

@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"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/dateutil"
@ -34,6 +33,22 @@ func Test_suggestDateForSearch(t *testing.T) {
raw: "today",
want: time.Date(2022, 5, 18, 0, 0, 0, 0, loc),
},
{
raw: "toda",
want: time.Date(2022, 5, 18, 0, 0, 0, 0, loc),
},
{
raw: "to",
want: time.Date(2022, 5, 18, 0, 0, 0, 0, loc),
},
{
raw: "yeste",
want: time.Date(2022, 5, 17, 0, 0, 0, 0, loc),
},
{
raw: "NoVem",
want: time.Date(2022, 11, 18, 14, 56, 33, 0, loc),
},
{
raw: "10 days from now",
want: time.Date(2022, 5, 28, 14, 56, 33, 0, loc),
@ -76,16 +91,14 @@ func TestSuggestDateObjectIdsFromFilter(t *testing.T) {
// given
dateObject1 := dateutil.NewDateObject(time.Now(), false)
dateObject2 := dateutil.NewDateObject(time.Now().Add(2*time.Hour), true)
req := &pb.RpcObjectSearchRequest{
Filters: []*model.BlockContentDataviewFilter{{
RelationKey: bundle.RelationKeyId.String(),
Condition: model.BlockContentDataviewFilter_In,
Value: pbtypes.StringList([]string{dateObject1.Id(), "plainObj1", "planObj2", dateObject2.Id()}),
}},
}
filters := []*model.BlockContentDataviewFilter{{
RelationKey: bundle.RelationKeyId.String(),
Condition: model.BlockContentDataviewFilter_In,
Value: pbtypes.StringList([]string{dateObject1.Id(), "plainObj1", "planObj2", dateObject2.Id()}),
}}
// when
ids := suggestDateObjectIds(req)
ids := suggestDateObjectIds("", filters)
// then
require.Len(t, ids, 2)

View file

@ -166,10 +166,7 @@ type objectArchiver interface {
}
func (s *service) deleteMigratedFilesInNonPersonalSpaces(ctx context.Context) error {
personalSpace, err := s.spaceService.GetPersonalSpace(ctx)
if err != nil {
return err
}
personalSpaceId := s.spaceService.PersonalSpaceId()
records, err := s.objectStore.QueryCrossSpace(database.Query{
Filters: []*model.BlockContentDataviewFilter{
@ -184,7 +181,7 @@ func (s *service) deleteMigratedFilesInNonPersonalSpaces(ctx context.Context) er
{
RelationKey: bundle.RelationKeySpaceId.String(),
Condition: model.BlockContentDataviewFilter_NotEqual,
Value: pbtypes.String(personalSpace.Id()),
Value: pbtypes.String(personalSpaceId),
},
},
})

View file

@ -97,6 +97,7 @@ func newFixture(t *testing.T) *fixture {
fileService := files.New()
spaceService := mock_space.NewMockService(t)
spaceService.EXPECT().GetPersonalSpace(mock.Anything).Return(nil, fmt.Errorf("not needed")).Maybe()
spaceService.EXPECT().PersonalSpaceId().Return("personalSpaceId").Maybe()
spaceIdResolver := mock_idresolver.NewMockResolver(t)
svc := New(testResolveRetryDelay, testResolveRetryDelay)

View file

@ -3,6 +3,7 @@ package history
import (
"context"
"encoding/hex"
"errors"
"fmt"
"slices"
"strings"
@ -20,6 +21,7 @@ import (
smartblock2 "github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/block/editor/state"
history2 "github.com/anyproto/anytype-heart/core/block/history"
"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/simple"
"github.com/anyproto/anytype-heart/core/block/source"
@ -27,11 +29,11 @@ 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"
"github.com/anyproto/anytype-heart/pkg/lib/logging"
"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/pbtypes"
)
@ -64,6 +66,7 @@ type history struct {
picker cache.ObjectGetter
objectStore objectstore.ObjectStore
spaceService space.Service
resolver idresolver.Resolver
heads map[string]string
}
@ -71,6 +74,7 @@ func (h *history) Init(a *app.App) (err error) {
h.picker = app.MustComponent[cache.ObjectGetter](a)
h.objectStore = a.MustComponent(objectstore.CName).(objectstore.ObjectStore)
h.spaceService = app.MustComponent[space.Service](a)
h.resolver = app.MustComponent[idresolver.Resolver](a)
return
}
@ -87,6 +91,7 @@ func (h *history) Show(id domain.FullID, versionID string) (bs *model.ObjectView
if err != nil {
return
}
s.SetDetailAndBundledRelation(bundle.RelationKeyId, pbtypes.String(id.ObjectID))
s.SetDetailAndBundledRelation(bundle.RelationKeySpaceId, pbtypes.String(id.SpaceID))
typeId, err := space.GetTypeIdByKey(context.Background(), s.ObjectTypeKey())
@ -95,32 +100,21 @@ func (h *history) Show(id domain.FullID, versionID string) (bs *model.ObjectView
}
s.SetDetailAndBundledRelation(bundle.RelationKeyType, pbtypes.String(typeId))
dependentObjectIDs := objectlink.DependentObjectIDs(s, space, objectlink.Flags{
Blocks: true,
Details: true,
Relations: false,
Types: true,
})
// nolint:errcheck
meta, _ := h.objectStore.QueryByIdCrossSpace(dependentObjectIDs)
meta = append(meta, database.Record{Details: s.CombinedDetails()})
details := make([]*model.ObjectViewDetailsSet, 0, len(meta))
for _, m := range meta {
details = append(details, &model.ObjectViewDetailsSet{
Id: pbtypes.GetString(m.Details, bundle.RelationKeyId.String()),
Details: m.Details,
})
details, err := h.buildDetails(s, space)
if err != nil {
log.With("error", err).Errorf("failed to collect details of dependent objects")
}
relations, err := h.objectStore.SpaceIndex(id.SpaceID).FetchRelationByLinks(s.PickRelationLinks())
if err != nil {
return nil, nil, fmt.Errorf("fetch relations by links: %w", err)
}
blocksParticipants, err := h.GetBlocksParticipants(id, versionID, s.Blocks())
if err != nil {
return nil, nil, fmt.Errorf("get blocks modifiers: %w", err)
}
return &model.ObjectView{
RootId: id.ObjectID,
Type: model.SmartBlockType(sbType),
@ -257,25 +251,12 @@ func (h *history) DiffVersions(req *pb.RpcHistoryDiffVersionsRequest) ([]*pb.Eve
if err != nil {
return nil, nil, fmt.Errorf("get space: %w", err)
}
dependentObjectIDs := objectlink.DependentObjectIDs(currState, spc, objectlink.Flags{
Blocks: true,
Details: true,
Relations: false,
Types: true,
})
meta, err := h.objectStore.QueryByIdCrossSpace(dependentObjectIDs)
details, err := h.buildDetails(currState, spc)
if err != nil {
return nil, nil, fmt.Errorf("get dependencies: %w", err)
return nil, nil, fmt.Errorf("get details: %w", err)
}
meta = append(meta, database.Record{Details: currState.CombinedDetails()})
details := make([]*model.ObjectViewDetailsSet, 0, len(meta))
for _, m := range meta {
details = append(details, &model.ObjectViewDetailsSet{
Id: pbtypes.GetString(m.Details, bundle.RelationKeyId.String()),
Details: m.Details,
})
}
objectView := &model.ObjectView{
RootId: id.ObjectID,
Type: model.SmartBlockType(sbType),
@ -286,6 +267,40 @@ func (h *history) DiffVersions(req *pb.RpcHistoryDiffVersionsRequest) ([]*pb.Eve
return historyEvents, objectView, nil
}
func (h *history) buildDetails(s *state.State, spc clientspace.Space) (details []*model.ObjectViewDetailsSet, resultErr error) {
rootDetails := s.CombinedDetails()
details = []*model.ObjectViewDetailsSet{{
Id: pbtypes.GetString(rootDetails, bundle.RelationKeyId.String()),
Details: rootDetails,
}}
dependentObjectIds := objectlink.DependentObjectIDsPerSpace(spc.Id(), s, spc, h.resolver, objectlink.Flags{
Blocks: true,
Details: true,
Relations: false,
Types: true,
})
for spaceId, perSpaceDepIds := range dependentObjectIds {
spaceIndex := h.objectStore.SpaceIndex(spaceId)
records, err := spaceIndex.QueryByIds(perSpaceDepIds)
if err != nil {
resultErr = errors.Join(resultErr, fmt.Errorf("failed to query dependencies for space %s: %w", spaceId, err))
continue
}
for _, record := range records {
details = append(details, &model.ObjectViewDetailsSet{
Id: pbtypes.GetString(record.Details, bundle.RelationKeyId.String()),
Details: record.Details,
})
}
}
return details, resultErr
}
func filterHistoryEvents(msg []simple.EventMessage) []*pb.EventMessage {
var response []*pb.EventMessage
for _, message := range msg {

View file

@ -14,8 +14,10 @@ import (
"github.com/anyproto/any-sync/util/crypto"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"go.uber.org/mock/gomock"
"github.com/anyproto/anytype-heart/core/block/object/idresolver/mock_idresolver"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
@ -1132,6 +1134,8 @@ func newFixtureDiffVersions(t *testing.T,
space := mock_clientspace.NewMockSpace(t)
ctrl := gomock.NewController(t)
treeBuilder := mock_objecttreebuilder.NewMockTreeBuilder(ctrl)
resolver := mock_idresolver.NewMockResolver(t)
resolver.EXPECT().ResolveSpaceID(mock.Anything).Return(spaceID, nil).Maybe()
if len(currChanges) > 0 {
configureTreeBuilder(treeBuilder, objectId, currVersionId, spaceID, currChanges, space, spaceService)
}
@ -1142,6 +1146,7 @@ func newFixtureDiffVersions(t *testing.T,
objectStore: objectstore.NewStoreFixture(t),
spaceService: spaceService,
heads: map[string]string{},
resolver: resolver,
}
return &historyFixture{
history: history,
@ -1164,6 +1169,7 @@ func configureTreeBuilder(treeBuilder *mock_objecttreebuilder.MockTreeBuilder,
changes: expectedChanges,
}, nil)
space.EXPECT().TreeBuilder().Return(treeBuilder)
space.EXPECT().Id().Return(spaceID).Maybe()
spaceService.EXPECT().Get(context.Background(), spaceID).Return(space, nil)
}

View file

@ -319,6 +319,7 @@ func TestReindex_addSyncRelations(t *testing.T) {
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeProfilePage).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatDerivedObject).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatObject).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeSpaceView).Return(idsLister{Ids: []string{}}, nil)
space1.EXPECT().DoLockedIfNotExists("1", mock.AnythingOfType("func() error")).Return(nil)
space1.EXPECT().DoLockedIfNotExists("2", mock.AnythingOfType("func() error")).Return(nil)
@ -358,6 +359,7 @@ func TestReindex_addSyncRelations(t *testing.T) {
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeProfilePage).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatDerivedObject).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeChatObject).Return(idsLister{Ids: []string{}}, nil)
fx.sourceFx.EXPECT().IDsListerBySmartblockType(space1, coresb.SmartBlockTypeSpaceView).Return(idsLister{Ids: []string{}}, nil)
space1.EXPECT().DoLockedIfNotExists("1", mock.AnythingOfType("func() error")).Return(nil)
space1.EXPECT().DoLockedIfNotExists("2", mock.AnythingOfType("func() error")).Return(nil)

View file

@ -102,7 +102,7 @@ func (mw *Middleware) ObjectSearch(cctx context.Context, req *pb.RpcObjectSearch
// Add dates only to the first page of search results
if req.Offset == 0 {
records, err = date.EnrichRecordsWithDateSuggestions(cctx, records, req, ds, getService[space.Service](mw))
records, err = date.EnrichRecordsWithDateSuggestions(cctx, req.SpaceId, req.FullText, records, req.Filters, ds, getService[space.Service](mw))
if err != nil {
return response(pb.RpcObjectSearchResponseError_UNKNOWN_ERROR, nil, err)
}
@ -144,6 +144,14 @@ func (mw *Middleware) ObjectSearchWithMeta(cctx context.Context, req *pb.RpcObje
SpaceId: req.SpaceId,
})
// Add dates only to the first page of search results
if req.Offset == 0 {
results, err = date.EnrichRecordsWithDateSuggestions(cctx, req.SpaceId, req.FullText, results, req.Filters, ds, getService[space.Service](mw))
if err != nil {
return response(pb.RpcObjectSearchWithMetaResponseError_UNKNOWN_ERROR, nil, err)
}
}
var resultsModels = make([]*model.SearchResult, 0, len(results))
for i, rec := range results {
if len(req.Keys) > 0 {

View file

@ -29,7 +29,7 @@ import (
const CName = "payments"
var log = logging.Logger(CName).Desugar()
var log = logging.Logger(CName)
const (
refreshIntervalSecs = 60
@ -150,7 +150,7 @@ func (s *service) Init(a *app.App) (err error) {
s.wallet = app.MustComponent[wallet.Wallet](a)
s.ns = app.MustComponent[nameservice.Service](a)
s.eventSender = app.MustComponent[event.Sender](a)
s.periodicGetStatus = periodicsync.NewPeriodicSync(refreshIntervalSecs, timeout, s.getPeriodicStatus, logger.CtxLogger{Logger: log})
s.periodicGetStatus = periodicsync.NewPeriodicSync(refreshIntervalSecs, timeout, s.getPeriodicStatus, logger.CtxLogger{Logger: log.Desugar()})
s.profileUpdater = app.MustComponent[globalNamesUpdater](a)
s.multiplayerLimitsUpdater = app.MustComponent[deletioncontroller.DeletionController](a)
s.fileLimitsUpdater = app.MustComponent[filesync.FileSync](a)

View file

@ -4,12 +4,14 @@ import (
"context"
"fmt"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/util/crypto"
"github.com/ipfs/go-cid"
"github.com/anyproto/anytype-heart/core/acl"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/core/inviteservice"
"github.com/anyproto/anytype-heart/core/spaceview"
"github.com/anyproto/anytype-heart/pb"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/space"
@ -315,6 +317,38 @@ func (mw *Middleware) SpaceLeaveApprove(cctx context.Context, req *pb.RpcSpaceLe
}
}
func (mw *Middleware) SpaceSetOrder(_ context.Context, request *pb.RpcSpaceSetOrderRequest) *pb.RpcSpaceSetOrderResponse {
response := func(code pb.RpcSpaceSetOrderResponseErrorCode, err error) *pb.RpcSpaceSetOrderResponse {
m := &pb.RpcSpaceSetOrderResponse{Error: &pb.RpcSpaceSetOrderResponseError{Code: code}}
if err != nil {
m.Error.Description = getErrorDescription(err)
}
return m
}
orderService := app.MustComponent[spaceview.OrderSetter](mw.applicationService.GetApp())
err := orderService.SetOrder(request.SpaceViewId, request.GetSpaceViewOrder())
if err != nil {
return response(pb.RpcSpaceSetOrderResponseError_UNKNOWN_ERROR, err)
}
return response(pb.RpcSpaceSetOrderResponseError_NULL, nil)
}
func (mw *Middleware) SpaceUnsetOrder(_ context.Context, request *pb.RpcSpaceUnsetOrderRequest) *pb.RpcSpaceUnsetOrderResponse {
response := func(code pb.RpcSpaceUnsetOrderResponseErrorCode, err error) *pb.RpcSpaceUnsetOrderResponse {
m := &pb.RpcSpaceUnsetOrderResponse{Error: &pb.RpcSpaceUnsetOrderResponseError{Code: code}}
if err != nil {
m.Error.Description = getErrorDescription(err)
}
return m
}
orderService := app.MustComponent[spaceview.OrderSetter](mw.applicationService.GetApp())
err := orderService.UnsetOrder(request.SpaceViewId)
if err != nil {
return response(pb.RpcSpaceUnsetOrderResponseError_UNKNOWN_ERROR, err)
}
return response(pb.RpcSpaceUnsetOrderResponseError_NULL, nil)
}
func join(ctx context.Context, aclService acl.AclService, req *pb.RpcSpaceJoinRequest) (err error) {
inviteFileKey, err := encode.DecodeKeyFromBase58(req.InviteFileKey)
if err != nil {

174
core/spaceview/order.go Normal file
View file

@ -0,0 +1,174 @@
package spaceview
import (
"fmt"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/anytype-heart/core/block/cache"
"github.com/anyproto/anytype-heart/core/block/editor"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
const CName = "core.spaceview.ordersetter"
type OrderSetter interface {
SetOrder(spaceViewId string, spaceViewOrder []string) error
UnsetOrder(spaceViewId string) error
app.Component
}
type orderSetter struct {
objectGetter cache.ObjectGetter
}
func New() OrderSetter {
return &orderSetter{}
}
func (o *orderSetter) Init(a *app.App) (err error) {
o.objectGetter = app.MustComponent[cache.ObjectGetter](a)
return
}
func (o *orderSetter) Name() (name string) {
return CName
}
func (o *orderSetter) SetOrder(spaceViewId string, spaceViewOrder []string) error {
if len(spaceViewOrder) < 1 {
return fmt.Errorf("insufficient space views for reordering")
}
if len(spaceViewOrder) == 1 {
return o.setInitOrder(spaceViewId)
}
// given space view is the first view in the order
if spaceViewOrder[0] == spaceViewId {
return o.setViewAtBeginning(spaceViewId, spaceViewOrder[1])
}
// given space view is the last view in the order
if spaceViewOrder[len(spaceViewOrder)-1] == spaceViewId {
return o.setViewAtEnd(spaceViewOrder, spaceViewId, spaceViewOrder[len(spaceViewOrder)-2])
}
return o.setBetween(spaceViewOrder, spaceViewId)
}
func (o *orderSetter) setInitOrder(spaceViewId string) error {
return cache.Do[*editor.SpaceView](o.objectGetter, spaceViewId, func(sv *editor.SpaceView) error {
_, err := sv.SetOrder("")
return err
})
}
func (o *orderSetter) UnsetOrder(spaceViewId string) error {
return cache.Do(o.objectGetter, spaceViewId, func(sb smartblock.SmartBlock) error {
state := sb.NewState()
state.RemoveDetail(bundle.RelationKeySpaceOrder.String())
return sb.Apply(state)
})
}
func (o *orderSetter) setViewAtBeginning(spaceViewId, afterViewId string) error {
var (
nextOrderID string
err error
)
err = cache.Do[*editor.SpaceView](o.objectGetter, afterViewId, func(sv *editor.SpaceView) error {
nextOrderID = pbtypes.GetString(sv.Details(), bundle.RelationKeySpaceOrder.String())
return nil
})
if err != nil {
return err
}
return cache.Do[*editor.SpaceView](o.objectGetter, spaceViewId, func(view *editor.SpaceView) error {
if nextOrderID == "" {
_, err = view.SetOrder("")
return err
}
return view.SetBetweenViews("", nextOrderID)
})
}
func (o *orderSetter) setViewAtEnd(order []string, spaceViewId, afterSpaceView string) error {
var lastOrderId string
// get the order for the previous view in the list.
cacheErr := cache.Do[*editor.SpaceView](o.objectGetter, afterSpaceView, func(sv *editor.SpaceView) error {
lastOrderId = pbtypes.GetString(sv.Details(), bundle.RelationKeySpaceOrder.String())
return nil
})
if cacheErr != nil {
return cacheErr
}
// if view doesn't have order in details, then set it for all previous ids
if lastOrderId == "" {
return o.setOrderForPreviousViews(order, spaceViewId)
}
return cache.Do[*editor.SpaceView](o.objectGetter, spaceViewId, func(sv *editor.SpaceView) error {
return sv.SetAfterGivenView(lastOrderId)
})
}
func (o *orderSetter) setBetween(order []string, spaceViewId string) error {
prevViewId, nextViewId := o.findNeighborViews(order, spaceViewId)
var prevOrderId, nextOrderId string
cacheErr := cache.Do[*editor.SpaceView](o.objectGetter, prevViewId, func(sv *editor.SpaceView) error {
prevOrderId = pbtypes.GetString(sv.Details(), bundle.RelationKeySpaceOrder.String())
return nil
})
if cacheErr != nil {
return cacheErr
}
if prevOrderId == "" {
return o.setOrderForPreviousViews(order, spaceViewId)
}
cacheErr = cache.Do[*editor.SpaceView](o.objectGetter, nextViewId, func(sv *editor.SpaceView) error {
nextOrderId = pbtypes.GetString(sv.Details(), bundle.RelationKeySpaceOrder.String())
return nil
})
if cacheErr != nil {
return cacheErr
}
return cache.Do[*editor.SpaceView](o.objectGetter, spaceViewId, func(view *editor.SpaceView) error {
if nextOrderId == "" {
return view.SetAfterGivenView(prevOrderId)
}
return view.SetBetweenViews(prevOrderId, nextOrderId)
})
}
func (o *orderSetter) findNeighborViews(order []string, spaceViewId string) (string, string) {
var prevViewId, nextViewId string
for i, id := range order {
if id == spaceViewId {
prevViewId = order[i-1]
nextViewId = order[i+1]
break
}
}
return prevViewId, nextViewId
}
func (o *orderSetter) setOrderForPreviousViews(order []string, spaceViewId string) error {
var (
prevOrderId string
err error
)
for _, id := range order {
cacheErr := cache.Do[*editor.SpaceView](o.objectGetter, id, func(sv *editor.SpaceView) error {
prevOrderId, err = sv.SetOrder(prevOrderId)
if err != nil {
return err
}
return nil
})
if cacheErr != nil {
return cacheErr
}
if id == spaceViewId {
break
}
}
return nil
}

View file

@ -0,0 +1,233 @@
package spaceview
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/anyproto/anytype-heart/core/block/cache/mock_cache"
"github.com/anyproto/anytype-heart/core/block/editor"
"github.com/anyproto/anytype-heart/core/block/editor/smartblock/smarttest"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
"github.com/anyproto/anytype-heart/util/pbtypes"
)
func TestOrderSetter_SetSpaceViewOrder(t *testing.T) {
t.Run("insufficient view", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
o := &orderSetter{objectGetter: objGetter}
// when
err := o.SetOrder("view1", []string{})
// then
assert.NotNil(t, err)
assert.Equal(t, "insufficient space views for reordering", err.Error())
})
t.Run("single view is pinned", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err := o.SetOrder("view1", []string{"view1"})
// then
assert.Nil(t, err)
assert.NotEmpty(t, pbtypes.Get(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String()))
})
t.Run("move view at the beginning", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
objGetter.EXPECT().GetObject(context.Background(), "view2").Return(mockSpaceView2, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err := o.SetOrder("view1", []string{"view1", "view2"})
// then
assert.Nil(t, err)
assert.NotEmpty(t, pbtypes.Get(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String()))
})
t.Run("move view at the beginning, order exists", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
view2Order, err := mockSpaceView2.SetOrder("")
assert.Nil(t, err)
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
objGetter.EXPECT().GetObject(context.Background(), "view2").Return(mockSpaceView2, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err = o.SetOrder("view1", []string{"view1", "view2", "view3"})
// then
assert.Nil(t, err)
assert.NotEmpty(t, pbtypes.Get(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String()))
view1Order := pbtypes.GetString(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String())
assert.True(t, view1Order < view2Order)
})
t.Run("move view at the end", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
mockSpaceView3 := &editor.SpaceView{SmartBlock: smarttest.New("view3")}
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
objGetter.EXPECT().GetObject(context.Background(), "view2").Return(mockSpaceView2, nil)
objGetter.EXPECT().GetObject(context.Background(), "view3").Return(mockSpaceView3, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err := o.SetOrder("view3", []string{"view1", "view2", "view3"})
// then
assert.Nil(t, err)
assert.NotNil(t, pbtypes.Get(mockSpaceView3.Details(), bundle.RelationKeySpaceOrder.String()))
view1Order := pbtypes.GetString(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String())
view2Order := pbtypes.GetString(mockSpaceView2.Details(), bundle.RelationKeySpaceOrder.String())
view3Order := pbtypes.GetString(mockSpaceView3.Details(), bundle.RelationKeySpaceOrder.String())
assert.True(t, view1Order < view2Order)
assert.True(t, view2Order < view3Order)
})
t.Run("move view at the end, order exists", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
mockSpaceView3 := &editor.SpaceView{SmartBlock: smarttest.New("view3")}
view1Order, err := mockSpaceView.SetOrder("")
view2Order, err := mockSpaceView2.SetOrder(view1Order)
assert.Nil(t, err)
objGetter.EXPECT().GetObject(context.Background(), "view2").Return(mockSpaceView2, nil)
objGetter.EXPECT().GetObject(context.Background(), "view3").Return(mockSpaceView3, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err = o.SetOrder("view3", []string{"view1", "view2", "view3"})
// then
assert.Nil(t, err)
view3Order := pbtypes.GetString(mockSpaceView3.Details(), bundle.RelationKeySpaceOrder.String())
assert.True(t, view2Order < view3Order)
})
t.Run("set view between: no order", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
mockSpaceView3 := &editor.SpaceView{SmartBlock: smarttest.New("view3")}
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
objGetter.EXPECT().GetObject(context.Background(), "view3").Return(mockSpaceView3, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err := o.SetOrder("view3", []string{"view1", "view3", "view2"})
// then
assert.Nil(t, err)
view1Order := pbtypes.GetString(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String())
view2Order := pbtypes.GetString(mockSpaceView2.Details(), bundle.RelationKeySpaceOrder.String())
view3Order := pbtypes.GetString(mockSpaceView3.Details(), bundle.RelationKeySpaceOrder.String())
assert.True(t, view1Order < view3Order)
assert.Empty(t, view2Order)
})
t.Run("set view between: next view doesn't have order", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
mockSpaceView3 := &editor.SpaceView{SmartBlock: smarttest.New("view3")}
view1Order, err := mockSpaceView.SetOrder("")
assert.Nil(t, err)
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
objGetter.EXPECT().GetObject(context.Background(), "view2").Return(mockSpaceView2, nil)
objGetter.EXPECT().GetObject(context.Background(), "view3").Return(mockSpaceView3, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err = o.SetOrder("view3", []string{"view1", "view3", "view2"})
// then
assert.Nil(t, err)
view3Order := pbtypes.GetString(mockSpaceView3.Details(), bundle.RelationKeySpaceOrder.String())
view2Order := pbtypes.GetString(mockSpaceView2.Details(), bundle.RelationKeySpaceOrder.String())
assert.True(t, view1Order < view3Order)
assert.Empty(t, view2Order)
})
t.Run("set view between: order exists", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
mockSpaceView2 := &editor.SpaceView{SmartBlock: smarttest.New("view2")}
mockSpaceView3 := &editor.SpaceView{SmartBlock: smarttest.New("view3")}
view1Order, err := mockSpaceView.SetOrder("")
view2Order, err := mockSpaceView2.SetOrder(view1Order)
assert.Nil(t, err)
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
objGetter.EXPECT().GetObject(context.Background(), "view2").Return(mockSpaceView2, nil)
objGetter.EXPECT().GetObject(context.Background(), "view3").Return(mockSpaceView3, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err = o.SetOrder("view3", []string{"view1", "view3", "view2"})
// then
assert.Nil(t, err)
view3Order := pbtypes.GetString(mockSpaceView3.Details(), bundle.RelationKeySpaceOrder.String())
assert.True(t, view1Order < view3Order)
assert.True(t, view3Order < view2Order)
})
}
func TestOrderSetter_UnsetOrder(t *testing.T) {
t.Run("unset order", func(t *testing.T) {
// given
objGetter := mock_cache.NewMockObjectGetter(t)
mockSpaceView := &editor.SpaceView{SmartBlock: smarttest.New("view1")}
view1Order, err := mockSpaceView.SetOrder("")
assert.Nil(t, err)
objGetter.EXPECT().GetObject(context.Background(), "view1").Return(mockSpaceView, nil)
o := &orderSetter{objectGetter: objGetter}
// when
err = o.UnsetOrder("view1")
// then
assert.Nil(t, err)
view1Order = pbtypes.GetString(mockSpaceView.Details(), bundle.RelationKeySpaceOrder.String())
assert.Empty(t, view1Order)
})
}

View file

@ -1,6 +1,8 @@
package subscription
import (
"maps"
"github.com/gogo/protobuf/types"
"github.com/anyproto/anytype-heart/util/slice"
@ -17,62 +19,72 @@ type entry struct {
data *types.Struct
subIds []string
subIsActive []bool
subFullDetailsSent []bool
subIsActive map[string]bool
subFullDetailsSent map[string]bool
}
func newEntry(id string, data *types.Struct) *entry {
return &entry{id: id, data: data, subIsActive: make(map[string]bool), subFullDetailsSent: make(map[string]bool)}
}
func (e *entry) Copy() *entry {
newSubIds := make([]string, len(e.subIds))
copy(newSubIds, e.subIds)
newSubIsActive := make(map[string]bool, len(e.subIsActive))
maps.Copy(newSubIsActive, e.subIsActive)
newSubFullDetailsSent := make(map[string]bool, len(e.subIsActive))
maps.Copy(newSubFullDetailsSent, e.subFullDetailsSent)
return &entry{
id: e.id,
data: e.data,
subIds: newSubIds,
subIsActive: newSubIsActive,
subFullDetailsSent: newSubFullDetailsSent,
}
}
// SetSub marks provided subscription for the entry as active (within the current pagination window) or inactive
func (e *entry) SetSub(subId string, isActive bool, isFullDetailSent bool) {
if pos := slice.FindPos(e.subIds, subId); pos == -1 {
e.subIds = append(e.subIds, subId)
e.subIsActive = append(e.subIsActive, isActive)
e.subFullDetailsSent = append(e.subFullDetailsSent, isFullDetailSent)
e.subIsActive[subId] = isActive
e.subFullDetailsSent[subId] = isFullDetailSent
} else {
e.subIsActive[pos] = isActive
e.subFullDetailsSent[pos] = isFullDetailSent
e.subIsActive[subId] = isActive
// Don't override existing value, because if the event was already sent for the subscription during session, it should not be sent again
if !e.subFullDetailsSent[subId] {
e.subFullDetailsSent[subId] = isFullDetailSent
}
}
}
// IsActive indicates that entry is inside the current pagination window for all of provided subscription IDs
func (e *entry) IsActive(subIds ...string) bool {
if len(subIds) == 0 {
return false
}
for _, id := range subIds {
if pos := slice.FindPos(e.subIds, id); pos != -1 {
if !e.subIsActive[pos] {
return false
}
} else {
return false
// GetActive returns all active subscriptions for entry
func (e *entry) GetActive() []string {
var subIsActive []string
for id, active := range e.subIsActive {
if active {
subIsActive = append(subIsActive, id)
}
}
return true
return subIsActive
}
// IsFullDetailsSent that in the context of ALL provided subscriptions we have previously sent the full ObjectSetDetails event
// if true this means that we can send incremental diff updates
func (e *entry) IsFullDetailsSent(subIds ...string) bool {
if len(subIds) == 0 {
return false
}
for _, id := range subIds {
if pos := slice.FindPos(e.subIds, id); pos != -1 {
if !e.subFullDetailsSent[pos] {
return false
}
} else {
return false
// GetFullDetailsSent returns all subscriptions for entry, for which full details are already sent
func (e *entry) GetFullDetailsSent() []string {
var detailsSent []string
for id, isFullDetailsSent := range e.subFullDetailsSent {
if isFullDetailsSent {
detailsSent = append(detailsSent, id)
}
}
return true
return detailsSent
}
func (e *entry) RemoveSubId(subId string) {
if pos := slice.FindPos(e.subIds, subId); pos != -1 {
e.subIds = slice.RemoveMut(e.subIds, subId)
e.subIsActive = append(e.subIsActive[:pos], e.subIsActive[pos+1:]...)
e.subFullDetailsSent = append(e.subFullDetailsSent[:pos], e.subFullDetailsSent[pos+1:]...)
delete(e.subIsActive, subId)
delete(e.subFullDetailsSent, subId)
}
}

View file

@ -3,27 +3,28 @@ package subscription
import (
"testing"
"github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
)
func TestEntry_SubIds(t *testing.T) {
e := &entry{}
e := newEntry("id", &types.Struct{})
e.SetSub("1", true, false)
assert.Len(t, e.SubIds(), 1)
e.SetSub("2", false, false)
assert.Len(t, e.SubIds(), 2)
e.SetSub("2", false, false)
assert.Len(t, e.SubIds(), 2)
assert.True(t, e.IsActive("1"))
assert.False(t, e.IsActive("1", "2"))
assert.Contains(t, e.GetActive(), "1")
assert.NotContains(t, e.GetActive(), []string{"1", "2"})
e.RemoveSubId("1")
assert.Len(t, e.SubIds(), 1)
e.SetSub("2", true, true)
e.SetSub("3", true, false)
assert.False(t, e.IsFullDetailsSent("2", "3"))
assert.True(t, e.IsFullDetailsSent("2"))
assert.Contains(t, e.GetFullDetailsSent(), "2")
assert.NotContains(t, e.GetFullDetailsSent(), "3")
e.SetSub("3", true, true)
assert.True(t, e.IsFullDetailsSent("2", "3"))
assert.NotContains(t, e.GetFullDetailsSent(), []string{"2", "3"})
}

View file

@ -246,10 +246,7 @@ func (s *spaceSubscriptions) fetchEntries(ids []string) []*entry {
log.Error("can't query by ids:", err)
}
for _, r := range recs {
e := &entry{
id: pbtypes.GetString(r.Details, bundle.RelationKeyId.String()),
data: r.Details,
}
e := newEntry(pbtypes.GetString(r.Details, bundle.RelationKeyId.String()), r.Details)
res = append(res, e)
}
return res

View file

@ -1,7 +1,7 @@
package subscription
import (
"github.com/gogo/protobuf/types"
"github.com/samber/lo"
"github.com/anyproto/anytype-heart/core/block/editor/state"
"github.com/anyproto/anytype-heart/pb"
@ -177,22 +177,7 @@ func (ctx *opCtx) detailsEvents() {
continue
}
prev := ctx.c.Get(info.id)
var prevData *types.Struct
if prev != nil && prev.IsActive(info.subIds...) && prev.IsFullDetailsSent(info.subIds...) {
prevData = prev.data
diff := pbtypes.StructDiff(prevData, curr.data)
msgs = append(msgs, state.StructDiffIntoEventsWithSubIds(info.id, diff, info.keys, info.subIds)...)
} else {
msgs = append(msgs, &pb.EventMessage{
Value: &pb.EventMessageValueOfObjectDetailsSet{
ObjectDetailsSet: &pb.EventObjectDetailsSet{
Id: curr.id,
Details: pbtypes.StructFilterKeys(curr.data, info.keys),
SubIds: info.subIds,
},
},
})
}
msgs = ctx.addDetailsEvents(prev, curr, info, msgs)
// save info for every sub because we don't want to send the details events again
for _, sub := range info.subIds {
curr.SetSub(sub, true, true)
@ -202,6 +187,44 @@ func (ctx *opCtx) detailsEvents() {
ctx.groupDetailsEvents(msgs)
}
func (ctx *opCtx) addDetailsEvents(prev, curr *entry, info struct {
id string
subIds []string
keys []string
}, msgs []*pb.EventMessage) []*pb.EventMessage {
var subIdsToSendAmendDetails, subIdsToSendSetDetails []string
if prev != nil {
active := prev.GetActive()
detailsSent := prev.GetFullDetailsSent()
subIdsToSendAmendDetails = lo.Intersect(active, detailsSent)
subIdsToSendSetDetails = slice.Difference(info.subIds, subIdsToSendAmendDetails)
if len(subIdsToSendAmendDetails) != 0 {
diff := pbtypes.StructDiff(prev.data, curr.data)
msgs = append(msgs, state.StructDiffIntoEventsWithSubIds(info.id, diff, info.keys, subIdsToSendAmendDetails)...)
}
if len(subIdsToSendSetDetails) != 0 {
msgs = ctx.appendObjectDetailsSetMessage(msgs, curr, subIdsToSendSetDetails, info.keys)
}
} else {
msgs = ctx.appendObjectDetailsSetMessage(msgs, curr, info.subIds, info.keys)
}
return msgs
}
func (ctx *opCtx) appendObjectDetailsSetMessage(msgs []*pb.EventMessage, curr *entry, subIds, keys []string) []*pb.EventMessage {
msgs = append(msgs, &pb.EventMessage{
Value: &pb.EventMessageValueOfObjectDetailsSet{
ObjectDetailsSet: &pb.EventObjectDetailsSet{
Id: curr.id,
Details: pbtypes.StructFilterKeys(curr.data, keys),
SubIds: subIds,
},
},
})
return msgs
}
func (ctx *opCtx) groupDetailsEvents(msgs []*pb.EventMessage) {
for _, msg := range msgs {
if v := msg.GetObjectDetailsAmend(); v != nil {

View file

@ -25,15 +25,15 @@ type dependencyService struct {
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}, spaceId, ds.depIdsByEntries(activeEntries, depKeys, depSub.forceIds))
depEntries := ds.depEntriesByEntries(&opCtx{entries: allEntries}, ds.depIdsByEntries(activeEntries, depKeys, depSub.forceIds))
depSub.init(depEntries)
return depSub
}
func (ds *dependencyService) refillSubscription(spaceId string, ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []string) {
func (ds *dependencyService) refillSubscription(ctx *opCtx, sub *simpleSub, entries []*entry, depKeys []string) {
depIds := ds.depIdsByEntries(entries, depKeys, sub.forceIds)
if !sub.isEqualIds(depIds) {
depEntries := ds.depEntriesByEntries(ctx, spaceId, depIds)
depEntries := ds.depEntriesByEntries(ctx, 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, spaceId string, depIds []string) (depEntries []*entry) {
func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, depIds []string) (depEntries []*entry) {
if len(depIds) == 0 {
return
}
@ -64,19 +64,7 @@ func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, spaceId string, dep
// priority: ctx.entries, cache, objectStore
if e = ctx.getEntry(id); e == nil {
if e = ds.s.cache.Get(id); e != nil {
newSubIds := make([]string, len(e.subIds))
newSubIsActive := make([]bool, len(e.subIsActive))
newSubFullDetailsSent := make([]bool, len(e.subFullDetailsSent))
copy(newSubIds, e.subIds)
copy(newSubIsActive, e.subIsActive)
copy(newSubFullDetailsSent, e.subFullDetailsSent)
e = &entry{
id: id,
data: e.data,
subIds: newSubIds,
subIsActive: newSubIsActive,
subFullDetailsSent: newSubFullDetailsSent,
}
e = e.Copy()
} else {
missIds = append(missIds, id)
}
@ -94,10 +82,7 @@ func (ds *dependencyService) depEntriesByEntries(ctx *opCtx, spaceId string, dep
log.Errorf("can't query by id: %v", err)
}
for _, r := range records {
e := &entry{
id: pbtypes.GetString(r.Details, "id"),
data: r.Details,
}
e := newEntry(pbtypes.GetString(r.Details, "id"), r.Details)
ctx.entries = append(ctx.entries, e)
depEntries = append(depEntries, e)
}

View file

@ -24,15 +24,15 @@ func genTagEntries() []*entry {
makeTag("tag_2"),
makeTag("tag_3"),
{id: "record_one", data: &types.Struct{Fields: map[string]*types.Value{
newEntry("record_one", &types.Struct{Fields: map[string]*types.Value{
kanbanKey: pbtypes.StringList([]string{"tag_1"}),
}}},
{id: "record_two", data: &types.Struct{Fields: map[string]*types.Value{
}}),
newEntry("record_two", &types.Struct{Fields: map[string]*types.Value{
kanbanKey: pbtypes.StringList([]string{"tag_2"}),
}}},
{id: "record_three", data: &types.Struct{Fields: map[string]*types.Value{
}}),
newEntry("record_three", &types.Struct{Fields: map[string]*types.Value{
kanbanKey: pbtypes.StringList([]string{"tag_1", "tag_2", "tag_3"}),
}}},
}}),
}
}
@ -51,11 +51,11 @@ func tagEntriesToGroups(entries []*entry) []*model.BlockContentDataviewGroup {
}
func makeTag(key string) *entry {
return &entry{id: key, data: &types.Struct{Fields: map[string]*types.Value{
return newEntry(key, &types.Struct{Fields: map[string]*types.Value{
bundle.RelationKeyId.String(): pbtypes.String(key),
bundle.RelationKeyRelationKey.String(): pbtypes.String(kanbanKey),
bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeyRelationOption.URL()),
}}}
}})
}
func TestGroupTag(t *testing.T) {

View file

@ -175,6 +175,12 @@ func (s *service) Close(ctx context.Context) error {
}
func (s *service) Search(req SubscribeRequest) (resp *SubscribeResponse, err error) {
// todo: removed temp fix after we will have session-scoped subscriptions
// this is to prevent multiple subscriptions with the same id in different spaces
err = s.Unsubscribe(req.SubId)
if err != nil {
return nil, err
}
spaceSubs, err := s.getSpaceSubscriptions(req.SpaceId)
if err != nil {
return nil, err
@ -183,6 +189,12 @@ func (s *service) Search(req SubscribeRequest) (resp *SubscribeResponse, err err
}
func (s *service) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest) (resp *pb.RpcObjectSubscribeIdsResponse, err error) {
// todo: removed temp fix after we will have session-scoped subscriptions
// this is to prevent multiple subscriptions with the same id in different spaces
err = s.Unsubscribe(req.SubId)
if err != nil {
return nil, err
}
spaceSubs, err := s.getSpaceSubscriptions(req.SpaceId)
if err != nil {
return nil, err
@ -195,6 +207,12 @@ func (s *service) SubscribeIds(subId string, ids []string) (records []*types.Str
}
func (s *service) SubscribeGroups(req pb.RpcObjectGroupsSubscribeRequest) (*pb.RpcObjectGroupsSubscribeResponse, error) {
// todo: removed temp fix after we will have session-scoped subscriptions
// this is to prevent multiple subscriptions with the same id in different spaces
err := s.Unsubscribe(req.SubId)
if err != nil {
return nil, err
}
spaceSubs, err := s.getSpaceSubscriptions(req.SpaceId)
if err != nil {
return nil, err
@ -482,10 +500,7 @@ func queryEntries(objectStore spaceindex.Store, f *database.Filters) ([]*entry,
}
entries := make([]*entry, 0, len(records))
for _, r := range records {
entries = append(entries, &entry{
id: pbtypes.GetString(r.Details, "id"),
data: r.Details,
})
entries = append(entries, newEntry(pbtypes.GetString(r.Details, "id"), r.Details))
}
return entries, nil
}
@ -547,10 +562,7 @@ func (s *spaceSubscriptions) SubscribeIdsReq(req pb.RpcObjectSubscribeIdsRequest
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{
id: pbtypes.GetString(r.Details, "id"),
data: r.Details,
})
entries = append(entries, newEntry(pbtypes.GetString(r.Details, "id"), r.Details))
}
if err = sub.init(entries); err != nil {
return
@ -648,10 +660,7 @@ func (s *spaceSubscriptions) SubscribeGroups(req pb.RpcObjectGroupsSubscribeRequ
entries := make([]*entry, 0, len(tagGrouper.Records))
for _, r := range tagGrouper.Records {
entries = append(entries, &entry{
id: pbtypes.GetString(r.Details, "id"),
data: r.Details,
})
entries = append(entries, newEntry(pbtypes.GetString(r.Details, "id"), r.Details))
}
if err := sub.init(entries); err != nil {
@ -756,10 +765,7 @@ func (s *spaceSubscriptions) recordsHandler() {
id := pbtypes.GetString(rec.(database.Record).Details, "id")
// nil previous version
nilIfExists(id)
entries = append(entries, &entry{
id: id,
data: rec.(database.Record).Details,
})
entries = append(entries, newEntry(id, rec.(database.Record).Details))
}
// filter nil entries
filtered := entries[:0]

View file

@ -85,11 +85,11 @@ func TestService_Search(t *testing.T) {
time.Sleep(batchTime + time.Millisecond)
spaceSub.onChange([]*entry{
{id: "1", data: &types.Struct{Fields: map[string]*types.Value{
newEntry("1", &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("one"),
"author": pbtypes.StringList([]string{"author2", "author3", "1"}),
}}},
}}),
})
assert.Equal(t, []string{"test"}, spaceSub.cache.entries["1"].SubIds())
@ -99,10 +99,10 @@ func TestService_Search(t *testing.T) {
fx.events = fx.events[:0]
spaceSub.onChange([]*entry{
{id: "1", data: &types.Struct{Fields: map[string]*types.Value{
newEntry("1", &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("one"),
}}},
}}),
})
assert.NoError(t, fx.Unsubscribe("test"))
@ -429,10 +429,10 @@ func TestService_Search(t *testing.T) {
require.NoError(t, err)
spaceSub.onChange([]*entry{
{id: "1", data: &types.Struct{Fields: map[string]*types.Value{
newEntry("1", &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("4"),
}}},
}}),
})
// should be 1,3 (2)
require.Len(t, fx.events[0].Messages, 3)
@ -441,10 +441,10 @@ func TestService_Search(t *testing.T) {
assert.NotEmpty(t, fx.events[0].Messages[2].GetSubscriptionRemove())
spaceSub.onChange([]*entry{
{id: "2", data: &types.Struct{Fields: map[string]*types.Value{
newEntry("2", &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("2"),
"name": pbtypes.String("6"),
}}},
}}),
})
// should be 2,1 (3)
@ -875,7 +875,33 @@ func TestService_Search(t *testing.T) {
assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyName.String()))
assert.Equal(t, "1", pbtypes.GetString(resp.Records[0], bundle.RelationKeyId.String()))
})
t.Run("Search: call onChange for records", func(t *testing.T) {
// given
fx := newFixture(t)
defer fx.a.Close(context.Background())
defer fx.ctrl.Finish()
newSub(fx, "test")
newSub(fx, "test2")
spaceSub, err := fx.getSpaceSubscriptions(testSpaceId)
assert.NoError(t, err)
e := spaceSub.ctxBuf.c.Get("1")
e.subFullDetailsSent["test2"] = false
// when
spaceSub.onChange([]*entry{
newEntry("1", &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String("1"),
"name": pbtypes.String("one"),
"author": pbtypes.StringList([]string{"author2", "author3", "1"}),
}}),
})
// then
assert.NotNil(t, spaceSub.ctxBuf.outputs[defaultOutput][0].GetObjectDetailsAmend())
assert.Contains(t, spaceSub.ctxBuf.outputs[defaultOutput][0].GetObjectDetailsAmend().GetSubIds(), "test")
assert.Contains(t, spaceSub.ctxBuf.outputs[defaultOutput][1].GetObjectDetailsSet().GetSubIds(), "test2")
})
t.Run("SubscribeGroup: tag group", func(t *testing.T) {
// given
fx := newFixtureWithRealObjectStore(t)

View file

@ -39,7 +39,7 @@ func (s *simpleSub) init(entries []*entry) (err error) {
for _, e := range entries {
e = s.cache.GetOrSet(e)
s.set[e.id] = struct{}{}
e.SetSub(s.id, true, false)
e.SetSub(s.id, true, true)
}
if s.ds != nil {
s.depKeys = s.ds.depKeys(s.spaceId, s.keys)
@ -112,7 +112,7 @@ func (s *simpleSub) onChange(ctx *opCtx) {
}
}
if changed && s.depSub != nil {
s.ds.refillSubscription(s.spaceId, ctx, s.depSub, s.getActiveEntries(), s.depKeys)
s.ds.refillSubscription(ctx, s.depSub, s.getActiveEntries(), s.depKeys)
}
}

View file

@ -126,7 +126,7 @@ func (s *sortedSub) init(entries []*entry) (err error) {
activeEntries := s.getActiveEntries()
var activeIds = make([]string, len(activeEntries))
for i, ae := range activeEntries {
ae.SetSub(s.id, true, false)
ae.SetSub(s.id, true, true)
activeIds[i] = ae.id
}
s.diff = newListDiff(activeIds)
@ -174,7 +174,7 @@ func (s *sortedSub) onChange(ctx *opCtx) {
}
wasAddOrRemove, ids := s.diff.diff(ctx, s.id, s.keys)
s.ds.depEntriesByEntries(ctx, s.spaceId, ids)
s.ds.depEntriesByEntries(ctx, ids)
hasChanges := false
for _, e := range ctx.entries {
@ -190,7 +190,7 @@ func (s *sortedSub) onChange(ctx *opCtx) {
}
if (wasAddOrRemove || hasChanges) && s.depSub != nil {
s.ds.refillSubscription(s.spaceId, ctx, s.depSub, s.activeEntriesBuf, s.depKeys)
s.ds.refillSubscription(ctx, s.depSub, s.activeEntriesBuf, s.depKeys)
}
if s.parent != nil {

View file

@ -113,10 +113,7 @@ func TestSubscription_Change(t *testing.T) {
}
require.NoError(t, sub.init(genEntries(9, false)))
ctx := &opCtx{c: sub.cache}
ctx.entries = append(ctx.entries, &entry{
id: "id4",
data: &types.Struct{Fields: map[string]*types.Value{"id": pbtypes.String("id4"), "order": pbtypes.Int64(6)}},
})
ctx.entries = append(ctx.entries, newEntry("id4", &types.Struct{Fields: map[string]*types.Value{"id": pbtypes.String("id4"), "order": pbtypes.Int64(6)}}))
sub.onChange(ctx)
assertCtxPosition(t, ctx, "id5", "")
assertCtxChange(t, ctx, "id4")

View file

@ -30,13 +30,10 @@ func genEntries(n int, backord bool) (res []*entry) {
}
func genEntry(id string, ord int64) *entry {
return &entry{
id: id,
data: &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String(id),
"order": pbtypes.Int64(ord),
}},
}
return newEntry(id, &types.Struct{Fields: map[string]*types.Value{
"id": pbtypes.String(id),
"order": pbtypes.Int64(ord),
}})
}
func assertCtxAdd(t *testing.T, ctx *opCtx, id, afterId string) {

View file

@ -37,5 +37,6 @@ func SyncRelationsSmartblockTypes() []smartblock.SmartBlockType {
smartblock.SmartBlockTypeProfilePage,
smartblock.SmartBlockTypeChatDerivedObject,
smartblock.SmartBlockTypeChatObject,
smartblock.SmartBlockTypeSpaceView,
}
}

View file

@ -3,6 +3,7 @@ package detailsupdater
import (
"context"
"errors"
"slices"
"sync"
"time"
@ -13,6 +14,7 @@ import (
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/core/syncstatus/detailsupdater/helper"
"github.com/anyproto/anytype-heart/core/syncstatus/filesyncstatus"
"github.com/anyproto/anytype-heart/core/syncstatus/syncsubscriptions"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
@ -222,6 +224,9 @@ func (u *syncStatusUpdater) updateObjectDetails(syncStatusDetails *syncStatusDet
}
func (u *syncStatusUpdater) setSyncDetails(sb smartblock.SmartBlock, status domain.ObjectSyncStatus, syncError domain.SyncError) error {
if !slices.Contains(helper.SyncRelationsSmartblockTypes(), sb.Type()) {
return nil
}
st := sb.NewState()
if !u.isLayoutSuitableForSyncRelations(sb.Details()) {
return nil

View file

@ -1152,10 +1152,18 @@
- [Rpc.Space.RequestDecline.Request](#anytype-Rpc-Space-RequestDecline-Request)
- [Rpc.Space.RequestDecline.Response](#anytype-Rpc-Space-RequestDecline-Response)
- [Rpc.Space.RequestDecline.Response.Error](#anytype-Rpc-Space-RequestDecline-Response-Error)
- [Rpc.Space.SetOrder](#anytype-Rpc-Space-SetOrder)
- [Rpc.Space.SetOrder.Request](#anytype-Rpc-Space-SetOrder-Request)
- [Rpc.Space.SetOrder.Response](#anytype-Rpc-Space-SetOrder-Response)
- [Rpc.Space.SetOrder.Response.Error](#anytype-Rpc-Space-SetOrder-Response-Error)
- [Rpc.Space.StopSharing](#anytype-Rpc-Space-StopSharing)
- [Rpc.Space.StopSharing.Request](#anytype-Rpc-Space-StopSharing-Request)
- [Rpc.Space.StopSharing.Response](#anytype-Rpc-Space-StopSharing-Response)
- [Rpc.Space.StopSharing.Response.Error](#anytype-Rpc-Space-StopSharing-Response-Error)
- [Rpc.Space.UnsetOrder](#anytype-Rpc-Space-UnsetOrder)
- [Rpc.Space.UnsetOrder.Request](#anytype-Rpc-Space-UnsetOrder-Request)
- [Rpc.Space.UnsetOrder.Response](#anytype-Rpc-Space-UnsetOrder-Response)
- [Rpc.Space.UnsetOrder.Response.Error](#anytype-Rpc-Space-UnsetOrder-Response-Error)
- [Rpc.Template](#anytype-Rpc-Template)
- [Rpc.Template.Clone](#anytype-Rpc-Template-Clone)
- [Rpc.Template.Clone.Request](#anytype-Rpc-Template-Clone-Request)
@ -1514,7 +1522,9 @@
- [Rpc.Space.ParticipantRemove.Response.Error.Code](#anytype-Rpc-Space-ParticipantRemove-Response-Error-Code)
- [Rpc.Space.RequestApprove.Response.Error.Code](#anytype-Rpc-Space-RequestApprove-Response-Error-Code)
- [Rpc.Space.RequestDecline.Response.Error.Code](#anytype-Rpc-Space-RequestDecline-Response-Error-Code)
- [Rpc.Space.SetOrder.Response.Error.Code](#anytype-Rpc-Space-SetOrder-Response-Error-Code)
- [Rpc.Space.StopSharing.Response.Error.Code](#anytype-Rpc-Space-StopSharing-Response-Error-Code)
- [Rpc.Space.UnsetOrder.Response.Error.Code](#anytype-Rpc-Space-UnsetOrder-Response-Error-Code)
- [Rpc.Template.Clone.Response.Error.Code](#anytype-Rpc-Template-Clone-Response-Error-Code)
- [Rpc.Template.CreateFromObject.Response.Error.Code](#anytype-Rpc-Template-CreateFromObject-Response-Error-Code)
- [Rpc.Template.ExportAll.Response.Error.Code](#anytype-Rpc-Template-ExportAll-Response-Error-Code)
@ -1998,6 +2008,8 @@
| SpaceMakeShareable | [Rpc.Space.MakeShareable.Request](#anytype-Rpc-Space-MakeShareable-Request) | [Rpc.Space.MakeShareable.Response](#anytype-Rpc-Space-MakeShareable-Response) | |
| SpaceParticipantRemove | [Rpc.Space.ParticipantRemove.Request](#anytype-Rpc-Space-ParticipantRemove-Request) | [Rpc.Space.ParticipantRemove.Response](#anytype-Rpc-Space-ParticipantRemove-Response) | |
| SpaceParticipantPermissionsChange | [Rpc.Space.ParticipantPermissionsChange.Request](#anytype-Rpc-Space-ParticipantPermissionsChange-Request) | [Rpc.Space.ParticipantPermissionsChange.Response](#anytype-Rpc-Space-ParticipantPermissionsChange-Response) | |
| SpaceSetOrder | [Rpc.Space.SetOrder.Request](#anytype-Rpc-Space-SetOrder-Request) | [Rpc.Space.SetOrder.Response](#anytype-Rpc-Space-SetOrder-Response) | |
| SpaceUnsetOrder | [Rpc.Space.UnsetOrder.Request](#anytype-Rpc-Space-UnsetOrder-Request) | [Rpc.Space.UnsetOrder.Response](#anytype-Rpc-Space-UnsetOrder-Response) | |
| ObjectOpen | [Rpc.Object.Open.Request](#anytype-Rpc-Object-Open-Request) | [Rpc.Object.Open.Response](#anytype-Rpc-Object-Open-Response) | Object *** |
| ObjectClose | [Rpc.Object.Close.Request](#anytype-Rpc-Object-Close-Request) | [Rpc.Object.Close.Response](#anytype-Rpc-Object-Close-Response) | |
| ObjectShow | [Rpc.Object.Show.Request](#anytype-Rpc-Object-Show-Request) | [Rpc.Object.Show.Response](#anytype-Rpc-Object-Show-Response) | |
@ -10123,6 +10135,7 @@ Get marks list in the selected range in text block.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| chatObjectId | [string](#string) | | |
| afterOrderId | [string](#string) | | OrderId of the message after which to get messages |
| beforeOrderId | [string](#string) | | OrderId of the message before which to get messages |
| limit | [int32](#int32) | | |
@ -18918,6 +18931,63 @@ Available undo/redo operations
<a name="anytype-Rpc-Space-SetOrder"></a>
### Rpc.Space.SetOrder
<a name="anytype-Rpc-Space-SetOrder-Request"></a>
### Rpc.Space.SetOrder.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| spaceViewId | [string](#string) | | |
| spaceViewOrder | [string](#string) | repeated | result order of space view ids |
<a name="anytype-Rpc-Space-SetOrder-Response"></a>
### Rpc.Space.SetOrder.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Space.SetOrder.Response.Error](#anytype-Rpc-Space-SetOrder-Response-Error) | | |
<a name="anytype-Rpc-Space-SetOrder-Response-Error"></a>
### Rpc.Space.SetOrder.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Space.SetOrder.Response.Error.Code](#anytype-Rpc-Space-SetOrder-Response-Error-Code) | | |
| description | [string](#string) | | |
<a name="anytype-Rpc-Space-StopSharing"></a>
### Rpc.Space.StopSharing
@ -18974,6 +19044,62 @@ Available undo/redo operations
<a name="anytype-Rpc-Space-UnsetOrder"></a>
### Rpc.Space.UnsetOrder
<a name="anytype-Rpc-Space-UnsetOrder-Request"></a>
### Rpc.Space.UnsetOrder.Request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| spaceViewId | [string](#string) | | |
<a name="anytype-Rpc-Space-UnsetOrder-Response"></a>
### Rpc.Space.UnsetOrder.Response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error | [Rpc.Space.UnsetOrder.Response.Error](#anytype-Rpc-Space-UnsetOrder-Response-Error) | | |
<a name="anytype-Rpc-Space-UnsetOrder-Response-Error"></a>
### Rpc.Space.UnsetOrder.Response.Error
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| code | [Rpc.Space.UnsetOrder.Response.Error.Code](#anytype-Rpc-Space-UnsetOrder-Response-Error-Code) | | |
| description | [string](#string) | | |
<a name="anytype-Rpc-Template"></a>
### Rpc.Template
@ -23093,7 +23219,7 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
| ---- | ------ | ----------- |
| NONE | 0 | |
| GET_STARTED | 1 | |
| EMPTY | 6 | |
| EMPTY | 2 | |
@ -23970,6 +24096,19 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
<a name="anytype-Rpc-Space-SetOrder-Response-Error-Code"></a>
### Rpc.Space.SetOrder.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | |
<a name="anytype-Rpc-Space-StopSharing-Response-Error-Code"></a>
### Rpc.Space.StopSharing.Response.Error.Code
@ -23987,6 +24126,19 @@ Middleware-to-front-end response, that can contain a NULL error or a non-NULL er
<a name="anytype-Rpc-Space-UnsetOrder-Response-Error-Code"></a>
### Rpc.Space.UnsetOrder.Response.Error.Code
| Name | Number | Description |
| ---- | ------ | ----------- |
| NULL | 0 | |
| UNKNOWN_ERROR | 1 | |
| BAD_INPUT | 2 | |
<a name="anytype-Rpc-Template-Clone-Response-Error-Code"></a>
### Rpc.Template.Clone.Response.Error.Code
@ -27930,7 +28082,7 @@ Contains basic information about a user account
| marketplaceWorkspaceId | [string](#string) | | marketplace workspace id |
| workspaceObjectId | [string](#string) | | workspace object id. used for space-level chat |
| deviceId | [string](#string) | | |
| accountSpaceId | [string](#string) | | |
| accountSpaceId | [string](#string) | | the first created private space. It&#39;s filled only when account is created |
| widgetsId | [string](#string) | | |
| spaceViewId | [string](#string) | | |
| techSpaceId | [string](#string) | | |
@ -28202,6 +28354,7 @@ Bookmark is to keep a web-link and to preview a content.
| includeTime | [bool](#bool) | | |
| id | [string](#string) | | |
| emptyPlacement | [Block.Content.Dataview.Sort.EmptyType](#anytype-model-Block-Content-Dataview-Sort-EmptyType) | | |
| noCollate | [bool](#bool) | | |

30
go.mod
View file

@ -8,12 +8,13 @@ require (
github.com/VividCortex/ewma v1.2.0
github.com/adrium/goheif v0.0.0-20230113233934-ca402e77a786
github.com/anyproto/any-store v0.1.3
github.com/anyproto/any-sync v0.5.18
github.com/anyproto/any-sync v0.5.21
github.com/anyproto/go-chash v0.1.0
github.com/anyproto/go-naturaldate/v2 v2.0.2-0.20230524105841-9829cfd13438
github.com/anyproto/lexid v0.0.2
github.com/anyproto/go-slip10 v1.0.0
github.com/anyproto/lexid v0.0.4
github.com/anyproto/protobuf v1.3.3-0.20240814124528-72b8c7e0e0f5
github.com/anyproto/tantivy-go v0.2.0
github.com/anyproto/tantivy-go v0.3.1
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/avast/retry-go/v4 v4.6.0
github.com/chai2010/webp v1.1.2-0.20240612091223-aa1b379218b7
@ -63,7 +64,7 @@ require (
github.com/libp2p/go-libp2p v0.37.0
github.com/libp2p/zeroconf/v2 v2.2.0
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/magiconair/properties v1.8.7
github.com/magiconair/properties v1.8.9
github.com/matishsiao/goInfo v0.0.0-20240924010139-10388a85396f
github.com/mattn/go-sqlite3 v1.14.22
github.com/mb0/diff v0.0.0-20131118162322-d8d9a906c24d
@ -71,7 +72,7 @@ require (
github.com/miolini/datacounter v1.0.3
github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-base32 v0.1.0
github.com/multiformats/go-multiaddr-dns v0.4.0
github.com/multiformats/go-multiaddr-dns v0.4.1
github.com/multiformats/go-multibase v0.2.0
github.com/multiformats/go-multihash v0.2.3
github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb
@ -99,12 +100,12 @@ require (
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f
golang.org/x/image v0.22.0
golang.org/x/image v0.23.0
golang.org/x/mobile v0.0.0-20241108191957-fa514ef75a0f
golang.org/x/net v0.31.0
golang.org/x/net v0.32.0
golang.org/x/oauth2 v0.24.0
golang.org/x/text v0.20.0
google.golang.org/grpc v1.68.0
golang.org/x/text v0.21.0
google.golang.org/grpc v1.68.1
gopkg.in/Graylog2/go-gelf.v2 v2.0.0-20180125164251-1832d8546a9f
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
@ -122,7 +123,6 @@ require (
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
github.com/anyproto/go-slip10 v1.0.0 // indirect
github.com/anyproto/go-slip21 v1.0.0 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@ -217,7 +217,7 @@ require (
github.com/prometheus/common v0.60.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.48.1 // indirect
github.com/quic-go/quic-go v0.48.2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/cors v1.11.0 // indirect
@ -246,11 +246,11 @@ require (
go.opentelemetry.io/otel v1.32.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/crypto v0.30.0 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/term v0.26.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/time v0.8.0 // indirect
golang.org/x/tools v0.27.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect

56
go.sum
View file

@ -78,8 +78,8 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
github.com/anyproto/any-store v0.1.3 h1:onWLP8tuWiUvYOyV3DoRODscTxAiGEjwQPm+NMxeq3M=
github.com/anyproto/any-store v0.1.3/go.mod h1:6/0OUKgSMWF/vYGoGYzQOl2CII5OdiuXbQlGDXYcNYc=
github.com/anyproto/any-sync v0.5.18 h1:isS9AXOs5b6kSM/fbANEvOxn8JJrSuaKKlrUWNLdTS4=
github.com/anyproto/any-sync v0.5.18/go.mod h1:K53/whh/9tmGbXrkPS59XyqWU3SaxhsX9g6VIYnBIlU=
github.com/anyproto/any-sync v0.5.21 h1:+Qx69Pij3QbLh2nRZEamD2WaSSy1uWHlXGMCIFEiKW0=
github.com/anyproto/any-sync v0.5.21/go.mod h1:K53/whh/9tmGbXrkPS59XyqWU3SaxhsX9g6VIYnBIlU=
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=
@ -98,16 +98,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/lexid v0.0.4 h1:2ztI0y5pNdtojd3vChw/YV/P6IO9pB7PccYysImDxWI=
github.com/anyproto/lexid v0.0.4/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.2.0 h1:+b778sOPy07KpJULL4ztCc106L+zdmwKCIB5UYnWrZo=
github.com/anyproto/tantivy-go v0.2.0/go.mod h1:MMLYW7e5SIzsHS3Q5CYiF1J7kJJaIRT+VVHGArU24IQ=
github.com/anyproto/tantivy-go v0.3.1 h1:59XePWnHlaTOgw1jVqpKD7oyZa8nwY5+U9UKnt0HHZU=
github.com/anyproto/tantivy-go v0.3.1/go.mod h1:7hhkPpyTq7+W1dx9Dcva4bsg4TLHq9xqmmYLCwqDq/k=
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=
@ -649,8 +649,8 @@ github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/z
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/matishsiao/goInfo v0.0.0-20240924010139-10388a85396f h1:XDrsC/9hdgiU9ecceSmYsS2E3fBtFiYc34dAMFgegnM=
github.com/matishsiao/goInfo v0.0.0-20240924010139-10388a85396f/go.mod h1:aEt7p9Rvh67BYApmZwNDPpgircTO2kgdmDUoF/1QmwA=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -711,8 +711,8 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
github.com/multiformats/go-multiaddr-dns v0.4.0 h1:P76EJ3qzBXpUXZ3twdCDx/kvagMsNo0LMFXpyms/zgU=
github.com/multiformats/go-multiaddr-dns v0.4.0/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
github.com/multiformats/go-multiaddr-dns v0.4.1 h1:whi/uCLbDS3mSEUMb1MsoT4uzUeZB0N32yzufqS0i5M=
github.com/multiformats/go-multiaddr-dns v0.4.1/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc=
github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E=
github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo=
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
@ -871,8 +871,8 @@ github.com/pseudomuto/protokit v0.2.1 h1:kCYpE3thoR6Esm0CUvd5xbrDTOZPvQPTDeyXpZf
github.com/pseudomuto/protokit v0.2.1/go.mod h1:gt7N5Rz2flBzYafvaxyIxMZC0TTF5jDZfRnw25hAAyo=
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.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg=
github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
@ -1091,8 +1091,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1113,8 +1113,8 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h
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=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g=
golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4=
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -1198,8 +1198,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI=
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1224,8 +1224,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1302,16 +1302,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1323,8 +1323,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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=
@ -1496,8 +1496,8 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

File diff suppressed because it is too large Load diff

View file

@ -492,6 +492,47 @@ message Rpc {
}
}
}
message SetOrder {
message Request {
string spaceViewId = 1;
repeated string spaceViewOrder = 2; // result order of space view ids
}
message Response {
Error error = 1;
message Error {
Code code = 1;
string description = 2;
enum Code {
NULL = 0;
UNKNOWN_ERROR = 1;
BAD_INPUT = 2;
}
}
}
}
message UnsetOrder {
message Request {
string spaceViewId = 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 Wallet {
@ -2776,7 +2817,7 @@ message Rpc {
enum UseCase {
NONE = 0;
GET_STARTED = 1;
EMPTY = 6;
EMPTY = 2;
}
}
@ -7587,6 +7628,7 @@ message Rpc {
message GetMessages {
message Request {
string chatObjectId = 1;
string afterOrderId = 4; // OrderId of the message after which to get messages
string beforeOrderId = 2; // OrderId of the message before which to get messages
int32 limit = 3;
}

View file

@ -63,6 +63,8 @@ service ClientCommands {
rpc SpaceMakeShareable (anytype.Rpc.Space.MakeShareable.Request) returns (anytype.Rpc.Space.MakeShareable.Response);
rpc SpaceParticipantRemove (anytype.Rpc.Space.ParticipantRemove.Request) returns (anytype.Rpc.Space.ParticipantRemove.Response);
rpc SpaceParticipantPermissionsChange (anytype.Rpc.Space.ParticipantPermissionsChange.Request) returns (anytype.Rpc.Space.ParticipantPermissionsChange.Response);
rpc SpaceSetOrder (anytype.Rpc.Space.SetOrder.Request) returns (anytype.Rpc.Space.SetOrder.Response);
rpc SpaceUnsetOrder (anytype.Rpc.Space.UnsetOrder.Request) returns (anytype.Rpc.Space.UnsetOrder.Response);
// Object
// ***

View file

@ -26,335 +26,337 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
func init() { proto.RegisterFile("pb/protos/service/service.proto", fileDescriptor_93a29dc403579097) }
var fileDescriptor_93a29dc403579097 = []byte{
// 5246 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0xdf, 0x6f, 0x1d, 0x49,
0x56, 0xf8, 0xc7, 0x2f, 0xdf, 0xf9, 0xd2, 0xcb, 0x0e, 0x70, 0x07, 0x86, 0xd9, 0x61, 0x37, 0xc9,
0x64, 0x92, 0x38, 0x89, 0xe3, 0xeb, 0x4c, 0x32, 0x3f, 0x56, 0xbb, 0x48, 0xc8, 0xb1, 0x63, 0x8f,
0x59, 0xdb, 0x31, 0xbe, 0xd7, 0x89, 0x34, 0x12, 0x12, 0xe5, 0x7b, 0xcb, 0xd7, 0x8d, 0xfb, 0x76,
0xf5, 0x76, 0xd7, 0xbd, 0xce, 0x5d, 0x04, 0x02, 0x81, 0x40, 0x20, 0x10, 0x2b, 0x7e, 0xbd, 0x22,
0xf1, 0xc2, 0xbf, 0xc2, 0xe3, 0x3e, 0xf2, 0x88, 0x66, 0x5e, 0xf8, 0x33, 0x50, 0x57, 0x55, 0xd7,
0x8f, 0xd3, 0xe7, 0x54, 0xb7, 0xf7, 0x29, 0xd1, 0x3d, 0x9f, 0x73, 0x4e, 0xfd, 0x3c, 0x75, 0xaa,
0xba, 0xba, 0x9d, 0xdc, 0x2e, 0xce, 0xb7, 0x8a, 0x52, 0x48, 0x51, 0x6d, 0x55, 0xbc, 0x5c, 0xa6,
0x13, 0xde, 0xfc, 0x3b, 0x54, 0x3f, 0x0f, 0xde, 0x65, 0xf9, 0x4a, 0xae, 0x0a, 0xfe, 0xd1, 0x87,
0x8e, 0x9c, 0x88, 0xf9, 0x9c, 0xe5, 0xd3, 0x4a, 0x23, 0x1f, 0x7d, 0xe0, 0x24, 0x7c, 0xc9, 0x73,
0x69, 0x7e, 0x7f, 0xf6, 0x9f, 0xff, 0xbb, 0x96, 0xbc, 0xb7, 0x93, 0xa5, 0x3c, 0x97, 0x3b, 0x46,
0x63, 0xf0, 0x75, 0xf2, 0xdd, 0xed, 0xa2, 0xd8, 0xe7, 0xf2, 0x35, 0x2f, 0xab, 0x54, 0xe4, 0x83,
0x4f, 0x86, 0xc6, 0xc1, 0xf0, 0xb4, 0x98, 0x0c, 0xb7, 0x8b, 0x62, 0xe8, 0x84, 0xc3, 0x53, 0xfe,
0xd3, 0x05, 0xaf, 0xe4, 0x47, 0xf7, 0xe2, 0x50, 0x55, 0x88, 0xbc, 0xe2, 0x83, 0x8b, 0xe4, 0x37,
0xb6, 0x8b, 0x62, 0xc4, 0xe5, 0x2e, 0xaf, 0x2b, 0x30, 0x92, 0x4c, 0xf2, 0xc1, 0x7a, 0x4b, 0x35,
0x04, 0xac, 0x8f, 0x87, 0xdd, 0xa0, 0xf1, 0x33, 0x4e, 0xbe, 0x53, 0xfb, 0xb9, 0x5c, 0xc8, 0xa9,
0xb8, 0xce, 0x07, 0x1f, 0xb7, 0x15, 0x8d, 0xc8, 0xda, 0xbe, 0x1b, 0x43, 0x8c, 0xd5, 0x37, 0xc9,
0xaf, 0xbe, 0x61, 0x59, 0xc6, 0xe5, 0x4e, 0xc9, 0xeb, 0x82, 0x87, 0x3a, 0x5a, 0x34, 0xd4, 0x32,
0x6b, 0xf7, 0x93, 0x28, 0x63, 0x0c, 0x7f, 0x9d, 0x7c, 0x57, 0x4b, 0x4e, 0xf9, 0x44, 0x2c, 0x79,
0x39, 0x40, 0xb5, 0x8c, 0x90, 0x68, 0xf2, 0x16, 0x04, 0x6d, 0xef, 0x88, 0x7c, 0xc9, 0x4b, 0x89,
0xdb, 0x36, 0xc2, 0xb8, 0x6d, 0x07, 0x19, 0xdb, 0x7f, 0xbb, 0x96, 0x7c, 0x7f, 0x7b, 0x32, 0x11,
0x8b, 0x5c, 0x1e, 0x8a, 0x09, 0xcb, 0x0e, 0xd3, 0xfc, 0xea, 0x98, 0x5f, 0xef, 0x5c, 0xd6, 0x7c,
0x3e, 0xe3, 0x83, 0xe7, 0x61, 0xab, 0x6a, 0x74, 0x68, 0xd9, 0xa1, 0x0f, 0x5b, 0xdf, 0x9f, 0xdd,
0x4c, 0xc9, 0x94, 0xe5, 0x1f, 0xd7, 0x92, 0x5b, 0xb0, 0x2c, 0x23, 0x91, 0x2d, 0xb9, 0x2b, 0xcd,
0xe7, 0x1d, 0x86, 0x43, 0xdc, 0x96, 0xe7, 0x8b, 0x9b, 0xaa, 0x99, 0x12, 0x65, 0xc9, 0xfb, 0xfe,
0x70, 0x19, 0xf1, 0x4a, 0x4d, 0xa7, 0x47, 0xf4, 0x88, 0x30, 0x88, 0xf5, 0xfc, 0xb8, 0x0f, 0x6a,
0xbc, 0xa5, 0xc9, 0xc0, 0x78, 0xcb, 0x44, 0x65, 0x9d, 0x3d, 0x44, 0x2d, 0x78, 0x84, 0xf5, 0xf5,
0xa8, 0x07, 0x69, 0x5c, 0xfd, 0x51, 0xf2, 0x6b, 0x6f, 0x44, 0x79, 0x55, 0x15, 0x6c, 0xc2, 0xcd,
0x54, 0xb8, 0x1f, 0x6a, 0x37, 0x52, 0x38, 0x1b, 0x1e, 0x74, 0x61, 0xde, 0xa0, 0x6d, 0x84, 0xaf,
0x0a, 0x0e, 0x63, 0x90, 0x53, 0xac, 0x85, 0xd4, 0xa0, 0x85, 0x90, 0xb1, 0x7d, 0x95, 0x0c, 0x9c,
0xed, 0xf3, 0x3f, 0xe6, 0x13, 0xb9, 0x3d, 0x9d, 0xc2, 0x5e, 0x71, 0xba, 0x8a, 0x18, 0x6e, 0x4f,
0xa7, 0x54, 0xaf, 0xe0, 0xa8, 0x71, 0x76, 0x9d, 0x7c, 0x00, 0x9c, 0x1d, 0xa6, 0x95, 0x72, 0xb8,
0x19, 0xb7, 0x62, 0x30, 0xeb, 0x74, 0xd8, 0x17, 0x37, 0x8e, 0xff, 0x7c, 0x2d, 0xf9, 0x1e, 0xe2,
0xf9, 0x94, 0xcf, 0xc5, 0x92, 0x0f, 0x9e, 0x76, 0x5b, 0xd3, 0xa4, 0xf5, 0xff, 0xe9, 0x0d, 0x34,
0x90, 0x61, 0x32, 0xe2, 0x19, 0x9f, 0x48, 0x72, 0x98, 0x68, 0x71, 0xe7, 0x30, 0xb1, 0x98, 0x37,
0xc3, 0x1a, 0xe1, 0x3e, 0x97, 0x3b, 0x8b, 0xb2, 0xe4, 0xb9, 0x24, 0xfb, 0xd2, 0x21, 0x9d, 0x7d,
0x19, 0xa0, 0x48, 0x7d, 0xf6, 0xb9, 0xdc, 0xce, 0x32, 0xb2, 0x3e, 0x5a, 0xdc, 0x59, 0x1f, 0x8b,
0x19, 0x0f, 0x93, 0xe4, 0xd7, 0xbd, 0x16, 0x93, 0x07, 0xf9, 0x85, 0x18, 0xd0, 0x6d, 0xa1, 0xe4,
0xd6, 0xc7, 0x7a, 0x27, 0x87, 0x54, 0xe3, 0xe5, 0xdb, 0x42, 0x94, 0x74, 0xb7, 0x68, 0x71, 0x67,
0x35, 0x2c, 0x66, 0x3c, 0xfc, 0x61, 0xf2, 0x9e, 0x89, 0x92, 0xcd, 0x7a, 0x76, 0x0f, 0x0d, 0xa1,
0x70, 0x41, 0xbb, 0xdf, 0x41, 0xb9, 0xe0, 0x60, 0x64, 0x26, 0xf8, 0x7c, 0x82, 0xea, 0x81, 0xd0,
0x73, 0x2f, 0x0e, 0xb5, 0x6c, 0xef, 0xf2, 0x8c, 0x93, 0xb6, 0xb5, 0xb0, 0xc3, 0xb6, 0x85, 0x8c,
0xed, 0x32, 0xf9, 0x2d, 0xdb, 0x2c, 0xf5, 0x3a, 0xaa, 0xe4, 0x75, 0x90, 0xde, 0x20, 0xea, 0xed,
0x43, 0xd6, 0xd7, 0x93, 0x7e, 0x70, 0xab, 0x3e, 0x66, 0x06, 0xe2, 0xf5, 0x01, 0xf3, 0xef, 0x5e,
0x1c, 0x32, 0xb6, 0xff, 0x6e, 0x2d, 0xf9, 0x81, 0x91, 0xbd, 0xcc, 0xd9, 0x79, 0xc6, 0xd5, 0x92,
0x78, 0xcc, 0xe5, 0xb5, 0x28, 0xaf, 0x46, 0xab, 0x7c, 0x42, 0x2c, 0xff, 0x38, 0xdc, 0xb1, 0xfc,
0x93, 0x4a, 0x5e, 0xc6, 0x67, 0x2a, 0x2a, 0x45, 0x01, 0x33, 0xbe, 0xa6, 0x06, 0x52, 0x14, 0x54,
0xc6, 0x17, 0x22, 0x2d, 0xab, 0x47, 0x75, 0xd8, 0xc4, 0xad, 0x1e, 0xf9, 0x71, 0xf2, 0x6e, 0x0c,
0x71, 0x61, 0xab, 0x19, 0xc0, 0x22, 0xbf, 0x48, 0x67, 0x67, 0xc5, 0xb4, 0x1e, 0xc6, 0x8f, 0xf0,
0x11, 0xea, 0x21, 0x44, 0xd8, 0x22, 0x50, 0xe3, 0xed, 0x1f, 0x5c, 0x62, 0x64, 0xa6, 0xd2, 0x5e,
0x29, 0xe6, 0x87, 0x7c, 0xc6, 0x26, 0x2b, 0x33, 0xff, 0x3f, 0x8b, 0x4d, 0x3c, 0x48, 0xdb, 0x42,
0x7c, 0x7e, 0x43, 0x2d, 0x53, 0x9e, 0x7f, 0x5f, 0x4b, 0xee, 0x35, 0xd5, 0xbf, 0x64, 0xf9, 0x8c,
0x9b, 0xfe, 0xd4, 0xa5, 0xdf, 0xce, 0xa7, 0xa7, 0xbc, 0x92, 0xac, 0x94, 0x83, 0x1f, 0xe1, 0x95,
0x8c, 0xe9, 0xd8, 0xb2, 0xfd, 0xf8, 0x97, 0xd2, 0x75, 0xbd, 0x3e, 0xaa, 0x03, 0x9b, 0x09, 0x01,
0x61, 0xaf, 0x2b, 0x09, 0x0c, 0x00, 0x77, 0x63, 0x88, 0xeb, 0x75, 0x25, 0x38, 0xc8, 0x97, 0xa9,
0xe4, 0xfb, 0x3c, 0xe7, 0x65, 0xbb, 0xd7, 0xb5, 0x6a, 0x88, 0x10, 0xbd, 0x4e, 0xa0, 0x2e, 0xd8,
0x04, 0xde, 0xec, 0xe2, 0xb8, 0x11, 0x31, 0xd2, 0x5a, 0x1e, 0x9f, 0xf4, 0x83, 0xdd, 0xee, 0xce,
0xf3, 0x79, 0xca, 0x97, 0xe2, 0x0a, 0xee, 0xee, 0x7c, 0x13, 0x1a, 0x20, 0x76, 0x77, 0x28, 0xe8,
0x56, 0x30, 0xcf, 0xcf, 0xeb, 0x94, 0x5f, 0x83, 0x15, 0xcc, 0x57, 0xae, 0xc5, 0xc4, 0x0a, 0x86,
0x60, 0xc6, 0xc3, 0x71, 0xf2, 0x2b, 0x4a, 0xf8, 0xfb, 0x22, 0xcd, 0x07, 0xb7, 0x11, 0xa5, 0x5a,
0x60, 0xad, 0xde, 0xa1, 0x01, 0x50, 0xe2, 0xfa, 0xd7, 0x1d, 0x96, 0x4f, 0x78, 0x86, 0x96, 0xd8,
0x89, 0xa3, 0x25, 0x0e, 0x30, 0x97, 0x3a, 0x28, 0x61, 0x1d, 0xbf, 0x46, 0x97, 0xac, 0x4c, 0xf3,
0xd9, 0x00, 0xd3, 0xf5, 0xe4, 0x44, 0xea, 0x80, 0x71, 0x60, 0x08, 0x1b, 0xc5, 0xed, 0xa2, 0x28,
0xeb, 0xb0, 0x88, 0x0d, 0xe1, 0x10, 0x89, 0x0e, 0xe1, 0x16, 0x8a, 0x7b, 0xdb, 0xe5, 0x93, 0x2c,
0xcd, 0xa3, 0xde, 0x0c, 0xd2, 0xc7, 0x9b, 0x43, 0xc1, 0xe0, 0x3d, 0xe4, 0x6c, 0xc9, 0x9b, 0x9a,
0x61, 0x2d, 0xe3, 0x03, 0xd1, 0xc1, 0x0b, 0x40, 0xb7, 0x4f, 0x53, 0xe2, 0x23, 0x76, 0xc5, 0xeb,
0x06, 0xe6, 0xf5, 0xba, 0x36, 0xc0, 0xf4, 0x03, 0x82, 0xd8, 0xa7, 0xe1, 0xa4, 0x71, 0xb5, 0x48,
0x3e, 0x50, 0xf2, 0x13, 0x56, 0xca, 0x74, 0x92, 0x16, 0x2c, 0x6f, 0xf2, 0x7f, 0x6c, 0x5e, 0xb7,
0x28, 0xeb, 0x72, 0xb3, 0x27, 0x6d, 0xdc, 0xfe, 0xdb, 0x5a, 0xf2, 0x31, 0xf4, 0x7b, 0xc2, 0xcb,
0x79, 0xaa, 0xb6, 0x91, 0x95, 0x0e, 0xc2, 0x83, 0x2f, 0xe3, 0x46, 0x5b, 0x0a, 0xb6, 0x34, 0x3f,
0xbc, 0xb9, 0xa2, 0x29, 0xd8, 0x1f, 0x24, 0x89, 0xde, 0xae, 0xa8, 0x2d, 0x65, 0x38, 0x6b, 0xcd,
0x3e, 0x26, 0xd8, 0x4f, 0x7e, 0x1c, 0x21, 0xdc, 0x52, 0xa1, 0x7f, 0x57, 0x3b, 0xe5, 0x01, 0xaa,
0xa1, 0x44, 0xc4, 0x52, 0x01, 0x10, 0x58, 0xd0, 0xd1, 0xa5, 0xb8, 0xc6, 0x0b, 0x5a, 0x4b, 0xe2,
0x05, 0x35, 0x84, 0x3b, 0xbb, 0x32, 0x05, 0xc5, 0xce, 0xae, 0x9a, 0x62, 0xc4, 0xce, 0xae, 0x20,
0x63, 0x0c, 0x8b, 0xe4, 0x37, 0x7d, 0xc3, 0x2f, 0x84, 0xb8, 0x9a, 0xb3, 0xf2, 0x6a, 0xf0, 0x98,
0x56, 0x6e, 0x18, 0xeb, 0x68, 0xa3, 0x17, 0xeb, 0xc2, 0x82, 0xef, 0xb0, 0x4e, 0x34, 0xce, 0xca,
0x0c, 0x84, 0x85, 0xc0, 0x86, 0x41, 0x88, 0xb0, 0x40, 0xa0, 0x2e, 0x72, 0xfb, 0xde, 0x46, 0x1c,
0xee, 0x96, 0x02, 0xf5, 0x11, 0xa7, 0x76, 0x4b, 0x08, 0x06, 0x87, 0xd0, 0x7e, 0xc9, 0x8a, 0x4b,
0x7c, 0x08, 0x29, 0x51, 0x7c, 0x08, 0x35, 0x08, 0xec, 0xef, 0x11, 0x67, 0xe5, 0xe4, 0x12, 0xef,
0x6f, 0x2d, 0x8b, 0xf7, 0xb7, 0x65, 0x60, 0x7f, 0x6b, 0xc1, 0x9b, 0x54, 0x5e, 0x1e, 0x71, 0xc9,
0xf0, 0xfe, 0x0e, 0x99, 0x78, 0x7f, 0xb7, 0x58, 0x97, 0xc9, 0xf8, 0x0e, 0x47, 0x8b, 0xf3, 0x6a,
0x52, 0xa6, 0xe7, 0x7c, 0x10, 0xb1, 0x62, 0x21, 0x22, 0x93, 0x21, 0x61, 0xe3, 0xf3, 0xe7, 0x6b,
0xc9, 0xed, 0xa6, 0xdb, 0x45, 0x55, 0xe9, 0x95, 0x15, 0xb8, 0xff, 0x1c, 0xef, 0x5f, 0x02, 0x27,
0x4e, 0x13, 0x7b, 0xa8, 0x79, 0x51, 0x15, 0x2f, 0xd2, 0x59, 0x5e, 0xd9, 0x42, 0x7d, 0xd9, 0xc7,
0xba, 0xa7, 0x40, 0x44, 0xd5, 0x5e, 0x8a, 0x6e, 0x41, 0x33, 0xfd, 0xd3, 0xc8, 0x0e, 0xa6, 0x15,
0x58, 0xd0, 0x9a, 0xf6, 0xf6, 0x08, 0x62, 0x41, 0xc3, 0x49, 0x38, 0x14, 0xf6, 0x4b, 0xb1, 0x28,
0xaa, 0x8e, 0xa1, 0x00, 0xa0, 0xf8, 0x50, 0x68, 0xc3, 0xc6, 0xe7, 0xdb, 0xe4, 0xb7, 0xfd, 0xe1,
0xe7, 0x37, 0xf6, 0x26, 0x3d, 0xa6, 0xb0, 0x26, 0x1e, 0xf6, 0xc5, 0x5d, 0x4a, 0xd7, 0x78, 0x96,
0xbb, 0x5c, 0xb2, 0x34, 0xab, 0x06, 0x0f, 0x70, 0x1b, 0x8d, 0x9c, 0x48, 0xe9, 0x30, 0x0e, 0xc6,
0xb7, 0xdd, 0x45, 0x91, 0xa5, 0x93, 0xf6, 0x59, 0xae, 0xd1, 0xb5, 0xe2, 0x78, 0x7c, 0xf3, 0x31,
0x18, 0xaf, 0x47, 0x5c, 0xea, 0xff, 0x8c, 0x57, 0x05, 0xc7, 0xe3, 0x75, 0x80, 0xc4, 0xe3, 0x35,
0x44, 0x61, 0x7d, 0x46, 0x5c, 0x1e, 0xb2, 0x95, 0x58, 0x10, 0xf1, 0xda, 0x8a, 0xe3, 0xf5, 0xf1,
0x31, 0x97, 0x55, 0x59, 0x0f, 0x07, 0xb9, 0xe4, 0x65, 0xce, 0xb2, 0xbd, 0x8c, 0xcd, 0xaa, 0x01,
0x11, 0x63, 0x42, 0x8a, 0xc8, 0xaa, 0x68, 0x1a, 0x69, 0xc6, 0x83, 0x6a, 0x8f, 0x2d, 0x45, 0x99,
0x4a, 0xba, 0x19, 0x1d, 0xd2, 0xd9, 0x8c, 0x01, 0x8a, 0x7a, 0xdb, 0x2e, 0x27, 0x97, 0xe9, 0x92,
0x4f, 0x23, 0xde, 0x1a, 0xa4, 0x87, 0x37, 0x0f, 0x45, 0x3a, 0x6d, 0x24, 0x16, 0xe5, 0x84, 0x93,
0x9d, 0xa6, 0xc5, 0x9d, 0x9d, 0x66, 0x31, 0xe3, 0xe1, 0xaf, 0xd6, 0x92, 0xdf, 0xd1, 0x52, 0xff,
0x80, 0x75, 0x97, 0x55, 0x97, 0xe7, 0x82, 0x95, 0xd3, 0xc1, 0xa7, 0x98, 0x1d, 0x14, 0xb5, 0xae,
0x9f, 0xdd, 0x44, 0x05, 0x36, 0xeb, 0x61, 0x5a, 0x79, 0x33, 0x0e, 0x6d, 0xd6, 0x00, 0x89, 0x37,
0x2b, 0x44, 0x61, 0x00, 0x51, 0x72, 0x7d, 0x98, 0xf1, 0x80, 0xd4, 0x0f, 0x4f, 0x34, 0xd6, 0x3b,
0x39, 0x18, 0x1f, 0x6b, 0x61, 0x38, 0x5a, 0x36, 0x29, 0x1b, 0xf8, 0x88, 0x19, 0xf6, 0xc5, 0x49,
0xcf, 0x76, 0x56, 0xc4, 0x3d, 0xb7, 0x66, 0xc6, 0xb0, 0x2f, 0x4e, 0x78, 0xf6, 0xc2, 0x5a, 0xcc,
0x33, 0x12, 0xda, 0x86, 0x7d, 0x71, 0x98, 0x7d, 0x19, 0xa6, 0x59, 0x17, 0x1e, 0x47, 0xec, 0xc0,
0xb5, 0x61, 0xa3, 0x17, 0x6b, 0x1c, 0xfe, 0xcd, 0x5a, 0xf2, 0x7d, 0xe7, 0xf1, 0x48, 0x4c, 0xd3,
0x8b, 0x95, 0x86, 0x5e, 0xb3, 0x6c, 0xc1, 0xab, 0xc1, 0x33, 0xca, 0x5a, 0x9b, 0xb5, 0x25, 0x78,
0x7e, 0x23, 0x1d, 0x38, 0x77, 0xb6, 0x8b, 0x22, 0x5b, 0x8d, 0xf9, 0xbc, 0xc8, 0xc8, 0xb9, 0x13,
0x20, 0xf1, 0xb9, 0x03, 0x51, 0x98, 0x95, 0x8f, 0x45, 0x9d, 0xf3, 0xa3, 0x59, 0xb9, 0x12, 0xc5,
0xb3, 0xf2, 0x06, 0x81, 0xb9, 0xd2, 0x58, 0xec, 0x88, 0x2c, 0xe3, 0x13, 0xd9, 0x7e, 0x48, 0x6b,
0x35, 0x1d, 0x11, 0xcf, 0x95, 0x00, 0xe9, 0xce, 0x33, 0x9a, 0x3d, 0x24, 0x2b, 0xf9, 0x8b, 0xd5,
0x61, 0x9a, 0x5f, 0x0d, 0xf0, 0xb4, 0xc0, 0x01, 0xc4, 0x79, 0x06, 0x0a, 0xc2, 0xbd, 0xea, 0x59,
0x3e, 0x15, 0xf8, 0x5e, 0xb5, 0x96, 0xc4, 0xf7, 0xaa, 0x86, 0x80, 0x26, 0x4f, 0x39, 0x65, 0xb2,
0x96, 0xc4, 0x4d, 0x1a, 0x02, 0x0b, 0x85, 0xe6, 0xd4, 0x9b, 0x0c, 0x85, 0xe0, 0x9c, 0x7b, 0xbd,
0x93, 0x83, 0x23, 0xb4, 0xd9, 0xb4, 0xee, 0x71, 0x39, 0xb9, 0xc4, 0x47, 0x68, 0x80, 0xc4, 0x47,
0x28, 0x44, 0x61, 0x95, 0xc6, 0xc2, 0x6e, 0xba, 0x1f, 0xe0, 0xe3, 0xa3, 0xb5, 0xe1, 0x5e, 0xef,
0xe4, 0xe0, 0x36, 0xf2, 0x60, 0xae, 0xda, 0x0c, 0x1d, 0xe4, 0x5a, 0x16, 0xdf, 0x46, 0x5a, 0x06,
0x96, 0x5e, 0x0b, 0xea, 0xe6, 0xc4, 0x4b, 0xef, 0xe4, 0xf1, 0xd2, 0x07, 0x9c, 0x71, 0xf2, 0x2f,
0x76, 0x1b, 0xa7, 0xa5, 0xc7, 0xa2, 0x9e, 0x23, 0xaf, 0x59, 0x96, 0x4e, 0x99, 0xe4, 0x63, 0x71,
0xc5, 0x73, 0x7c, 0xc7, 0x64, 0x4a, 0xab, 0xf9, 0x61, 0xa0, 0x10, 0xdf, 0x31, 0xc5, 0x15, 0xe1,
0x38, 0xd1, 0xf4, 0x59, 0xc5, 0x77, 0x58, 0x45, 0x44, 0xb2, 0x00, 0x89, 0x8f, 0x13, 0x88, 0xc2,
0x7c, 0x55, 0xcb, 0x5f, 0xbe, 0x2d, 0x78, 0x99, 0xf2, 0x7c, 0xc2, 0xf1, 0x7c, 0x15, 0x52, 0xf1,
0x7c, 0x15, 0xa1, 0xe1, 0x5e, 0x6d, 0x97, 0x49, 0xfe, 0x62, 0x35, 0x4e, 0xe7, 0xbc, 0x92, 0x6c,
0x5e, 0xe0, 0x7b, 0x35, 0x00, 0xc5, 0xf7, 0x6a, 0x6d, 0xb8, 0x75, 0x34, 0x64, 0x03, 0x62, 0xfb,
0x6e, 0x07, 0x24, 0x22, 0x77, 0x3b, 0x08, 0x14, 0x36, 0xac, 0x03, 0xd0, 0xe3, 0xd5, 0x96, 0x95,
0xe8, 0xf1, 0x2a, 0x4d, 0xb7, 0x0e, 0xdc, 0x2c, 0x33, 0xaa, 0xa7, 0x66, 0x47, 0xd1, 0x47, 0xfe,
0x14, 0xdd, 0xe8, 0xc5, 0xe2, 0x27, 0x7c, 0xa7, 0x3c, 0x63, 0x6a, 0xd9, 0x8a, 0x1c, 0xa3, 0x35,
0x4c, 0x9f, 0x13, 0x3e, 0x8f, 0x35, 0x0e, 0xff, 0x62, 0x2d, 0xf9, 0x08, 0xf3, 0xf8, 0xaa, 0x50,
0x7e, 0x9f, 0x76, 0xdb, 0xd2, 0x24, 0x71, 0x79, 0x25, 0xae, 0x61, 0xca, 0xf0, 0x27, 0xc9, 0x87,
0x8d, 0xc8, 0xdd, 0x6d, 0x31, 0x05, 0x08, 0x93, 0x36, 0x5b, 0x7e, 0xc8, 0x59, 0xf7, 0x5b, 0xbd,
0x79, 0xb7, 0x1f, 0x0a, 0xcb, 0x55, 0x81, 0xfd, 0x90, 0xb5, 0x61, 0xc4, 0xc4, 0x7e, 0x08, 0xc1,
0xdc, 0xec, 0xf4, 0xab, 0xf7, 0x26, 0x95, 0x97, 0x2a, 0xdf, 0x02, 0xb3, 0x33, 0x28, 0xab, 0x85,
0x88, 0xd9, 0x49, 0xc2, 0x30, 0x23, 0x69, 0xc0, 0x7a, 0x6e, 0x62, 0xb1, 0xdc, 0x1a, 0xf2, 0x67,
0xe6, 0xc3, 0x6e, 0x10, 0x8e, 0xd7, 0x46, 0x6c, 0xb6, 0x3e, 0x8f, 0x63, 0x16, 0xc0, 0xf6, 0x67,
0xa3, 0x17, 0x6b, 0x1c, 0xfe, 0x59, 0xf2, 0xbd, 0x56, 0xc5, 0xf6, 0x38, 0x93, 0x8b, 0x92, 0x4f,
0x07, 0x5b, 0x1d, 0xe5, 0x6e, 0x40, 0xeb, 0xfa, 0x69, 0x7f, 0x85, 0x56, 0x8e, 0xde, 0x70, 0x7a,
0x58, 0xd9, 0x32, 0x3c, 0x8b, 0x99, 0x0c, 0xd9, 0x68, 0x8e, 0x4e, 0xeb, 0xb4, 0xb6, 0xd9, 0xfe,
0xe8, 0xda, 0x5e, 0xb2, 0x34, 0x53, 0x8f, 0xb9, 0x3e, 0x8d, 0x19, 0x0d, 0xd0, 0xe8, 0x36, 0x9b,
0x54, 0x69, 0x45, 0x66, 0x35, 0xc7, 0xbd, 0xed, 0xd9, 0x13, 0x3a, 0x12, 0x20, 0xbb, 0xb3, 0xcd,
0x9e, 0xb4, 0x71, 0x2b, 0x9b, 0x25, 0xaf, 0xfe, 0xd9, 0x1f, 0xe4, 0x98, 0x57, 0xa3, 0x8a, 0x8c,
0xf4, 0xcd, 0x9e, 0xb4, 0xf1, 0xfa, 0xa7, 0xc9, 0x87, 0x6d, 0xaf, 0x66, 0x21, 0xda, 0xea, 0x34,
0x05, 0xd6, 0xa2, 0xa7, 0xfd, 0x15, 0xdc, 0x96, 0xe6, 0xab, 0xb4, 0x92, 0xa2, 0x5c, 0x8d, 0x2e,
0xc5, 0x75, 0x73, 0x67, 0x3c, 0x9c, 0xad, 0x06, 0x18, 0x7a, 0x04, 0xb1, 0xa5, 0xc1, 0xc9, 0x96,
0x2b, 0x77, 0xb7, 0xbc, 0x22, 0x5c, 0x79, 0x44, 0x87, 0xab, 0x90, 0x74, 0xb1, 0xaa, 0xa9, 0x95,
0xbb, 0x08, 0xbf, 0x8e, 0x17, 0xb5, 0x7d, 0x19, 0xfe, 0x61, 0x37, 0xe8, 0x32, 0x16, 0x23, 0xde,
0x4d, 0x2f, 0x2e, 0x6c, 0x9d, 0xf0, 0x92, 0xfa, 0x08, 0x91, 0xb1, 0x10, 0xa8, 0x4b, 0xba, 0xf7,
0xd2, 0x8c, 0xab, 0x13, 0xfd, 0x57, 0x17, 0x17, 0x99, 0x60, 0x53, 0x90, 0x74, 0xd7, 0xe2, 0xa1,
0x2f, 0x27, 0x92, 0x6e, 0x8c, 0x73, 0x57, 0xce, 0x6a, 0xe9, 0x29, 0x9f, 0x88, 0x7c, 0x92, 0x66,
0xf0, 0x0a, 0x9d, 0xd2, 0xb4, 0x42, 0xe2, 0xca, 0x59, 0x0b, 0x72, 0x0b, 0x63, 0x2d, 0xaa, 0xa7,
0x7d, 0x53, 0xfe, 0xfb, 0x6d, 0x45, 0x4f, 0x4c, 0x2c, 0x8c, 0x08, 0xe6, 0xf6, 0x9e, 0xb5, 0xf0,
0xac, 0x50, 0xc6, 0xef, 0xb4, 0xb5, 0xb4, 0x84, 0xd8, 0x7b, 0x86, 0x84, 0xdb, 0x43, 0xd5, 0xbf,
0xef, 0x8a, 0xeb, 0x5c, 0x19, 0xbd, 0xdb, 0x56, 0x69, 0x64, 0xc4, 0x1e, 0x0a, 0x32, 0xc6, 0xf0,
0x4f, 0x92, 0xff, 0xaf, 0x0c, 0x97, 0xa2, 0x18, 0xdc, 0x42, 0x14, 0x4a, 0xef, 0xb6, 0xdb, 0x6d,
0x52, 0xee, 0x2e, 0x6d, 0xda, 0xb1, 0x71, 0x56, 0xb1, 0x19, 0x1f, 0xdc, 0x23, 0x7a, 0x5c, 0x49,
0x89, 0x4b, 0x9b, 0x6d, 0x2a, 0x1c, 0x15, 0xc7, 0x62, 0x6a, 0xac, 0x23, 0x35, 0xb4, 0xc2, 0xd8,
0xa8, 0xf0, 0x21, 0x97, 0xcc, 0x1c, 0xb3, 0x65, 0x3a, 0xb3, 0x0b, 0x8e, 0x8e, 0x5b, 0x15, 0x48,
0x66, 0x1c, 0x33, 0xf4, 0x20, 0x22, 0x99, 0x21, 0x61, 0xe3, 0xf3, 0x9f, 0xd7, 0x92, 0x3b, 0x8e,
0xd9, 0x6f, 0x4e, 0xeb, 0x0e, 0xf2, 0x0b, 0x51, 0xa7, 0x3e, 0x87, 0x69, 0x7e, 0x55, 0x0d, 0xbe,
0xa0, 0x4c, 0xe2, 0xbc, 0x2d, 0xca, 0x97, 0x37, 0xd6, 0x73, 0x59, 0x6b, 0x73, 0x94, 0xe5, 0x9e,
0x67, 0x6b, 0x0d, 0x90, 0xb5, 0xda, 0x13, 0x2f, 0xc8, 0x11, 0x59, 0x6b, 0x8c, 0x77, 0x5d, 0x6c,
0x9d, 0x67, 0x22, 0x87, 0x5d, 0xec, 0x2c, 0xd4, 0x42, 0xa2, 0x8b, 0x5b, 0x90, 0x8b, 0xc7, 0x8d,
0x48, 0x9f, 0xba, 0x6c, 0x67, 0x19, 0x88, 0xc7, 0x56, 0xd5, 0x02, 0x44, 0x3c, 0x46, 0x41, 0xe3,
0xe7, 0x34, 0xf9, 0x4e, 0xdd, 0xa4, 0x27, 0x25, 0x5f, 0xa6, 0x1c, 0x5e, 0xbd, 0xf0, 0x24, 0xc4,
0xfc, 0x0f, 0x09, 0x37, 0xb3, 0xce, 0xf2, 0xaa, 0xc8, 0x58, 0x75, 0x69, 0x1e, 0xc6, 0x87, 0x75,
0x6e, 0x84, 0xf0, 0x71, 0xfc, 0xfd, 0x0e, 0xca, 0x05, 0xf5, 0x46, 0x66, 0x43, 0xcc, 0x03, 0x5c,
0xb5, 0x15, 0x66, 0xd6, 0x3b, 0x39, 0x77, 0xe2, 0xbd, 0xcf, 0xb2, 0x8c, 0x97, 0xab, 0x46, 0x76,
0xc4, 0xf2, 0xf4, 0x82, 0x57, 0x12, 0x9c, 0x78, 0x1b, 0x6a, 0x08, 0x31, 0xe2, 0xc4, 0x3b, 0x82,
0xbb, 0x6c, 0x1e, 0x78, 0x3e, 0xc8, 0xa7, 0xfc, 0x2d, 0xc8, 0xe6, 0xa1, 0x1d, 0xc5, 0x10, 0xd9,
0x3c, 0xc5, 0xba, 0x93, 0xdf, 0x17, 0x99, 0x98, 0x5c, 0x99, 0x25, 0x20, 0xec, 0x60, 0x25, 0x81,
0x6b, 0xc0, 0xdd, 0x18, 0xe2, 0x16, 0x01, 0x25, 0x38, 0xe5, 0x45, 0xc6, 0x26, 0xf0, 0xfe, 0x8d,
0xd6, 0x31, 0x32, 0x62, 0x11, 0x80, 0x0c, 0x28, 0xae, 0xb9, 0xd7, 0x83, 0x15, 0x17, 0x5c, 0xeb,
0xb9, 0x1b, 0x43, 0xdc, 0x32, 0xa8, 0x04, 0xa3, 0x22, 0x4b, 0x25, 0x98, 0x06, 0x5a, 0x43, 0x49,
0x88, 0x69, 0x10, 0x12, 0xc0, 0xe4, 0x11, 0x2f, 0x67, 0x1c, 0x35, 0xa9, 0x24, 0x51, 0x93, 0x0d,
0xe1, 0xae, 0x69, 0xea, 0xba, 0x8b, 0x62, 0x05, 0xae, 0x69, 0x9a, 0x6a, 0x89, 0x62, 0x45, 0x5c,
0xd3, 0x0c, 0x00, 0x50, 0xc4, 0x13, 0x56, 0x49, 0xbc, 0x88, 0x4a, 0x12, 0x2d, 0x62, 0x43, 0xb8,
0x35, 0x5a, 0x17, 0x71, 0x21, 0xc1, 0x1a, 0x6d, 0x0a, 0xe0, 0x3d, 0x81, 0xbe, 0x4d, 0xca, 0x5d,
0x24, 0xd1, 0xbd, 0xc2, 0xe5, 0x5e, 0xca, 0xb3, 0x69, 0x05, 0x22, 0x89, 0x69, 0xf7, 0x46, 0x4a,
0x44, 0x92, 0x36, 0x05, 0x86, 0x92, 0x39, 0x1f, 0xc7, 0x6a, 0x07, 0x8e, 0xc6, 0xef, 0xc6, 0x10,
0x17, 0x9f, 0x9a, 0x42, 0xef, 0xb0, 0xb2, 0x4c, 0xeb, 0xc5, 0xff, 0x01, 0x5e, 0xa0, 0x46, 0x4e,
0xc4, 0x27, 0x8c, 0x03, 0xd3, 0xab, 0x09, 0xdc, 0x58, 0xc1, 0x60, 0xe8, 0xfe, 0x24, 0xca, 0xb8,
0x8c, 0x53, 0x49, 0xbc, 0x47, 0xa8, 0x58, 0x6b, 0x22, 0x4f, 0x50, 0x1f, 0x74, 0x61, 0xde, 0x6b,
0x14, 0xd6, 0xc5, 0x91, 0x58, 0xf2, 0xb1, 0x78, 0xf9, 0x36, 0xad, 0x64, 0x9a, 0xcf, 0xcc, 0xca,
0xfd, 0x9c, 0xb0, 0x84, 0xc1, 0xc4, 0x6b, 0x14, 0x9d, 0x4a, 0x2e, 0x81, 0x00, 0x65, 0x39, 0xe6,
0xd7, 0x68, 0x02, 0x01, 0x2d, 0x5a, 0x8e, 0x48, 0x20, 0x62, 0xbc, 0x3b, 0x47, 0xb1, 0xce, 0xcd,
0xbb, 0xa6, 0x63, 0xd1, 0xe4, 0x72, 0x94, 0x35, 0x08, 0x12, 0x5b, 0xd9, 0xa8, 0x82, 0xdb, 0x5f,
0x5a, 0xff, 0x6e, 0x8a, 0x3d, 0x24, 0xec, 0xb4, 0xa7, 0xd9, 0xa3, 0x1e, 0x24, 0xe2, 0xca, 0xdd,
0x03, 0xa0, 0x5c, 0xb5, 0xaf, 0x01, 0x3c, 0xea, 0x41, 0x7a, 0x67, 0x32, 0x7e, 0xb5, 0x5e, 0xb0,
0xc9, 0xd5, 0xac, 0x14, 0x8b, 0x7c, 0xba, 0x23, 0x32, 0x51, 0x82, 0x33, 0x99, 0xa0, 0xd4, 0x00,
0x25, 0xce, 0x64, 0x3a, 0x54, 0x5c, 0x06, 0xe7, 0x97, 0x62, 0x3b, 0x4b, 0x67, 0x70, 0x47, 0x1d,
0x18, 0x52, 0x00, 0x91, 0xc1, 0xa1, 0x20, 0x32, 0x88, 0xf4, 0x8e, 0x5b, 0xa6, 0x13, 0x96, 0x69,
0x7f, 0x5b, 0xb4, 0x99, 0x00, 0xec, 0x1c, 0x44, 0x88, 0x02, 0x52, 0xcf, 0xf1, 0xa2, 0xcc, 0x0f,
0x72, 0x29, 0xc8, 0x7a, 0x36, 0x40, 0x67, 0x3d, 0x3d, 0x10, 0x84, 0xd5, 0x31, 0x7f, 0x5b, 0x97,
0xa6, 0xfe, 0x07, 0x0b, 0xab, 0xf5, 0xef, 0x43, 0x23, 0x8f, 0x85, 0x55, 0xc0, 0x81, 0xca, 0x18,
0x27, 0x7a, 0xc0, 0x44, 0xb4, 0xc3, 0x61, 0xf2, 0xb0, 0x1b, 0xc4, 0xfd, 0x8c, 0xe4, 0x2a, 0xe3,
0x31, 0x3f, 0x0a, 0xe8, 0xe3, 0xa7, 0x01, 0xdd, 0x71, 0x4b, 0x50, 0x9f, 0x4b, 0x3e, 0xb9, 0x6a,
0x5d, 0x6b, 0x0a, 0x0b, 0xaa, 0x11, 0xe2, 0xb8, 0x85, 0x40, 0xf1, 0x2e, 0x3a, 0x98, 0x88, 0x3c,
0xd6, 0x45, 0xb5, 0xbc, 0x4f, 0x17, 0x19, 0xce, 0x6d, 0x7e, 0xad, 0xd4, 0x8c, 0x4c, 0xdd, 0x4d,
0x1b, 0x84, 0x05, 0x1f, 0x22, 0x36, 0xbf, 0x24, 0xec, 0x72, 0x72, 0xe8, 0xf3, 0xa8, 0x7d, 0xe7,
0xbb, 0x65, 0xe5, 0x88, 0xbe, 0xf3, 0x4d, 0xb1, 0x74, 0x25, 0xf5, 0x18, 0xe9, 0xb0, 0x12, 0x8e,
0x93, 0x27, 0xfd, 0x60, 0xb7, 0xe5, 0x09, 0x7c, 0xee, 0x64, 0x9c, 0x95, 0xda, 0xeb, 0x66, 0xc4,
0x90, 0xc3, 0x88, 0x2d, 0x4f, 0x04, 0x07, 0x21, 0x2c, 0xf0, 0xbc, 0x23, 0x72, 0xc9, 0x73, 0x89,
0x85, 0xb0, 0xd0, 0x98, 0x01, 0x63, 0x21, 0x8c, 0x52, 0x00, 0xe3, 0x56, 0x9d, 0x07, 0x71, 0x79,
0xcc, 0xe6, 0x68, 0xc6, 0xa6, 0xcf, 0x7a, 0xb4, 0x3c, 0x36, 0x6e, 0x01, 0xe7, 0x3d, 0xe4, 0xf3,
0xbd, 0x8c, 0x59, 0x39, 0xb3, 0xa7, 0x1b, 0xd3, 0xc1, 0x53, 0xda, 0x4e, 0x48, 0x12, 0x0f, 0xf9,
0xe2, 0x1a, 0x20, 0xec, 0x1c, 0xcc, 0xd9, 0xcc, 0xd6, 0x14, 0xa9, 0x81, 0x92, 0xb7, 0xaa, 0xfa,
0xb0, 0x1b, 0x04, 0x7e, 0x5e, 0xa7, 0x53, 0x2e, 0x22, 0x7e, 0x94, 0xbc, 0x8f, 0x1f, 0x08, 0x82,
0xec, 0xad, 0xae, 0xb7, 0xde, 0xd1, 0x6d, 0xe7, 0x53, 0xb3, 0x8f, 0x1d, 0x12, 0xcd, 0x03, 0xb8,
0x58, 0xf6, 0x46, 0xf0, 0x60, 0x8e, 0x36, 0x07, 0xb4, 0xb1, 0x39, 0x6a, 0xcf, 0x5f, 0xfb, 0xcc,
0x51, 0x0c, 0x36, 0x3e, 0x7f, 0x66, 0xe6, 0xe8, 0x2e, 0x93, 0xac, 0xce, 0xdb, 0x5f, 0xa7, 0xfc,
0xda, 0x6c, 0x84, 0x91, 0xfa, 0x36, 0xd4, 0x50, 0xbd, 0xec, 0x07, 0x76, 0xc5, 0x5b, 0xbd, 0xf9,
0x88, 0x6f, 0xb3, 0x43, 0xe8, 0xf4, 0x0d, 0xb6, 0x0a, 0x5b, 0xbd, 0xf9, 0x88, 0x6f, 0xf3, 0x16,
0x71, 0xa7, 0x6f, 0xf0, 0x2a, 0xf1, 0x56, 0x6f, 0xde, 0xf8, 0xfe, 0xcb, 0x66, 0xe2, 0xfa, 0xce,
0xeb, 0x3c, 0x6c, 0x22, 0xd3, 0x25, 0xc7, 0xd2, 0xc9, 0xd0, 0x9e, 0x45, 0x63, 0xe9, 0x24, 0xad,
0xe2, 0x7d, 0x7a, 0x06, 0x2b, 0xc5, 0x89, 0xa8, 0x52, 0xf5, 0x90, 0xfe, 0x79, 0x0f, 0xa3, 0x0d,
0x1c, 0xdb, 0x34, 0xc5, 0x94, 0xdc, 0xe3, 0xc6, 0x00, 0x75, 0xb7, 0x98, 0x9f, 0x44, 0xec, 0xb5,
0x2f, 0x33, 0x6f, 0xf6, 0xa4, 0xdd, 0x83, 0xbf, 0x80, 0xf1, 0x9f, 0x38, 0xc6, 0x7a, 0x15, 0x7d,
0xe8, 0xf8, 0xb4, 0xbf, 0x82, 0x71, 0xff, 0xd7, 0xcd, 0xbe, 0x02, 0xfa, 0x37, 0x93, 0xe0, 0x59,
0x1f, 0x8b, 0x60, 0x22, 0x3c, 0xbf, 0x91, 0x8e, 0x29, 0xc8, 0xdf, 0x37, 0x1b, 0xe8, 0x06, 0x55,
0xef, 0x72, 0xbc, 0x2a, 0xa7, 0xbc, 0x34, 0x73, 0x22, 0xd6, 0xad, 0x0e, 0x86, 0x33, 0xe3, 0xf3,
0x1b, 0x6a, 0x79, 0x1f, 0x22, 0x0a, 0x60, 0xf3, 0xce, 0xa1, 0x57, 0x9e, 0x98, 0x65, 0x8f, 0x86,
0x05, 0xfa, 0xe2, 0xa6, 0x6a, 0xd4, 0x5c, 0xf1, 0x60, 0xf5, 0x5d, 0x83, 0xe7, 0x3d, 0x0d, 0x07,
0x5f, 0x3a, 0xf8, 0xec, 0x66, 0x4a, 0xa6, 0x2c, 0xff, 0xb1, 0x96, 0xdc, 0x0f, 0x58, 0xf7, 0x3c,
0x01, 0x9c, 0x7a, 0xfc, 0x38, 0x62, 0x9f, 0x52, 0xb2, 0x85, 0xfb, 0xdd, 0x5f, 0x4e, 0xd9, 0x7d,
0xb5, 0x27, 0x50, 0xd9, 0x4b, 0x33, 0xc9, 0xcb, 0xf6, 0x57, 0x7b, 0x42, 0xbb, 0x9a, 0x1a, 0xd2,
0x5f, 0xed, 0x89, 0xe0, 0xde, 0x57, 0x7b, 0x10, 0xcf, 0xe8, 0x57, 0x7b, 0x50, 0x6b, 0xd1, 0xaf,
0xf6, 0xc4, 0x35, 0xa8, 0xf0, 0xde, 0x14, 0x41, 0x9f, 0x5b, 0xf7, 0xb2, 0x18, 0x1e, 0x63, 0x3f,
0xbb, 0x89, 0x0a, 0xb1, 0xc0, 0x69, 0x4e, 0xdd, 0x73, 0xeb, 0xd1, 0xa6, 0xc1, 0x5d, 0xb7, 0xad,
0xde, 0xbc, 0xf1, 0xfd, 0x53, 0xb3, 0xbb, 0xb1, 0xe1, 0x5c, 0x94, 0xea, 0x8b, 0x4d, 0x1b, 0xb1,
0xf0, 0x5c, 0x5b, 0xf0, 0x7b, 0xfe, 0x49, 0x3f, 0x98, 0xa8, 0x6e, 0x4d, 0x98, 0x4e, 0x1f, 0x76,
0x19, 0x02, 0x5d, 0xbe, 0xd5, 0x9b, 0x27, 0x96, 0x11, 0xed, 0x5b, 0xf7, 0x76, 0x0f, 0x63, 0x61,
0x5f, 0x3f, 0xed, 0xaf, 0x60, 0xdc, 0x2f, 0x4d, 0xda, 0xe8, 0xbb, 0x57, 0xfd, 0xbc, 0xd9, 0x65,
0x6a, 0x14, 0x74, 0xf3, 0xb0, 0x2f, 0x1e, 0x4b, 0x20, 0xfc, 0x25, 0xb4, 0x2b, 0x81, 0x40, 0x97,
0xd1, 0xcf, 0x6e, 0xa6, 0x64, 0xca, 0xf2, 0x4f, 0x6b, 0xc9, 0x6d, 0xb2, 0x2c, 0x66, 0x1c, 0x7c,
0xd1, 0xd7, 0x32, 0x18, 0x0f, 0x5f, 0xde, 0x58, 0xcf, 0x14, 0xea, 0x5f, 0xd7, 0x92, 0x3b, 0x91,
0x42, 0xe9, 0x01, 0x72, 0x03, 0xeb, 0xe1, 0x40, 0xf9, 0xe1, 0xcd, 0x15, 0xa9, 0xe5, 0xde, 0xc7,
0x47, 0xed, 0xcf, 0xd9, 0x44, 0x6c, 0x8f, 0xe8, 0xcf, 0xd9, 0x74, 0x6b, 0xc1, 0x43, 0x1e, 0x76,
0xde, 0x6c, 0xba, 0xd0, 0x43, 0x1e, 0x75, 0x43, 0x0d, 0xec, 0x39, 0xd6, 0x3b, 0x39, 0xcc, 0xc9,
0xcb, 0xb7, 0x05, 0xcb, 0xa7, 0xb4, 0x13, 0x2d, 0xef, 0x76, 0x62, 0x39, 0x78, 0x38, 0x56, 0x4b,
0x4f, 0x45, 0xb3, 0x91, 0x7a, 0x44, 0xe9, 0x5b, 0x24, 0x7a, 0x38, 0xd6, 0x42, 0x09, 0x6f, 0x26,
0x6b, 0x8c, 0x79, 0x03, 0xc9, 0xe2, 0xe3, 0x3e, 0x28, 0x48, 0xd1, 0xad, 0x37, 0x7b, 0xe6, 0xfe,
0x24, 0x66, 0xa5, 0x75, 0xee, 0xbe, 0xd9, 0x93, 0x26, 0xdc, 0x8e, 0xb8, 0xfc, 0x8a, 0xb3, 0x29,
0x2f, 0xa3, 0x6e, 0x2d, 0xd5, 0xcb, 0xad, 0x4f, 0x63, 0x6e, 0x77, 0x44, 0xb6, 0x98, 0xe7, 0xa6,
0x33, 0x49, 0xb7, 0x3e, 0xd5, 0xed, 0x16, 0xd0, 0xf0, 0x58, 0xd0, 0xb9, 0x55, 0xe9, 0xe5, 0xe3,
0xb8, 0x99, 0x20, 0xab, 0xdc, 0xe8, 0xc5, 0xd2, 0xf5, 0x34, 0xc3, 0xa8, 0xa3, 0x9e, 0x60, 0x24,
0x6d, 0xf6, 0xa4, 0xe1, 0xf9, 0x9c, 0xe7, 0xd6, 0x8e, 0xa7, 0xad, 0x0e, 0x5b, 0xad, 0x21, 0xf5,
0xb4, 0xbf, 0x02, 0x3c, 0x0d, 0x35, 0xa3, 0xea, 0x30, 0xad, 0xe4, 0x5e, 0x9a, 0x65, 0x83, 0x8d,
0xc8, 0x30, 0x69, 0xa0, 0xe8, 0x69, 0x28, 0x02, 0x13, 0x23, 0xb9, 0x39, 0x3d, 0xcc, 0x07, 0x5d,
0x76, 0x14, 0xd5, 0x6b, 0x24, 0xfb, 0x34, 0x38, 0xd1, 0xf2, 0x9a, 0xda, 0xd6, 0x76, 0x18, 0x6f,
0xb8, 0x56, 0x85, 0xb7, 0x7a, 0xf3, 0xe0, 0x71, 0xbb, 0xa2, 0xd4, 0xca, 0x72, 0x8f, 0x32, 0x11,
0xac, 0x24, 0xf7, 0x3b, 0x28, 0x70, 0x2a, 0xa8, 0xa7, 0xd1, 0x9b, 0x74, 0x3a, 0xe3, 0x12, 0x7d,
0x52, 0xe4, 0x03, 0xd1, 0x27, 0x45, 0x00, 0x04, 0x5d, 0xa7, 0x7f, 0xb7, 0xc7, 0xa1, 0x07, 0x53,
0xac, 0xeb, 0x8c, 0xb2, 0x47, 0xc5, 0xba, 0x0e, 0xa5, 0x41, 0x34, 0xb0, 0x6e, 0xcd, 0xeb, 0xf8,
0x8f, 0x63, 0x66, 0xc0, 0x3b, 0xf9, 0x1b, 0xbd, 0x58, 0xb0, 0xa2, 0x38, 0x87, 0xe9, 0x3c, 0x95,
0xd8, 0x8a, 0xe2, 0xd9, 0xa8, 0x91, 0xd8, 0x8a, 0xd2, 0x46, 0xa9, 0xea, 0xd5, 0x39, 0xc2, 0xc1,
0x34, 0x5e, 0x3d, 0xcd, 0xf4, 0xab, 0x9e, 0x65, 0x5b, 0x0f, 0x36, 0x73, 0x3b, 0x64, 0xe4, 0xa5,
0xd9, 0x2c, 0x23, 0x63, 0x5b, 0xbd, 0xa6, 0x09, 0xc1, 0x58, 0xd4, 0xa1, 0x14, 0xe0, 0x81, 0x7d,
0xcd, 0x35, 0xcf, 0x5e, 0x8b, 0x82, 0xb3, 0x92, 0xe5, 0x13, 0x74, 0x73, 0xaa, 0x0c, 0xb6, 0xc8,
0xd8, 0xe6, 0x94, 0xd4, 0x00, 0x8f, 0xcd, 0xc3, 0x17, 0x2c, 0x91, 0xa9, 0x60, 0xdf, 0x64, 0x0c,
0xdf, 0xaf, 0x7c, 0xd4, 0x83, 0x84, 0x8f, 0xcd, 0x1b, 0xc0, 0x1e, 0x7c, 0x6b, 0xa7, 0x9f, 0x46,
0x4c, 0x85, 0x68, 0x6c, 0x23, 0x4c, 0xab, 0x80, 0x41, 0x6d, 0x13, 0x5c, 0x2e, 0x7f, 0xc2, 0x57,
0xd8, 0xa0, 0x76, 0xf9, 0xa9, 0x42, 0x62, 0x83, 0xba, 0x8d, 0x82, 0x3c, 0xd3, 0xdf, 0x07, 0x3d,
0x88, 0xe8, 0xfb, 0x5b, 0x9f, 0xf5, 0x4e, 0x0e, 0xcc, 0x9c, 0xdd, 0x74, 0x19, 0x3c, 0x27, 0x40,
0x0a, 0xba, 0x9b, 0x2e, 0xf1, 0xc7, 0x04, 0x1b, 0xbd, 0x58, 0xf8, 0x48, 0x9e, 0x49, 0xfe, 0xb6,
0x79, 0x56, 0x8e, 0x14, 0x57, 0xc9, 0x5b, 0x0f, 0xcb, 0x1f, 0x76, 0x83, 0xee, 0x02, 0xec, 0x49,
0x29, 0x26, 0xbc, 0xaa, 0xcc, 0x37, 0xfe, 0xc2, 0x1b, 0x46, 0x46, 0x36, 0x04, 0x5f, 0xf8, 0xbb,
0x17, 0x87, 0x5c, 0xcf, 0x18, 0x91, 0xfb, 0xea, 0xcd, 0x03, 0x54, 0xb3, 0xfd, 0xc1, 0x9b, 0xf5,
0x4e, 0xce, 0x4d, 0x2f, 0x23, 0xf5, 0x3f, 0x73, 0xf3, 0x10, 0x55, 0xc7, 0xbe, 0x70, 0xf3, 0xa8,
0x07, 0x69, 0x5c, 0x7d, 0x95, 0xbc, 0x7b, 0x28, 0x66, 0x23, 0x9e, 0x4f, 0x07, 0x3f, 0x08, 0xaf,
0xd0, 0x8a, 0xd9, 0xb0, 0xfe, 0xd9, 0x1a, 0xbd, 0x45, 0x89, 0xdd, 0x25, 0xc0, 0x5d, 0x7e, 0xbe,
0x98, 0x8d, 0x24, 0x93, 0xe0, 0x12, 0xa0, 0xfa, 0x7d, 0x58, 0x0b, 0x88, 0x4b, 0x80, 0x01, 0x00,
0xec, 0x8d, 0x4b, 0xce, 0x51, 0x7b, 0xb5, 0x20, 0x6a, 0xcf, 0x00, 0x2e, 0x8b, 0xb0, 0xf6, 0xea,
0x44, 0x1d, 0x5e, 0xda, 0x73, 0x3a, 0x4a, 0x4a, 0x64, 0x11, 0x6d, 0xca, 0x0d, 0x6e, 0x5d, 0x7d,
0xf5, 0xd5, 0x91, 0xc5, 0x7c, 0xce, 0xca, 0x15, 0x18, 0xdc, 0xa6, 0x96, 0x1e, 0x40, 0x0c, 0x6e,
0x14, 0x74, 0xb3, 0xb6, 0x69, 0xe6, 0xc9, 0xd5, 0xbe, 0x28, 0xc5, 0x42, 0xa6, 0x39, 0x87, 0x5f,
0x9e, 0xb0, 0x0d, 0xea, 0x33, 0xc4, 0xac, 0xa5, 0x58, 0x97, 0xe5, 0x2a, 0x42, 0xdf, 0x27, 0x54,
0x5f, 0xfe, 0xad, 0xa4, 0x28, 0xe1, 0xf3, 0x44, 0x6d, 0x05, 0x42, 0x44, 0x96, 0x4b, 0xc2, 0xa0,
0xef, 0x4f, 0xd2, 0x7c, 0x86, 0xf6, 0xfd, 0x89, 0xff, 0xdd, 0xcc, 0x3b, 0x34, 0xe0, 0x26, 0x94,
0x6e, 0x34, 0x3d, 0x01, 0xcc, 0xbb, 0x9c, 0x68, 0xa3, 0xfb, 0x04, 0x31, 0xa1, 0x70, 0x12, 0xb8,
0x7a, 0x55, 0xf0, 0x9c, 0x4f, 0x9b, 0x5b, 0x73, 0x98, 0xab, 0x80, 0x88, 0xba, 0x82, 0xa4, 0x8b,
0x45, 0x4a, 0x7e, 0xba, 0xc8, 0x4f, 0x4a, 0x71, 0x91, 0x66, 0xbc, 0x04, 0xb1, 0x48, 0xab, 0x7b,
0x72, 0x22, 0x16, 0x61, 0x9c, 0xbb, 0x7e, 0xa1, 0xa4, 0xc1, 0xe7, 0xab, 0xc7, 0x25, 0x9b, 0xc0,
0xeb, 0x17, 0xda, 0x46, 0x1b, 0x23, 0x4e, 0x06, 0x23, 0xb8, 0x97, 0xe8, 0x68, 0xd7, 0xf9, 0x4a,
0x8d, 0x0f, 0xf3, 0x2e, 0xa1, 0xfa, 0x9a, 0x64, 0x05, 0x12, 0x1d, 0x63, 0x0e, 0x23, 0x89, 0x44,
0x27, 0xae, 0xe1, 0x96, 0x12, 0xc5, 0x1d, 0x9b, 0x6b, 0x45, 0x60, 0x29, 0xd1, 0x36, 0x1a, 0x21,
0xb1, 0x94, 0xb4, 0x20, 0x10, 0x90, 0x9a, 0x69, 0x30, 0x43, 0x03, 0x92, 0x95, 0x46, 0x03, 0x92,
0x4f, 0xb9, 0x40, 0x71, 0x90, 0xa7, 0x32, 0x65, 0xd9, 0x88, 0xcb, 0x13, 0x56, 0xb2, 0x39, 0x97,
0xbc, 0x84, 0x81, 0xc2, 0x20, 0xc3, 0x80, 0x21, 0x02, 0x05, 0xc5, 0x1a, 0x87, 0xbf, 0x97, 0xbc,
0x5f, 0xaf, 0xfb, 0x3c, 0x37, 0x7f, 0xa8, 0xe2, 0xa5, 0xfa, 0x0b, 0x37, 0x83, 0x0f, 0xac, 0x8d,
0x91, 0x2c, 0x39, 0x9b, 0x37, 0xb6, 0xdf, 0xb3, 0xbf, 0x2b, 0xf0, 0xe9, 0x5a, 0x3d, 0x9e, 0x8f,
0x85, 0x4c, 0x2f, 0xea, 0x6d, 0xb6, 0x79, 0x83, 0x08, 0x8c, 0x67, 0x5f, 0x3c, 0x8c, 0x7c, 0x8b,
0x02, 0xe3, 0x5c, 0x9c, 0xf6, 0xa5, 0xa7, 0xbc, 0xc8, 0x60, 0x9c, 0x0e, 0xb4, 0x15, 0x40, 0xc4,
0x69, 0x14, 0x74, 0x93, 0xd3, 0x17, 0x8f, 0x79, 0xbc, 0x32, 0x63, 0xde, 0xaf, 0x32, 0xe3, 0xe0,
0xa5, 0x8c, 0x2c, 0x79, 0xff, 0x88, 0xcf, 0xcf, 0x79, 0x59, 0x5d, 0xa6, 0xc5, 0x7e, 0x9d, 0x70,
0x31, 0xb9, 0x80, 0xaf, 0x2d, 0x3a, 0x62, 0x68, 0x11, 0x22, 0x2b, 0x25, 0x50, 0xb7, 0x12, 0x38,
0xe0, 0xa0, 0x3a, 0x66, 0x73, 0xae, 0xbe, 0xac, 0x01, 0x56, 0x02, 0xcf, 0x88, 0x07, 0x11, 0x2b,
0x01, 0x09, 0x7b, 0xef, 0x77, 0x39, 0xe6, 0x94, 0xcf, 0xea, 0x11, 0x56, 0x9e, 0xb0, 0xd5, 0x9c,
0xe7, 0xd2, 0x98, 0x04, 0x67, 0xf2, 0x9e, 0x49, 0x9c, 0x27, 0xce, 0xe4, 0xfb, 0xe8, 0x79, 0xa1,
0x29, 0x68, 0xf8, 0x13, 0x51, 0x4a, 0xfd, 0x67, 0x68, 0xce, 0xca, 0x0c, 0x84, 0xa6, 0xb0, 0x51,
0x03, 0x92, 0x08, 0x4d, 0x71, 0x0d, 0xef, 0xfb, 0xed, 0x41, 0x19, 0x5e, 0xf3, 0xd2, 0x8e, 0x93,
0x97, 0x73, 0x96, 0x66, 0x66, 0x34, 0xfc, 0x28, 0x62, 0x9b, 0xd0, 0x21, 0xbe, 0xdf, 0xde, 0x57,
0xd7, 0xfb, 0xe2, 0x7d, 0xbc, 0x84, 0xe0, 0x11, 0x41, 0x87, 0x7d, 0xe2, 0x11, 0x41, 0xb7, 0x96,
0xdb, 0xb9, 0x3b, 0x56, 0x71, 0x2b, 0x45, 0xec, 0x88, 0x29, 0x3c, 0x2f, 0xf4, 0x6c, 0x02, 0x90,
0xd8, 0xb9, 0x47, 0x15, 0x5c, 0x6a, 0xe0, 0xb0, 0xbd, 0x34, 0x67, 0x59, 0xfa, 0x33, 0x98, 0xd6,
0x7b, 0x76, 0x1a, 0x82, 0x48, 0x0d, 0x70, 0x12, 0x73, 0xb5, 0xcf, 0xe5, 0x38, 0xad, 0x43, 0xff,
0xc3, 0x48, 0xbb, 0x29, 0xa2, 0xdb, 0x95, 0x47, 0x7a, 0xdf, 0x68, 0x85, 0xcd, 0xba, 0x5d, 0x14,
0xa3, 0x7a, 0x55, 0x3d, 0xe5, 0x13, 0x9e, 0x16, 0x72, 0xf0, 0x79, 0xbc, 0xad, 0x00, 0x4e, 0x5c,
0xb4, 0xe8, 0xa1, 0xe6, 0x3d, 0xbe, 0xaf, 0x63, 0xc9, 0x48, 0xff, 0x7d, 0xb6, 0xb3, 0x8a, 0x97,
0x26, 0xd1, 0xd8, 0xe7, 0x12, 0xcc, 0x4e, 0x8f, 0x1b, 0x7a, 0x60, 0x5d, 0x51, 0x62, 0x76, 0xc6,
0x35, 0xdc, 0x61, 0x9f, 0xc7, 0x9d, 0xf2, 0x4a, 0x64, 0x4b, 0xae, 0xee, 0x1b, 0x3e, 0x21, 0x8d,
0x79, 0x14, 0x71, 0xd8, 0x47, 0xd3, 0x2e, 0x5b, 0x6b, 0xbb, 0xdd, 0xce, 0x57, 0x07, 0xf0, 0xca,
0x04, 0x62, 0x49, 0x61, 0x44, 0xb6, 0x16, 0xc1, 0xbd, 0xc3, 0xf0, 0x52, 0xb0, 0xe9, 0x84, 0x55,
0xf2, 0x84, 0xad, 0x32, 0xc1, 0xa6, 0x6a, 0x5d, 0x87, 0x87, 0xe1, 0x0d, 0x33, 0xf4, 0x21, 0xea,
0x30, 0x9c, 0x82, 0xfd, 0xec, 0x4c, 0xfd, 0xd9, 0x39, 0x73, 0x97, 0x13, 0x66, 0x67, 0xaa, 0xbc,
0xf0, 0x1e, 0xe7, 0xbd, 0x38, 0xe4, 0xde, 0x41, 0xd3, 0x22, 0x95, 0x86, 0xdc, 0xc1, 0x74, 0x82,
0x04, 0xe4, 0xe3, 0x08, 0xe1, 0xbe, 0x4b, 0xa1, 0x7f, 0x6f, 0xfe, 0x72, 0x8a, 0x34, 0x5f, 0xb2,
0x7e, 0x82, 0xe9, 0xfa, 0xd0, 0xd0, 0xff, 0xc0, 0xdd, 0x66, 0x4f, 0xda, 0xa5, 0x99, 0x3b, 0x97,
0x4c, 0x6e, 0x4f, 0xa7, 0x47, 0xbc, 0x42, 0x5e, 0x28, 0xaf, 0x85, 0x43, 0x27, 0x25, 0xd2, 0xcc,
0x36, 0xe5, 0x06, 0x7a, 0x2d, 0x7b, 0x39, 0x4d, 0xa5, 0x91, 0x35, 0x37, 0xa4, 0x9f, 0xb4, 0x0d,
0xb4, 0x29, 0xa2, 0x56, 0x34, 0xed, 0x62, 0x79, 0xcd, 0x8c, 0xc5, 0x6c, 0x96, 0x71, 0x03, 0x9d,
0x72, 0xa6, 0x3f, 0xe4, 0xb7, 0xd5, 0xb6, 0x85, 0x82, 0x44, 0x2c, 0x8f, 0x2a, 0xb8, 0x34, 0xb2,
0xc6, 0xf4, 0x23, 0xa9, 0xa6, 0x61, 0xd7, 0xdb, 0x66, 0x02, 0x80, 0x48, 0x23, 0x51, 0xd0, 0xbd,
0xf7, 0x56, 0x8b, 0xf7, 0x79, 0xd3, 0x12, 0xf0, 0x13, 0x44, 0x4a, 0xd9, 0x13, 0x13, 0xef, 0xbd,
0x21, 0x98, 0xdb, 0x27, 0x00, 0x0f, 0x2f, 0x56, 0x07, 0x53, 0xb8, 0x4f, 0x80, 0xfa, 0x8a, 0x21,
0xf6, 0x09, 0x14, 0x1b, 0x76, 0x9d, 0x3d, 0xf7, 0x3a, 0x64, 0x95, 0xab, 0x1c, 0xd2, 0x75, 0x28,
0x18, 0xeb, 0x3a, 0x4a, 0x21, 0x6c, 0x52, 0xff, 0x68, 0x0d, 0x69, 0x52, 0xec, 0x5c, 0xed, 0x41,
0x17, 0xe6, 0xe2, 0x92, 0xdd, 0x4f, 0xaa, 0x2b, 0x4b, 0xf8, 0x17, 0xfc, 0xb5, 0x90, 0x88, 0x4b,
0x2d, 0x48, 0xdb, 0x7e, 0xf1, 0xf1, 0x7f, 0x7d, 0x73, 0x6b, 0xed, 0x17, 0xdf, 0xdc, 0x5a, 0xfb,
0x9f, 0x6f, 0x6e, 0xad, 0xfd, 0xfc, 0xdb, 0x5b, 0xef, 0xfc, 0xe2, 0xdb, 0x5b, 0xef, 0xfc, 0xf7,
0xb7, 0xb7, 0xde, 0xf9, 0xfa, 0x5d, 0xf3, 0xe7, 0x48, 0xcf, 0xff, 0x9f, 0xfa, 0xa3, 0xa2, 0xcf,
0xff, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x51, 0x19, 0x1a, 0x8e, 0xb2, 0x74, 0x00, 0x00,
// 5279 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x9d, 0x5b, 0x6f, 0x24, 0x49,
0x56, 0xf8, 0xc7, 0x2f, 0xff, 0xf9, 0x93, 0xcb, 0x0e, 0x50, 0x03, 0xc3, 0xec, 0xb0, 0xdb, 0xb7,
0xe9, 0xb6, 0xdd, 0x6d, 0xbb, 0xdc, 0xd3, 0x3d, 0x3d, 0xb3, 0xda, 0x45, 0x42, 0x6e, 0xbb, 0xed,
0x31, 0x6b, 0xbb, 0x8d, 0xab, 0xdc, 0x2d, 0x8d, 0x84, 0x44, 0x38, 0x2b, 0x5c, 0x4e, 0x9c, 0x95,
0x91, 0x9b, 0x19, 0x55, 0xee, 0x5a, 0x04, 0x02, 0x81, 0x40, 0x20, 0x10, 0x2b, 0x6e, 0xaf, 0x48,
0x7c, 0x1a, 0x1e, 0xf7, 0x91, 0x47, 0x34, 0x23, 0x1e, 0xf8, 0x16, 0x28, 0x23, 0x23, 0xe3, 0x72,
0xf2, 0x9c, 0xc8, 0xf4, 0x3e, 0x75, 0xab, 0xce, 0xef, 0x9c, 0x13, 0xd7, 0x13, 0x27, 0x22, 0x23,
0xd3, 0xd1, 0xdd, 0xfc, 0x62, 0x3b, 0x2f, 0x84, 0x14, 0xe5, 0x76, 0xc9, 0x8b, 0x45, 0x12, 0xf3,
0xe6, 0xdf, 0xa1, 0xfa, 0x79, 0xf0, 0x3e, 0xcb, 0x96, 0x72, 0x99, 0xf3, 0x4f, 0x3e, 0xb6, 0x64,
0x2c, 0x66, 0x33, 0x96, 0x4d, 0xca, 0x1a, 0xf9, 0xe4, 0x23, 0x2b, 0xe1, 0x0b, 0x9e, 0x49, 0xfd,
0xfb, 0xb3, 0xff, 0xf9, 0xdf, 0x95, 0xe8, 0x83, 0xdd, 0x34, 0xe1, 0x99, 0xdc, 0xd5, 0x1a, 0x83,
0xaf, 0xa3, 0xef, 0xee, 0xe4, 0xf9, 0x01, 0x97, 0x6f, 0x78, 0x51, 0x26, 0x22, 0x1b, 0x7c, 0x3a,
0xd4, 0x0e, 0x86, 0x67, 0x79, 0x3c, 0xdc, 0xc9, 0xf3, 0xa1, 0x15, 0x0e, 0xcf, 0xf8, 0x4f, 0xe7,
0xbc, 0x94, 0x9f, 0x3c, 0x0c, 0x43, 0x65, 0x2e, 0xb2, 0x92, 0x0f, 0x2e, 0xa3, 0xdf, 0xd8, 0xc9,
0xf3, 0x11, 0x97, 0x7b, 0xbc, 0xaa, 0xc0, 0x48, 0x32, 0xc9, 0x07, 0x6b, 0x2d, 0x55, 0x1f, 0x30,
0x3e, 0xd6, 0xbb, 0x41, 0xed, 0x67, 0x1c, 0x7d, 0xa7, 0xf2, 0x73, 0x35, 0x97, 0x13, 0x71, 0x93,
0x0d, 0xee, 0xb7, 0x15, 0xb5, 0xc8, 0xd8, 0x7e, 0x10, 0x42, 0xb4, 0xd5, 0xb7, 0xd1, 0xaf, 0xbe,
0x65, 0x69, 0xca, 0xe5, 0x6e, 0xc1, 0xab, 0x82, 0xfb, 0x3a, 0xb5, 0x68, 0x58, 0xcb, 0x8c, 0xdd,
0x4f, 0x83, 0x8c, 0x36, 0xfc, 0x75, 0xf4, 0xdd, 0x5a, 0x72, 0xc6, 0x63, 0xb1, 0xe0, 0xc5, 0x00,
0xd5, 0xd2, 0x42, 0xa2, 0xc9, 0x5b, 0x10, 0xb4, 0xbd, 0x2b, 0xb2, 0x05, 0x2f, 0x24, 0x6e, 0x5b,
0x0b, 0xc3, 0xb6, 0x2d, 0xa4, 0x6d, 0xff, 0xed, 0x4a, 0xf4, 0xfd, 0x9d, 0x38, 0x16, 0xf3, 0x4c,
0x1e, 0x89, 0x98, 0xa5, 0x47, 0x49, 0x76, 0x7d, 0xc2, 0x6f, 0x76, 0xaf, 0x2a, 0x3e, 0x9b, 0xf2,
0xc1, 0x73, 0xbf, 0x55, 0x6b, 0x74, 0x68, 0xd8, 0xa1, 0x0b, 0x1b, 0xdf, 0x9f, 0xdf, 0x4e, 0x49,
0x97, 0xe5, 0x1f, 0x57, 0xa2, 0x3b, 0xb0, 0x2c, 0x23, 0x91, 0x2e, 0xb8, 0x2d, 0xcd, 0x8b, 0x0e,
0xc3, 0x3e, 0x6e, 0xca, 0xf3, 0xc5, 0x6d, 0xd5, 0x74, 0x89, 0xd2, 0xe8, 0x43, 0x77, 0xb8, 0x8c,
0x78, 0xa9, 0xa6, 0xd3, 0x63, 0x7a, 0x44, 0x68, 0xc4, 0x78, 0x7e, 0xd2, 0x07, 0xd5, 0xde, 0x92,
0x68, 0xa0, 0xbd, 0xa5, 0xa2, 0x34, 0xce, 0xd6, 0x51, 0x0b, 0x0e, 0x61, 0x7c, 0x3d, 0xee, 0x41,
0x6a, 0x57, 0x7f, 0x14, 0xfd, 0xda, 0x5b, 0x51, 0x5c, 0x97, 0x39, 0x8b, 0xb9, 0x9e, 0x0a, 0x8f,
0x7c, 0xed, 0x46, 0x0a, 0x67, 0xc3, 0x6a, 0x17, 0xe6, 0x0c, 0xda, 0x46, 0xf8, 0x3a, 0xe7, 0x30,
0x06, 0x59, 0xc5, 0x4a, 0x48, 0x0d, 0x5a, 0x08, 0x69, 0xdb, 0xd7, 0xd1, 0xc0, 0xda, 0xbe, 0xf8,
0x63, 0x1e, 0xcb, 0x9d, 0xc9, 0x04, 0xf6, 0x8a, 0xd5, 0x55, 0xc4, 0x70, 0x67, 0x32, 0xa1, 0x7a,
0x05, 0x47, 0xb5, 0xb3, 0x9b, 0xe8, 0x23, 0xe0, 0xec, 0x28, 0x29, 0x95, 0xc3, 0xad, 0xb0, 0x15,
0x8d, 0x19, 0xa7, 0xc3, 0xbe, 0xb8, 0x76, 0xfc, 0xe7, 0x2b, 0xd1, 0xf7, 0x10, 0xcf, 0x67, 0x7c,
0x26, 0x16, 0x7c, 0xf0, 0xb4, 0xdb, 0x5a, 0x4d, 0x1a, 0xff, 0x9f, 0xdd, 0x42, 0x03, 0x19, 0x26,
0x23, 0x9e, 0xf2, 0x58, 0x92, 0xc3, 0xa4, 0x16, 0x77, 0x0e, 0x13, 0x83, 0x39, 0x33, 0xac, 0x11,
0x1e, 0x70, 0xb9, 0x3b, 0x2f, 0x0a, 0x9e, 0x49, 0xb2, 0x2f, 0x2d, 0xd2, 0xd9, 0x97, 0x1e, 0x8a,
0xd4, 0xe7, 0x80, 0xcb, 0x9d, 0x34, 0x25, 0xeb, 0x53, 0x8b, 0x3b, 0xeb, 0x63, 0x30, 0xed, 0x21,
0x8e, 0x7e, 0xdd, 0x69, 0x31, 0x79, 0x98, 0x5d, 0x8a, 0x01, 0xdd, 0x16, 0x4a, 0x6e, 0x7c, 0xac,
0x75, 0x72, 0x48, 0x35, 0x5e, 0xbd, 0xcb, 0x45, 0x41, 0x77, 0x4b, 0x2d, 0xee, 0xac, 0x86, 0xc1,
0xb4, 0x87, 0x3f, 0x8c, 0x3e, 0xd0, 0x51, 0xb2, 0x59, 0xcf, 0x1e, 0xa2, 0x21, 0x14, 0x2e, 0x68,
0x8f, 0x3a, 0x28, 0x1b, 0x1c, 0xb4, 0x4c, 0x07, 0x9f, 0x4f, 0x51, 0x3d, 0x10, 0x7a, 0x1e, 0x86,
0xa1, 0x96, 0xed, 0x3d, 0x9e, 0x72, 0xd2, 0x76, 0x2d, 0xec, 0xb0, 0x6d, 0x20, 0x6d, 0xbb, 0x88,
0x7e, 0xcb, 0x34, 0x4b, 0xb5, 0x8e, 0x2a, 0x79, 0x15, 0xa4, 0x37, 0x88, 0x7a, 0xbb, 0x90, 0xf1,
0xb5, 0xd9, 0x0f, 0x6e, 0xd5, 0x47, 0xcf, 0x40, 0xbc, 0x3e, 0x60, 0xfe, 0x3d, 0x0c, 0x43, 0xda,
0xf6, 0xdf, 0xad, 0x44, 0x3f, 0xd0, 0xb2, 0x57, 0x19, 0xbb, 0x48, 0xb9, 0x5a, 0x12, 0x4f, 0xb8,
0xbc, 0x11, 0xc5, 0xf5, 0x68, 0x99, 0xc5, 0xc4, 0xf2, 0x8f, 0xc3, 0x1d, 0xcb, 0x3f, 0xa9, 0xe4,
0x64, 0x7c, 0xba, 0xa2, 0x52, 0xe4, 0x30, 0xe3, 0x6b, 0x6a, 0x20, 0x45, 0x4e, 0x65, 0x7c, 0x3e,
0xd2, 0xb2, 0x7a, 0x5c, 0x85, 0x4d, 0xdc, 0xea, 0xb1, 0x1b, 0x27, 0x1f, 0x84, 0x10, 0x1b, 0xb6,
0x9a, 0x01, 0x2c, 0xb2, 0xcb, 0x64, 0x7a, 0x9e, 0x4f, 0xaa, 0x61, 0xfc, 0x18, 0x1f, 0xa1, 0x0e,
0x42, 0x84, 0x2d, 0x02, 0xd5, 0xde, 0xfe, 0xc1, 0x26, 0x46, 0x7a, 0x2a, 0xed, 0x17, 0x62, 0x76,
0xc4, 0xa7, 0x2c, 0x5e, 0xea, 0xf9, 0xff, 0x79, 0x68, 0xe2, 0x41, 0xda, 0x14, 0xe2, 0xc5, 0x2d,
0xb5, 0x74, 0x79, 0xfe, 0x7d, 0x25, 0x7a, 0xd8, 0x54, 0xff, 0x8a, 0x65, 0x53, 0xae, 0xfb, 0xb3,
0x2e, 0xfd, 0x4e, 0x36, 0x39, 0xe3, 0xa5, 0x64, 0x85, 0x1c, 0xfc, 0x08, 0xaf, 0x64, 0x48, 0xc7,
0x94, 0xed, 0xc7, 0xbf, 0x94, 0xae, 0xed, 0xf5, 0x51, 0x15, 0xd8, 0x74, 0x08, 0xf0, 0x7b, 0x5d,
0x49, 0x60, 0x00, 0x78, 0x10, 0x42, 0x6c, 0xaf, 0x2b, 0xc1, 0x61, 0xb6, 0x48, 0x24, 0x3f, 0xe0,
0x19, 0x2f, 0xda, 0xbd, 0x5e, 0xab, 0xfa, 0x08, 0xd1, 0xeb, 0x04, 0x6a, 0x83, 0x8d, 0xe7, 0xcd,
0x2c, 0x8e, 0x1b, 0x01, 0x23, 0xad, 0xe5, 0x71, 0xb3, 0x1f, 0x6c, 0x77, 0x77, 0x8e, 0xcf, 0x33,
0xbe, 0x10, 0xd7, 0x70, 0x77, 0xe7, 0x9a, 0xa8, 0x01, 0x62, 0x77, 0x87, 0x82, 0x76, 0x05, 0x73,
0xfc, 0xbc, 0x49, 0xf8, 0x0d, 0x58, 0xc1, 0x5c, 0xe5, 0x4a, 0x4c, 0xac, 0x60, 0x08, 0xa6, 0x3d,
0x9c, 0x44, 0xbf, 0xa2, 0x84, 0xbf, 0x2f, 0x92, 0x6c, 0x70, 0x17, 0x51, 0xaa, 0x04, 0xc6, 0xea,
0x3d, 0x1a, 0x00, 0x25, 0xae, 0x7e, 0xdd, 0x65, 0x59, 0xcc, 0x53, 0xb4, 0xc4, 0x56, 0x1c, 0x2c,
0xb1, 0x87, 0xd9, 0xd4, 0x41, 0x09, 0xab, 0xf8, 0x35, 0xba, 0x62, 0x45, 0x92, 0x4d, 0x07, 0x98,
0xae, 0x23, 0x27, 0x52, 0x07, 0x8c, 0x03, 0x43, 0x58, 0x2b, 0xee, 0xe4, 0x79, 0x51, 0x85, 0x45,
0x6c, 0x08, 0xfb, 0x48, 0x70, 0x08, 0xb7, 0x50, 0xdc, 0xdb, 0x1e, 0x8f, 0xd3, 0x24, 0x0b, 0x7a,
0xd3, 0x48, 0x1f, 0x6f, 0x16, 0x05, 0x83, 0xf7, 0x88, 0xb3, 0x05, 0x6f, 0x6a, 0x86, 0xb5, 0x8c,
0x0b, 0x04, 0x07, 0x2f, 0x00, 0xed, 0x3e, 0x4d, 0x89, 0x8f, 0xd9, 0x35, 0xaf, 0x1a, 0x98, 0x57,
0xeb, 0xda, 0x00, 0xd3, 0xf7, 0x08, 0x62, 0x9f, 0x86, 0x93, 0xda, 0xd5, 0x3c, 0xfa, 0x48, 0xc9,
0x4f, 0x59, 0x21, 0x93, 0x38, 0xc9, 0x59, 0xd6, 0xe4, 0xff, 0xd8, 0xbc, 0x6e, 0x51, 0xc6, 0xe5,
0x56, 0x4f, 0x5a, 0xbb, 0xfd, 0xb7, 0x95, 0xe8, 0x3e, 0xf4, 0x7b, 0xca, 0x8b, 0x59, 0xa2, 0xb6,
0x91, 0x65, 0x1d, 0x84, 0x07, 0x5f, 0x86, 0x8d, 0xb6, 0x14, 0x4c, 0x69, 0x7e, 0x78, 0x7b, 0x45,
0x9b, 0x0c, 0x8d, 0x74, 0x6a, 0xfd, 0xba, 0x98, 0xb4, 0x8e, 0x59, 0x46, 0x4d, 0xbe, 0xac, 0x84,
0x44, 0x32, 0xd4, 0x82, 0xc0, 0x0c, 0x3f, 0xcf, 0xca, 0xc6, 0x3a, 0x36, 0xc3, 0xad, 0x38, 0x38,
0xc3, 0x3d, 0x4c, 0x7b, 0xf8, 0x83, 0x28, 0xaa, 0x37, 0x5b, 0x6a, 0x43, 0xec, 0xc7, 0x1c, 0xbd,
0x0b, 0xf3, 0x76, 0xc3, 0xf7, 0x03, 0x84, 0x5d, 0xe8, 0xea, 0xdf, 0xd5, 0x3e, 0x7f, 0x80, 0x6a,
0x28, 0x11, 0xb1, 0xd0, 0x01, 0x04, 0x16, 0x74, 0x74, 0x25, 0x6e, 0xf0, 0x82, 0x56, 0x92, 0x70,
0x41, 0x35, 0x61, 0x4f, 0xde, 0x74, 0x41, 0xb1, 0x93, 0xb7, 0xa6, 0x18, 0xa1, 0x93, 0x37, 0xc8,
0x68, 0xc3, 0x22, 0xfa, 0x4d, 0xd7, 0xf0, 0x4b, 0x21, 0xae, 0x67, 0xac, 0xb8, 0x1e, 0x3c, 0xa1,
0x95, 0x1b, 0xc6, 0x38, 0xda, 0xe8, 0xc5, 0xda, 0xa0, 0xe6, 0x3a, 0xac, 0xd2, 0xa4, 0xf3, 0x22,
0x05, 0x41, 0xcd, 0xb3, 0xa1, 0x11, 0x22, 0xa8, 0x11, 0xa8, 0x1d, 0x95, 0xae, 0xb7, 0x11, 0x87,
0x7b, 0x3d, 0x4f, 0x7d, 0xc4, 0xa9, 0xbd, 0x1e, 0x82, 0xc1, 0x21, 0x74, 0x50, 0xb0, 0xfc, 0x0a,
0x1f, 0x42, 0x4a, 0x14, 0x1e, 0x42, 0x0d, 0x02, 0xfb, 0x7b, 0xc4, 0x59, 0x11, 0x5f, 0xe1, 0xfd,
0x5d, 0xcb, 0xc2, 0xfd, 0x6d, 0x18, 0xd8, 0xdf, 0xb5, 0xe0, 0x6d, 0x22, 0xaf, 0x8e, 0xb9, 0x64,
0x78, 0x7f, 0xfb, 0x4c, 0xb8, 0xbf, 0x5b, 0xac, 0xcd, 0xc3, 0x5c, 0x87, 0xa3, 0xf9, 0x45, 0x19,
0x17, 0xc9, 0x05, 0x1f, 0x04, 0xac, 0x18, 0x88, 0xc8, 0xc3, 0x48, 0x58, 0xfb, 0xfc, 0xf9, 0x4a,
0x74, 0xb7, 0xe9, 0x76, 0x51, 0x96, 0x3a, 0xe6, 0xf9, 0xee, 0x5f, 0xe0, 0xfd, 0x4b, 0xe0, 0xc4,
0x59, 0x68, 0x0f, 0x35, 0x67, 0x4d, 0xc0, 0x8b, 0x74, 0x9e, 0x95, 0xa6, 0x50, 0x5f, 0xf6, 0xb1,
0xee, 0x28, 0x10, 0x6b, 0x42, 0x2f, 0x45, 0xbb, 0x1c, 0xeb, 0xfe, 0x69, 0x64, 0x87, 0x93, 0x12,
0x2c, 0xc7, 0x4d, 0x7b, 0x3b, 0x04, 0xb1, 0x1c, 0xe3, 0x24, 0x1c, 0x0a, 0x07, 0x85, 0x98, 0xe7,
0x65, 0xc7, 0x50, 0x00, 0x50, 0x78, 0x28, 0xb4, 0x61, 0xed, 0xf3, 0x5d, 0xf4, 0xdb, 0xee, 0xf0,
0x73, 0x1b, 0x7b, 0x8b, 0x1e, 0x53, 0x58, 0x13, 0x0f, 0xfb, 0xe2, 0x36, 0x21, 0x6d, 0x3c, 0xcb,
0x3d, 0x2e, 0x59, 0x92, 0x96, 0x83, 0x55, 0xdc, 0x46, 0x23, 0x27, 0x12, 0x52, 0x8c, 0x83, 0xf1,
0x6d, 0x6f, 0x9e, 0xa7, 0x49, 0xdc, 0x3e, 0x89, 0xd6, 0xba, 0x46, 0x1c, 0x8e, 0x6f, 0x2e, 0x06,
0xe3, 0x75, 0xb5, 0xe4, 0xab, 0xff, 0x8c, 0x97, 0x39, 0xc7, 0xe3, 0xb5, 0x87, 0x84, 0xe3, 0x35,
0x44, 0x61, 0x7d, 0x46, 0x5c, 0x1e, 0xb1, 0xa5, 0x98, 0x13, 0xf1, 0xda, 0x88, 0xc3, 0xf5, 0x71,
0x31, 0x9b, 0x13, 0x1a, 0x0f, 0x87, 0x99, 0xe4, 0x45, 0xc6, 0xd2, 0xfd, 0x94, 0x4d, 0xcb, 0x01,
0x11, 0x63, 0x7c, 0x8a, 0xc8, 0x09, 0x69, 0x1a, 0x69, 0xc6, 0xc3, 0x72, 0x9f, 0x2d, 0x44, 0x91,
0x48, 0xba, 0x19, 0x2d, 0xd2, 0xd9, 0x8c, 0x1e, 0x8a, 0x7a, 0xdb, 0x29, 0xe2, 0xab, 0x64, 0xc1,
0x27, 0x01, 0x6f, 0x0d, 0xd2, 0xc3, 0x9b, 0x83, 0x22, 0x9d, 0x36, 0x12, 0xf3, 0x22, 0xe6, 0x64,
0xa7, 0xd5, 0xe2, 0xce, 0x4e, 0x33, 0x98, 0xf6, 0xf0, 0x57, 0x2b, 0xd1, 0xef, 0xd4, 0x52, 0xf7,
0x78, 0x78, 0x8f, 0x95, 0x57, 0x17, 0x82, 0x15, 0x93, 0xc1, 0x67, 0x98, 0x1d, 0x14, 0x35, 0xae,
0x9f, 0xdd, 0x46, 0x05, 0x36, 0xeb, 0x51, 0x52, 0x3a, 0x33, 0x0e, 0x6d, 0x56, 0x0f, 0x09, 0x37,
0x2b, 0x44, 0x61, 0x00, 0x51, 0xf2, 0xfa, 0x28, 0x66, 0x95, 0xd4, 0xf7, 0xcf, 0x63, 0xd6, 0x3a,
0x39, 0x18, 0x1f, 0x2b, 0xa1, 0x3f, 0x5a, 0xb6, 0x28, 0x1b, 0xf8, 0x88, 0x19, 0xf6, 0xc5, 0x49,
0xcf, 0x66, 0x56, 0x84, 0x3d, 0xb7, 0x66, 0xc6, 0xb0, 0x2f, 0x4e, 0x78, 0x76, 0xc2, 0x5a, 0xc8,
0x33, 0x12, 0xda, 0x86, 0x7d, 0x71, 0x98, 0x7d, 0x69, 0xa6, 0x59, 0x17, 0x9e, 0x04, 0xec, 0xc0,
0xb5, 0x61, 0xa3, 0x17, 0xab, 0x1d, 0xfe, 0xcd, 0x4a, 0xf4, 0x7d, 0xeb, 0xf1, 0x58, 0x4c, 0x92,
0xcb, 0x65, 0x0d, 0xbd, 0x61, 0xe9, 0x9c, 0x97, 0x83, 0x67, 0x94, 0xb5, 0x36, 0x6b, 0x4a, 0xf0,
0xfc, 0x56, 0x3a, 0x70, 0xee, 0xec, 0xe4, 0x79, 0xba, 0x1c, 0xf3, 0x59, 0x9e, 0x92, 0x73, 0xc7,
0x43, 0xc2, 0x73, 0x07, 0xa2, 0x30, 0x2b, 0x1f, 0x8b, 0x2a, 0xe7, 0x47, 0xb3, 0x72, 0x25, 0x0a,
0x67, 0xe5, 0x0d, 0x02, 0x73, 0xa5, 0xb1, 0xd8, 0x15, 0x69, 0xca, 0x63, 0xd9, 0x7e, 0xc4, 0x6c,
0x34, 0x2d, 0x11, 0xce, 0x95, 0x00, 0x69, 0x4f, 0x63, 0x9a, 0x3d, 0x24, 0x2b, 0xf8, 0xcb, 0xe5,
0x51, 0x92, 0x5d, 0x0f, 0xf0, 0xb4, 0xc0, 0x02, 0xc4, 0x69, 0x0c, 0x0a, 0xc2, 0xbd, 0xea, 0x79,
0x36, 0x11, 0xf8, 0x5e, 0xb5, 0x92, 0x84, 0xf7, 0xaa, 0x9a, 0x80, 0x26, 0xcf, 0x38, 0x65, 0xb2,
0x92, 0x84, 0x4d, 0x6a, 0x02, 0x0b, 0x85, 0xfa, 0xcc, 0x9e, 0x0c, 0x85, 0xe0, 0x94, 0x7e, 0xad,
0x93, 0x83, 0x23, 0xb4, 0xd9, 0xb4, 0xee, 0x73, 0x19, 0x5f, 0xe1, 0x23, 0xd4, 0x43, 0xc2, 0x23,
0x14, 0xa2, 0xb0, 0x4a, 0x63, 0x61, 0x36, 0xdd, 0xab, 0xf8, 0xf8, 0x68, 0x6d, 0xb8, 0xd7, 0x3a,
0x39, 0xb8, 0x8d, 0x3c, 0x9c, 0xa9, 0x36, 0x43, 0x07, 0x79, 0x2d, 0x0b, 0x6f, 0x23, 0x0d, 0x03,
0x4b, 0x5f, 0x0b, 0xaa, 0xe6, 0xc4, 0x4b, 0x6f, 0xe5, 0xe1, 0xd2, 0x7b, 0x9c, 0x76, 0xf2, 0x2f,
0x66, 0x1b, 0x57, 0x4b, 0x4f, 0x44, 0x35, 0x47, 0xde, 0xb0, 0x34, 0x99, 0x30, 0xc9, 0xc7, 0xe2,
0x9a, 0x67, 0xf8, 0x8e, 0x49, 0x97, 0xb6, 0xe6, 0x87, 0x9e, 0x42, 0x78, 0xc7, 0x14, 0x56, 0x84,
0xe3, 0xa4, 0xa6, 0xcf, 0x4b, 0xbe, 0xcb, 0x4a, 0x22, 0x92, 0x79, 0x48, 0x78, 0x9c, 0x40, 0x14,
0xe6, 0xab, 0xb5, 0xfc, 0xd5, 0xbb, 0x9c, 0x17, 0x09, 0xcf, 0x62, 0x8e, 0xe7, 0xab, 0x90, 0x0a,
0xe7, 0xab, 0x08, 0x0d, 0xf7, 0x6a, 0x7b, 0x4c, 0xf2, 0x97, 0xcb, 0x71, 0x32, 0xe3, 0xa5, 0x64,
0xb3, 0x1c, 0xdf, 0xab, 0x01, 0x28, 0xbc, 0x57, 0x6b, 0xc3, 0xad, 0xa3, 0x21, 0x13, 0x10, 0xdb,
0x37, 0x53, 0x20, 0x11, 0xb8, 0x99, 0x42, 0xa0, 0xb0, 0x61, 0x2d, 0x80, 0x1e, 0x0e, 0xb7, 0xac,
0x04, 0x0f, 0x87, 0x69, 0xba, 0x75, 0xe0, 0x66, 0x98, 0x51, 0x35, 0x35, 0x3b, 0x8a, 0x3e, 0x72,
0xa7, 0xe8, 0x46, 0x2f, 0x16, 0x3f, 0xe1, 0x3b, 0xe3, 0x29, 0x53, 0xcb, 0x56, 0xe0, 0x18, 0xad,
0x61, 0xfa, 0x9c, 0xf0, 0x39, 0xac, 0x76, 0xf8, 0x17, 0x2b, 0xd1, 0x27, 0x98, 0xc7, 0xd7, 0xb9,
0xf2, 0xfb, 0xb4, 0xdb, 0x56, 0x4d, 0x12, 0x57, 0x6f, 0xc2, 0x1a, 0xba, 0x0c, 0x7f, 0x12, 0x7d,
0xdc, 0x88, 0xec, 0xcd, 0x1c, 0x5d, 0x00, 0x3f, 0x69, 0x33, 0xe5, 0x87, 0x9c, 0x71, 0xbf, 0xdd,
0x9b, 0xb7, 0xfb, 0x21, 0xbf, 0x5c, 0x25, 0xd8, 0x0f, 0x19, 0x1b, 0x5a, 0x4c, 0xec, 0x87, 0x10,
0xcc, 0xce, 0x4e, 0xb7, 0x7a, 0x6f, 0x13, 0x79, 0xa5, 0xf2, 0x2d, 0x30, 0x3b, 0xbd, 0xb2, 0x1a,
0x88, 0x98, 0x9d, 0x24, 0x0c, 0x33, 0x92, 0x06, 0xac, 0xe6, 0x26, 0x16, 0xcb, 0x8d, 0x21, 0x77,
0x66, 0xae, 0x77, 0x83, 0x70, 0xbc, 0x36, 0x62, 0xbd, 0xf5, 0x79, 0x12, 0xb2, 0x00, 0xb6, 0x3f,
0x1b, 0xbd, 0x58, 0xed, 0xf0, 0xcf, 0xa2, 0xef, 0xb5, 0x2a, 0xb6, 0xcf, 0x99, 0x9c, 0x17, 0x7c,
0x32, 0xd8, 0xee, 0x28, 0x77, 0x03, 0x1a, 0xd7, 0x4f, 0xfb, 0x2b, 0xb4, 0x72, 0xf4, 0x86, 0xab,
0x87, 0x95, 0x29, 0xc3, 0xb3, 0x90, 0x49, 0x9f, 0x0d, 0xe6, 0xe8, 0xb4, 0x4e, 0x6b, 0x9b, 0xed,
0x8e, 0xae, 0x9d, 0x05, 0x4b, 0x52, 0xf5, 0x90, 0xee, 0xb3, 0x90, 0x51, 0x0f, 0x0d, 0x6e, 0xb3,
0x49, 0x95, 0x56, 0x64, 0x56, 0x73, 0xdc, 0xd9, 0x9e, 0x6d, 0xd2, 0x91, 0x00, 0xd9, 0x9d, 0x6d,
0xf5, 0xa4, 0xb5, 0x5b, 0xd9, 0x2c, 0x79, 0xd5, 0xcf, 0xee, 0x20, 0xc7, 0xbc, 0x6a, 0x55, 0x64,
0xa4, 0x6f, 0xf5, 0xa4, 0xb5, 0xd7, 0x3f, 0x8d, 0x3e, 0x6e, 0x7b, 0xd5, 0x0b, 0xd1, 0x76, 0xa7,
0x29, 0xb0, 0x16, 0x3d, 0xed, 0xaf, 0x60, 0xb7, 0x34, 0x5f, 0x25, 0xa5, 0x14, 0xc5, 0x72, 0x74,
0x25, 0x6e, 0x9a, 0x1b, 0xef, 0xfe, 0x6c, 0xd5, 0xc0, 0xd0, 0x21, 0x88, 0x2d, 0x0d, 0x4e, 0xb6,
0x5c, 0xd9, 0x9b, 0xf1, 0x25, 0xe1, 0xca, 0x21, 0x3a, 0x5c, 0xf9, 0xa4, 0x8d, 0x55, 0x4d, 0xad,
0xec, 0x35, 0xfe, 0x35, 0xbc, 0xa8, 0xed, 0xab, 0xfc, 0xeb, 0xdd, 0xa0, 0xcd, 0x58, 0xb4, 0x78,
0x2f, 0xb9, 0xbc, 0x34, 0x75, 0xc2, 0x4b, 0xea, 0x22, 0x44, 0xc6, 0x42, 0xa0, 0x36, 0xe9, 0xde,
0x4f, 0x52, 0xae, 0x4e, 0xf4, 0x5f, 0x5f, 0x5e, 0xa6, 0x82, 0x4d, 0x40, 0xd2, 0x5d, 0x89, 0x87,
0xae, 0x9c, 0x48, 0xba, 0x31, 0xce, 0x3e, 0x23, 0xae, 0xa4, 0x67, 0x3c, 0x16, 0x59, 0x9c, 0xa4,
0xf0, 0x02, 0xa0, 0xd2, 0x34, 0x42, 0xe2, 0x19, 0x71, 0x0b, 0xb2, 0x0b, 0x63, 0x25, 0xaa, 0xa6,
0x7d, 0x53, 0xfe, 0x47, 0x6d, 0x45, 0x47, 0x4c, 0x2c, 0x8c, 0x08, 0x66, 0xf7, 0x9e, 0x95, 0xf0,
0x3c, 0x57, 0xc6, 0xef, 0xb5, 0xb5, 0x6a, 0x09, 0xb1, 0xf7, 0xf4, 0x09, 0xbb, 0x87, 0xaa, 0x7e,
0xdf, 0x13, 0x37, 0x99, 0x32, 0xfa, 0xa0, 0xad, 0xd2, 0xc8, 0x88, 0x3d, 0x14, 0x64, 0xb4, 0xe1,
0x9f, 0x44, 0xff, 0x5f, 0x19, 0x2e, 0x44, 0x3e, 0xb8, 0x83, 0x28, 0x14, 0xce, 0x5d, 0xbd, 0xbb,
0xa4, 0xdc, 0x5e, 0x39, 0x35, 0x63, 0xe3, 0xbc, 0x64, 0x53, 0x3e, 0x78, 0x48, 0xf4, 0xb8, 0x92,
0x12, 0x57, 0x4e, 0xdb, 0x94, 0x3f, 0x2a, 0x4e, 0xc4, 0x44, 0x5b, 0x47, 0x6a, 0x68, 0x84, 0xa1,
0x51, 0xe1, 0x42, 0x36, 0x99, 0x39, 0x61, 0x8b, 0x64, 0x6a, 0x16, 0x9c, 0x3a, 0x6e, 0x95, 0x20,
0x99, 0xb1, 0xcc, 0xd0, 0x81, 0x88, 0x64, 0x86, 0x84, 0xb5, 0xcf, 0x7f, 0x5e, 0x89, 0xee, 0x59,
0xe6, 0xa0, 0x39, 0xad, 0x3b, 0xcc, 0x2e, 0x45, 0x95, 0xfa, 0x1c, 0x25, 0xd9, 0x75, 0x39, 0xf8,
0x82, 0x32, 0x89, 0xf3, 0xa6, 0x28, 0x5f, 0xde, 0x5a, 0xcf, 0x66, 0xad, 0xcd, 0x51, 0x96, 0x7d,
0x9e, 0x5d, 0x6b, 0x80, 0xac, 0xd5, 0x9c, 0x78, 0x41, 0x8e, 0xc8, 0x5a, 0x43, 0xbc, 0xed, 0x62,
0xe3, 0x3c, 0x15, 0x19, 0xec, 0x62, 0x6b, 0xa1, 0x12, 0x12, 0x5d, 0xdc, 0x82, 0x6c, 0x3c, 0x6e,
0x44, 0xf5, 0xa9, 0xcb, 0x4e, 0x9a, 0x82, 0x78, 0x6c, 0x54, 0x0d, 0x40, 0xc4, 0x63, 0x14, 0xd4,
0x7e, 0xce, 0xa2, 0xef, 0x54, 0x4d, 0x7a, 0x5a, 0xf0, 0x45, 0xc2, 0xe1, 0xd5, 0x0b, 0x47, 0x42,
0xcc, 0x7f, 0x9f, 0xb0, 0x33, 0xeb, 0x3c, 0x2b, 0xf3, 0x94, 0x95, 0x57, 0xfa, 0x61, 0xbc, 0x5f,
0xe7, 0x46, 0x08, 0x1f, 0xc7, 0x3f, 0xea, 0xa0, 0x6c, 0x50, 0x6f, 0x64, 0x26, 0xc4, 0xac, 0xe2,
0xaa, 0xad, 0x30, 0xb3, 0xd6, 0xc9, 0xd9, 0x13, 0xef, 0x03, 0x96, 0xa6, 0xbc, 0x58, 0x36, 0xb2,
0x63, 0x96, 0x25, 0x97, 0xbc, 0x94, 0xe0, 0xc4, 0x5b, 0x53, 0x43, 0x88, 0x11, 0x27, 0xde, 0x01,
0xdc, 0x66, 0xf3, 0xc0, 0xf3, 0x61, 0x36, 0xe1, 0xef, 0x40, 0x36, 0x0f, 0xed, 0x28, 0x86, 0xc8,
0xe6, 0x29, 0xd6, 0x9e, 0xfc, 0xbe, 0x4c, 0x45, 0x7c, 0xad, 0x97, 0x00, 0xbf, 0x83, 0x95, 0x04,
0xae, 0x01, 0x0f, 0x42, 0x88, 0x5d, 0x04, 0x94, 0xe0, 0x8c, 0xe7, 0x29, 0x8b, 0xe1, 0xfd, 0x9b,
0x5a, 0x47, 0xcb, 0x88, 0x45, 0x00, 0x32, 0xa0, 0xb8, 0xfa, 0x5e, 0x0f, 0x56, 0x5c, 0x70, 0xad,
0xe7, 0x41, 0x08, 0xb1, 0xcb, 0xa0, 0x12, 0x8c, 0xf2, 0x34, 0x91, 0x60, 0x1a, 0xd4, 0x1a, 0x4a,
0x42, 0x4c, 0x03, 0x9f, 0x00, 0x26, 0x8f, 0x79, 0x31, 0xe5, 0xa8, 0x49, 0x25, 0x09, 0x9a, 0x6c,
0x08, 0x7b, 0xc9, 0xb4, 0xae, 0xbb, 0xc8, 0x97, 0xe0, 0x92, 0xa9, 0xae, 0x96, 0xc8, 0x97, 0xc4,
0x25, 0x53, 0x0f, 0x00, 0x45, 0x3c, 0x65, 0xa5, 0xc4, 0x8b, 0xa8, 0x24, 0xc1, 0x22, 0x36, 0x84,
0x5d, 0xa3, 0xeb, 0x22, 0xce, 0x25, 0x58, 0xa3, 0x75, 0x01, 0x9c, 0x27, 0xd0, 0x77, 0x49, 0xb9,
0x8d, 0x24, 0x75, 0xaf, 0x70, 0xb9, 0x9f, 0xf0, 0x74, 0x52, 0x82, 0x48, 0xa2, 0xdb, 0xbd, 0x91,
0x12, 0x91, 0xa4, 0x4d, 0x81, 0xa1, 0xa4, 0xcf, 0xc7, 0xb1, 0xda, 0x81, 0xa3, 0xf1, 0x07, 0x21,
0xc4, 0xc6, 0xa7, 0xa6, 0xd0, 0xbb, 0xac, 0x28, 0x92, 0x6a, 0xf1, 0x5f, 0xc5, 0x0b, 0xd4, 0xc8,
0x89, 0xf8, 0x84, 0x71, 0x60, 0x7a, 0x35, 0x81, 0x1b, 0x2b, 0x18, 0x0c, 0xdd, 0x9f, 0x06, 0x19,
0x9b, 0x71, 0x2a, 0x89, 0xf3, 0x08, 0x15, 0x6b, 0x4d, 0xe4, 0x09, 0xea, 0x6a, 0x17, 0xe6, 0xbc,
0x04, 0x62, 0x5c, 0x1c, 0x8b, 0x05, 0x1f, 0x8b, 0x57, 0xef, 0x92, 0x52, 0x26, 0xd9, 0x54, 0xaf,
0xdc, 0xcf, 0x09, 0x4b, 0x18, 0x4c, 0xbc, 0x04, 0xd2, 0xa9, 0x64, 0x13, 0x08, 0x50, 0x96, 0x13,
0x7e, 0x83, 0x26, 0x10, 0xd0, 0xa2, 0xe1, 0x88, 0x04, 0x22, 0xc4, 0xdb, 0x73, 0x14, 0xe3, 0x5c,
0xbf, 0x29, 0x3b, 0x16, 0x4d, 0x2e, 0x47, 0x59, 0x83, 0x20, 0xb1, 0x95, 0x0d, 0x2a, 0xd8, 0xfd,
0xa5, 0xf1, 0x6f, 0xa7, 0xd8, 0x3a, 0x61, 0xa7, 0x3d, 0xcd, 0x1e, 0xf7, 0x20, 0x11, 0x57, 0xf6,
0x1e, 0x00, 0xe5, 0xaa, 0x7d, 0x0d, 0xe0, 0x71, 0x0f, 0xd2, 0x39, 0x93, 0x71, 0xab, 0xf5, 0x92,
0xc5, 0xd7, 0xd3, 0x42, 0xcc, 0xb3, 0xc9, 0xae, 0x48, 0x45, 0x01, 0xce, 0x64, 0xbc, 0x52, 0x03,
0x94, 0x38, 0x93, 0xe9, 0x50, 0xb1, 0x19, 0x9c, 0x5b, 0x8a, 0x9d, 0x34, 0x99, 0xc2, 0x1d, 0xb5,
0x67, 0x48, 0x01, 0x44, 0x06, 0x87, 0x82, 0xc8, 0x20, 0xaa, 0x77, 0xdc, 0x32, 0x89, 0x59, 0x5a,
0xfb, 0xdb, 0xa6, 0xcd, 0x78, 0x60, 0xe7, 0x20, 0x42, 0x14, 0x90, 0x7a, 0x8e, 0xe7, 0x45, 0x76,
0x98, 0x49, 0x41, 0xd6, 0xb3, 0x01, 0x3a, 0xeb, 0xe9, 0x80, 0x20, 0xac, 0x8e, 0xf9, 0xbb, 0xaa,
0x34, 0xd5, 0x3f, 0x58, 0x58, 0xad, 0x7e, 0x1f, 0x6a, 0x79, 0x28, 0xac, 0x02, 0x0e, 0x54, 0x46,
0x3b, 0xa9, 0x07, 0x4c, 0x40, 0xdb, 0x1f, 0x26, 0xeb, 0xdd, 0x20, 0xee, 0x67, 0x24, 0x97, 0x29,
0x0f, 0xf9, 0x51, 0x40, 0x1f, 0x3f, 0x0d, 0x68, 0x8f, 0x5b, 0xbc, 0xfa, 0x5c, 0xf1, 0xf8, 0xba,
0x75, 0xad, 0xc9, 0x2f, 0x68, 0x8d, 0x10, 0xc7, 0x2d, 0x04, 0x8a, 0x77, 0xd1, 0x61, 0x2c, 0xb2,
0x50, 0x17, 0x55, 0xf2, 0x3e, 0x5d, 0xa4, 0x39, 0xbb, 0xf9, 0x35, 0x52, 0x3d, 0x32, 0xeb, 0x6e,
0xda, 0x20, 0x2c, 0xb8, 0x10, 0xb1, 0xf9, 0x25, 0x61, 0x9b, 0x93, 0x43, 0x9f, 0xc7, 0xed, 0x3b,
0xdf, 0x2d, 0x2b, 0xc7, 0xf4, 0x9d, 0x6f, 0x8a, 0xa5, 0x2b, 0x59, 0x8f, 0x91, 0x0e, 0x2b, 0xfe,
0x38, 0xd9, 0xec, 0x07, 0xdb, 0x2d, 0x8f, 0xe7, 0x73, 0x37, 0xe5, 0xac, 0xa8, 0xbd, 0x6e, 0x05,
0x0c, 0x59, 0x8c, 0xd8, 0xf2, 0x04, 0x70, 0x10, 0xc2, 0x3c, 0xcf, 0xbb, 0x22, 0x93, 0x3c, 0x93,
0x58, 0x08, 0xf3, 0x8d, 0x69, 0x30, 0x14, 0xc2, 0x28, 0x05, 0x30, 0x6e, 0xd5, 0x79, 0x10, 0x97,
0x27, 0x6c, 0x86, 0x66, 0x6c, 0xf5, 0x59, 0x4f, 0x2d, 0x0f, 0x8d, 0x5b, 0xc0, 0x39, 0x0f, 0xf9,
0x5c, 0x2f, 0x63, 0x56, 0x4c, 0xcd, 0xe9, 0xc6, 0x64, 0xf0, 0x94, 0xb6, 0xe3, 0x93, 0xc4, 0x43,
0xbe, 0xb0, 0x06, 0x08, 0x3b, 0x87, 0x33, 0x36, 0x35, 0x35, 0x45, 0x6a, 0xa0, 0xe4, 0xad, 0xaa,
0xae, 0x77, 0x83, 0xc0, 0xcf, 0x9b, 0x64, 0xc2, 0x45, 0xc0, 0x8f, 0x92, 0xf7, 0xf1, 0x03, 0x41,
0x90, 0xbd, 0x55, 0xf5, 0xae, 0x77, 0x74, 0x3b, 0xd9, 0x44, 0xef, 0x63, 0x87, 0x44, 0xf3, 0x00,
0x2e, 0x94, 0xbd, 0x11, 0x3c, 0x98, 0xa3, 0xcd, 0x01, 0x6d, 0x68, 0x8e, 0x9a, 0xf3, 0xd7, 0x3e,
0x73, 0x14, 0x83, 0xb5, 0xcf, 0x9f, 0xe9, 0x39, 0xba, 0xc7, 0x24, 0xab, 0xf2, 0xf6, 0x37, 0x09,
0xbf, 0xd1, 0x1b, 0x61, 0xa4, 0xbe, 0x0d, 0x35, 0x54, 0xaf, 0x2a, 0x82, 0x5d, 0xf1, 0x76, 0x6f,
0x3e, 0xe0, 0x5b, 0xef, 0x10, 0x3a, 0x7d, 0x83, 0xad, 0xc2, 0x76, 0x6f, 0x3e, 0xe0, 0x5b, 0xbf,
0x03, 0xdd, 0xe9, 0x1b, 0xbc, 0x08, 0xbd, 0xdd, 0x9b, 0xd7, 0xbe, 0xff, 0xb2, 0x99, 0xb8, 0xae,
0xf3, 0x2a, 0x0f, 0x8b, 0x65, 0xb2, 0xe0, 0x58, 0x3a, 0xe9, 0xdb, 0x33, 0x68, 0x28, 0x9d, 0xa4,
0x55, 0x9c, 0x0f, 0xe7, 0x60, 0xa5, 0x38, 0x15, 0x65, 0xa2, 0x1e, 0xd2, 0x3f, 0xef, 0x61, 0xb4,
0x81, 0x43, 0x9b, 0xa6, 0x90, 0x92, 0x7d, 0xdc, 0xe8, 0xa1, 0xf6, 0x16, 0xf3, 0x66, 0xc0, 0x5e,
0xfb, 0x32, 0xf3, 0x56, 0x4f, 0xda, 0x3e, 0xf8, 0xf3, 0x18, 0xf7, 0x89, 0x63, 0xa8, 0x57, 0xd1,
0x87, 0x8e, 0x4f, 0xfb, 0x2b, 0x68, 0xf7, 0x7f, 0xdd, 0xec, 0x2b, 0xa0, 0x7f, 0x3d, 0x09, 0x9e,
0xf5, 0xb1, 0x08, 0x26, 0xc2, 0xf3, 0x5b, 0xe9, 0xe8, 0x82, 0xfc, 0x7d, 0xb3, 0x81, 0x6e, 0x50,
0xf5, 0x2e, 0x87, 0x7a, 0xf7, 0x4f, 0xcf, 0x89, 0x50, 0xb7, 0x5a, 0x18, 0xce, 0x8c, 0x17, 0xb7,
0xd4, 0x72, 0x3e, 0xa3, 0xe4, 0xc1, 0xfa, 0x9d, 0x43, 0xa7, 0x3c, 0x21, 0xcb, 0x0e, 0x0d, 0x0b,
0xf4, 0xc5, 0x6d, 0xd5, 0xa8, 0xb9, 0xe2, 0xc0, 0xea, 0xab, 0x0c, 0xcf, 0x7b, 0x1a, 0xf6, 0xbe,
0xd3, 0xf0, 0xf9, 0xed, 0x94, 0x74, 0x59, 0xfe, 0x63, 0x25, 0x7a, 0xe4, 0xb1, 0xf6, 0x79, 0x02,
0x38, 0xf5, 0xf8, 0x71, 0xc0, 0x3e, 0xa5, 0x64, 0x0a, 0xf7, 0xbb, 0xbf, 0x9c, 0xb2, 0xfd, 0xe6,
0x90, 0xa7, 0xb2, 0x9f, 0xa4, 0x92, 0x17, 0xed, 0x6f, 0x0e, 0xf9, 0x76, 0x6b, 0x6a, 0x48, 0x7f,
0x73, 0x28, 0x80, 0x3b, 0xdf, 0x1c, 0x42, 0x3c, 0xa3, 0xdf, 0x1c, 0x42, 0xad, 0x05, 0xbf, 0x39,
0x14, 0xd6, 0xa0, 0xc2, 0x7b, 0x53, 0x84, 0xfa, 0xdc, 0xba, 0x97, 0x45, 0xff, 0x18, 0xfb, 0xd9,
0x6d, 0x54, 0x88, 0x05, 0xae, 0xe6, 0xd4, 0x3d, 0xb7, 0x1e, 0x6d, 0xea, 0xdd, 0x75, 0xdb, 0xee,
0xcd, 0x6b, 0xdf, 0x3f, 0xd5, 0xbb, 0x1b, 0x13, 0xce, 0x45, 0xa1, 0xbe, 0x37, 0xb5, 0x11, 0x0a,
0xcf, 0x95, 0x05, 0xb7, 0xe7, 0x37, 0xfb, 0xc1, 0x44, 0x75, 0x2b, 0x42, 0x77, 0xfa, 0xb0, 0xcb,
0x10, 0xe8, 0xf2, 0xed, 0xde, 0x3c, 0xb1, 0x8c, 0xd4, 0xbe, 0xeb, 0xde, 0xee, 0x61, 0xcc, 0xef,
0xeb, 0xa7, 0xfd, 0x15, 0xb4, 0xfb, 0x85, 0x4e, 0x1b, 0x5d, 0xf7, 0xaa, 0x9f, 0xb7, 0xba, 0x4c,
0x8d, 0xbc, 0x6e, 0x1e, 0xf6, 0xc5, 0x43, 0x09, 0x84, 0xbb, 0x84, 0x76, 0x25, 0x10, 0xe8, 0x32,
0xfa, 0xf9, 0xed, 0x94, 0x74, 0x59, 0xfe, 0x69, 0x25, 0xba, 0x4b, 0x96, 0x45, 0x8f, 0x83, 0x2f,
0xfa, 0x5a, 0x06, 0xe3, 0xe1, 0xcb, 0x5b, 0xeb, 0xe9, 0x42, 0xfd, 0xeb, 0x4a, 0x74, 0x2f, 0x50,
0xa8, 0x7a, 0x80, 0xdc, 0xc2, 0xba, 0x3f, 0x50, 0x7e, 0x78, 0x7b, 0x45, 0x6a, 0xb9, 0x77, 0xf1,
0x51, 0xfb, 0x63, 0x3c, 0x01, 0xdb, 0x23, 0xfa, 0x63, 0x3c, 0xdd, 0x5a, 0xf0, 0x90, 0x87, 0x5d,
0x34, 0x9b, 0x2e, 0xf4, 0x90, 0x47, 0xdd, 0x50, 0x03, 0x7b, 0x8e, 0xb5, 0x4e, 0x0e, 0x73, 0xf2,
0xea, 0x5d, 0xce, 0xb2, 0x09, 0xed, 0xa4, 0x96, 0x77, 0x3b, 0x31, 0x1c, 0x3c, 0x1c, 0xab, 0xa4,
0x67, 0xa2, 0xd9, 0x48, 0x3d, 0xa6, 0xf4, 0x0d, 0x12, 0x3c, 0x1c, 0x6b, 0xa1, 0x84, 0x37, 0x9d,
0x35, 0x86, 0xbc, 0x81, 0x64, 0xf1, 0x49, 0x1f, 0x14, 0xa4, 0xe8, 0xc6, 0x9b, 0x39, 0x73, 0xdf,
0x0c, 0x59, 0x69, 0x9d, 0xbb, 0x6f, 0xf5, 0xa4, 0x09, 0xb7, 0x23, 0x2e, 0xbf, 0xe2, 0x6c, 0xc2,
0x8b, 0xa0, 0x5b, 0x43, 0xf5, 0x72, 0xeb, 0xd2, 0x98, 0xdb, 0x5d, 0x91, 0xce, 0x67, 0x99, 0xee,
0x4c, 0xd2, 0xad, 0x4b, 0x75, 0xbb, 0x05, 0x34, 0x3c, 0x16, 0xb4, 0x6e, 0x55, 0x7a, 0xf9, 0x24,
0x6c, 0xc6, 0xcb, 0x2a, 0x37, 0x7a, 0xb1, 0x74, 0x3d, 0xf5, 0x30, 0xea, 0xa8, 0x27, 0x18, 0x49,
0x5b, 0x3d, 0x69, 0x78, 0x3e, 0xe7, 0xb8, 0x35, 0xe3, 0x69, 0xbb, 0xc3, 0x56, 0x6b, 0x48, 0x3d,
0xed, 0xaf, 0x00, 0x4f, 0x43, 0xf5, 0xa8, 0x3a, 0x4a, 0x4a, 0xb9, 0x9f, 0xa4, 0xe9, 0x60, 0x23,
0x30, 0x4c, 0x1a, 0x28, 0x78, 0x1a, 0x8a, 0xc0, 0xc4, 0x48, 0x6e, 0x4e, 0x0f, 0xb3, 0x41, 0x97,
0x1d, 0x45, 0xf5, 0x1a, 0xc9, 0x2e, 0x0d, 0x4e, 0xb4, 0x9c, 0xa6, 0x36, 0xb5, 0x1d, 0x86, 0x1b,
0xae, 0x55, 0xe1, 0xed, 0xde, 0x3c, 0x78, 0xdc, 0xae, 0x28, 0xb5, 0xb2, 0x3c, 0xa4, 0x4c, 0x78,
0x2b, 0xc9, 0xa3, 0x0e, 0x0a, 0x9c, 0x0a, 0xd6, 0xd3, 0xe8, 0x6d, 0x32, 0x99, 0x72, 0x89, 0x3e,
0x29, 0x72, 0x81, 0xe0, 0x93, 0x22, 0x00, 0x82, 0xae, 0xab, 0x7f, 0x37, 0xc7, 0xa1, 0x87, 0x13,
0xac, 0xeb, 0xb4, 0xb2, 0x43, 0x85, 0xba, 0x0e, 0xa5, 0x41, 0x34, 0x30, 0x6e, 0xf5, 0xeb, 0xf8,
0x4f, 0x42, 0x66, 0xc0, 0x3b, 0xf9, 0x1b, 0xbd, 0x58, 0xb0, 0xa2, 0x58, 0x87, 0xc9, 0x2c, 0x91,
0xd8, 0x8a, 0xe2, 0xd8, 0xa8, 0x90, 0xd0, 0x8a, 0xd2, 0x46, 0xa9, 0xea, 0x55, 0x39, 0xc2, 0xe1,
0x24, 0x5c, 0xbd, 0x9a, 0xe9, 0x57, 0x3d, 0xc3, 0xb6, 0x1e, 0x6c, 0x66, 0x66, 0xc8, 0xc8, 0x2b,
0xbd, 0x59, 0x46, 0xc6, 0xb6, 0x7a, 0x4d, 0x13, 0x82, 0xa1, 0xa8, 0x43, 0x29, 0xc0, 0x03, 0xfb,
0x8a, 0x6b, 0x9e, 0xbd, 0xe6, 0x39, 0x67, 0x05, 0xcb, 0x62, 0x74, 0x73, 0xaa, 0x0c, 0xb6, 0xc8,
0xd0, 0xe6, 0x94, 0xd4, 0x00, 0x8f, 0xcd, 0xfd, 0x17, 0x2c, 0x91, 0xa9, 0x60, 0xde, 0x64, 0xf4,
0xdf, 0xaf, 0x7c, 0xdc, 0x83, 0x84, 0x8f, 0xcd, 0x1b, 0xc0, 0x1c, 0x7c, 0xd7, 0x4e, 0x3f, 0x0b,
0x98, 0xf2, 0xd1, 0xd0, 0x46, 0x98, 0x56, 0x01, 0x83, 0xda, 0x24, 0xb8, 0x5c, 0xfe, 0x84, 0x2f,
0xb1, 0x41, 0x6d, 0xf3, 0x53, 0x85, 0x84, 0x06, 0x75, 0x1b, 0x05, 0x79, 0xa6, 0xbb, 0x0f, 0x5a,
0x0d, 0xe8, 0xbb, 0x5b, 0x9f, 0xb5, 0x4e, 0x0e, 0xcc, 0x9c, 0xbd, 0x64, 0xe1, 0x3d, 0x27, 0x40,
0x0a, 0xba, 0x97, 0x2c, 0xf0, 0xc7, 0x04, 0x1b, 0xbd, 0x58, 0xf8, 0x48, 0x9e, 0x49, 0xfe, 0xae,
0x79, 0x56, 0x8e, 0x14, 0x57, 0xc9, 0x5b, 0x0f, 0xcb, 0xd7, 0xbb, 0x41, 0x7b, 0x01, 0xf6, 0xb4,
0x10, 0x31, 0x2f, 0x4b, 0xfd, 0x85, 0x42, 0xff, 0x86, 0x91, 0x96, 0x0d, 0xc1, 0xf7, 0x09, 0x1f,
0x86, 0x21, 0xdb, 0x33, 0x5a, 0x64, 0xbf, 0x7a, 0xb3, 0x8a, 0x6a, 0xb6, 0x3f, 0x78, 0xb3, 0xd6,
0xc9, 0xd9, 0xe9, 0xa5, 0xa5, 0xee, 0x67, 0x6e, 0xd6, 0x51, 0x75, 0xec, 0x0b, 0x37, 0x8f, 0x7b,
0x90, 0xda, 0xd5, 0x57, 0xd1, 0xfb, 0x47, 0x62, 0x3a, 0xe2, 0xd9, 0x64, 0xf0, 0x03, 0xff, 0x0a,
0xad, 0x98, 0x0e, 0xab, 0x9f, 0x8d, 0xd1, 0x3b, 0x94, 0xd8, 0x5e, 0x02, 0xdc, 0xe3, 0x17, 0xf3,
0xe9, 0x48, 0x32, 0x09, 0x2e, 0x01, 0xaa, 0xdf, 0x87, 0x95, 0x80, 0xb8, 0x04, 0xe8, 0x01, 0xc0,
0xde, 0xb8, 0xe0, 0x1c, 0xb5, 0x57, 0x09, 0x82, 0xf6, 0x34, 0x60, 0xb3, 0x08, 0x63, 0xaf, 0x4a,
0xd4, 0xe1, 0xa5, 0x3d, 0xab, 0xa3, 0xa4, 0x44, 0x16, 0xd1, 0xa6, 0xec, 0xe0, 0xae, 0xab, 0xaf,
0xbe, 0x3a, 0x32, 0x9f, 0xcd, 0x58, 0xb1, 0x04, 0x83, 0x5b, 0xd7, 0xd2, 0x01, 0x88, 0xc1, 0x8d,
0x82, 0x76, 0xd6, 0x36, 0xcd, 0x1c, 0x5f, 0x1f, 0x88, 0x42, 0xcc, 0x65, 0x92, 0x71, 0xf8, 0xe5,
0x09, 0xd3, 0xa0, 0x2e, 0x43, 0xcc, 0x5a, 0x8a, 0xb5, 0x59, 0xae, 0x22, 0xea, 0xfb, 0x84, 0xea,
0xbb, 0xc5, 0xa5, 0x14, 0x05, 0x7c, 0x9e, 0x58, 0x5b, 0x81, 0x10, 0x91, 0xe5, 0x92, 0x30, 0xe8,
0xfb, 0xd3, 0x24, 0x9b, 0xa2, 0x7d, 0x7f, 0xea, 0x7e, 0xf5, 0xf3, 0x1e, 0x0d, 0xd8, 0x09, 0x55,
0x37, 0x5a, 0x3d, 0x01, 0xf4, 0xbb, 0x9c, 0x68, 0xa3, 0xbb, 0x04, 0x31, 0xa1, 0x70, 0x12, 0xb8,
0x7a, 0x9d, 0xf3, 0x8c, 0x4f, 0x9a, 0x5b, 0x73, 0x98, 0x2b, 0x8f, 0x08, 0xba, 0x82, 0xa4, 0x8d,
0x45, 0x4a, 0x7e, 0x36, 0xcf, 0x4e, 0x0b, 0x71, 0x99, 0xa4, 0xbc, 0x00, 0xb1, 0xa8, 0x56, 0x77,
0xe4, 0x44, 0x2c, 0xc2, 0x38, 0x7b, 0xfd, 0x42, 0x49, 0xbd, 0x8f, 0x6f, 0x8f, 0x0b, 0x16, 0xc3,
0xeb, 0x17, 0xb5, 0x8d, 0x36, 0x46, 0x9c, 0x0c, 0x06, 0x70, 0x27, 0xd1, 0xa9, 0x5d, 0x67, 0x4b,
0x35, 0x3e, 0xf4, 0xbb, 0x84, 0xea, 0x5b, 0x98, 0x25, 0x48, 0x74, 0xb4, 0x39, 0x8c, 0x24, 0x12,
0x9d, 0xb0, 0x86, 0x5d, 0x4a, 0x14, 0x77, 0xa2, 0xaf, 0x15, 0x81, 0xa5, 0xa4, 0xb6, 0xd1, 0x08,
0x89, 0xa5, 0xa4, 0x05, 0x81, 0x80, 0xd4, 0x4c, 0x83, 0x29, 0x1a, 0x90, 0x8c, 0x34, 0x18, 0x90,
0x5c, 0xca, 0x06, 0x8a, 0xc3, 0x2c, 0x91, 0x09, 0x4b, 0x47, 0x5c, 0x9e, 0xb2, 0x82, 0xcd, 0xb8,
0xe4, 0x05, 0x0c, 0x14, 0x1a, 0x19, 0x7a, 0x0c, 0x11, 0x28, 0x28, 0x56, 0x3b, 0xfc, 0xbd, 0xe8,
0xc3, 0x6a, 0xdd, 0xe7, 0x99, 0xfe, 0x33, 0x1b, 0xaf, 0xd4, 0xdf, 0xe7, 0x19, 0x7c, 0x64, 0x6c,
0x8c, 0x64, 0xc1, 0xd9, 0xac, 0xb1, 0xfd, 0x81, 0xf9, 0x5d, 0x81, 0x4f, 0x57, 0xaa, 0xf1, 0x7c,
0x22, 0x64, 0x72, 0x59, 0x6d, 0xb3, 0xf5, 0x1b, 0x44, 0x60, 0x3c, 0xbb, 0xe2, 0x61, 0xe0, 0x5b,
0x14, 0x18, 0x67, 0xe3, 0xb4, 0x2b, 0x3d, 0xe3, 0x79, 0x0a, 0xe3, 0xb4, 0xa7, 0xad, 0x00, 0x22,
0x4e, 0xa3, 0xa0, 0x9d, 0x9c, 0xae, 0x78, 0xcc, 0xc3, 0x95, 0x19, 0xf3, 0x7e, 0x95, 0x19, 0x7b,
0x2f, 0x65, 0xa4, 0xd1, 0x87, 0xc7, 0x7c, 0x76, 0xc1, 0x8b, 0xf2, 0x2a, 0xc9, 0x0f, 0xaa, 0x84,
0x8b, 0xc9, 0x39, 0x7c, 0x6d, 0xd1, 0x12, 0x43, 0x83, 0x10, 0x59, 0x29, 0x81, 0xda, 0x95, 0xc0,
0x02, 0x87, 0xe5, 0x09, 0x9b, 0x71, 0xf5, 0x65, 0x0d, 0xb0, 0x12, 0x38, 0x46, 0x1c, 0x88, 0x58,
0x09, 0x48, 0xd8, 0x79, 0xbf, 0xcb, 0x32, 0x67, 0x7c, 0x5a, 0x8d, 0xb0, 0xe2, 0x94, 0x2d, 0x67,
0x3c, 0x93, 0xda, 0x24, 0x38, 0x93, 0x77, 0x4c, 0xe2, 0x3c, 0x71, 0x26, 0xdf, 0x47, 0xcf, 0x09,
0x4d, 0x5e, 0xc3, 0x9f, 0x8a, 0x42, 0xd6, 0x7f, 0x44, 0xe7, 0xbc, 0x48, 0x41, 0x68, 0xf2, 0x1b,
0xd5, 0x23, 0x89, 0xd0, 0x14, 0xd6, 0x70, 0xbe, 0x3e, 0xef, 0x95, 0xe1, 0x0d, 0x2f, 0xcc, 0x38,
0x79, 0x35, 0x63, 0x49, 0xaa, 0x47, 0xc3, 0x8f, 0x02, 0xb6, 0x09, 0x1d, 0xe2, 0xeb, 0xf3, 0x7d,
0x75, 0x9d, 0xef, 0xf5, 0x87, 0x4b, 0x08, 0x1e, 0x11, 0x74, 0xd8, 0x27, 0x1e, 0x11, 0x74, 0x6b,
0xd9, 0x9d, 0xbb, 0x65, 0x15, 0xb7, 0x54, 0xc4, 0xae, 0x98, 0xc0, 0xf3, 0x42, 0xc7, 0x26, 0x00,
0x89, 0x9d, 0x7b, 0x50, 0xc1, 0xa6, 0x06, 0x16, 0xdb, 0x4f, 0x32, 0x96, 0x26, 0x3f, 0x83, 0x69,
0xbd, 0x63, 0xa7, 0x21, 0x88, 0xd4, 0x00, 0x27, 0x31, 0x57, 0x07, 0x5c, 0x8e, 0x93, 0x2a, 0xf4,
0xaf, 0x07, 0xda, 0x4d, 0x11, 0xdd, 0xae, 0x1c, 0xd2, 0xf9, 0x46, 0x2b, 0x6c, 0xd6, 0x9d, 0x3c,
0x1f, 0x55, 0xab, 0xea, 0x19, 0x8f, 0x79, 0x92, 0xcb, 0xc1, 0x8b, 0x70, 0x5b, 0x01, 0x9c, 0xb8,
0x68, 0xd1, 0x43, 0xcd, 0x79, 0x7c, 0x5f, 0xc5, 0x92, 0x51, 0xfd, 0xd7, 0xe5, 0xce, 0x4b, 0x5e,
0xe8, 0x44, 0xe3, 0x80, 0x4b, 0x30, 0x3b, 0x1d, 0x6e, 0xe8, 0x80, 0x55, 0x45, 0x89, 0xd9, 0x19,
0xd6, 0xb0, 0x87, 0x7d, 0x0e, 0x77, 0xc6, 0x4b, 0x91, 0x2e, 0xb8, 0xba, 0x6f, 0xb8, 0x49, 0x1a,
0x73, 0x28, 0xe2, 0xb0, 0x8f, 0xa6, 0x6d, 0xb6, 0xd6, 0x76, 0xbb, 0x93, 0x2d, 0x0f, 0xe1, 0x95,
0x09, 0xc4, 0x92, 0xc2, 0x88, 0x6c, 0x2d, 0x80, 0x3b, 0x87, 0xe1, 0x85, 0x60, 0x93, 0x98, 0x95,
0xf2, 0x94, 0x2d, 0x53, 0xc1, 0x26, 0x6a, 0x5d, 0x87, 0x87, 0xe1, 0x0d, 0x33, 0x74, 0x21, 0xea,
0x30, 0x9c, 0x82, 0xdd, 0xec, 0x4c, 0xfd, 0xd1, 0x3c, 0x7d, 0x97, 0x13, 0x66, 0x67, 0xaa, 0xbc,
0xf0, 0x1e, 0xe7, 0xc3, 0x30, 0x64, 0xdf, 0x41, 0xab, 0x45, 0x2a, 0x0d, 0xb9, 0x87, 0xe9, 0x78,
0x09, 0xc8, 0xfd, 0x00, 0x61, 0xbf, 0x4b, 0x51, 0xff, 0xde, 0xfc, 0xdd, 0x17, 0xa9, 0xbf, 0x64,
0xbd, 0x89, 0xe9, 0xba, 0xd0, 0xd0, 0xfd, 0xc0, 0xdd, 0x56, 0x4f, 0xda, 0xa6, 0x99, 0xbb, 0x57,
0x4c, 0xee, 0x4c, 0x26, 0xc7, 0xbc, 0x44, 0x5e, 0x28, 0xaf, 0x84, 0x43, 0x2b, 0x25, 0xd2, 0xcc,
0x36, 0x65, 0x07, 0x7a, 0x25, 0x7b, 0x35, 0x49, 0xa4, 0x96, 0x35, 0x37, 0xa4, 0x37, 0xdb, 0x06,
0xda, 0x14, 0x51, 0x2b, 0x9a, 0xb6, 0xb1, 0xbc, 0x62, 0xc6, 0x62, 0x3a, 0x4d, 0xb9, 0x86, 0xce,
0x38, 0xab, 0x3f, 0xe4, 0xb7, 0xdd, 0xb6, 0x85, 0x82, 0x44, 0x2c, 0x0f, 0x2a, 0xd8, 0x34, 0xb2,
0xc2, 0xea, 0x47, 0x52, 0x4d, 0xc3, 0xae, 0xb5, 0xcd, 0x78, 0x00, 0x91, 0x46, 0xa2, 0xa0, 0x7d,
0xef, 0xad, 0x12, 0x1f, 0xf0, 0xa6, 0x25, 0xe0, 0x27, 0x88, 0x94, 0xb2, 0x23, 0x26, 0xde, 0x7b,
0x43, 0x30, 0xbb, 0x4f, 0x00, 0x1e, 0x5e, 0x2e, 0x0f, 0x27, 0x70, 0x9f, 0x00, 0xf5, 0x15, 0x43,
0xec, 0x13, 0x28, 0xd6, 0xef, 0x3a, 0x73, 0xee, 0x75, 0xc4, 0x4a, 0x5b, 0x39, 0xa4, 0xeb, 0x50,
0x30, 0xd4, 0x75, 0x94, 0x82, 0xdf, 0xa4, 0xee, 0xd1, 0x1a, 0xd2, 0xa4, 0xd8, 0xb9, 0xda, 0x6a,
0x17, 0x66, 0xe3, 0x92, 0xd9, 0x4f, 0xaa, 0x2b, 0x4b, 0xf8, 0x17, 0xfc, 0x6b, 0x21, 0x11, 0x97,
0x5a, 0x50, 0x6d, 0xfb, 0xe5, 0xfd, 0xff, 0xfc, 0xe6, 0xce, 0xca, 0x2f, 0xbe, 0xb9, 0xb3, 0xf2,
0xdf, 0xdf, 0xdc, 0x59, 0xf9, 0xf9, 0xb7, 0x77, 0xde, 0xfb, 0xc5, 0xb7, 0x77, 0xde, 0xfb, 0xaf,
0x6f, 0xef, 0xbc, 0xf7, 0xf5, 0xfb, 0xfa, 0x8f, 0xa9, 0x5e, 0xfc, 0x3f, 0xf5, 0x27, 0x51, 0x9f,
0xff, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x39, 0xd6, 0xda, 0x85, 0x70, 0x75, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -422,6 +424,8 @@ type ClientCommandsClient interface {
SpaceMakeShareable(ctx context.Context, in *pb.RpcSpaceMakeShareableRequest, opts ...grpc.CallOption) (*pb.RpcSpaceMakeShareableResponse, error)
SpaceParticipantRemove(ctx context.Context, in *pb.RpcSpaceParticipantRemoveRequest, opts ...grpc.CallOption) (*pb.RpcSpaceParticipantRemoveResponse, error)
SpaceParticipantPermissionsChange(ctx context.Context, in *pb.RpcSpaceParticipantPermissionsChangeRequest, opts ...grpc.CallOption) (*pb.RpcSpaceParticipantPermissionsChangeResponse, error)
SpaceSetOrder(ctx context.Context, in *pb.RpcSpaceSetOrderRequest, opts ...grpc.CallOption) (*pb.RpcSpaceSetOrderResponse, error)
SpaceUnsetOrder(ctx context.Context, in *pb.RpcSpaceUnsetOrderRequest, opts ...grpc.CallOption) (*pb.RpcSpaceUnsetOrderResponse, error)
// Object
// ***
ObjectOpen(ctx context.Context, in *pb.RpcObjectOpenRequest, opts ...grpc.CallOption) (*pb.RpcObjectOpenResponse, error)
@ -1113,6 +1117,24 @@ func (c *clientCommandsClient) SpaceParticipantPermissionsChange(ctx context.Con
return out, nil
}
func (c *clientCommandsClient) SpaceSetOrder(ctx context.Context, in *pb.RpcSpaceSetOrderRequest, opts ...grpc.CallOption) (*pb.RpcSpaceSetOrderResponse, error) {
out := new(pb.RpcSpaceSetOrderResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/SpaceSetOrder", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *clientCommandsClient) SpaceUnsetOrder(ctx context.Context, in *pb.RpcSpaceUnsetOrderRequest, opts ...grpc.CallOption) (*pb.RpcSpaceUnsetOrderResponse, error) {
out := new(pb.RpcSpaceUnsetOrderResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/SpaceUnsetOrder", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *clientCommandsClient) ObjectOpen(ctx context.Context, in *pb.RpcObjectOpenRequest, opts ...grpc.CallOption) (*pb.RpcObjectOpenResponse, error) {
out := new(pb.RpcObjectOpenResponse)
err := c.cc.Invoke(ctx, "/anytype.ClientCommands/ObjectOpen", in, out, opts...)
@ -3198,6 +3220,8 @@ type ClientCommandsServer interface {
SpaceMakeShareable(context.Context, *pb.RpcSpaceMakeShareableRequest) *pb.RpcSpaceMakeShareableResponse
SpaceParticipantRemove(context.Context, *pb.RpcSpaceParticipantRemoveRequest) *pb.RpcSpaceParticipantRemoveResponse
SpaceParticipantPermissionsChange(context.Context, *pb.RpcSpaceParticipantPermissionsChangeRequest) *pb.RpcSpaceParticipantPermissionsChangeResponse
SpaceSetOrder(context.Context, *pb.RpcSpaceSetOrderRequest) *pb.RpcSpaceSetOrderResponse
SpaceUnsetOrder(context.Context, *pb.RpcSpaceUnsetOrderRequest) *pb.RpcSpaceUnsetOrderResponse
// Object
// ***
ObjectOpen(context.Context, *pb.RpcObjectOpenRequest) *pb.RpcObjectOpenResponse
@ -3615,6 +3639,12 @@ func (*UnimplementedClientCommandsServer) SpaceParticipantRemove(ctx context.Con
func (*UnimplementedClientCommandsServer) SpaceParticipantPermissionsChange(ctx context.Context, req *pb.RpcSpaceParticipantPermissionsChangeRequest) *pb.RpcSpaceParticipantPermissionsChangeResponse {
return nil
}
func (*UnimplementedClientCommandsServer) SpaceSetOrder(ctx context.Context, req *pb.RpcSpaceSetOrderRequest) *pb.RpcSpaceSetOrderResponse {
return nil
}
func (*UnimplementedClientCommandsServer) SpaceUnsetOrder(ctx context.Context, req *pb.RpcSpaceUnsetOrderRequest) *pb.RpcSpaceUnsetOrderResponse {
return nil
}
func (*UnimplementedClientCommandsServer) ObjectOpen(ctx context.Context, req *pb.RpcObjectOpenRequest) *pb.RpcObjectOpenResponse {
return nil
}
@ -5099,6 +5129,42 @@ func _ClientCommands_SpaceParticipantPermissionsChange_Handler(srv interface{},
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_SpaceSetOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcSpaceSetOrderRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientCommandsServer).SpaceSetOrder(ctx, in), nil
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/anytype.ClientCommands/SpaceSetOrder",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientCommandsServer).SpaceSetOrder(ctx, req.(*pb.RpcSpaceSetOrderRequest)), nil
}
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_SpaceUnsetOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcSpaceUnsetOrderRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientCommandsServer).SpaceUnsetOrder(ctx, in), nil
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/anytype.ClientCommands/SpaceUnsetOrder",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientCommandsServer).SpaceUnsetOrder(ctx, req.(*pb.RpcSpaceUnsetOrderRequest)), nil
}
return interceptor(ctx, in, info, handler)
}
func _ClientCommands_ObjectOpen_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(pb.RpcObjectOpenRequest)
if err := dec(in); err != nil {
@ -9301,6 +9367,14 @@ var _ClientCommands_serviceDesc = grpc.ServiceDesc{
MethodName: "SpaceParticipantPermissionsChange",
Handler: _ClientCommands_SpaceParticipantPermissionsChange_Handler,
},
{
MethodName: "SpaceSetOrder",
Handler: _ClientCommands_SpaceSetOrder_Handler,
},
{
MethodName: "SpaceUnsetOrder",
Handler: _ClientCommands_SpaceUnsetOrder_Handler,
},
{
MethodName: "ObjectOpen",
Handler: _ClientCommands_ObjectOpen_Handler,

View file

@ -9,7 +9,7 @@ import (
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
const RelationChecksum = "0585cf84a06a32d7fa898e2d07c15cb6e3d0e2b2201fcae6125955df1f51f8f8"
const RelationChecksum = "5694f1d0c15a9a770f961a84dd5ee2af89886c00522f4150c601d40dadc502e0"
const (
RelationKeyTag domain.RelationKey = "tag"
RelationKeyCamera domain.RelationKey = "camera"
@ -144,6 +144,7 @@ const (
RelationKeyChatId domain.RelationKey = "chatId"
RelationKeyMentions domain.RelationKey = "mentions"
RelationKeyTimestamp domain.RelationKey = "timestamp"
RelationKeySpaceOrder domain.RelationKey = "spaceOrder"
)
var (
@ -1672,6 +1673,20 @@ var (
ReadOnlyRelation: true,
Scope: model.Relation_type,
},
RelationKeySpaceOrder: {
DataSource: model.Relation_details,
Description: "Space order",
Format: model.RelationFormat_longtext,
Hidden: true,
Id: "_brspaceOrder",
Key: "spaceOrder",
MaxCount: 1,
Name: "Space order",
ReadOnly: true,
ReadOnlyRelation: true,
Scope: model.Relation_type,
},
RelationKeySpaceRemoteStatus: {
DataSource: model.Relation_derived,

View file

@ -1361,5 +1361,15 @@
"name": "Timestamp",
"readonly": true,
"source": "derived"
},
{
"description": "Space order",
"format": "longtext",
"hidden": true,
"key": "spaceOrder",
"maxCount": 1,
"name": "Space order",
"readonly": true,
"source": "details"
}
]

View file

@ -172,15 +172,16 @@ func (b *queryBuilder) extractOrder(sorts []*model.BlockContentDataviewSort) Set
}
keyOrder := &KeyOrder{
SpaceID: b.spaceId,
Key: sort.RelationKey,
Type: sort.Type,
EmptyPlacement: sort.EmptyPlacement,
IncludeTime: isIncludeTime(sorts, sort),
relationFormat: format,
Store: b.objectStore,
arena: b.arena,
collatorBuffer: b.collatorBuffer,
SpaceID: b.spaceId,
Key: sort.RelationKey,
Type: sort.Type,
EmptyPlacement: sort.EmptyPlacement,
IncludeTime: isIncludeTime(sorts, sort),
relationFormat: format,
Store: b.objectStore,
arena: b.arena,
collatorBuffer: b.collatorBuffer,
disableCollator: sort.NoCollate,
}
order = b.appendCustomOrder(sort, order, keyOrder)
}

View file

@ -50,17 +50,18 @@ func (so SetOrder) AnystoreSort() query.Sort {
}
type KeyOrder struct {
SpaceID string
Key string
Type model.BlockContentDataviewSortType
EmptyPlacement model.BlockContentDataviewSortEmptyType
relationFormat model.RelationFormat
IncludeTime bool
Store ObjectStore
Options map[string]string
arena *anyenc.Arena
collatorBuffer *collate.Buffer
collator *collate.Collator
SpaceID string
Key string
Type model.BlockContentDataviewSortType
EmptyPlacement model.BlockContentDataviewSortEmptyType
relationFormat model.RelationFormat
IncludeTime bool
Store ObjectStore
Options map[string]string
arena *anyenc.Arena
collatorBuffer *collate.Buffer
collator *collate.Collator
disableCollator bool
}
func (ko *KeyOrder) ensureCollator() {
@ -92,6 +93,9 @@ func (ko *KeyOrder) Compare(a, b *types.Struct) int {
func (ko *KeyOrder) AnystoreSort() query.Sort {
switch ko.relationFormat {
case model.RelationFormat_shorttext, model.RelationFormat_longtext:
if ko.disableCollator {
return ko.basicSort(anyenc.TypeString)
}
return ko.textSort()
case model.RelationFormat_number:
return ko.basicSort(anyenc.TypeNumber)
@ -210,7 +214,7 @@ func (ko *KeyOrder) tryCompareStrings(av *types.Value, bv *types.Value) int {
comp = -1
}
}
if aString && bString && comp == 0 {
if aString && bString && comp == 0 && !ko.disableCollator {
ko.ensureCollator()
comp = ko.collator.CompareString(av.GetStringValue(), bv.GetStringValue())
}

View file

@ -383,6 +383,12 @@ func TestKeyOrder_Compare(t *testing.T) {
asc := &KeyOrder{arena: arena, Key: "k", Type: model.BlockContentDataviewSort_Desc, relationFormat: model.RelationFormat_number}
assertCompare(t, asc, a, b, 1)
})
t.Run("disable_collate", func(t *testing.T) {
a := &types.Struct{Fields: map[string]*types.Value{bundle.RelationKeySpaceOrder.String(): pbtypes.String("--UK")}}
b := &types.Struct{Fields: map[string]*types.Value{bundle.RelationKeySpaceOrder.String(): pbtypes.String("--jc")}}
ko := &KeyOrder{disableCollator: true, arena: arena, Key: bundle.RelationKeySpaceOrder.String(), Type: model.BlockContentDataviewSort_Asc, relationFormat: model.RelationFormat_shorttext}
assertCompare(t, ko, a, b, -1)
})
}
func TestKeyUnicodeOrder_Compare(t *testing.T) {

View file

@ -11,6 +11,7 @@ package ftsearch
#cgo android,amd64 LDFLAGS:-L${SRCDIR}/../../../../deps/libs/android-amd64 -ltantivy_go -lm -pthread -ldl
#cgo android,arm64 LDFLAGS:-L${SRCDIR}/../../../../deps/libs/android-arm64 -ltantivy_go -lm -pthread -ldl
#cgo linux,amd64 LDFLAGS:-L${SRCDIR}/../../../../deps/libs/linux-amd64-musl -Wl,--allow-multiple-definition -ltantivy_go -lm
#cgo linux,arm64 LDFLAGS:-L${SRCDIR}/../../../../deps/libs/linux-arm64-musl -Wl,--allow-multiple-definition -ltantivy_go -lm
*/
import "C"
import (
@ -21,10 +22,10 @@ import (
"strings"
"sync"
"time"
"unicode"
"github.com/anyproto/any-sync/app"
tantivy "github.com/anyproto/tantivy-go"
"github.com/samber/lo"
"github.com/valyala/fastjson"
"github.com/anyproto/anytype-heart/core/wallet"
@ -37,7 +38,7 @@ const (
CName = "fts"
ftsDir = "fts"
ftsDir2 = "fts_tantivy"
ftsVer = "9"
ftsVer = "10"
docLimit = 10000
fieldTitle = "Title"
@ -62,7 +63,7 @@ type FTSearch interface {
NewAutoBatcher() AutoBatcher
BatchIndex(ctx context.Context, docs []SearchDoc, deletedDocs []string) (err error)
BatchDeleteObjects(ids []string) (err error)
Search(spaceIds []string, query string) (results []*DocumentMatch, err error)
Search(spaceIds string, query string) (results []*DocumentMatch, err error)
Iterate(objectId string, fields []string, shouldContinue func(doc *SearchDoc) bool) (err error)
DeleteObject(id string) error
DocCount() (uint64, error)
@ -101,6 +102,7 @@ type ftSearchTantivy struct {
schema *tantivy.Schema
parserPool *fastjson.ParserPool
mu sync.Mutex
blevePath string
}
func TantivyNew() FTSearch {
@ -140,6 +142,7 @@ func (f *ftSearchTantivy) DeleteObject(objectId string) error {
func (f *ftSearchTantivy) Init(a *app.App) error {
repoPath := app.MustComponent[wallet.Wallet](a).RepoPath()
f.rootPath = filepath.Join(repoPath, ftsDir2)
f.blevePath = filepath.Join(repoPath, ftsDir)
f.ftsPath = filepath.Join(repoPath, ftsDir2, ftsVer)
return tantivy.LibInit(false, true, "release")
}
@ -169,7 +172,7 @@ func (f *ftSearchTantivy) Run(context.Context) error {
}
err = builder.AddTextField(
fieldId,
fieldId, // 0
true,
true,
false,
@ -178,7 +181,7 @@ func (f *ftSearchTantivy) Run(context.Context) error {
)
err = builder.AddTextField(
fieldIdRaw,
fieldIdRaw, // 1
true,
true,
true,
@ -187,7 +190,7 @@ func (f *ftSearchTantivy) Run(context.Context) error {
)
err = builder.AddTextField(
fieldSpace,
fieldSpace, // 2
true,
false,
true,
@ -196,25 +199,7 @@ func (f *ftSearchTantivy) Run(context.Context) error {
)
err = builder.AddTextField(
fieldTitle,
true,
true,
false,
tantivy.IndexRecordOptionWithFreqsAndPositions,
tantivy.TokenizerNgram,
)
err = builder.AddTextField(
fieldTitleZh,
true,
true,
false,
tantivy.IndexRecordOptionWithFreqsAndPositions,
tantivy.TokenizerJieba,
)
err = builder.AddTextField(
fieldText,
fieldTitle, // 3
true,
true,
false,
@ -223,7 +208,25 @@ func (f *ftSearchTantivy) Run(context.Context) error {
)
err = builder.AddTextField(
fieldTextZh,
fieldTitleZh, // 4
true,
true,
false,
tantivy.IndexRecordOptionWithFreqsAndPositions,
tantivy.TokenizerJieba,
)
err = builder.AddTextField(
fieldText, // 5
true,
true,
false,
tantivy.IndexRecordOptionWithFreqsAndPositions,
tantivy.TokenizerSimple,
)
err = builder.AddTextField(
fieldTextZh, // 6
true,
true,
false,
@ -366,28 +369,52 @@ func (f *ftSearchTantivy) BatchIndex(ctx context.Context, docs []SearchDoc, dele
return f.index.AddAndConsumeDocuments(tantivyDocs...)
}
func (f *ftSearchTantivy) Search(spaceIds []string, query string) (results []*DocumentMatch, err error) {
spaceIdsQuery := getSpaceIdsQuery(spaceIds)
func (f *ftSearchTantivy) Search(spaceId string, query string) (results []*DocumentMatch, err error) {
query = prepareQuery(query)
if query == "" {
return nil, nil
}
if spaceIdsQuery != "" {
query = fmt.Sprintf("%s AND %s", spaceIdsQuery, query)
qb := tantivy.NewQueryBuilder()
if len(spaceId) != 0 {
qb.Query(tantivy.Must, fieldSpace, spaceId, tantivy.TermQuery, 1.0)
}
if containsChineseCharacters(query) {
qb.BooleanQuery(tantivy.Must, qb.NestedBuilder().
Query(tantivy.Should, fieldTitleZh, query, tantivy.PhrasePrefixQuery, 5.0).
Query(tantivy.Should, fieldTitleZh, query, tantivy.PhraseQuery, 5.0).
Query(tantivy.Should, fieldTitleZh, query, tantivy.EveryTermQuery, 0.75).
Query(tantivy.Should, fieldTitleZh, query, tantivy.OneOfTermQuery, 0.5).
Query(tantivy.Should, fieldTextZh, query, tantivy.PhrasePrefixQuery, 1.0).
Query(tantivy.Should, fieldTextZh, query, tantivy.PhraseQuery, 1.0).
Query(tantivy.Should, fieldTextZh, query, tantivy.EveryTermQuery, 0.5).
Query(tantivy.Should, fieldTextZh, query, tantivy.OneOfTermQuery, 0.25),
1.0,
)
} else {
qb.BooleanQuery(tantivy.Must, qb.NestedBuilder().
Query(tantivy.Should, fieldTitle, query, tantivy.PhrasePrefixQuery, 10.0).
Query(tantivy.Should, fieldTitle, query, tantivy.PhraseQuery, 10.0).
Query(tantivy.Should, fieldTitle, query, tantivy.EveryTermQuery, 0.75).
Query(tantivy.Should, fieldTitle, query, tantivy.OneOfTermQuery, 0.5).
Query(tantivy.Should, fieldText, query, tantivy.PhrasePrefixQuery, 1.0).
Query(tantivy.Should, fieldText, query, tantivy.PhraseQuery, 1.0).
Query(tantivy.Should, fieldText, query, tantivy.EveryTermQuery, 0.5).
Query(tantivy.Should, fieldText, query, tantivy.OneOfTermQuery, 0.25),
1.0,
)
}
finalQuery := qb.Build()
sCtx := tantivy.NewSearchContextBuilder().
SetQuery(query).
SetQueryFromJson(&finalQuery).
SetDocsLimit(100).
SetWithHighlights(true).
AddFieldDefaultWeight(fieldId).
AddFieldDefaultWeight(fieldSpace).
AddField(fieldTitle, 10.0).
AddField(fieldTitleZh, 10.0).
AddFieldDefaultWeight(fieldText).
AddFieldDefaultWeight(fieldTextZh).
Build()
result, err := f.index.Search(sCtx)
result, err := f.index.SearchJson(sCtx)
if err != nil {
return nil, wrapError(err)
}
@ -432,6 +459,15 @@ func (f *ftSearchTantivy) Search(spaceIds []string, query string) (results []*Do
)
}
func containsChineseCharacters(s string) bool {
for _, r := range s {
if unicode.Is(unicode.Han, r) {
return true
}
}
return false
}
func extractHighlight(object *fastjson.Object, fragments map[string]*Highlight, fieldName string) {
highlightObj := object.Get(fragment)
if highlightObj == nil {
@ -459,26 +495,6 @@ func wrapError(err error) error {
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 ""
}
var builder strings.Builder
var sep string
builder.WriteString("(")
for _, id := range ids {
builder.WriteString(sep)
builder.WriteString(fieldSpace)
builder.WriteString(":")
builder.WriteString(id)
sep = " OR "
}
builder.WriteString(")")
return builder.String()
}
func (f *ftSearchTantivy) Delete(id string) error {
return f.BatchDeleteObjects([]string{id})
}
@ -498,24 +514,12 @@ func (f *ftSearchTantivy) Close(ctx context.Context) error {
}
func (f *ftSearchTantivy) cleanupBleve() {
_ = os.RemoveAll(filepath.Join(f.rootPath, ftsDir))
_ = os.RemoveAll(f.blevePath)
}
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(char)
}
}
resultQuery := escapedQuery.String()
if resultQuery == "" {
return resultQuery
}
return "(\"" + resultQuery + "\" OR " + resultQuery + ")"
return query
}

View file

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"os"
"strings"
"testing"
"github.com/anyproto/any-sync/app"
@ -76,23 +75,15 @@ func TestDifferentSpaces(t *testing.T) {
SpaceId: "space2",
}))
search, err := ft.Search([]string{"space1"}, "one")
search, err := ft.Search("space1", "one")
require.NoError(t, err)
require.Len(t, search, 1)
search, err = ft.Search([]string{"space2"}, "one")
search, err = ft.Search("space2", "one")
require.NoError(t, err)
require.Len(t, search, 1)
search, err = ft.Search([]string{"space1", "space2"}, "one")
require.NoError(t, err)
require.Len(t, search, 2)
search, err = ft.Search([]string{""}, "one")
require.NoError(t, err)
require.Len(t, search, 2)
search, err = ft.Search(nil, "one")
search, err = ft.Search("", "one")
require.NoError(t, err)
require.Len(t, search, 2)
@ -115,7 +106,12 @@ func TestNewFTSearch(t *testing.T) {
{
name: "assertFoundCaseSensitivePartsOfTheWords",
tester: assertFoundCaseSensitivePartsOfTheWords,
}, {
},
{
name: "assertPrefix",
tester: assertPrefix,
},
{
name: "assertChineseFound",
tester: assertChineseFound,
},
@ -133,6 +129,50 @@ func TestNewFTSearch(t *testing.T) {
}
}
func assertPrefix(t *testing.T, tmpDir string) {
fixture := newFixture(tmpDir, t)
ft := fixture.ft
require.NoError(t, ft.Index(SearchDoc{
Id: "1",
Title: "I love my mum",
Text: "",
}))
require.NoError(t, ft.Index(SearchDoc{
Id: "2",
Title: "",
Text: "Something completely different",
}))
require.NoError(t, ft.Index(SearchDoc{
Id: "4",
Title: "Just random filler",
Text: "",
}))
require.NoError(t, ft.Index(SearchDoc{
Id: "4",
Title: "Another text for fun",
Text: "",
}))
validateSearch(t, ft, "", "I love", 1)
validateSearch(t, ft, "", "I lo", 1)
validateSearch(t, ft, "", "I", 1)
validateSearch(t, ft, "", "lov", 1)
validateSearch(t, ft, "", "Something", 1)
validateSearch(t, ft, "", "Some", 1)
validateSearch(t, ft, "", "comp", 1)
validateSearch(t, ft, "", "diff", 1)
validateSearch(t, ft, "", "Something c", 1)
validateSearch(t, ft, "", "Something different", 1)
validateSearch(t, ft, "", "different something", 1)
_ = ft.Close(nil)
}
func assertFoundCaseSensitivePartsOfTheWords(t *testing.T, tmpDir string) {
fixture := newFixture(tmpDir, t)
ft := fixture.ft
@ -252,7 +292,7 @@ func assertSearch(t *testing.T, tmpDir string) {
}
func validateSearch(t *testing.T, ft FTSearch, spaceID, qry string, times int) {
res, err := ft.Search([]string{spaceID}, qry)
res, err := ft.Search(spaceID, qry)
require.NoError(t, err)
assert.Len(t, res, times)
}
@ -292,51 +332,11 @@ 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", 4)
_ = 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)

View file

@ -281,7 +281,7 @@ func (s *dsObjectStore) performQuery(q database.Query) (records []database.Recor
}
func (s *dsObjectStore) performFulltextSearch(text string, spaceId string) ([]database.FulltextResult, error) {
ftsResults, err := s.fts.Search([]string{spaceId}, text)
ftsResults, err := s.fts.Search(spaceId, text)
if err != nil {
return nil, fmt.Errorf("fullText search: %w", err)
}

View file

@ -5,6 +5,7 @@ import (
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
"github.com/anyproto/any-sync/app/logger"
@ -83,11 +84,23 @@ func (s *lumberjackSink) Sync() error {
}
func newLumberjackSink(u *url.URL) (zap.Sink, error) {
// if android, limit the log file size to 10MB
if runtime.GOOS == "android" || runtime.GOARCH == "ios" {
return &lumberjackSink{
Logger: &lumberjack.Logger{
Filename: u.Path,
MaxSize: 10,
MaxBackups: 2,
Compress: false,
},
}, nil
}
return &lumberjackSink{
Logger: &lumberjack.Logger{
Filename: u.Path,
MaxSize: 1,
MaxAge: 28,
Filename: u.Path,
MaxSize: 100,
MaxBackups: 10,
Compress: true,
},
}, nil
}
@ -95,9 +108,11 @@ func newLumberjackSink(u *url.URL) (zap.Sink, error) {
func Init(root string, logLevels string, sendLogs bool, saveLogs bool) {
if root != "" {
environment.ROOT_PATH = filepath.Join(root, "common")
err := os.Mkdir(environment.ROOT_PATH, 0755)
err := os.MkdirAll(environment.ROOT_PATH, 0755)
if err != nil {
fmt.Println("failed to create global dir", err)
if !os.IsExist(err) {
fmt.Println("failed to create global dir", err)
}
}
}
@ -129,15 +144,19 @@ func registerLumberjackSink(globalRoot string, config *logger.Config) {
fmt.Println("globalRoot dir is not set")
return
}
err := zap.RegisterSink(lumberjackScheme, newLumberjackSink)
logsDir := filepath.Join(globalRoot, "logs")
err := os.Mkdir(logsDir, 0755)
if err != nil && !os.IsExist(err) {
fmt.Println("failed to create logs dir", err)
// do not continue if logs dir can't be created
return
}
err = zap.RegisterSink(lumberjackScheme, newLumberjackSink)
if err != nil {
fmt.Println("failed to register lumberjack sink", err)
}
logsDir := filepath.Join(globalRoot, "logs")
err = os.Mkdir(logsDir, 0755)
if err != nil {
fmt.Println("failed to create globalRoot dir", err)
}
environment.LOG_PATH = filepath.Join(logsDir, "anytype.log")
config.AddOutputPaths = append(config.AddOutputPaths, lumberjackScheme+":"+environment.LOG_PATH)
}

File diff suppressed because it is too large Load diff

View file

@ -430,6 +430,7 @@ message Block {
bool includeTime = 5;
string id = 6;
EmptyType emptyPlacement = 7;
bool noCollate = 8;
enum Type {
Asc = 0;
@ -660,7 +661,7 @@ message Account {
string workspaceObjectId = 15; // workspace object id. used for space-level chat
string deviceId = 8;
string accountSpaceId = 9;
string accountSpaceId = 9; // the first created private space. It's filled only when account is created
string widgetsId = 10;
string spaceViewId = 13;
string techSpaceId = 14;

View file

@ -13,12 +13,13 @@ import (
const CName = coordinatorclient.CName
type coordinatorClient struct {
limiter chan struct{}
coordinatorclient.CoordinatorClient
delController deletioncontroller.DeletionController
}
func New() coordinatorclient.CoordinatorClient {
return &coordinatorClient{}
return &coordinatorClient{limiter: make(chan struct{}, 1)}
}
func (c *coordinatorClient) Init(a *app.App) (err error) {
@ -32,7 +33,14 @@ func (c *coordinatorClient) Name() string {
}
func (c *coordinatorClient) SpaceSign(ctx context.Context, payload coordinatorclient.SpaceSignPayload) (receipt *coordinatorproto.SpaceReceiptWithSignature, err error) {
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-c.limiter:
}
res, err := c.CoordinatorClient.SpaceSign(ctx, payload)
c.limiter <- struct{}{}
if err != nil {
return nil, err
}

View file

@ -7,32 +7,6 @@ import (
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/loader"
)
func (s *service) createPersonalSpace(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.CreatePersonalSpace(ctx, s.accountMetadataPayload)
if err != nil {
return
}
_, err = ctrl.Current().(loader.LoadWaiter).WaitLoad(ctx)
s.mu.Lock()
defer s.mu.Unlock()
close(wait)
if err != nil {
s.waiting[s.personalSpaceId] = controllerWaiter{
wait: wait,
err: err,
}
return
}
s.spaceControllers[s.personalSpaceId] = ctrl
return
}
func (s *service) create(ctx context.Context) (sp clientspace.Space, err error) {
coreSpace, err := s.spaceCore.Create(ctx, s.repKey, s.AccountMetadataPayload())
if err != nil {

View file

@ -90,7 +90,11 @@ 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() != "" {
res, err := accountObject.GetAnalyticsId()
if err != nil {
return err
}
if res != "" {
shouldMigrateProfile = false
hasIcon, err = accountObject.IsIconMigrated()
return err

View file

@ -83,8 +83,7 @@ func TestRunner_Run(t *testing.T) {
}))
err := fx.smartBlock.Apply(st)
require.NoError(t, err)
initDetails := pbtypes.ToStruct(map[string]any{})
fx.accountObject.EXPECT().CombinedDetails().Return(initDetails)
fx.accountObject.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(fx.accountObject)
})
@ -119,8 +118,7 @@ func TestRunner_Run(t *testing.T) {
}))
err := fx.smartBlock.Apply(st)
require.NoError(t, err)
initDetails := pbtypes.ToStruct(map[string]any{})
fx.accountObject.EXPECT().CombinedDetails().Return(initDetails)
fx.accountObject.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(fx.accountObject)
})
@ -157,10 +155,7 @@ func TestRunner_Run(t *testing.T) {
}))
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().GetAnalyticsId().Return("analyticsId", nil)
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)
@ -183,10 +178,7 @@ func TestRunner_Run(t *testing.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().GetAnalyticsId().Return("analyticsId", nil)
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)

View file

@ -318,6 +318,51 @@ func (_c *MockService_Delete_Call) RunAndReturn(run func(context.Context, string
return _c
}
// FirstCreatedSpaceId provides a mock function with given fields:
func (_m *MockService) FirstCreatedSpaceId() string {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for FirstCreatedSpaceId")
}
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockService_FirstCreatedSpaceId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FirstCreatedSpaceId'
type MockService_FirstCreatedSpaceId_Call struct {
*mock.Call
}
// FirstCreatedSpaceId is a helper method to define mock.On call
func (_e *MockService_Expecter) FirstCreatedSpaceId() *MockService_FirstCreatedSpaceId_Call {
return &MockService_FirstCreatedSpaceId_Call{Call: _e.mock.On("FirstCreatedSpaceId")}
}
func (_c *MockService_FirstCreatedSpaceId_Call) Run(run func()) *MockService_FirstCreatedSpaceId_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_FirstCreatedSpaceId_Call) Return(_a0 string) *MockService_FirstCreatedSpaceId_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_FirstCreatedSpaceId_Call) RunAndReturn(run func() string) *MockService_FirstCreatedSpaceId_Call {
_c.Call.Return(run)
return _c
}
// Get provides a mock function with given fields: ctx, id
func (_m *MockService) Get(ctx context.Context, id string) (clientspace.Space, error) {
ret := _m.Called(ctx, id)

View file

@ -63,13 +63,13 @@ type Service interface {
Delete(ctx context.Context, id string) (err error)
TechSpaceId() string
PersonalSpaceId() string
FirstCreatedSpaceId() 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
}
@ -107,6 +107,8 @@ type service struct {
ctx context.Context // use ctx for the long operations within the lifecycle of the service, excluding Run
ctxCancel context.CancelFunc
isClosing atomic.Bool
firstCreatedSpaceId string
}
func (s *service) Delete(ctx context.Context, id string) (err error) {
@ -238,25 +240,6 @@ func (s *service) initAccount(ctx context.Context) (err error) {
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
@ -276,7 +259,7 @@ func (s *service) createAccount(ctx context.Context) (err error) {
if err != nil {
return fmt.Errorf("init tech space: %w", err)
}
err = s.createPersonalSpace(ctx)
firstSpace, err := s.create(ctx)
if err != nil {
if errors.Is(err, spacesyncproto.ErrSpaceMissing) || errors.Is(err, treechangeproto.ErrGetTree) {
err = ErrSpaceNotExists
@ -288,6 +271,9 @@ func (s *service) createAccount(ctx context.Context) (err error) {
}
return fmt.Errorf("init personal space: %w", err)
}
s.firstCreatedSpaceId = firstSpace.Id()
s.techSpace.WakeUpViews()
// only persist networkId after successful space init
err = s.config.PersistAccountNetworkId()
@ -309,18 +295,6 @@ 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)
@ -481,6 +455,10 @@ func (s *service) PersonalSpaceId() string {
return s.personalSpaceId
}
func (s *service) FirstCreatedSpaceId() string {
return s.firstCreatedSpaceId
}
func (s *service) getTechSpace(ctx context.Context) (*clientspace.TechSpace, error) {
select {
case <-s.techSpaceReady:

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/commonspace/mock_commonspace"
"github.com/anyproto/any-sync/commonspace/object/accountdata"
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
"github.com/anyproto/any-sync/coordinator/coordinatorclient/mock_coordinatorclient"
@ -46,7 +47,6 @@ const (
testPersonalSpaceID = "personal.12345"
)
// TODO Revive tests
func TestService_Init(t *testing.T) {
t.Run("tech space getter", func(t *testing.T) {
serv := New().(*service)
@ -75,28 +75,9 @@ func TestService_Init(t *testing.T) {
t.Run("new account", func(t *testing.T) {
newFixture(t, nil)
})
t.Run("old account, analytics id migrated", func(t *testing.T) {
t.Run("old account", 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()
})
})
@ -105,14 +86,6 @@ func TestService_Init(t *testing.T) {
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()
})
})
@ -125,11 +98,6 @@ func TestService_Init(t *testing.T) {
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()
})
})
@ -403,8 +371,13 @@ func (fx *fixture) expectRun(t *testing.T, expectOldAccount func(t *testing.T, f
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)
prCtrl.EXPECT().SpaceId().Return(fx.spaceId)
commonSpace := mock_commonspace.NewMockSpace(fx.ctrl)
commonSpace.EXPECT().Id().Return(fx.spaceId).AnyTimes()
fx.spaceCore.EXPECT().Create(mock.Anything, mock.Anything, mock.Anything).Return(&spacecore.AnySpace{Space: commonSpace}, nil)
fx.factory.EXPECT().CreateShareableSpace(mock.Anything, mock.Anything).Return(prCtrl, nil)
lw := lwMock{clientSpace}
clientSpace.EXPECT().Id().Return(fx.spaceId)
prCtrl.EXPECT().Current().Return(lw)
prCtrl.EXPECT().Close(mock.Anything).Return(nil)
ts.EXPECT().WakeUpViews()

View file

@ -3,6 +3,7 @@ package techspace
import (
"context"
"errors"
"fmt"
"sync"
"time"
@ -30,10 +31,12 @@ var log = logger.NewNamed(CName)
const spaceViewCheckTimeout = time.Second * 15
var (
ErrSpaceViewExists = errors.New("spaceView exists")
ErrSpaceViewNotExists = errors.New("spaceView not exists")
ErrNotASpaceView = errors.New("smartblock not a spaceView")
ErrNotStarted = errors.New("techspace not started")
ErrSpaceViewExists = errors.New("spaceView exists")
ErrSpaceViewNotExists = errors.New("spaceView not exists")
ErrAccountObjectNotExists = errors.New("accountObject not exists")
ErrNotASpaceView = errors.New("smartblock not a spaceView")
ErrNotAnAccountObject = errors.New("smartblock not an accountObject")
ErrNotStarted = errors.New("techspace not started")
)
type AccountObject interface {
@ -44,7 +47,6 @@ type AccountObject interface {
IsIconMigrated() (bool, error)
SetAnalyticsId(analyticsId string) (err error)
GetAnalyticsId() (string, error)
GetPrivateAnalyticsId() string
}
type TechSpace interface {
@ -120,9 +122,12 @@ func (s *techSpace) Run(techCoreSpace commonspace.Space, objectCache objectcache
s.objectCache = objectCache
if !create {
exists, err := s.accountObjectExists(s.ctx)
if err != nil || exists {
if err != nil {
return err
}
if exists {
return nil
}
}
return s.accountObjectCreate(s.ctx)
}
@ -358,12 +363,11 @@ func (s *techSpace) DoAccountObject(ctx context.Context, apply func(accountObjec
}
obj, err := s.objectCache.GetObject(ctx, id)
if err != nil {
// TODO: [PS] check specific error
return ErrSpaceViewNotExists
return fmt.Errorf("account object not exists %w: %w", ErrAccountObjectNotExists, err)
}
accountObject, ok := obj.(AccountObject)
if !ok {
return ErrNotASpaceView
return ErrNotAnAccountObject
}
accountObject.Lock()

View file

@ -41,7 +41,8 @@ func (w *spaceWaiter) waitSpace(ctx context.Context, spaceId string) (sp clients
// if there is no such space view then there is no space
exists, err := techSpace.SpaceViewExists(ctx, spaceId)
if err != nil {
return nil, fmt.Errorf("space view exists error: %w", err)
// func returns error only on derive
return nil, fmt.Errorf("space view derive error: %w", err)
}
if !exists {
return nil, ErrSpaceNotExists

View file

@ -1,11 +1,12 @@
b9ce3724a4b77c7d08d74843c08c0961ccbff8d446c6186ce0e7fd484bb1cc04 deps/libs/android-386.tar.gz
902dc8730451ad3e0e21d1d59cea3a833bb98bb7dc944b4263e5dbe955835101 deps/libs/android-amd64.tar.gz
9cd93ffd7ec2ab96ef0c3720ef30a1c1f290b785b0764cc9aae1f4eceaf128ca deps/libs/android-arm.tar.gz
220b5876c642080f39e23a0033e4b853d749c38b02b19c8b605571c53f05f833 deps/libs/android-arm64.tar.gz
d691873e86e6677e7df748982f274a0bfea92e6ac6e558c5c5d542263944436b deps/libs/darwin-amd64.tar.gz
83f4360fd53777805ba349924ade7fb1ebce00818bc2e37da87ccf7f8c53f024 deps/libs/darwin-arm64.tar.gz
a22f251a7b12152503d6b175e57c47f9117cccd0e3182e4febedda6615fcbd36 deps/libs/ios-amd64.tar.gz
1875f72dd8d87d833639d1ffef63d6a9e3a6175e442f1cf2954973b81f676125 deps/libs/ios-arm64.tar.gz
e873c9439307e5bacbe48a03bbc112a5550b5d907567950bd9cc33728d4f8cd3 deps/libs/ios-arm64-sim.tar.gz
63bf26424e423230d7f4a267d103ff91db8b5e9ad24916b104190f0ae006d480 deps/libs/linux-amd64-musl.tar.gz
d4269f6bc1fd70e8e15b4f396d9bb1ba046835ba75731d12071a9d079ec0ce4d deps/libs/windows-amd64.tar.gz
bd658eb370191a0154ac47e0f61fa6d91e8313de7e64cfede5078fea93e4eb34 deps/libs/android-386.tar.gz
a5d3083ac3eacbc0970153d0a5891412a595dcefe0dbe5b1134108ae5eac7072 deps/libs/android-amd64.tar.gz
9411be7eda46fbd1548ca2804d1056b735a989df740129f67b924c407a9ce3a1 deps/libs/android-arm.tar.gz
09a8b921b8d1385c7114ec67f6e665a448f7329642b178b84ecfdd7faf1828e1 deps/libs/android-arm64.tar.gz
2f27b349b54d5982347f20b56ae8e4bacce5436fb3a1dd213f3c1bfc3ed60b0b deps/libs/darwin-amd64.tar.gz
a518db7c5f9ebeb267966e390f788b76ee2643353af381e61110111546d3291b deps/libs/darwin-arm64.tar.gz
1da257cbf8cf27bfeda21b5dc4c432412b58e06b80fe3653384b1bc5c12de004 deps/libs/ios-amd64.tar.gz
6d7238b2743a23a745a52a1efb56760e3168e0601b292c96446afb7b737e5096 deps/libs/ios-arm64.tar.gz
d412c6864853d916dd507508ec4a2f63b8eddc48a3e619e74dc7a90aaeb3f1a9 deps/libs/ios-arm64-sim.tar.gz
35db326fee587c60cfec806847bff9706c8a209d46ee7449bb8664ee3ba815d5 deps/libs/linux-amd64-musl.tar.gz
6029bdc9ef576e4473bb15e967255f76f25e12e211ae131cb887211916ca0fed deps/libs/linux-arm64-musl.tar.gz
7475c129c4e18a93dfb8e583da95abf073d70f8a589291cf5d5ca6f8c71021e5 deps/libs/windows-amd64.tar.gz

View file

@ -81,12 +81,13 @@ var (
// TODO: GO-2009 Now we need to create widgets by hands, widget import is not implemented yet
widgetParams = map[pb.RpcObjectImportUseCaseRequestUseCase][]widgetParameters{
pb.RpcObjectImportUseCaseRequest_EMPTY: {
{model.BlockContentWidget_CompactList, widget.DefaultWidgetFavorite, "", false},
{model.BlockContentWidget_CompactList, widget.DefaultWidgetSet, "", false},
{model.BlockContentWidget_CompactList, widget.DefaultWidgetRecent, "", false},
{model.BlockContentWidget_Link, "bafyreic75ulgm2yz426hjwdjkzqw3kafniknki7qkhufqgrspmxzdppixa", "", true},
},
pb.RpcObjectImportUseCaseRequest_GET_STARTED: {
{model.BlockContentWidget_Link, "bafyreic75ulgm2yz426hjwdjkzqw3kafniknki7qkhufqgrspmxzdppixa", "", true},
{model.BlockContentWidget_Link, "bafyreiccjf5vbijsmr55ypsnnzltmcvl4n63g73twwxqnfkn5usoq2iqyi", "", true},
{model.BlockContentWidget_View, "bafyreifjgm3iy4o6o4zyf33ld3dnweo2grhvakvr7psn5twjge3xo3627m", "66f6775526909528d002c932", true},
{model.BlockContentWidget_View, "bafyreihrzztw2xcmxxz5uz5xodncby23xdacalcek2dtxxu77yn6wvzsq4", "6182a74fcae0300221f9f207", true},
{model.BlockContentWidget_CompactList, widget.DefaultWidgetRecentOpen, "", false},
},
}
)

Binary file not shown.

View file

@ -10,8 +10,8 @@ import (
const (
shortDateIdLayout = "2006-01-02"
dateIdLayout = "2006-01-02-15-04-05Z-0700"
shortDateNameLayout = "Mon, Jan 02, 2006"
dateNameLayout = "Mon, Jan 02, 2006 3:04 PM"
shortDateNameLayout = "Mon, Jan 2, 2006"
dateNameLayout = "Mon, Jan 2, 2006 3:04 PM"
)
type DateObject interface {

View file

@ -17,17 +17,17 @@ func TestNewDateObject(t *testing.T) {
{
ts: time.Date(2024, time.November, 7, 12, 25, 59, 0, time.UTC),
expectedId: "_date_2024-11-07-12-25-59Z_0000",
expectedName: "Thu, Nov 07, 2024 12:25 PM",
expectedName: "Thu, Nov 7, 2024 12:25 PM",
},
{
ts: time.Date(1998, time.January, 1, 0, 1, 1, 0, time.UTC),
expectedId: "_date_1998-01-01-00-01-01Z_0000",
expectedName: "Thu, Jan 01, 1998 12:01 AM",
expectedName: "Thu, Jan 1, 1998 12:01 AM",
},
{
ts: time.Date(1998, time.January, 1, 0, 1, 1, 0, time.FixedZone("UTC", +4*60*60)),
expectedId: "_date_1998-01-01-00-01-01Z_0400",
expectedName: "Thu, Jan 01, 1998 12:01 AM",
expectedName: "Thu, Jan 1, 1998 12:01 AM",
},
{
ts: time.Date(2124, time.December, 25, 23, 34, 0, 0, time.UTC),
@ -56,17 +56,17 @@ func TestNewDateObject(t *testing.T) {
{
ts: time.Date(2024, time.November, 7, 12, 25, 59, 0, time.UTC),
expectedId: "_date_2024-11-07",
expectedName: "Thu, Nov 07, 2024",
expectedName: "Thu, Nov 7, 2024",
},
{
ts: time.Date(1998, time.January, 1, 0, 1, 1, 0, time.UTC),
expectedId: "_date_1998-01-01",
expectedName: "Thu, Jan 01, 1998",
expectedName: "Thu, Jan 1, 1998",
},
{
ts: time.Date(1998, time.January, 1, 0, 1, 1, 0, time.FixedZone("UTC", +4*60*60)),
expectedId: "_date_1998-01-01",
expectedName: "Thu, Jan 01, 1998",
expectedName: "Thu, Jan 1, 1998",
},
{
ts: time.Date(2124, time.December, 25, 23, 34, 0, 0, time.UTC),

View file

@ -0,0 +1,48 @@
package metricsid
import (
"bytes"
"github.com/anyproto/any-sync/util/crypto"
"github.com/anyproto/any-sync/util/strkey"
"github.com/anyproto/go-slip10"
)
const (
metricsVersionByte strkey.VersionByte = 0xce
MetricsDerivationPath = "m/99999'/0'"
)
func deriveFromPrivKey(path string, privKey crypto.PrivKey) (key crypto.PrivKey, err error) {
rawBytes, err := privKey.Raw()
if err != nil {
return nil, err
}
node, err := slip10.DeriveForPath(path, rawBytes)
if err != nil {
return nil, err
}
return genKey(node)
}
func genKey(node slip10.Node) (key crypto.PrivKey, err error) {
reader := bytes.NewReader(node.RawSeed())
key, _, err = crypto.GenerateEd25519Key(reader)
return
}
func encodeMetricsId(pubKey crypto.PubKey) (string, error) {
raw, err := pubKey.Raw()
if err != nil {
return "", err
}
return strkey.Encode(metricsVersionByte, raw)
}
func DeriveMetricsId(privKey crypto.PrivKey) (string, error) {
key, err := deriveFromPrivKey(MetricsDerivationPath, privKey)
if err != nil {
return "", err
}
return encodeMetricsId(key.GetPublic())
}

Some files were not shown because too many files have changed in this diff Show more