@libp2p/interface-compliance-tests 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +25 -0
  3. package/dist/src/connection/connection.d.ts +5 -0
  4. package/dist/src/connection/connection.d.ts.map +1 -0
  5. package/dist/src/connection/connection.js +148 -0
  6. package/dist/src/connection/connection.js.map +1 -0
  7. package/dist/src/connection/index.d.ts +5 -0
  8. package/dist/src/connection/index.d.ts.map +1 -0
  9. package/dist/src/connection/index.js +5 -0
  10. package/dist/src/connection/index.js.map +1 -0
  11. package/dist/src/crypto/index.d.ts +5 -0
  12. package/dist/src/crypto/index.d.ts.map +1 -0
  13. package/dist/src/crypto/index.js +78 -0
  14. package/dist/src/crypto/index.js.map +1 -0
  15. package/dist/src/index.d.ts +5 -0
  16. package/dist/src/index.d.ts.map +1 -0
  17. package/dist/src/index.js +2 -0
  18. package/dist/src/index.js.map +1 -0
  19. package/dist/src/peer-discovery/index.d.ts +6 -0
  20. package/dist/src/peer-discovery/index.d.ts.map +1 -0
  21. package/dist/src/peer-discovery/index.js +63 -0
  22. package/dist/src/peer-discovery/index.js.map +1 -0
  23. package/dist/src/pubsub/api.d.ts +6 -0
  24. package/dist/src/pubsub/api.d.ts.map +1 -0
  25. package/dist/src/pubsub/api.js +65 -0
  26. package/dist/src/pubsub/api.js.map +1 -0
  27. package/dist/src/pubsub/connection-handlers.d.ts +6 -0
  28. package/dist/src/pubsub/connection-handlers.d.ts.map +1 -0
  29. package/dist/src/pubsub/connection-handlers.js +279 -0
  30. package/dist/src/pubsub/connection-handlers.js.map +1 -0
  31. package/dist/src/pubsub/emit-self.d.ts +6 -0
  32. package/dist/src/pubsub/emit-self.d.ts.map +1 -0
  33. package/dist/src/pubsub/emit-self.js +51 -0
  34. package/dist/src/pubsub/emit-self.js.map +1 -0
  35. package/dist/src/pubsub/index.d.ts +6 -0
  36. package/dist/src/pubsub/index.d.ts.map +1 -0
  37. package/dist/src/pubsub/index.js +17 -0
  38. package/dist/src/pubsub/index.js.map +1 -0
  39. package/dist/src/pubsub/messages.d.ts +6 -0
  40. package/dist/src/pubsub/messages.d.ts.map +1 -0
  41. package/dist/src/pubsub/messages.js +93 -0
  42. package/dist/src/pubsub/messages.js.map +1 -0
  43. package/dist/src/pubsub/multiple-nodes.d.ts +6 -0
  44. package/dist/src/pubsub/multiple-nodes.d.ts.map +1 -0
  45. package/dist/src/pubsub/multiple-nodes.js +283 -0
  46. package/dist/src/pubsub/multiple-nodes.js.map +1 -0
  47. package/dist/src/pubsub/two-nodes.d.ts +6 -0
  48. package/dist/src/pubsub/two-nodes.d.ts.map +1 -0
  49. package/dist/src/pubsub/two-nodes.js +127 -0
  50. package/dist/src/pubsub/two-nodes.js.map +1 -0
  51. package/dist/src/pubsub/utils.d.ts +3 -0
  52. package/dist/src/pubsub/utils.d.ts.map +1 -0
  53. package/dist/src/pubsub/utils.js +11 -0
  54. package/dist/src/pubsub/utils.js.map +1 -0
  55. package/dist/src/record/index.d.ts +5 -0
  56. package/dist/src/record/index.d.ts.map +1 -0
  57. package/dist/src/record/index.js +25 -0
  58. package/dist/src/record/index.js.map +1 -0
  59. package/dist/src/stream-muxer/base-test.d.ts +5 -0
  60. package/dist/src/stream-muxer/base-test.d.ts.map +1 -0
  61. package/dist/src/stream-muxer/base-test.js +123 -0
  62. package/dist/src/stream-muxer/base-test.js.map +1 -0
  63. package/dist/src/stream-muxer/close-test.d.ts +5 -0
  64. package/dist/src/stream-muxer/close-test.d.ts.map +1 -0
  65. package/dist/src/stream-muxer/close-test.js +103 -0
  66. package/dist/src/stream-muxer/close-test.js.map +1 -0
  67. package/dist/src/stream-muxer/index.d.ts +5 -0
  68. package/dist/src/stream-muxer/index.d.ts.map +1 -0
  69. package/dist/src/stream-muxer/index.js +13 -0
  70. package/dist/src/stream-muxer/index.js.map +1 -0
  71. package/dist/src/stream-muxer/mega-stress-test.d.ts +5 -0
  72. package/dist/src/stream-muxer/mega-stress-test.d.ts.map +1 -0
  73. package/dist/src/stream-muxer/mega-stress-test.js +8 -0
  74. package/dist/src/stream-muxer/mega-stress-test.js.map +1 -0
  75. package/dist/src/stream-muxer/spawner.d.ts +4 -0
  76. package/dist/src/stream-muxer/spawner.d.ts.map +1 -0
  77. package/dist/src/stream-muxer/spawner.js +32 -0
  78. package/dist/src/stream-muxer/spawner.js.map +1 -0
  79. package/dist/src/stream-muxer/stress-test.d.ts +5 -0
  80. package/dist/src/stream-muxer/stress-test.d.ts.map +1 -0
  81. package/dist/src/stream-muxer/stress-test.js +21 -0
  82. package/dist/src/stream-muxer/stress-test.js.map +1 -0
  83. package/dist/src/topology/multicodec-topology.d.ts +5 -0
  84. package/dist/src/topology/multicodec-topology.d.ts.map +1 -0
  85. package/dist/src/topology/multicodec-topology.js +109 -0
  86. package/dist/src/topology/multicodec-topology.js.map +1 -0
  87. package/dist/src/topology/topology.d.ts +5 -0
  88. package/dist/src/topology/topology.d.ts.map +1 -0
  89. package/dist/src/topology/topology.js +29 -0
  90. package/dist/src/topology/topology.js.map +1 -0
  91. package/dist/src/transport/dial-test.d.ts +5 -0
  92. package/dist/src/transport/dial-test.d.ts.map +1 -0
  93. package/dist/src/transport/dial-test.js +78 -0
  94. package/dist/src/transport/dial-test.js.map +1 -0
  95. package/dist/src/transport/filter-test.d.ts +5 -0
  96. package/dist/src/transport/filter-test.d.ts.map +1 -0
  97. package/dist/src/transport/filter-test.js +19 -0
  98. package/dist/src/transport/filter-test.js.map +1 -0
  99. package/dist/src/transport/index.d.ts +18 -0
  100. package/dist/src/transport/index.d.ts.map +1 -0
  101. package/dist/src/transport/index.js +11 -0
  102. package/dist/src/transport/index.js.map +1 -0
  103. package/dist/src/transport/listen-test.d.ts +5 -0
  104. package/dist/src/transport/listen-test.d.ts.map +1 -0
  105. package/dist/src/transport/listen-test.js +116 -0
  106. package/dist/src/transport/listen-test.js.map +1 -0
  107. package/dist/src/transport/utils/index.d.ts +8 -0
  108. package/dist/src/transport/utils/index.d.ts.map +1 -0
  109. package/dist/src/transport/utils/index.js +104 -0
  110. package/dist/src/transport/utils/index.js.map +1 -0
  111. package/dist/src/utils/peers.d.ts +7 -0
  112. package/dist/src/utils/peers.d.ts.map +1 -0
  113. package/dist/src/utils/peers.js +26 -0
  114. package/dist/src/utils/peers.js.map +1 -0
  115. package/dist/test/connection/index.spec.d.ts +2 -0
  116. package/dist/test/connection/index.spec.d.ts.map +1 -0
  117. package/dist/test/connection/index.spec.js +71 -0
  118. package/dist/test/connection/index.spec.js.map +1 -0
  119. package/dist/test/crypto/index.spec.d.ts +2 -0
  120. package/dist/test/crypto/index.spec.d.ts.map +1 -0
  121. package/dist/test/crypto/index.spec.js +11 -0
  122. package/dist/test/crypto/index.spec.js.map +1 -0
  123. package/dist/test/crypto/mock-crypto.d.ts +4 -0
  124. package/dist/test/crypto/mock-crypto.d.ts.map +1 -0
  125. package/dist/test/crypto/mock-crypto.js +93 -0
  126. package/dist/test/crypto/mock-crypto.js.map +1 -0
  127. package/dist/test/peer-discovery/index.spec.d.ts +2 -0
  128. package/dist/test/peer-discovery/index.spec.d.ts.map +1 -0
  129. package/dist/test/peer-discovery/index.spec.js +18 -0
  130. package/dist/test/peer-discovery/index.spec.js.map +1 -0
  131. package/dist/test/peer-discovery/mock-discovery.d.ts +20 -0
  132. package/dist/test/peer-discovery/mock-discovery.d.ts.map +1 -0
  133. package/dist/test/peer-discovery/mock-discovery.js +39 -0
  134. package/dist/test/peer-discovery/mock-discovery.js.map +1 -0
  135. package/dist/test/topology/mock-peer-store.d.ts +12 -0
  136. package/dist/test/topology/mock-peer-store.d.ts.map +1 -0
  137. package/dist/test/topology/mock-peer-store.js +18 -0
  138. package/dist/test/topology/mock-peer-store.js.map +1 -0
  139. package/dist/test/topology/multicodec-topology.spec.d.ts +2 -0
  140. package/dist/test/topology/multicodec-topology.spec.d.ts.map +1 -0
  141. package/dist/test/topology/multicodec-topology.spec.js +45 -0
  142. package/dist/test/topology/multicodec-topology.spec.js.map +1 -0
  143. package/dist/test/topology/topology.spec.d.ts +2 -0
  144. package/dist/test/topology/topology.spec.d.ts.map +1 -0
  145. package/dist/test/topology/topology.spec.js +21 -0
  146. package/dist/test/topology/topology.spec.js.map +1 -0
  147. package/dist/tsconfig.tsbuildinfo +1 -0
  148. package/package.json +120 -4
  149. package/src/connection/README.md +256 -0
  150. package/src/connection/connection.ts +178 -0
  151. package/src/connection/index.ts +7 -0
  152. package/src/crypto/index.ts +104 -0
  153. package/src/index.ts +5 -0
  154. package/src/peer-discovery/index.ts +87 -0
  155. package/src/pubsub/api.ts +89 -0
  156. package/src/pubsub/connection-handlers.ts +356 -0
  157. package/src/pubsub/emit-self.ts +67 -0
  158. package/src/pubsub/index.ts +20 -0
  159. package/src/pubsub/messages.ts +111 -0
  160. package/src/pubsub/multiple-nodes.ts +353 -0
  161. package/src/pubsub/two-nodes.ts +175 -0
  162. package/src/pubsub/utils.ts +13 -0
  163. package/src/record/index.ts +32 -0
  164. package/src/stream-muxer/base-test.ts +154 -0
  165. package/src/stream-muxer/close-test.ts +124 -0
  166. package/src/stream-muxer/index.ts +15 -0
  167. package/src/stream-muxer/mega-stress-test.ts +11 -0
  168. package/src/stream-muxer/spawner.ts +52 -0
  169. package/src/stream-muxer/stress-test.ts +24 -0
  170. package/src/topology/multicodec-topology.ts +136 -0
  171. package/src/topology/topology.ts +38 -0
  172. package/src/transport/dial-test.ts +98 -0
  173. package/src/transport/filter-test.ts +26 -0
  174. package/src/transport/index.ts +29 -0
  175. package/src/transport/listen-test.ts +152 -0
  176. package/src/transport/utils/index.ts +123 -0
  177. package/src/utils/peers.ts +25 -0
