From 8a8b433e38b2f2a07975d9a2112a286584f61f3e Mon Sep 17 00:00:00 2001 From: Dmitry Osipov Date: Wed, 27 Dec 2023 16:34:44 +0400 Subject: [PATCH 1/3] update --- src/batchState.ts | 20 +++++++- src/handlers/cb-nft.ts | 103 +++++++++++++++++++++++------------------ src/main.ts | 4 +- 3 files changed, 79 insertions(+), 48 deletions(-) diff --git a/src/batchState.ts b/src/batchState.ts index 5477ab6..4bb7a39 100644 --- a/src/batchState.ts +++ b/src/batchState.ts @@ -1,7 +1,8 @@ import { Store } from '@subsquid/typeorm-store'; -import { Account, Nft, NftCollection, Transfer } from './model'; import { randomUUID } from 'crypto'; import { In } from 'typeorm'; + +import { Account, Nft, NftCollection, Transfer } from './model'; import { logger } from './logger'; export class BatchState { @@ -32,20 +33,25 @@ export class BatchState { async save() { if (this.accounts.size > 0) { await this.store.save(Array.from(this.accounts.values())); + logger.info('Accounts saved', { count: this.accounts.size }); } if (this.collections.size > 0) { await this.store.save(Array.from(this.collections.values())); + logger.info('Collections saved', { count: this.collections.size }); } if (this.nfts.size > 0) { await this.store.save(Array.from(this.nfts.values())); + logger.info('Nfts saved', { count: this.nfts.size }); } if (this.transfers.size > 0) { await this.store.save(Array.from(this.transfers.values())); + logger.info('Transfers saved', { count: this.transfers.size }); } if (this.burntNfts.size > 0) { const transfers = await this.store.findBy(Transfer, { nft: { id: In(Array.from(this.burntNfts.keys())) } }); await this.store.remove(transfers); await this.store.remove(Array.from(this.burntNfts.values())); + logger.info('Nfts deleted', { count: this.burntNfts.size, transfersCount: transfers.length }); } } @@ -116,6 +122,7 @@ export class BatchState { const id = `${collection.id}-${tokenId}`; const owner = await this.getAccount(ownerAddress); + let nft = mint ? new Nft({ id, @@ -131,9 +138,18 @@ export class BatchState { }) : await this.getNft(id); + if (!nft) { + logger.error('NFT not found', { id: id, block: blockNumber.toString() }); + return; + } + nft.attribUrl = attribUrl; - logger.info('Mint', { owner: ownerAddress, collection: collection.id, id }); + logger.info(mint ? 'Mint' : 'Nft Changed', { + id, + owner: ownerAddress, + block: blockNumber.toString(), + }); this.nfts.set(`${collection.id}-${tokenId}`, nft); } diff --git a/src/handlers/cb-nft.ts b/src/handlers/cb-nft.ts index 2432dfe..928354a 100644 --- a/src/handlers/cb-nft.ts +++ b/src/handlers/cb-nft.ts @@ -1,14 +1,17 @@ import { ProgramMetadata } from '@gear-js/api'; -import { BatchState } from '../batchState'; import { readFileSync } from 'fs'; + +import { getCollectionDescription, getCollectionName } from './helpers'; +import { BatchState } from '../batchState'; import { MasterNftEvent } from '../types'; import { getDate } from '../utils'; -import { getCollectionDescription, getCollectionName } from './helpers'; +import { logger } from '../logger'; const meta = ProgramMetadata.from(readFileSync('./assets/cb-nft.meta.txt', 'utf8')); export async function cbNftHandler( state: BatchState, + id: string, payload: string, source: string, blockNumber: bigint, @@ -16,48 +19,60 @@ export async function cbNftHandler( linkIsFull = false, ) { const data = meta.createType(meta.types.others.output, payload); - if (data.isMinted || data.isNftChanged) { - const action = data.isMinted ? data.asMinted : data.asNftChanged; - const tokenId = action.tokenId.toString(); - const { media, owner, activities, link } = action.meta; - let collection = await state.getCollection(source); - if (!collection) { - const [collectionName, collectionDesc] = await Promise.all([ - getCollectionName(meta, source), - getCollectionDescription(meta, source), - ]); - collection = state.newCollection(source, collectionName, collectionDesc); - } - await state.mintNft( - tokenId, - collection, - owner.toHex(), - activities.map(([name, times, ts]) => { - const timesFormatted = name.toString() === 'NFT minted' ? ', ' : ` ${times.toString()} times, `; - const date = getDate(ts.toString()); - const dateFormatted = name.toString() === 'NFT minted' ? `date: ${date}` : `last game date: ${date}`; - return `${name}${timesFormatted}${dateFormatted}`; - }), - collection.description, - collection.name + ' - ' + media.toString(), - linkIsFull ? link.toString() : `${link.toString()}/${tokenId}.png`, - blockNumber, - ts, - data.isMinted, - ); - } else if (data.isTransferred) { - const { tokenId, owner, recipient } = data.asTransferred; - const collection = await state.getCollection(source); - await state.transferNft(tokenId.toString(), collection, owner.toHex(), recipient.toHex(), ts, blockNumber); - } else if (data.isBurnt) { - const { tokenId } = data.asBurnt; - await state.burnNft(tokenId.toString(), source); - } else if (data.isApproved) { - const { approvedAccount, tokenId } = data.asApproved; - await state.approveAccount(tokenId.toString(), source, approvedAccount.toHex()); - } else if (data.isApprovalRevoked) { - const { tokenId } = data.asApprovalRevoked; - await state.revokeApprove(tokenId.toString(), source); + try { + if (data.isMinted || data.isNftChanged) { + const action = data.isMinted ? data.asMinted : data.asNftChanged; + + const tokenId = action.tokenId.toString(); + + const { media, owner, activities, link } = action.meta; + let collection = await state.getCollection(source); + if (!collection) { + const [collectionName, collectionDesc] = await Promise.all([ + getCollectionName(meta, source), + getCollectionDescription(meta, source), + ]); + collection = state.newCollection(source, collectionName, collectionDesc); + } + + await state.mintNft( + tokenId, + collection, + owner.toHex(), + activities.map(([name, times, ts]) => { + const timesFormatted = name.toString() === 'NFT minted' ? ', ' : ` ${times.toString()} times, `; + const date = getDate(ts.toString()); + const dateFormatted = name.toString() === 'NFT minted' ? `date: ${date}` : `last game date: ${date}`; + return `${name}${timesFormatted}${dateFormatted}`; + }), + collection.description, + collection.name + ' - ' + tokenId, + linkIsFull ? link.toString() : `${link.toString()}/${media.toString()}.png`, + blockNumber, + ts, + data.isMinted, + ); + } else if (data.isTransferred) { + const { tokenId, owner, recipient } = data.asTransferred; + const collection = await state.getCollection(source); + await state.transferNft(tokenId.toString(), collection, owner.toHex(), recipient.toHex(), ts, blockNumber); + } else if (data.isBurnt) { + const { tokenId } = data.asBurnt; + await state.burnNft(tokenId.toString(), source); + } else if (data.isApproved) { + const { approvedAccount, tokenId } = data.asApproved; + await state.approveAccount(tokenId.toString(), source, approvedAccount.toHex()); + } else if (data.isApprovalRevoked) { + const { tokenId } = data.asApprovalRevoked; + await state.revokeApprove(tokenId.toString(), source); + } + } catch (err) { + logger.error('Error while processing CB NFT', { + err: err.message, + payload: data.toJSON(), + msgId: id, + bn: blockNumber.toString(), + }); } } diff --git a/src/main.ts b/src/main.ts index 171e0cb..efd3323 100644 --- a/src/main.ts +++ b/src/main.ts @@ -35,14 +35,14 @@ processor.run(new TypeormDatabase(), async (ctx) => { if (event.name !== 'Gear.UserMessageSent') continue; const { - message: { source, payload, details }, + message: { source, payload, details, id }, } = event.args as UserMessageSentArgs; if (payload === '0x') continue; if (details && details.code.__kind !== 'Success') continue; if (programs.includes(source)) { - await cbNftHandler(state, payload, source, blockNumber, ts); + await cbNftHandler(state, id, payload, source, blockNumber, ts); } else if (simpleNfts.includes(source)) { await draftNftHandler(state, payload, source, blockNumber, ts); } From a26f04f70ce33e76ea254e0dbe04e5d0693b9d8d Mon Sep 17 00:00:00 2001 From: Dmitry Osipov Date: Wed, 27 Dec 2023 16:53:32 +0400 Subject: [PATCH 2/3] update storage meta --- assets/cb-storage.meta.txt | 2 +- src/handlers/migrated-nft.ts | 6 +++--- src/types/cb-nft.ts | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/assets/cb-storage.meta.txt b/assets/cb-storage.meta.txt index 22e38a5..11b4f67 100644 --- a/assets/cb-storage.meta.txt +++ b/assets/cb-storage.meta.txt @@ -1 +1 @@ -000200010000000000010600000001100000000000000001110000000112000000c128740008186e66745f696f1c496e69744e465400002001106e616d65040118537472696e6700012c6465736372697074696f6e040118537472696e67000140697066735f666f6c6465725f6c696e6b040118537472696e6700011461646d696e08011c4163746f72496400014c73746172745f6e756d6265725f6f665f6e667414010c75333200015c6e65775f73746172745f6e756d6265725f6f665f6e667414010c7533320001386e756d6265725f6f665f6e66747314010c7533320001346d656469615f6d6f64756c757314010c75333200000400000502000810106773746418636f6d6d6f6e287072696d6974697665731c4163746f724964000004000c01205b75383b2033325d00000c0000032000000010001000000503001400000505001808186e66745f696f244e4654416374696f6e000140104d696e74040124726563697069656e7408011c4163746f7249640000001c417070726f76650c011c6163636f756e7408011c4163746f724964000140617070726f7665645f6163636f756e7408011c4163746f724964000120746f6b656e5f696414010c753332000100385265766f6b65417070726f76616c08011c6163636f756e7408011c4163746f724964000120746f6b656e5f696414010c753332000200104275726e08011c6163636f756e7408011c4163746f724964000120746f6b656e5f696414010c7533320003006c416363657074546f6b656e46726f6d4f7468657253746f72616765080120746f6b656e5f696414010c7533320001106d6574611c0138496e6e6572546f6b656e4d657461000400205472616e736665720c011c6163636f756e7408011c4163746f724964000124726563697069656e7408011c4163746f724964000120746f6b656e5f696414010c753332000500144f776e6572040120746f6b656e5f696414010c75333200060038546f6b656e73466f724f776e65720401206f776e65725f696408011c4163746f72496400070030416464417474726962757465080120746f6b656e5f696414010c753332000124617474726962757465040118537472696e670008002041646441646d696e04012061646d696e5f696408011c4163746f7249640009002c44656c65746541646d696e04012061646d696e5f696408011c4163746f724964000a0038557064617465497066734c696e6b040140697066735f666f6c6465725f6c696e6b040118537472696e67000b00485570646174654e756d6265724f664e6674730401386e756d6265725f6f665f6e66747314010c753332000c005855706461746553746172744e756d6265724f664e667404014c73746172745f6e756d6265725f6f665f6e667414010c753332000d00244275726e466f726365040124746f6b656e5f6964733401205665633c7533323e000e0024416464546f6b656e73040118746f6b656e733801685665633c287533322c20496e6e6572546f6b656e4d657461293e000f00001c08186e66745f696f38496e6e6572546f6b656e4d65746100001001146d6564696114010c7533320001146f776e657208011c4163746f7249640001286163746976697469657320015c5665633c28537472696e672c207531362c20753634293e0001106c696e6b3001384f7074696f6e3c537472696e673e0000200000022400240000040c04282c002800000504002c00000506003004184f7074696f6e04045401040108104e6f6e6500000010536f6d650400040000010000340000021400380000023c003c00000408141c004008186e66745f696f204e46545265706c79000124184d696e746564080120746f6b656e5f696414010c7533320001106d6574611c0138496e6e6572546f6b656e4d657461000000144f776e65720801146f776e657208011c4163746f724964000120746f6b656e5f696414010c75333200010038546f6b656e73466f724f776e6572040118746f6b656e733401205665633c7533323e000200284e66744368616e6765640401106d6574611c0138496e6e6572546f6b656e4d65746100030020417070726f766564000400144275726e740401106d6574611c0138496e6e6572546f6b656e4d6574610005002c5472616e7366657272656400060034546f6b656e41636365707465640401106d6574611c0138496e6e6572546f6b656e4d6574610007003c417070726f76616c5265766f6b6564000800004408186e66745f696f285374617465517565727900013424546f6b656e496e666f040014010c75333200000024416c6c546f6b656e7300010040416c6c546f6b656e735261774461746100020034546f6b656e73496e52616e676508011066726f6d14010c753332000108746f14010c753332000300504e756d6265724f664d696e746564546f6b656e73000400304f776e65724f66546f6b656e040014010c7533320005003849706673466f6c6465724c696e6b0006001841646d696e730007003c417070726f76616c4f66546f6b656e040014010c75333200080030416c6c417070726f76616c7300090038546f6b656e73466f724f776e6572040008011c4163746f724964000a003c4d61784e756d6265724f664e667473000b004053746172744e756d6265724f664e6674000c00004808186e66745f696f2853746174655265706c7900013424546f6b656e496e666f04004c012c4f7074696f6e3c4e66743e00000024416c6c546f6b656e73040058014c5665633c284163746f7249642c204e6674293e00010040416c6c546f6b656e7352617744617461040060014c5665633c496e6e6572546f6b656e4d6574613e00020034546f6b656e73496e52616e6765040058014c5665633c284163746f7249642c204e6674293e000300504e756d6265724f664d696e746564546f6b656e7304002c010c753634000400304f776e65724f66546f6b656e040008011c4163746f7249640005003849706673466f6c6465724c696e6b0400040118537472696e670006001841646d696e7304006401305665633c4163746f7249643e0007003c417070726f76616c4f66546f6b656e040068013c4f7074696f6e3c4163746f7249643e00080030416c6c417070726f76616c7304006c014c5665633c287533322c204163746f724964293e00090038546f6b656e73466f724f776e657204003401205665633c7533323e000a003c4d61784e756d6265724f664e667473040014010c753332000b004053746172744e756d6265724f664e6674040014010c753332000c00004c04184f7074696f6e04045401500108104e6f6e6500000010536f6d6504005000000100005008186e66745f696f0c4e667400001401146f776e657208011c4163746f7249640001106e616d65040118537472696e6700012c6465736372697074696f6e040118537472696e670001246d656469615f75726c040118537472696e670001286174747269625f75726c54012c5665633c537472696e673e0000540000020400580000025c005c00000408085000600000021c006400000208006804184f7074696f6e04045401080108104e6f6e6500000010536f6d6504000800000100006c00000270007000000408140800 \ No newline at end of file +0002000100000000000106000000011000000000000000011100000001120000000529740008186e66745f696f1c496e69744e465400002001106e616d65040118537472696e6700012c6465736372697074696f6e040118537472696e67000140697066735f666f6c6465725f6c696e6b040118537472696e6700011461646d696e08011c4163746f72496400014c73746172745f6e756d6265725f6f665f6e667414010c75333200015c6e65775f73746172745f6e756d6265725f6f665f6e667414010c7533320001386e756d6265725f6f665f6e66747314010c7533320001346d656469615f6d6f64756c757314010c75333200000400000502000810106773746418636f6d6d6f6e287072696d6974697665731c4163746f724964000004000c01205b75383b2033325d00000c0000032000000010001000000503001400000505001808186e66745f696f244e4654416374696f6e000140104d696e74040124726563697069656e7408011c4163746f7249640000001c417070726f76650c011c6163636f756e7408011c4163746f724964000140617070726f7665645f6163636f756e7408011c4163746f724964000120746f6b656e5f696414010c753332000100385265766f6b65417070726f76616c08011c6163636f756e7408011c4163746f724964000120746f6b656e5f696414010c753332000200104275726e08011c6163636f756e7408011c4163746f724964000120746f6b656e5f696414010c7533320003006c416363657074546f6b656e46726f6d4f7468657253746f72616765080120746f6b656e5f696414010c7533320001106d6574611c0138496e6e6572546f6b656e4d657461000400205472616e736665720c011c6163636f756e7408011c4163746f724964000124726563697069656e7408011c4163746f724964000120746f6b656e5f696414010c753332000500144f776e6572040120746f6b656e5f696414010c75333200060038546f6b656e73466f724f776e65720401206f776e65725f696408011c4163746f72496400070030416464417474726962757465080120746f6b656e5f696414010c753332000124617474726962757465040118537472696e670008002041646441646d696e04012061646d696e5f696408011c4163746f7249640009002c44656c65746541646d696e04012061646d696e5f696408011c4163746f724964000a0038557064617465497066734c696e6b040140697066735f666f6c6465725f6c696e6b040118537472696e67000b00485570646174654e756d6265724f664e6674730401386e756d6265725f6f665f6e66747314010c753332000c005855706461746553746172744e756d6265724f664e667404014c73746172745f6e756d6265725f6f665f6e667414010c753332000d00244275726e466f726365040124746f6b656e5f6964733401205665633c7533323e000e0024416464546f6b656e73040118746f6b656e733801685665633c287533322c20496e6e6572546f6b656e4d657461293e000f00001c08186e66745f696f38496e6e6572546f6b656e4d6574610000140120746f6b656e5f696414010c7533320001146d6564696114010c7533320001146f776e657208011c4163746f7249640001286163746976697469657320015c5665633c28537472696e672c207531362c20753634293e0001106c696e6b3001384f7074696f6e3c537472696e673e0000200000022400240000040c04282c002800000504002c00000506003004184f7074696f6e04045401040108104e6f6e6500000010536f6d650400040000010000340000021400380000023c003c00000408141c004008186e66745f696f204e46545265706c79000124184d696e746564080120746f6b656e5f696414010c7533320001106d6574611c0138496e6e6572546f6b656e4d657461000000144f776e65720801146f776e657208011c4163746f724964000120746f6b656e5f696414010c75333200010038546f6b656e73466f724f776e6572040118746f6b656e733401205665633c7533323e000200284e66744368616e6765640401106d6574611c0138496e6e6572546f6b656e4d65746100030020417070726f766564000400144275726e740401106d6574611c0138496e6e6572546f6b656e4d6574610005002c5472616e7366657272656400060034546f6b656e41636365707465640401106d6574611c0138496e6e6572546f6b656e4d6574610007003c417070726f76616c5265766f6b6564000800004408186e66745f696f285374617465517565727900013424546f6b656e496e666f040014010c75333200000024416c6c546f6b656e7300010040416c6c546f6b656e735261774461746100020034546f6b656e73496e52616e676508011066726f6d14010c753332000108746f14010c753332000300504e756d6265724f664d696e746564546f6b656e73000400304f776e65724f66546f6b656e040014010c7533320005003849706673466f6c6465724c696e6b0006001841646d696e730007003c417070726f76616c4f66546f6b656e040014010c75333200080030416c6c417070726f76616c7300090038546f6b656e73466f724f776e6572040008011c4163746f724964000a003c4d61784e756d6265724f664e667473000b004053746172744e756d6265724f664e6674000c00004808186e66745f696f2853746174655265706c7900013424546f6b656e496e666f04004c012c4f7074696f6e3c4e66743e00000024416c6c546f6b656e73040058014c5665633c284163746f7249642c204e6674293e00010040416c6c546f6b656e7352617744617461040060014c5665633c496e6e6572546f6b656e4d6574613e00020034546f6b656e73496e52616e6765040058014c5665633c284163746f7249642c204e6674293e000300504e756d6265724f664d696e746564546f6b656e7304002c010c753634000400304f776e65724f66546f6b656e040008011c4163746f7249640005003849706673466f6c6465724c696e6b0400040118537472696e670006001841646d696e7304006401305665633c4163746f7249643e0007003c417070726f76616c4f66546f6b656e040068013c4f7074696f6e3c4163746f7249643e00080030416c6c417070726f76616c7304006c014c5665633c287533322c204163746f724964293e00090038546f6b656e73466f724f776e657204003401205665633c7533323e000a003c4d61784e756d6265724f664e667473040014010c753332000b004053746172744e756d6265724f664e6674040014010c753332000c00004c04184f7074696f6e04045401500108104e6f6e6500000010536f6d6504005000000100005008186e66745f696f0c4e667400001401146f776e657208011c4163746f7249640001106e616d65040118537472696e6700012c6465736372697074696f6e040118537472696e670001246d656469615f75726c040118537472696e670001286174747269625f75726c54012c5665633c537472696e673e0000540000020400580000025c005c00000408085000600000021c006400000208006804184f7074696f6e04045401080108104e6f6e6500000010536f6d6504000800000100006c00000270007000000408140800 \ No newline at end of file diff --git a/src/handlers/migrated-nft.ts b/src/handlers/migrated-nft.ts index 13c447c..c236a98 100644 --- a/src/handlers/migrated-nft.ts +++ b/src/handlers/migrated-nft.ts @@ -43,9 +43,9 @@ export async function readMigratedNfts(state: BatchState) { const mediaLink = link.asIpfsFolderLink; if (data.isAllTokensRawData) { - for (const { media, owner, activities } of data.asAllTokensRawData) { + for (const { media, owner, activities, tokenId } of data.asAllTokensRawData) { await state.mintNft( - media.toString(), + tokenId.toString(), collection, owner.toHex(), activities.map(([name, times, ts]) => { @@ -55,7 +55,7 @@ export async function readMigratedNfts(state: BatchState) { return `${name}${timesFormatted}${dateFormatted}`; }), description, - name + ' - ' + media.toString(), + name + ' - ' + tokenId.toString(), `${mediaLink}/${media.toString()}.png`, blockNumber, timestamp, diff --git a/src/types/cb-nft.ts b/src/types/cb-nft.ts index af0c0a0..80bff7a 100644 --- a/src/types/cb-nft.ts +++ b/src/types/cb-nft.ts @@ -3,6 +3,7 @@ import { Hash } from '@polkadot/types/interfaces'; import { ITuple } from '@polkadot/types/types'; export interface InnerTokenMeta extends Struct { + tokenId: u32; media: u32; owner: Hash; activities: Vec>; From f9dba2fcb5125515e2461babb24107a019ca1793 Mon Sep 17 00:00:00 2001 From: Dmitry Osipov Date: Wed, 27 Dec 2023 19:39:39 +0300 Subject: [PATCH 3/3] update cb meta --- assets/cb-nft.meta.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/cb-nft.meta.txt b/assets/cb-nft.meta.txt index e8c215f..6a22fec 100644 --- a/assets/cb-nft.meta.txt +++ b/assets/cb-nft.meta.txt @@ -1 +1 @@ -000200010000000000010900000001140000000000011500000000011600000001170000006933700008346d61737465725f6e66745f696f34496e69744d61737465724e465400001401106e616d65040118537472696e6700012c6465736372697074696f6e040118537472696e6700014c6e756d6265725f6f665f636f6e74726163747308010c75313600012c6e66745f636f64655f69640c011048323536000118636f6e666967180118436f6e66696700000400000502000800000504000c083c7072696d69746976655f74797065731048323536000004001001205b75383b2033325d0000100000032000000014001400000503001808346d61737465725f6e66745f696f18436f6e66696700003401406e66745f6372656174696f6e5f6761731c010c7536340001306e66745f6d696e745f6761731c010c75363400013c6e66745f617070726f76655f6761731c010c7536340001406e66745f7472616e736665725f6761731c010c7536340001406e66745f6163636570745f746f6b656e1c010c7536340001306e66745f6275726e5f6761731c010c7536340001346164645f6d656469615f6761731c010c7536340001446164645f6174747269627574655f6761731c010c7536340001447265706c795f6465706f7369745f6761731c010c753634000150746f6b656e735f666f725f6f776e65725f6761731c010c75363400014461637469766974795f696e666f5f6761731c010c753634000178616d6f756e745f6f665f636f6e74726163745f7065725f6f6e655f6d736708010c7531360001786d61785f6e756d6265725f6f665f626c6f636b735f666f725f7265706c7920010c75333200001c00000506002000000505002408346d61737465725f6e66745f696f3c4d61737465724e4654416374696f6e00014034416c6c6f775472616e736665720400280110626f6f6c00000034416c6c6f774d6573736167657304002c013c4d61737465724e465453746174757300010024416c6c6f774d696e740400280110626f6f6c000200104d696e74000300104275726e0801146f776e657230011c4163746f724964000120746f6b656e5f696420010c7533320004001c417070726f7665080140617070726f7665645f6163636f756e7430011c4163746f724964000120746f6b656e5f696420010c753332000500385265766f6b65417070726f76616c040120746f6b656e5f696420010c753332000600205472616e736665720c01146f776e657230011c4163746f724964000124726563697069656e7430011c4163746f724964000120746f6b656e5f696420010c75333200070038546f6b656e73466f724f776e65720401206f776e65725f696430011c4163746f7249640008002041646441646d696e04012061646d696e5f696430011c4163746f7249640009002c44656c65746541646d696e04012061646d696e5f696430011c4163746f724964000a004c4164645665726966696564436f6e747261637408012c636f6e74726163745f696430011c4163746f724964000124617474726962757465040118537472696e67000b00304164644174747269627574650801146f776e657230011c4163746f724964000120746f6b656e5f696420010c753332000c00244372656174654e66740c0140697066735f666f6c6465725f6c696e6b040118537472696e6700015473746172745f6e756d626572735f6f665f6e6674733401205665633c7533323e000168616d6f756e745f6f665f6e6674735f7065725f73746f7261676520010c753332000d0030557064617465436f6e6669673001406e66745f6372656174696f6e5f67617338012c4f7074696f6e3c7536343e00013c6e66745f617070726f76655f67617338012c4f7074696f6e3c7536343e0001406e66745f7472616e736665725f67617338012c4f7074696f6e3c7536343e0001406e66745f6163636570745f746f6b656e38012c4f7074696f6e3c7536343e0001306e66745f6275726e5f67617338012c4f7074696f6e3c7536343e0001306e66745f6d696e745f67617338012c4f7074696f6e3c7536343e0001346164645f6d656469615f67617338012c4f7074696f6e3c7536343e0001446164645f6174747269627574655f67617338012c4f7074696f6e3c7536343e0001447265706c795f6465706f7369745f67617338012c4f7074696f6e3c7536343e000150746f6b656e735f666f725f6f776e65725f67617338012c4f7074696f6e3c7536343e00014461637469766974795f696e666f5f67617338012c4f7074696f6e3c7536343e0001786d61785f6e756d6265725f6f665f626c6f636b735f666f725f7265706c793c012c4f7074696f6e3c7533323e000e00184d696e74546f0c0120746f6b656e5f696420010c753332000124726563697069656e7430011c4163746f7249640001106d657461400138496e6e6572546f6b656e4d657461000f00002800000500002c08346d61737465725f6e66745f696f3c4d61737465724e465453746174757300010c18416374697665000000304372656174696e674e465473000100184c6f636b6564000200003010106773746418636f6d6d6f6e287072696d6974697665731c4163746f724964000004001001205b75383b2033325d00003400000220003804184f7074696f6e040454011c0108104e6f6e6500000010536f6d6504001c00000100003c04184f7074696f6e04045401200108104e6f6e6500000010536f6d6504002000000100004008186e66745f696f38496e6e6572546f6b656e4d65746100001001146d6564696120010c7533320001146f776e657230011c4163746f7249640001286163746976697469657344015c5665633c28537472696e672c207531362c20753634293e0001106c696e6b4c01384f7074696f6e3c537472696e673e0000440000024800480000040c04081c004c04184f7074696f6e04045401040108104e6f6e6500000010536f6d6504000400000100005008346d61737465725f6e66745f696f384d61737465724e46545265706c7900010438546f6b656e73466f724f776e6572040118746f6b656e733401205665633c7533323e000000005408346d61737465725f6e66745f696f384d61737465724e46544576656e7400011c184d696e746564080120746f6b656e5f696420010c7533320001106d657461400138496e6e6572546f6b656e4d657461000000284e66744368616e676564080120746f6b656e5f696420010c7533320001106d657461400138496e6e6572546f6b656e4d65746100010020417070726f766564080140617070726f7665645f6163636f756e7430011c4163746f724964000120746f6b656e5f696420010c7533320002003c417070726f76616c5265766f6b6564040120746f6b656e5f696420010c7533320003002c5472616e736665727265640c01146f776e657230011c4163746f724964000124726563697069656e7430011c4163746f724964000120746f6b656e5f696420010c753332000400144275726e74040120746f6b656e5f696420010c753332000500304163746976697479496e666f08011c6163636f756e7430011c4163746f7249640001206163746976697479040118537472696e67000600005808346d61737465725f6e66745f696f28537461746551756572790001301841646d696e730000002853746f726167654964730001005447657453746f7261676549644279416464726573730401286163636f756e745f696430011c4163746f724964000200445665726966696564436f6e74726163747300030018537461747573000400444e756d6265724f66436f6e747261637473000500244e6674436f64654964000600104e616d650007002c4465736372697074696f6e00080018436f6e666967000900405472616e7366657273416c6c6f776564000a00384d696e74696e67416c6c6f776564000b00005c08346d61737465725f6e66745f696f2853746174655265706c790001301841646d696e7304006001305665633c4163746f7249643e0000002853746f7261676549647304006001305665633c4163746f7249643e0001004853746f726167654964427941646472657373040030011c4163746f724964000200445665726966696564436f6e74726163747304006401585665633c284163746f7249642c20537472696e67293e0003001853746174757304002c013c4d61737465724e4654537461747573000400444e756d6265724f66436f6e747261637473040008010c753136000500244e6674436f6465496404006c0118436f64654964000600104e616d650400040118537472696e670007002c4465736372697074696f6e0400040118537472696e6700080018436f6e6669670400180118436f6e666967000900405472616e7366657273416c6c6f7765640400280110626f6f6c000a00384d696e74696e67416c6c6f7765640400280110626f6f6c000b000060000002300064000002680068000004083004006c10106773746418636f6d6d6f6e287072696d69746976657318436f64654964000004001001205b75383b2033325d0000 \ No newline at end of file +00020001000000000001090000000114000000000001150000000001160000000117000000a134700008346d61737465725f6e66745f696f34496e69744d61737465724e465400001401106e616d65040118537472696e6700012c6465736372697074696f6e040118537472696e6700014c6e756d6265725f6f665f636f6e74726163747308010c75313600012c6e66745f636f64655f69640c011048323536000118636f6e666967180118436f6e66696700000400000502000800000504000c083c7072696d69746976655f74797065731048323536000004001001205b75383b2033325d0000100000032000000014001400000503001808346d61737465725f6e66745f696f18436f6e66696700003401406e66745f6372656174696f6e5f6761731c010c7536340001306e66745f6d696e745f6761731c010c75363400013c6e66745f617070726f76655f6761731c010c7536340001406e66745f7472616e736665725f6761731c010c7536340001406e66745f6163636570745f746f6b656e1c010c7536340001306e66745f6275726e5f6761731c010c7536340001346164645f6d656469615f6761731c010c7536340001446164645f6174747269627574655f6761731c010c7536340001447265706c795f6465706f7369745f6761731c010c753634000150746f6b656e735f666f725f6f776e65725f6761731c010c75363400014461637469766974795f696e666f5f6761731c010c753634000178616d6f756e745f6f665f636f6e74726163745f7065725f6f6e655f6d736708010c7531360001786d61785f6e756d6265725f6f665f626c6f636b735f666f725f7265706c7920010c75333200001c00000506002000000505002408346d61737465725f6e66745f696f3c4d61737465724e4654416374696f6e00014034416c6c6f775472616e736665720400280110626f6f6c00000034416c6c6f774d6573736167657304002c013c4d61737465724e465453746174757300010024416c6c6f774d696e740400280110626f6f6c000200104d696e74000300104275726e0801146f776e657230011c4163746f724964000120746f6b656e5f696420010c7533320004001c417070726f7665080140617070726f7665645f6163636f756e7430011c4163746f724964000120746f6b656e5f696420010c753332000500385265766f6b65417070726f76616c040120746f6b656e5f696420010c753332000600205472616e736665720c01146f776e657230011c4163746f724964000124726563697069656e7430011c4163746f724964000120746f6b656e5f696420010c75333200070038546f6b656e73466f724f776e65720401206f776e65725f696430011c4163746f7249640008002041646441646d696e04012061646d696e5f696430011c4163746f7249640009002c44656c65746541646d696e04012061646d696e5f696430011c4163746f724964000a004c4164645665726966696564436f6e747261637408012c636f6e74726163745f696430011c4163746f724964000124617474726962757465040118537472696e67000b00304164644174747269627574650801146f776e657230011c4163746f724964000120746f6b656e5f696420010c753332000c00244372656174654e6674140140697066735f666f6c6465725f6c696e6b040118537472696e6700015473746172745f6e756d626572735f6f665f6e6674733401205665633c7533323e0001646e65775f73746172745f6e756d626572735f6f665f6e6674733401205665633c7533323e000168616d6f756e745f6f665f6e6674735f7065725f73746f7261676520010c7533320001346d656469615f6d6f64756c757320010c753332000d0030557064617465436f6e6669673001406e66745f6372656174696f6e5f67617338012c4f7074696f6e3c7536343e00013c6e66745f617070726f76655f67617338012c4f7074696f6e3c7536343e0001406e66745f7472616e736665725f67617338012c4f7074696f6e3c7536343e0001406e66745f6163636570745f746f6b656e38012c4f7074696f6e3c7536343e0001306e66745f6275726e5f67617338012c4f7074696f6e3c7536343e0001306e66745f6d696e745f67617338012c4f7074696f6e3c7536343e0001346164645f6d656469615f67617338012c4f7074696f6e3c7536343e0001446164645f6174747269627574655f67617338012c4f7074696f6e3c7536343e0001447265706c795f6465706f7369745f67617338012c4f7074696f6e3c7536343e000150746f6b656e735f666f725f6f776e65725f67617338012c4f7074696f6e3c7536343e00014461637469766974795f696e666f5f67617338012c4f7074696f6e3c7536343e0001786d61785f6e756d6265725f6f665f626c6f636b735f666f725f7265706c793c012c4f7074696f6e3c7533323e000e00184d696e74546f0c0120746f6b656e5f696420010c753332000124726563697069656e7430011c4163746f7249640001106d657461400138496e6e6572546f6b656e4d657461000f00002800000500002c08346d61737465725f6e66745f696f3c4d61737465724e465453746174757300010c18416374697665000000304372656174696e674e465473000100184c6f636b6564000200003010106773746418636f6d6d6f6e287072696d6974697665731c4163746f724964000004001001205b75383b2033325d00003400000220003804184f7074696f6e040454011c0108104e6f6e6500000010536f6d6504001c00000100003c04184f7074696f6e04045401200108104e6f6e6500000010536f6d6504002000000100004008186e66745f696f38496e6e6572546f6b656e4d6574610000140120746f6b656e5f696420010c7533320001146d6564696120010c7533320001146f776e657230011c4163746f7249640001286163746976697469657344015c5665633c28537472696e672c207531362c20753634293e0001106c696e6b4c01384f7074696f6e3c537472696e673e0000440000024800480000040c04081c004c04184f7074696f6e04045401040108104e6f6e6500000010536f6d6504000400000100005008346d61737465725f6e66745f696f384d61737465724e46545265706c7900010438546f6b656e73466f724f776e6572040118746f6b656e733401205665633c7533323e000000005408346d61737465725f6e66745f696f384d61737465724e46544576656e7400011c184d696e746564080120746f6b656e5f696420010c7533320001106d657461400138496e6e6572546f6b656e4d657461000000284e66744368616e676564080120746f6b656e5f696420010c7533320001106d657461400138496e6e6572546f6b656e4d65746100010020417070726f766564080140617070726f7665645f6163636f756e7430011c4163746f724964000120746f6b656e5f696420010c7533320002003c417070726f76616c5265766f6b6564040120746f6b656e5f696420010c7533320003002c5472616e736665727265640c01146f776e657230011c4163746f724964000124726563697069656e7430011c4163746f724964000120746f6b656e5f696420010c753332000400144275726e74040120746f6b656e5f696420010c753332000500304163746976697479496e666f08011c6163636f756e7430011c4163746f7249640001206163746976697479040118537472696e67000600005808346d61737465725f6e66745f696f28537461746551756572790001301841646d696e730000002853746f726167654964730001005447657453746f7261676549644279416464726573730401286163636f756e745f696430011c4163746f724964000200445665726966696564436f6e74726163747300030018537461747573000400444e756d6265724f66436f6e747261637473000500244e6674436f64654964000600104e616d650007002c4465736372697074696f6e00080018436f6e666967000900405472616e7366657273416c6c6f776564000a00384d696e74696e67416c6c6f776564000b00005c08346d61737465725f6e66745f696f2853746174655265706c790001301841646d696e7304006001305665633c4163746f7249643e0000002853746f7261676549647304006001305665633c4163746f7249643e0001004853746f726167654964427941646472657373040030011c4163746f724964000200445665726966696564436f6e74726163747304006401585665633c284163746f7249642c20537472696e67293e0003001853746174757304002c013c4d61737465724e4654537461747573000400444e756d6265724f66436f6e747261637473040008010c753136000500244e6674436f6465496404006c0118436f64654964000600104e616d650400040118537472696e670007002c4465736372697074696f6e0400040118537472696e6700080018436f6e6669670400180118436f6e666967000900405472616e7366657273416c6c6f7765640400280110626f6f6c000a00384d696e74696e67416c6c6f7765640400280110626f6f6c000b000060000002300064000002680068000004083004006c10106773746418636f6d6d6f6e287072696d69746976657318436f64654964000004001001205b75383b2033325d0000 \ No newline at end of file