@@ -0,0 +1,29 @@
1
+ import dial from './dial-test.js'
2
+ import listen from './listen-test.js'
3
+ import filter from './filter-test.js'
4
+ import type { TestSetup } from '../index.js'
5
+ import type { Transport, Upgrader } from '@libp2p/interfaces/transport'
6
+ import type { Multiaddr } from '@multiformats/multiaddr'
7
+
8
+ export interface Connector {
9
+ delay: (ms: number) => void
10
+ restore: () => void
11
+ }
12
+
13
+ export interface TransportTestFixtures {
14
+ addrs: Multiaddr[]
15
+ transport: Transport<{}, {}>
16
+ connector: Connector
17
+ }
18
+
19
+ export interface SetupArgs {
20
+ upgrader: Upgrader
21
+ }
22
+
23
+ export default (common: TestSetup<TransportTestFixtures, SetupArgs>) => {
24
+ describe('interface-transport', () => {
25
+ dial(common)
26
+ listen(common)
27
+ filter(common)
28
+ })
29
+ }
@@ -0,0 +1,152 @@
1
+ /* eslint max-nested-callbacks: ["error", 8] */
2
+ import { expect } from 'aegir/utils/chai.js'
3
+ import sinon from 'sinon'
4
+ import pWaitFor from 'p-wait-for'
5
+ import { pipe } from 'it-pipe'
6
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
7
+ import { isValidTick, mockUpgrader } from './utils/index.js'
8
+ import defer from 'p-defer'
9
+ import type { TestSetup } from '../index.js'
10
+ import type { Transport } from '@libp2p/interfaces/transport'
11
+ import type { TransportTestFixtures, SetupArgs } from './index.js'
12
+ import type { Multiaddr } from '@multiformats/multiaddr'
13
+ import type { Connection } from '@libp2p/interfaces/connection'
14
+
15
+ export default (common: TestSetup<TransportTestFixtures, SetupArgs>) => {
16
+ describe('listen', () => {
17
+ const upgrader = mockUpgrader()
18
+ let addrs: Multiaddr[]
19
+ let transport: Transport<any, any>
20
+
21
+ before(async () => {
22
+ ({ transport, addrs } = await common.setup({ upgrader }))
23
+ })
24
+
25
+ after(async () => {
26
+ await common.teardown()
27
+ })
28
+
29
+ afterEach(() => {
30
+ sinon.restore()
31
+ })
32
+
33
+ it('simple', async () => {
34
+ const listener = transport.createListener({}, (conn) => {})
35
+ await listener.listen(addrs[0])
36
+ await listener.close()
37
+ })
38
+
39
+ it('close listener with connections, through timeout', async () => {
40
+ const upgradeSpy = sinon.spy(upgrader, 'upgradeInbound')
41
+ const listenerConns: Connection[] = []
42
+
43
+ const listener = transport.createListener({}, (conn) => {
44
+ listenerConns.push(conn)
45
+ })
46
+
47
+ // Listen
48
+ await listener.listen(addrs[0])
49
+
50
+ // Create two connections to the listener
51
+ const [conn1] = await Promise.all([
52
+ transport.dial(addrs[0]),
53
+ transport.dial(addrs[0])
54
+ ])
55
+
56
+ // Give the listener a chance to finish its upgrade
57
+ await pWaitFor(() => listenerConns.length === 2)
58
+
59
+ const { stream: stream1 } = await conn1.newStream(['/test/protocol'])
60
+
61
+ // Wait for the data send and close to finish
62
+ await Promise.all([
63
+ pipe(
64
+ [uint8ArrayFromString('Some data that is never handled')],
65
+ stream1
66
+ ),
67
+ // Closer the listener (will take a couple of seconds to time out)
68
+ listener.close()
69
+ ])
70
+
71
+ await stream1.close()
72
+ await conn1.close()
73
+
74
+ expect(isValidTick(conn1.stat.timeline.close)).to.equal(true)
75
+ listenerConns.forEach(conn => {
76
+ expect(isValidTick(conn.stat.timeline.close)).to.equal(true)
77
+ })
78
+
79
+ // 2 dials = 2 connections upgraded
80
+ expect(upgradeSpy.callCount).to.equal(2)
81
+ })
82
+
83
+ it('should not handle connection if upgradeInbound throws', async () => {
84
+ sinon.stub(upgrader, 'upgradeInbound').throws()
85
+
86
+ const listener = transport.createListener(() => {
87
+ throw new Error('should not handle the connection if upgradeInbound throws')
88
+ })
89
+
90
+ // Listen
91
+ await listener.listen(addrs[0])
92
+
93
+ // Create a connection to the listener
94
+ const conn = await transport.dial(addrs[0])
95
+
96
+ await pWaitFor(() => typeof conn.stat.timeline.close === 'number')
97
+ await listener.close()
98
+ })
99
+
100
+ describe('events', () => {
101
+ it('connection', async () => {
102
+ const upgradeSpy = sinon.spy(upgrader, 'upgradeInbound')
103
+ const listener = transport.createListener({})
104
+ const deferred = defer()
105
+ let conn
106
+
107
+ listener.on('connection', (c) => {
108
+ conn = c
109
+ deferred.resolve()
110
+ })
111
+
112
+ void (async () => {
113
+ await listener.listen(addrs[0])
114
+ await transport.dial(addrs[0])
115
+ })()
116
+
117
+ await deferred.promise
118
+
119
+ await expect(upgradeSpy.getCall(0).returnValue).to.eventually.equal(conn)
120
+ expect(upgradeSpy.callCount).to.equal(1)
121
+ await listener.close()
122
+ })
123
+
124
+ it('listening', (done) => {
125
+ const listener = transport.createListener({})
126
+ listener.on('listening', () => {
127
+ listener.close().then(done, done)
128
+ })
129
+ void listener.listen(addrs[0])
130
+ })
131
+
132
+ it('error', (done) => {
133
+ const listener = transport.createListener({})
134
+ listener.on('error', (err) => {
135
+ expect(err).to.exist()
136
+ listener.close().then(done, done)
137
+ })
138
+ listener.emit('error', new Error('my err'))
139
+ })
140
+
141
+ it('close', (done) => {
142
+ const listener = transport.createListener({})
143
+ listener.on('close', done)
144
+
145
+ void (async () => {
146
+ await listener.listen(addrs[0])
147
+ await listener.close()
148
+ })()
149
+ })
150
+ })
151
+ })
152
+ }
@@ -0,0 +1,123 @@
1
+ import { expect } from 'aegir/utils/chai.js'
2
+ import type { Upgrader, MultiaddrConnection } from '@libp2p/interfaces/transport'
3
+ import type { Connection, StreamData } from '@libp2p/interfaces/connection'
4
+ import type { MuxedStream } from '@libp2p/interfaces/stream-muxer'
5
+ // @ts-expect-error no types
6
+ import pair from 'it-pair'
7
+ import { PeerId } from '@libp2p/peer-id'
8
+ import * as PeerIdFactory from '@libp2p/peer-id-factory'
9
+ /**
10
+ * A tick is considered valid if it happened between now
11
+ * and `ms` milliseconds ago
12
+ */
13
+ export function isValidTick (date?: number, ms: number = 5000) {
14
+ if (date == null) {
15
+ throw new Error('date must be a number')
16
+ }
17
+
18
+ const now = Date.now()
19
+
20
+ if (date > now - ms && date <= now) {
21
+ return true
22
+ }
23
+
24
+ return false
25
+ }
26
+
27
+ export function mockUpgrader () {
28
+ const ensureProps = (multiaddrConnection: MultiaddrConnection) => {
29
+ ['sink', 'source', 'remoteAddr', 'conn', 'timeline', 'close'].forEach(prop => {
30
+ expect(multiaddrConnection).to.have.property(prop)
31
+ })
32
+ expect(isValidTick(multiaddrConnection.timeline.open)).to.equal(true)
33
+ return multiaddrConnection
34
+ }
35
+ const upgrader: Upgrader = {
36
+ async upgradeOutbound (multiaddrConnection) {
37
+ ensureProps(multiaddrConnection)
38
+ return await createConnection(multiaddrConnection, 'outbound')
39
+ },
40
+ async upgradeInbound (multiaddrConnection) {
41
+ ensureProps(multiaddrConnection)
42
+ return await createConnection(multiaddrConnection, 'inbound')
43
+ }
44
+ }
45
+
46
+ return upgrader
47
+ }
48
+
49
+ async function createConnection (maConn: MultiaddrConnection, direction: 'inbound' | 'outbound'): Promise<Connection> {
50
+ const localAddr = maConn.localAddr
51
+ const remoteAddr = maConn.remoteAddr
52
+
53
+ if (localAddr == null) {
54
+ throw new Error('No localAddr found on MultiaddrConnection')
55
+ }
56
+
57
+ const localPeerIdStr = localAddr.getPeerId()
58
+ const remotePeerIdStr = remoteAddr.getPeerId()
59
+ const localPeer = localPeerIdStr != null ? PeerId.fromString(localPeerIdStr) : await PeerIdFactory.createEd25519PeerId()
60
+ const remotePeer = remotePeerIdStr != null ? PeerId.fromString(remotePeerIdStr) : await PeerIdFactory.createEd25519PeerId()
61
+
62
+ const streams: Array<MuxedStream<Uint8Array>> = []
63
+ let streamId = 0
64
+
65
+ const registry = new Map()
66
+
67
+ return {
68
+ id: 'mock-connection',
69
+ localAddr,
70
+ remoteAddr,
71
+ localPeer,
72
+ remotePeer,
73
+ stat: {
74
+ status: 'OPEN',
75
+ direction,
76
+ timeline: maConn.timeline,
77
+ multiplexer: 'test-multiplexer',
78
+ encryption: 'yes-yes-very-secure'
79
+ },
80
+ registry,
81
+ tags: [],
82
+ streams,
83
+ newStream: async (protocols) => {
84
+ if (protocols.length === 0) {
85
+ throw new Error('protocols must have a length')
86
+ }
87
+
88
+ const echo = pair()
89
+
90
+ const id = `${streamId++}`
91
+ const stream: MuxedStream = {
92
+ id,
93
+ sink: echo.sink,
94
+ source: echo.source,
95
+ close: () => {},
96
+ abort: () => {},
97
+ reset: () => {},
98
+ timeline: {
99
+ open: 0
100
+ },
101
+ [Symbol.asyncIterator]: echo.source
102
+ }
103
+
104
+ const streamData = {
105
+ protocol: protocols[0],
106
+ stream
107
+ }
108
+
109
+ registry.set(id, streamData)
110
+
111
+ return streamData
112
+ },
113
+ addStream: (muxedStream: MuxedStream, streamData: StreamData) => {
114
+
115
+ },
116
+ removeStream: (id: string) => {
117
+ registry.delete(id)
118
+ },
119
+ close: async () => {
120
+ await maConn.close()
121
+ }
122
+ }
123
+ }
@@ -0,0 +1,25 @@
1
+ export default [{
2
+ id: 'QmNMMAqSxPetRS1cVMmutW5BCN1qQQyEr4u98kUvZjcfEw',
3
+ privKey: 'CAASpQkwggShAgEAAoIBAQDPek2aeHMa0blL42RTKd6xgtkk4Zkldvq4LHxzcag5uXepiQzWANEUvoD3KcUTmMRmx14PvsxdLCNst7S2JSa0R2n5wSRs14zGy6892lx4H4tLBD1KSpQlJ6vabYM1CJhIQRG90BtzDPrJ/X1iJ2HA0PPDz0Mflam2QUMDDrU0IuV2m7gSCJ5r4EmMs3U0xnH/1gShkVx4ir0WUdoWf5KQUJOmLn1clTRHYPv4KL9A/E38+imNAXfkH3c2T7DrCcYRkZSpK+WecjMsH1dCX15hhhggNqfp3iulO1tGPxHjm7PDGTPUjpCWKpD5e50sLqsUwexac1ja6ktMfszIR+FPAgMBAAECggEAB2H2uPRoRCAKU+T3gO4QeoiJaYKNjIO7UCplE0aMEeHDnEjAKC1HQ1G0DRdzZ8sb0fxuIGlNpFMZv5iZ2ZFg2zFfV//DaAwTek9tIOpQOAYHUtgHxkj5FIlg2BjlflGb+ZY3J2XsVB+2HNHkUEXOeKn2wpTxcoJE07NmywkO8Zfr1OL5oPxOPlRN1gI4ffYH2LbfaQVtRhwONR2+fs5ISfubk5iKso6BX4moMYkxubYwZbpucvKKi/rIjUA3SK86wdCUnno1KbDfdXSgCiUlvxt/IbRFXFURQoTV6BOi3sP5crBLw8OiVubMr9/8WE6KzJ0R7hPd5+eeWvYiYnWj4QKBgQD6jRlAFo/MgPO5NZ/HRAk6LUG+fdEWexA+GGV7CwJI61W/Dpbn9ZswPDhRJKo3rquyDFVZPdd7+RlXYg1wpmp1k54z++L1srsgj72vlg4I8wkZ4YLBg0+zVgHlQ0kxnp16DvQdOgiRFvMUUMEgetsoIx1CQWTd67hTExGsW+WAZQKBgQDT/WaHWvwyq9oaZ8G7F/tfeuXvNTk3HIJdfbWGgRXB7lJ7Gf6FsX4x7PeERfL5a67JLV6JdiLLVuYC2CBhipqLqC2DB962aKMvxobQpSljBBZvZyqP1IGPoKskrSo+2mqpYkeCLbDMuJ1nujgMP7gqVjabs2zj6ACKmmpYH/oNowJ/T0ZVtvFsjkg+1VsiMupUARRQuPUWMwa9HOibM1NIZcoQV2NGXB5Z++kR6JqxQO0DZlKArrviclderUdY+UuuY4VRiSEprpPeoW7ZlbTku/Ap8QZpWNEzZorQDro7bnfBW91fX9/81ets/gCPGrfEn+58U3pdb9oleCOQc/ifpQKBgBTYGbi9bYbd9vgZs6bd2M2um+VFanbMytS+g5bSIn2LHXkVOT2UEkB+eGf9KML1n54QY/dIMmukA8HL1oNAyalpw+/aWj+9Ui5kauUhGEywHjSeBEVYM9UXizxz+m9rsoktLLLUI0o97NxCJzitG0Kub3gn0FEogsUeIc7AdinZAoGBANnM1vcteSQDs7x94TDEnvvqwSkA2UWyLidD2jXgE0PG4V6tTkK//QPBmC9eq6TIqXkzYlsErSw4XeKO91knFofmdBzzVh/ddgx/NufJV4tXF+a2iTpqYBUJiz9wpIKgf43/Ob+P1EA99GAhSdxz1ess9O2aTqf3ANzn6v6g62Pv',
4
+ pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPek2aeHMa0blL42RTKd6xgtkk4Zkldvq4LHxzcag5uXepiQzWANEUvoD3KcUTmMRmx14PvsxdLCNst7S2JSa0R2n5wSRs14zGy6892lx4H4tLBD1KSpQlJ6vabYM1CJhIQRG90BtzDPrJ/X1iJ2HA0PPDz0Mflam2QUMDDrU0IuV2m7gSCJ5r4EmMs3U0xnH/1gShkVx4ir0WUdoWf5KQUJOmLn1clTRHYPv4KL9A/E38+imNAXfkH3c2T7DrCcYRkZSpK+WecjMsH1dCX15hhhggNqfp3iulO1tGPxHjm7PDGTPUjpCWKpD5e50sLqsUwexac1ja6ktMfszIR+FPAgMBAAE='
5
+ }, {
6
+ id: 'QmW8rAgaaA6sRydK1k6vonShQME47aDxaFidbtMevWs73t',
7
+ privKey: 'CAASpwkwggSjAgEAAoIBAQCTU3gVDv3SRXLOsFln9GEf1nJ/uCEDhOG10eC0H9l9IPpVxjuPT1ep+ykFUdvefq3D3q+W3hbmiHm81o8dYv26RxZIEioToUWp7Ec5M2B/niYoE93za9/ZDwJdl7eh2hNKwAdxTmdbXUPjkIU4vLyHKRFbJIn9X8w9djldz8hoUvC1BK4L1XrT6F2l0ruJXErH2ZwI1youfSzo87TdXIoFKdrQLuW6hOtDCGKTiS+ab/DkMODc6zl8N47Oczv7vjzoWOJMUJs1Pg0ZsD1zmISY38P0y/QyEhatZn0B8BmSWxlLQuukatzOepQI6k+HtfyAAjn4UEqnMaXTP1uwLldVAgMBAAECggEAHq2f8MqpYjLiAFZKl9IUs3uFZkEiZsgx9BmbMAb91Aec+WWJG4OLHrNVTG1KWp+IcaQablEa9bBvoToQnS7y5OpOon1d066egg7Ymfmv24NEMM5KRpktCNcOSA0CySpPIB6yrg6EiUr3ixiaFUGABKkxmwgVz/Q15IqM0ZMmCUsC174PMAz1COFZxD0ZX0zgHblOJQW3dc0X3XSzhht8vU02SMoVObQHQfeXEHv3K/RiVj/Ax0bTc5JVkT8dm8xksTtsFCNOzRBqFS6MYqX6U/u0Onz3Jm5Jt7fLWb5n97gZR4SleyGrqxYNb46d9X7mP0ie7E6bzFW0DsWBIeAqVQKBgQDW0We2L1n44yOvJaMs3evpj0nps13jWidt2I3RlZXjWzWHiYQfvhWUWqps/xZBnAYgnN/38xbKzHZeRNhrqOo+VB0WK1IYl0lZVE4l6TNKCsLsUfQzsb1pePkd1eRZA+TSqsi+I/IOQlQU7HA0bMrah/5FYyUBP0jYvCOvYTlZuwKBgQCvkcVRydVlzjUgv7lY5lYvT8IHV5iYO4Qkk2q6Wjv9VUKAJZauurMdiy05PboWfs5kbETdwFybXMBcknIvZO4ihxmwL8mcoNwDVZHI4bXapIKMTCyHgUKvJ9SeTcKGC7ZuQJ8mslRmYox/HloTOXEJgQgPRxXcwa3amzvdZI+6LwKBgQCLsnQqgxKUi0m6bdR2qf7vzTH4258z6X34rjpT0F5AEyF1edVFOz0XU/q+lQhpNEi7zqjLuvbYfSyA026WXKuwSsz7jMJ/oWqev/duKgAjp2npesY/E9gkjfobD+zGgoS9BzkyhXe1FCdP0A6L2S/1+zg88WOwMvJxl6/xLl24XwKBgCm60xSajX8yIQyUpWBM9yUtpueJ2Xotgz4ST+bVNbcEAddll8gWFiaqgug9FLLuFu5lkYTHiPtgc1RNdphvO+62/9MRuLDixwh/2TPO+iNqwKDKJjda8Nei9vVddCPaOtU/xNQ0xLzFJbG9LBmvqH9izOCcu8SJwGHaTcNUeJj/AoGADCJ26cY30c13F/8awAAmFYpZWCuTP5ppTsRmjd63ixlrqgkeLGpJ7kYb5fXkcTycRGYgP0e1kssBGcmE7DuG955fx3ZJESX3GQZ+XfMHvYGONwF1EiK1f0p6+GReC2VlQ7PIkoD9o0hojM6SnWvv9EXNjCPALEbfPFFvcniKVsE=',
8
+ pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCTU3gVDv3SRXLOsFln9GEf1nJ/uCEDhOG10eC0H9l9IPpVxjuPT1ep+ykFUdvefq3D3q+W3hbmiHm81o8dYv26RxZIEioToUWp7Ec5M2B/niYoE93za9/ZDwJdl7eh2hNKwAdxTmdbXUPjkIU4vLyHKRFbJIn9X8w9djldz8hoUvC1BK4L1XrT6F2l0ruJXErH2ZwI1youfSzo87TdXIoFKdrQLuW6hOtDCGKTiS+ab/DkMODc6zl8N47Oczv7vjzoWOJMUJs1Pg0ZsD1zmISY38P0y/QyEhatZn0B8BmSWxlLQuukatzOepQI6k+HtfyAAjn4UEqnMaXTP1uwLldVAgMBAAE='
9
+ }, {
10
+ id: 'QmZqCdSzgpsmB3Qweb9s4fojAoqELWzqku21UVrqtVSKi4',
11
+ privKey: 'CAASpgkwggSiAgEAAoIBAQCdbSEsTmw7lp5HagRcx57DaLiSUEkh4iBcKc7Y+jHICEIA8NIVi9FlfGEZj9G21FpiTR4Cy+BLVEuf8Nm90bym4iV+cSumeS21fvD8xGTEbeKGljs6OYHy3M45JhWF85gqHQJOqZufI2NRDuRgMZEO2+qGEXmSlv9mMXba/+9ecze8nSpB7bG2Z2pnKDeYwhF9Cz+ElMyn7TBWDjJERGVgFbTpdM3rBnbhB/TGpvs732QqZmIBlxnDb/Jn0l1gNZCgkEDcJ/0NDMBJTQ8vbvcdmaw3eaMPLkn1ix4wdu9QWCA0IBtuY1R7vSUtf4irnLJG7DnAw2GfM5QrF3xF1GLXAgMBAAECggEAQ1N0qHoxl5pmvqv8iaFlqLSUmx5y6GbI6CGJMQpvV9kQQU68yjItr3VuIXx8d/CBZyEMAK4oko7OeOyMcr3MLKLy3gyQWnXgsopDjhZ/8fH8uwps8g2+IZuFJrO+6LaxEPGvFu06fOiphPUVfn40R2KN/iBjGeox+AaXijmCqaV2vEdNJJPpMfz6VKZBDLTrbiqvo/3GN1U99PUqfPWpOWR29oAhh/Au6blSqvqTUPXB2+D/X6e1JXv31mxMPK68atDHSUjZWKB9lE4FMK1bkSKJRbyXmNIlbZ9V8X4/0r8/6T7JnW7ZT8ugRkquohmwgG7KkDXB1YsOCKXYUqzVYQKBgQDtnopFXWYl7XUyePJ/2MA5i7eoko9jmF44L31irqmHc5unNf6JlNBjlxTNx3WyfzhUzrn3c18psnGkqtow0tkBj5hmqn8/WaPbc5UA/5R1FNaNf8W5khn7MDm6KtYRPjN9djqTDiVHyC6ljONYd+5S+MqyKVWZ3t/xvG60sw85qwKBgQCpmpDtL+2JBwkfeUr3LyDcQxvbfzcv8lXj2otopWxWiLiZF1HzcqgAa2CIwu9kCGEt9Zr+9E4uINbe1To0b01/FhvR6xKO/ukceGA/mBB3vsKDcRmvpBUp+3SmnhY0nOk+ArQl4DhJ34k8pDM3EDPrixPf8SfVdU/8IM32lsdHhQKBgHLgpvCKCwxjFLnmBzcPzz8C8TOqR3BbBZIcQ34l+wflOGdKj1hsfaLoM8KYn6pAHzfBCd88A9Hg11hI0VuxVACRL5jS7NnvuGwsIOluppNEE8Ys86aXn7/0vLPoab3EWJhbRE48FIHzobmft3nZ4XpzlWs02JGfUp1IAC2UM9QpAoGAeWy3pZhSr2/iEC5+hUmwdQF2yEbj8+fDpkWo2VrVnX506uXPPkQwE1zM2Bz31t5I9OaJ+U5fSpcoPpDaAwBMs1fYwwlRWB8YNdHY1q6/23svN3uZsC4BGPV2JnO34iMUudilsRg+NGVdk5TbNejbwx7nM8Urh59djFzQGGMKeSECgYA0QMCARPpdMY50Mf2xQaCP7HfMJhESSPaBq9V3xY6ToEOEnXgAR5pNjnU85wnspHp+82r5XrKfEQlFxGpj2YA4DRRmn239sjDa29qP42UNAFg1+C3OvXTht1d5oOabaGhU0udwKmkEKUbb0bG5xPQJ5qeSJ5T1gLzLk3SIP0GlSw==',
12
+ pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdbSEsTmw7lp5HagRcx57DaLiSUEkh4iBcKc7Y+jHICEIA8NIVi9FlfGEZj9G21FpiTR4Cy+BLVEuf8Nm90bym4iV+cSumeS21fvD8xGTEbeKGljs6OYHy3M45JhWF85gqHQJOqZufI2NRDuRgMZEO2+qGEXmSlv9mMXba/+9ecze8nSpB7bG2Z2pnKDeYwhF9Cz+ElMyn7TBWDjJERGVgFbTpdM3rBnbhB/TGpvs732QqZmIBlxnDb/Jn0l1gNZCgkEDcJ/0NDMBJTQ8vbvcdmaw3eaMPLkn1ix4wdu9QWCA0IBtuY1R7vSUtf4irnLJG7DnAw2GfM5QrF3xF1GLXAgMBAAE='
13
+ }, {
14
+ id: 'QmR5VwgsL7jyfZHAGyp66tguVrQhCRQuRc3NokocsCZ3fA',
15
+ privKey: 'CAASpwkwggSjAgEAAoIBAQCGXYU+uc2nn1zuJhfdFOl34upztnrD1gpHu58ousgHdGlGgYgbqLBAvIAauXdEL0+e30HofjA634SQxE+9nV+0FQBam1DDzHQlXsuwHV+2SKvSDkk4bVllMFpu2SJtts6VH+OXC/2ANJOm+eTALykQPYXgLIBxrhp/eD+Jz5r6wW2nq3k6OmYyK/4pgGzFjo5UyX+fa/171AJ68UPboFpDy6BZCcUjS0ondxPvD7cv5jMNqqMKIB/7rpi8n+Q3oeccRqVL56wH+FE3/QLjwYHwY6ILNRyvNXRqHjwBEXB2R5moXN0AFUWTw9rt3KhFiEjR1U81BTw5/xS7W2Iu0FgZAgMBAAECggEAS64HK8JZfE09eYGJNWPe8ECmD1C7quw21BpwVe+GVPSTizvQHswPohbKDMNj0srXDMPxCnNw1OgqcaOwyjsGuZaOoXoTroTM8nOHRIX27+PUqzaStS6aCG2IsiCozKUHjGTuupftS7XRaF4eIsUtWtFcQ1ytZ9pJYHypRQTi5NMSrTze5ThjnWxtHilK7gnBXik+aR0mYEVfSn13czQEC4rMOs+b9RAc/iibDNoLopfIdvmCCvfxzmySnR7Cu1iSUAONkir7PB+2Mt/qRFCH6P+jMamtCgQ8AmifXgVmDUlun+4MnKg3KrPd6ZjOEKhVe9mCHtGozk65RDREShfDdQKBgQDi+x2MuRa9peEMOHnOyXTS+v+MFcfmG0InsO08rFNBKZChLB+c9UHBdIvexpfBHigSyERfuDye4z6lxi8ZnierWMYJP30nxmrnxwTGTk1MQquhfs1A0kpmDnPsjlOS/drEIEIssNx2WbfJ7YtMxLWBtp+BJzGpQmr0LKC+NHRSrwKBgQCXiy2kJESIUkIs2ihV55hhT6/bZo1B1O5DPA2nkjOBXqXF6fvijzMDX82JjLd07lQZlI0n1Q/Hw0p4iYi9YVd2bLkLXF5UIb2qOeHj76enVFOrPHUSkC9Y2g/0Xs+60Ths2xRd8RrrfQU3kl5iVpBywkCIrb2M5+wRnNTk1W3TtwKBgQCvplyrteAfSurpJhs9JzE8w/hWU9SqAZYkWQp91W1oE95Um2yrbjBAoQxMjaqKS+f/APPIjy56Vqj4aHGyhW11b/Fw3qzfxvCcBKtxOs8eoMlo5FO6QgJJEA4tlcafDcvp0nzjUMqK28safLU7503+33B35fjMXxWdd5u9FaKfCQKBgC4W6j6tuRosymuRvgrCcRnHfpify/5loEFallyMnpWOD6Tt0OnK25z/GifnYDRz96gAAh5HMpFy18dpLOlMHamqz2yhHx8/U8vd5tHIJZlCkF/X91M5/uxrBccwvsT2tM6Got8fYSyVzWxlW8dUxIHiinYHQUsFjkqdBDLEpq5pAoGASoTw5RBEWFM0GuAZdXsyNyxU+4S+grkTS7WdW/Ymkukh+bJZbnvF9a6MkSehqXnknthmufonds2AFNS//63gixENsoOhzT5+2cdfc6tJECvJ9xXVXkf85AoQ6T/RrXF0W4m9yQyCngNJUrKUOIH3oDIfdZITlYzOC3u1ojj7VuQ=',
16
+ pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCGXYU+uc2nn1zuJhfdFOl34upztnrD1gpHu58ousgHdGlGgYgbqLBAvIAauXdEL0+e30HofjA634SQxE+9nV+0FQBam1DDzHQlXsuwHV+2SKvSDkk4bVllMFpu2SJtts6VH+OXC/2ANJOm+eTALykQPYXgLIBxrhp/eD+Jz5r6wW2nq3k6OmYyK/4pgGzFjo5UyX+fa/171AJ68UPboFpDy6BZCcUjS0ondxPvD7cv5jMNqqMKIB/7rpi8n+Q3oeccRqVL56wH+FE3/QLjwYHwY6ILNRyvNXRqHjwBEXB2R5moXN0AFUWTw9rt3KhFiEjR1U81BTw5/xS7W2Iu0FgZAgMBAAE='
17
+ }, {
18
+ id: 'QmScLDqRg7H6ipCYxm9fVk152UWavQFKscTdoT4YNHxgqp',
19
+ privKey: 'CAASpwkwggSjAgEAAoIBAQCWEHaTZ6LBLFP5OPrUqjDM/cF4b2zrfh1Zm3kd02ZtgQB3iYtZqRPJT5ctT3A7WdVF/7dCxPGOCkJlLekTx4Y4gD8JtjA+EfN9fR/2RBKbti2N3CD4vkGp9ss4hbBFcXIhl8zuD/ELHutbV6b8b4QXJGnxfp/B+1kNPnyd7SJznS0QyvI8OLI1nAkVKdYLDRW8kPKeHyx1xhdNDuTQVTFyAjRGQ4e3UYFB7bYIHW3E6kCtCoJDlj+JPC02Yt1LHzIzZVLvPvNFnYY2mag6OiGFuh/oMBIqvnPc1zRZ3eLUqeGZjQVaoR0kdgZUKz7Q2TBeNldxK/s6XO0DnkQTlelNAgMBAAECggEAdmt1dyswR2p4tdIeNpY7Pnj9JNIhTNDPznefI0dArCdBvBMhkVaYk6MoNIxcj6l7YOrDroAF8sXr0TZimMY6B/pERKCt/z1hPWTxRQBBAvnHhwvwRPq2jK6BfhAZoyM8IoBNKowP9mum5QUNdGV4Al8s73KyFX0IsCfgZSvNpRdlt+DzPh+hu/CyoZaMpRchJc1UmK8Fyk3KfO+m0DZNfHP5P08lXNfM6MZLgTJVVgERHyG+vBOzTd2RElMe19nVCzHwb3dPPRZSQ7Fnz3rA+GeLqsM2Zi4HNhfbD1OcD9C4wDj5tYL6hWTkdz4IlfVcjCeUHxgIOhdDV2K+OwbuAQKBgQD0FjUZ09UW2FQ/fitbvIB5f1SkXWPxTF9l6mAeuXhoGv2EtQUO4vq/PK6N08RjrZdWQy6UsqHgffi7lVQ8o3hvCKdbtf4sP+cM92OrY0WZV89os79ndj4tyvmnP8WojwRjt/2XEfgdoWcgWxW9DiYINTOQVimZX+X/3on4s8hEgQKBgQCdY3kOMbyQeLTRkqHXjVTY4ddO+v4S4wOUa1l4rTqAbq1W3JYWwoDQgFuIu3limIHmjnSJpCD4EioXFsM7p6csenoc20sHxsaHnJ6Mn5Te41UYmY9EW0otkQ0C3KbXM0hwQkjyplnEmZawGKmjEHW8DJ3vRYTv9TUCgYKxDHgOzQKBgB4A/NYH7BG61eBYKgxEx6YnuMfbkwV+Vdu5S8d7FQn3B2LgvZZu4FPRqcNVXLbEB+5ao8czjiKCWaj1Wj15+rvrXGcxn+Tglg5J+r5+nXeUC7LbJZQaPNp0MOwWMr3dlrSLUWjYlJ9Pz9VyXOG4c4Rexc/gR4zK9QLW4C7qKpwBAoGAZzyUb0cYlPtYQA+asTU3bnvVKy1f8yuNcZFowst+EDiI4u0WVh+HNzy6zdmLKa03p+/RaWeLaK0hhrubnEnAUmCUMNF3ScaM+u804LDcicc8TkKLwx7ObU0z56isl4RAA8K27tNHFrpYKXJD834cfBkaj5ReOrfw6Y/iFhhDuBECgYEA8gbC76uz7LSHhW30DSRTcqOzTyoe2oYKQaxuxYNp7vSSOkcdRen+mrdflDvud2q/zN2QdL4pgqdldHlR35M/lJ0f0B6zp74jlzbO9700wzsOqreezGc5eWiroDL100U9uIZ50BKb8CKtixIHpinUSPIUcVDkSAZ2y7mbfCxQwqQ=',
20
+ pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCWEHaTZ6LBLFP5OPrUqjDM/cF4b2zrfh1Zm3kd02ZtgQB3iYtZqRPJT5ctT3A7WdVF/7dCxPGOCkJlLekTx4Y4gD8JtjA+EfN9fR/2RBKbti2N3CD4vkGp9ss4hbBFcXIhl8zuD/ELHutbV6b8b4QXJGnxfp/B+1kNPnyd7SJznS0QyvI8OLI1nAkVKdYLDRW8kPKeHyx1xhdNDuTQVTFyAjRGQ4e3UYFB7bYIHW3E6kCtCoJDlj+JPC02Yt1LHzIzZVLvPvNFnYY2mag6OiGFuh/oMBIqvnPc1zRZ3eLUqeGZjQVaoR0kdgZUKz7Q2TBeNldxK/s6XO0DnkQTlelNAgMBAAE='
21
+ }, {
22
+ id: 'QmckxVrJw1Yo8LqvmDJNUmdAsKtSbiKWmrXJFyKmUraBoN',
23
+ privKey: 'CAASpwkwggSjAgEAAoIBAQC1/GFud/7xutux7qRfMj1sIdMRh99/chR6HqVj6LQqrgk4jil0mdN/LCk/tqPqmDtObHdmEhCoybzuhLbCKgUqryKDwO6yBJHSKWY9QqrKZtLJ37SgKwGjE3+NUD4r1dJHhtQrICFdOdSCBzs/v8gi+J+KZLHo7+Nms4z09ysy7qZh94Pd7cW4gmSMergqUeANLD9C0ERw1NXolswOW7Bi7UGr7yuBxejICLO3nkxe0OtpQBrYrqdCD9vs3t/HQZbPWVoiRj4VO7fxkAPKLl30HzcIfxj/ayg8NHcH59d08D+N2v5Sdh28gsiYKIPE9CXvuw//HUY2WVRY5fDC5JglAgMBAAECggEBAKb5aN/1w3pBqz/HqRMbQpYLNuD33M3PexBNPAy+P0iFpDo63bh5Rz+A4lvuFNmzUX70MFz7qENlzi6+n/zolxMB29YtWBUH8k904rTEjXXl//NviQgITZk106tx+4k2x5gPEm57LYGfBOdFAUzNhzDnE2LkXwRNzkS161f7zKwOEsaGWRscj6UvhO4MIFxjb32CVwt5eK4yOVqtyMs9u30K4Og+AZYTlhtm+bHg6ndCCBO6CQurCQ3jD6YOkT+L3MotKqt1kORpvzIB0ujZRf49Um8wlcjC5G9aexBeGriXaVdPF62zm7GA7RMsbQM/6aRbA1fEQXvJhHUNF9UFeaECgYEA8wCjKqQA7UQnHjRwTsktdwG6szfxd7z+5MTqHHTWhWzgcQLgdh5/dO/zanEoOThadMk5C1Bqjq96gH2xim8dg5XQofSVtV3Ui0dDa+XRB3E3fyY4D3RF5hHv85O0GcvQc6DIb+Ja1oOhvHowFB1C+CT3yEgwzX/EK9xpe+KtYAkCgYEAv7hCnj/DcZFU3fAfS+unBLuVoVJT/drxv66P686s7J8UM6tW+39yDBZ1IcwY9vHFepBvxY2fFfEeLI02QFM+lZXVhNGzFkP90agNHK01psGgrmIufl9zAo8WOKgkLgbYbSHzkkDeqyjEPU+B0QSsZOCE+qLCHSdsnTmo/TjQhj0CgYAz1+j3yfGgrS+jVBC53lXi0+2fGspbf2jqKdDArXSvFqFzuudki/EpY6AND4NDYfB6hguzjD6PnoSGMUrVfAtR7X6LbwEZpqEX7eZGeMt1yQPMDr1bHrVi9mS5FMQR1NfuM1lP9Xzn00GIUpE7WVrWUhzDEBPJY/7YVLf0hFH08QKBgDWBRQZJIVBmkNrHktRrVddaSq4U/d/Q5LrsCrpymYwH8WliHgpeTQPWmKXwAd+ZJdXIzYjCt202N4eTeVqGYOb6Q/anV2WVYBbM4avpIxoA28kPGY6nML+8EyWIt2ApBOmgGgvtEreNzwaVU9NzjHEyv6n7FlVwlT1jxCe3XWq5AoGASYPKQoPeDlW+NmRG7z9EJXJRPVtmLL40fmGgtju9QIjLnjuK8XaczjAWT+ySI93Whu+Eujf2Uj7Q+NfUjvAEzJgwzuOd3jlQvoALq11kuaxlNQTn7rx0A1QhBgUJE8AkvShPC9FEnA4j/CLJU0re9H/8VvyN6qE0Mho0+YbjpP8=',
24
+ pubKey: 'CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1/GFud/7xutux7qRfMj1sIdMRh99/chR6HqVj6LQqrgk4jil0mdN/LCk/tqPqmDtObHdmEhCoybzuhLbCKgUqryKDwO6yBJHSKWY9QqrKZtLJ37SgKwGjE3+NUD4r1dJHhtQrICFdOdSCBzs/v8gi+J+KZLHo7+Nms4z09ysy7qZh94Pd7cW4gmSMergqUeANLD9C0ERw1NXolswOW7Bi7UGr7yuBxejICLO3nkxe0OtpQBrYrqdCD9vs3t/HQZbPWVoiRj4VO7fxkAPKLl30HzcIfxj/ayg8NHcH59d08D+N2v5Sdh28gsiYKIPE9CXvuw//HUY2WVRY5fDC5JglAgMBAAE='
25
+ }]