@zoralabs/coins 2.1.2 → 2.2.1

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 (97) hide show
  1. package/.turbo/turbo-build$colon$js.log +152 -0
  2. package/CHANGELOG.md +54 -0
  3. package/abis/BaseCoin.json +26 -0
  4. package/abis/BaseTest.json +2 -7
  5. package/abis/CoinConstants.json +0 -104
  6. package/abis/ContentCoin.json +26 -0
  7. package/abis/CreatorCoin.json +30 -4
  8. package/abis/FeeEstimatorHook.json +0 -5
  9. package/abis/ICoin.json +26 -0
  10. package/abis/ICoinV3.json +26 -0
  11. package/abis/ICreatorCoin.json +39 -0
  12. package/abis/IERC721.json +36 -36
  13. package/abis/IHasCoinType.json +15 -0
  14. package/abis/IHasTotalSupplyForPositions.json +15 -0
  15. package/abis/IZoraFactory.json +52 -0
  16. package/abis/IZoraHookRegistry.json +188 -0
  17. package/abis/VmContractHelper227.json +233 -0
  18. package/abis/ZoraFactoryImpl.json +32 -6
  19. package/abis/ZoraHookRegistry.json +375 -0
  20. package/abis/{CreatorCoinHook.json → ZoraV4CoinHook.json} +1 -1
  21. package/addresses/8453.json +2 -1
  22. package/dist/index.cjs +72 -10
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.js +72 -10
  25. package/dist/index.js.map +1 -1
  26. package/dist/wagmiGenerated.d.ts +90 -10
  27. package/dist/wagmiGenerated.d.ts.map +1 -1
  28. package/foundry.toml +4 -1
  29. package/package/wagmiGenerated.ts +72 -10
  30. package/package.json +6 -4
  31. package/script/PrintRegisterUpgradePath.s.sol +0 -7
  32. package/script/TestBackingCoinSwap.s.sol +0 -1
  33. package/script/TestV4Swap.s.sol +0 -1
  34. package/script/UpgradeFactoryImpl.s.sol +1 -1
  35. package/src/BaseCoin.sol +15 -12
  36. package/src/ContentCoin.sol +10 -0
  37. package/src/CreatorCoin.sol +28 -7
  38. package/src/ZoraFactoryImpl.sol +62 -23
  39. package/src/deployment/CoinsDeployerBase.sol +24 -58
  40. package/src/hook-registry/ZoraHookRegistry.sol +93 -0
  41. package/src/hooks/{BaseZoraV4CoinHook.sol → ZoraV4CoinHook.sol} +13 -8
  42. package/src/interfaces/ICoin.sol +19 -1
  43. package/src/interfaces/ICreatorCoin.sol +4 -0
  44. package/src/interfaces/IZoraFactory.sol +32 -10
  45. package/src/interfaces/IZoraHookRegistry.sol +47 -0
  46. package/src/libs/CoinConstants.sol +0 -32
  47. package/src/libs/CoinRewardsV4.sol +53 -15
  48. package/src/libs/CreatorCoinConstants.sol +0 -1
  49. package/src/libs/HooksDeployment.sol +13 -65
  50. package/src/libs/MarketConstants.sol +11 -3
  51. package/src/libs/V4Liquidity.sol +30 -0
  52. package/src/version/ContractVersionBase.sol +1 -1
  53. package/test/CoinUniV4.t.sol +33 -30
  54. package/test/ContentCoinRewards.t.sol +320 -0
  55. package/test/CreatorCoin.t.sol +1 -1
  56. package/test/CreatorCoinRewards.t.sol +375 -0
  57. package/test/DeploymentHooks.t.sol +10 -10
  58. package/test/Factory.t.sol +24 -7
  59. package/test/HooksDeployment.t.sol +4 -4
  60. package/test/LiquidityMigration.t.sol +4 -9
  61. package/test/Upgrades.t.sol +44 -48
  62. package/test/ZoraHookRegistry.t.sol +266 -0
  63. package/test/utils/BaseTest.sol +25 -42
  64. package/test/utils/FeeEstimatorHook.sol +4 -6
  65. package/test/utils/RewardTestHelpers.sol +106 -0
  66. package/.turbo/turbo-build.log +0 -199
  67. package/abis/AutoSwapperTest.json +0 -618
  68. package/abis/BadImpl.json +0 -15
  69. package/abis/BaseZoraV4CoinHook.json +0 -1664
  70. package/abis/CoinTest.json +0 -819
  71. package/abis/CoinUniV4Test.json +0 -1128
  72. package/abis/ContentCoinHook.json +0 -1733
  73. package/abis/CreatorCoinTest.json +0 -887
  74. package/abis/Deploy.json +0 -9
  75. package/abis/DeployHooks.json +0 -9
  76. package/abis/DeployScript.json +0 -35
  77. package/abis/DeployedCoinVersionLookupTest.json +0 -740
  78. package/abis/DifferentNamespaceVersionLookup.json +0 -39
  79. package/abis/FactoryTest.json +0 -748
  80. package/abis/FakeHookNoInterface.json +0 -21
  81. package/abis/GenerateDeterministicParams.json +0 -9
  82. package/abis/HooksDeploymentTest.json +0 -645
  83. package/abis/HooksTest.json +0 -709
  84. package/abis/InvalidLiquidityMigrationReceiver.json +0 -21
  85. package/abis/LiquidityMigrationReceiver.json +0 -103
  86. package/abis/LiquidityMigrationTest.json +0 -889
  87. package/abis/MockBadFactory.json +0 -15
  88. package/abis/MultiOwnableTest.json +0 -766
  89. package/abis/PrintUpgradeCommand.json +0 -9
  90. package/abis/TestDeployedCoinVersionLookupImplementation.json +0 -39
  91. package/abis/TestV4Swap.json +0 -9
  92. package/abis/UpgradeFactoryImpl.json +0 -9
  93. package/abis/UpgradeHooks.json +0 -35
  94. package/abis/UpgradesTest.json +0 -723
  95. package/src/hooks/ContentCoinHook.sol +0 -27
  96. package/src/hooks/CreatorCoinHook.sol +0 -27
  97. package/src/libs/CreatorCoinRewards.sol +0 -34
@@ -0,0 +1,233 @@
1
+ [
2
+ {
3
+ "type": "function",
4
+ "name": "deployCode",
5
+ "inputs": [
6
+ {
7
+ "name": "_artifact",
8
+ "type": "string",
9
+ "internalType": "string"
10
+ },
11
+ {
12
+ "name": "_value",
13
+ "type": "uint256",
14
+ "internalType": "uint256"
15
+ },
16
+ {
17
+ "name": "_salt",
18
+ "type": "bytes32",
19
+ "internalType": "bytes32"
20
+ }
21
+ ],
22
+ "outputs": [
23
+ {
24
+ "name": "",
25
+ "type": "address",
26
+ "internalType": "address"
27
+ }
28
+ ],
29
+ "stateMutability": "nonpayable"
30
+ },
31
+ {
32
+ "type": "function",
33
+ "name": "deployCode",
34
+ "inputs": [
35
+ {
36
+ "name": "_artifact",
37
+ "type": "string",
38
+ "internalType": "string"
39
+ },
40
+ {
41
+ "name": "_args",
42
+ "type": "bytes",
43
+ "internalType": "bytes"
44
+ },
45
+ {
46
+ "name": "_salt",
47
+ "type": "bytes32",
48
+ "internalType": "bytes32"
49
+ }
50
+ ],
51
+ "outputs": [
52
+ {
53
+ "name": "",
54
+ "type": "address",
55
+ "internalType": "address"
56
+ }
57
+ ],
58
+ "stateMutability": "nonpayable"
59
+ },
60
+ {
61
+ "type": "function",
62
+ "name": "deployCode",
63
+ "inputs": [
64
+ {
65
+ "name": "_artifact",
66
+ "type": "string",
67
+ "internalType": "string"
68
+ },
69
+ {
70
+ "name": "_value",
71
+ "type": "uint256",
72
+ "internalType": "uint256"
73
+ }
74
+ ],
75
+ "outputs": [
76
+ {
77
+ "name": "",
78
+ "type": "address",
79
+ "internalType": "address"
80
+ }
81
+ ],
82
+ "stateMutability": "nonpayable"
83
+ },
84
+ {
85
+ "type": "function",
86
+ "name": "deployCode",
87
+ "inputs": [
88
+ {
89
+ "name": "_artifact",
90
+ "type": "string",
91
+ "internalType": "string"
92
+ },
93
+ {
94
+ "name": "_salt",
95
+ "type": "bytes32",
96
+ "internalType": "bytes32"
97
+ }
98
+ ],
99
+ "outputs": [
100
+ {
101
+ "name": "",
102
+ "type": "address",
103
+ "internalType": "address"
104
+ }
105
+ ],
106
+ "stateMutability": "nonpayable"
107
+ },
108
+ {
109
+ "type": "function",
110
+ "name": "deployCode",
111
+ "inputs": [
112
+ {
113
+ "name": "_artifact",
114
+ "type": "string",
115
+ "internalType": "string"
116
+ },
117
+ {
118
+ "name": "_args",
119
+ "type": "bytes",
120
+ "internalType": "bytes"
121
+ }
122
+ ],
123
+ "outputs": [
124
+ {
125
+ "name": "",
126
+ "type": "address",
127
+ "internalType": "address"
128
+ }
129
+ ],
130
+ "stateMutability": "nonpayable"
131
+ },
132
+ {
133
+ "type": "function",
134
+ "name": "deployCode",
135
+ "inputs": [
136
+ {
137
+ "name": "_artifact",
138
+ "type": "string",
139
+ "internalType": "string"
140
+ },
141
+ {
142
+ "name": "_args",
143
+ "type": "bytes",
144
+ "internalType": "bytes"
145
+ },
146
+ {
147
+ "name": "_value",
148
+ "type": "uint256",
149
+ "internalType": "uint256"
150
+ },
151
+ {
152
+ "name": "_salt",
153
+ "type": "bytes32",
154
+ "internalType": "bytes32"
155
+ }
156
+ ],
157
+ "outputs": [
158
+ {
159
+ "name": "",
160
+ "type": "address",
161
+ "internalType": "address"
162
+ }
163
+ ],
164
+ "stateMutability": "nonpayable"
165
+ },
166
+ {
167
+ "type": "function",
168
+ "name": "deployCode",
169
+ "inputs": [
170
+ {
171
+ "name": "_artifact",
172
+ "type": "string",
173
+ "internalType": "string"
174
+ }
175
+ ],
176
+ "outputs": [
177
+ {
178
+ "name": "",
179
+ "type": "address",
180
+ "internalType": "address"
181
+ }
182
+ ],
183
+ "stateMutability": "nonpayable"
184
+ },
185
+ {
186
+ "type": "function",
187
+ "name": "deployCode",
188
+ "inputs": [
189
+ {
190
+ "name": "_artifact",
191
+ "type": "string",
192
+ "internalType": "string"
193
+ },
194
+ {
195
+ "name": "_args",
196
+ "type": "bytes",
197
+ "internalType": "bytes"
198
+ },
199
+ {
200
+ "name": "_value",
201
+ "type": "uint256",
202
+ "internalType": "uint256"
203
+ }
204
+ ],
205
+ "outputs": [
206
+ {
207
+ "name": "",
208
+ "type": "address",
209
+ "internalType": "address"
210
+ }
211
+ ],
212
+ "stateMutability": "nonpayable"
213
+ },
214
+ {
215
+ "type": "function",
216
+ "name": "getCode",
217
+ "inputs": [
218
+ {
219
+ "name": "_artifact",
220
+ "type": "string",
221
+ "internalType": "string"
222
+ }
223
+ ],
224
+ "outputs": [
225
+ {
226
+ "name": "",
227
+ "type": "bytes",
228
+ "internalType": "bytes"
229
+ }
230
+ ],
231
+ "stateMutability": "nonpayable"
232
+ }
233
+ ]
@@ -3,22 +3,22 @@
3
3
  "type": "constructor",
4
4
  "inputs": [
5
5
  {
6
- "name": "_coinV4Impl",
6
+ "name": "coinV4Impl_",
7
7
  "type": "address",
8
8
  "internalType": "address"
9
9
  },
10
10
  {
11
- "name": "_creatorCoinImpl",
11
+ "name": "creatorCoinImpl_",
12
12
  "type": "address",
13
13
  "internalType": "address"
14
14
  },
15
15
  {
16
- "name": "_contentCoinHook",
16
+ "name": "hook_",
17
17
  "type": "address",
18
18
  "internalType": "address"
19
19
  },
20
20
  {
21
- "name": "_creatorCoinHook",
21
+ "name": "zoraHookRegistry_",
22
22
  "type": "address",
23
23
  "internalType": "address"
24
24
  }
@@ -212,7 +212,7 @@
212
212
  "internalType": "int24"
213
213
  },
214
214
  {
215
- "name": "orderSize",
215
+ "name": "",
216
216
  "type": "uint256",
217
217
  "internalType": "uint256"
218
218
  }
@@ -453,7 +453,7 @@
453
453
  "internalType": "address"
454
454
  },
455
455
  {
456
- "name": "hook",
456
+ "name": "deployHook",
457
457
  "type": "address",
458
458
  "internalType": "address"
459
459
  },
@@ -496,6 +496,19 @@
496
496
  ],
497
497
  "stateMutability": "view"
498
498
  },
499
+ {
500
+ "type": "function",
501
+ "name": "hook",
502
+ "inputs": [],
503
+ "outputs": [
504
+ {
505
+ "name": "",
506
+ "type": "address",
507
+ "internalType": "address"
508
+ }
509
+ ],
510
+ "stateMutability": "view"
511
+ },
499
512
  {
500
513
  "type": "function",
501
514
  "name": "implementation",
@@ -599,6 +612,19 @@
599
612
  "outputs": [],
600
613
  "stateMutability": "payable"
601
614
  },
615
+ {
616
+ "type": "function",
617
+ "name": "zoraHookRegistry",
618
+ "inputs": [],
619
+ "outputs": [
620
+ {
621
+ "name": "",
622
+ "type": "address",
623
+ "internalType": "address"
624
+ }
625
+ ],
626
+ "stateMutability": "view"
627
+ },
602
628
  {
603
629
  "type": "event",
604
630
  "name": "CoinCreated",
@@ -0,0 +1,375 @@
1
+ [
2
+ {
3
+ "type": "constructor",
4
+ "inputs": [],
5
+ "stateMutability": "nonpayable"
6
+ },
7
+ {
8
+ "type": "function",
9
+ "name": "addOwner",
10
+ "inputs": [
11
+ {
12
+ "name": "account",
13
+ "type": "address",
14
+ "internalType": "address"
15
+ }
16
+ ],
17
+ "outputs": [],
18
+ "stateMutability": "nonpayable"
19
+ },
20
+ {
21
+ "type": "function",
22
+ "name": "addOwners",
23
+ "inputs": [
24
+ {
25
+ "name": "accounts",
26
+ "type": "address[]",
27
+ "internalType": "address[]"
28
+ }
29
+ ],
30
+ "outputs": [],
31
+ "stateMutability": "nonpayable"
32
+ },
33
+ {
34
+ "type": "function",
35
+ "name": "getHookAddresses",
36
+ "inputs": [],
37
+ "outputs": [
38
+ {
39
+ "name": "",
40
+ "type": "address[]",
41
+ "internalType": "address[]"
42
+ }
43
+ ],
44
+ "stateMutability": "view"
45
+ },
46
+ {
47
+ "type": "function",
48
+ "name": "getHookTag",
49
+ "inputs": [
50
+ {
51
+ "name": "hook",
52
+ "type": "address",
53
+ "internalType": "address"
54
+ }
55
+ ],
56
+ "outputs": [
57
+ {
58
+ "name": "",
59
+ "type": "string",
60
+ "internalType": "string"
61
+ }
62
+ ],
63
+ "stateMutability": "view"
64
+ },
65
+ {
66
+ "type": "function",
67
+ "name": "getHookVersion",
68
+ "inputs": [
69
+ {
70
+ "name": "hook",
71
+ "type": "address",
72
+ "internalType": "address"
73
+ }
74
+ ],
75
+ "outputs": [
76
+ {
77
+ "name": "version",
78
+ "type": "string",
79
+ "internalType": "string"
80
+ }
81
+ ],
82
+ "stateMutability": "pure"
83
+ },
84
+ {
85
+ "type": "function",
86
+ "name": "getHooks",
87
+ "inputs": [],
88
+ "outputs": [
89
+ {
90
+ "name": "",
91
+ "type": "tuple[]",
92
+ "internalType": "struct IZoraHookRegistry.ZoraHook[]",
93
+ "components": [
94
+ {
95
+ "name": "hook",
96
+ "type": "address",
97
+ "internalType": "address"
98
+ },
99
+ {
100
+ "name": "tag",
101
+ "type": "string",
102
+ "internalType": "string"
103
+ },
104
+ {
105
+ "name": "version",
106
+ "type": "string",
107
+ "internalType": "string"
108
+ }
109
+ ]
110
+ }
111
+ ],
112
+ "stateMutability": "view"
113
+ },
114
+ {
115
+ "type": "function",
116
+ "name": "initialize",
117
+ "inputs": [
118
+ {
119
+ "name": "initialOwners",
120
+ "type": "address[]",
121
+ "internalType": "address[]"
122
+ }
123
+ ],
124
+ "outputs": [],
125
+ "stateMutability": "nonpayable"
126
+ },
127
+ {
128
+ "type": "function",
129
+ "name": "isOwner",
130
+ "inputs": [
131
+ {
132
+ "name": "account",
133
+ "type": "address",
134
+ "internalType": "address"
135
+ }
136
+ ],
137
+ "outputs": [
138
+ {
139
+ "name": "",
140
+ "type": "bool",
141
+ "internalType": "bool"
142
+ }
143
+ ],
144
+ "stateMutability": "view"
145
+ },
146
+ {
147
+ "type": "function",
148
+ "name": "isRegisteredHook",
149
+ "inputs": [
150
+ {
151
+ "name": "hook",
152
+ "type": "address",
153
+ "internalType": "address"
154
+ }
155
+ ],
156
+ "outputs": [
157
+ {
158
+ "name": "",
159
+ "type": "bool",
160
+ "internalType": "bool"
161
+ }
162
+ ],
163
+ "stateMutability": "view"
164
+ },
165
+ {
166
+ "type": "function",
167
+ "name": "owners",
168
+ "inputs": [],
169
+ "outputs": [
170
+ {
171
+ "name": "",
172
+ "type": "address[]",
173
+ "internalType": "address[]"
174
+ }
175
+ ],
176
+ "stateMutability": "view"
177
+ },
178
+ {
179
+ "type": "function",
180
+ "name": "registerHooks",
181
+ "inputs": [
182
+ {
183
+ "name": "hooks",
184
+ "type": "address[]",
185
+ "internalType": "address[]"
186
+ },
187
+ {
188
+ "name": "tags",
189
+ "type": "string[]",
190
+ "internalType": "string[]"
191
+ }
192
+ ],
193
+ "outputs": [],
194
+ "stateMutability": "nonpayable"
195
+ },
196
+ {
197
+ "type": "function",
198
+ "name": "removeHooks",
199
+ "inputs": [
200
+ {
201
+ "name": "hooks",
202
+ "type": "address[]",
203
+ "internalType": "address[]"
204
+ }
205
+ ],
206
+ "outputs": [],
207
+ "stateMutability": "nonpayable"
208
+ },
209
+ {
210
+ "type": "function",
211
+ "name": "removeOwner",
212
+ "inputs": [
213
+ {
214
+ "name": "account",
215
+ "type": "address",
216
+ "internalType": "address"
217
+ }
218
+ ],
219
+ "outputs": [],
220
+ "stateMutability": "nonpayable"
221
+ },
222
+ {
223
+ "type": "function",
224
+ "name": "removeOwners",
225
+ "inputs": [
226
+ {
227
+ "name": "accounts",
228
+ "type": "address[]",
229
+ "internalType": "address[]"
230
+ }
231
+ ],
232
+ "outputs": [],
233
+ "stateMutability": "nonpayable"
234
+ },
235
+ {
236
+ "type": "function",
237
+ "name": "revokeOwnership",
238
+ "inputs": [],
239
+ "outputs": [],
240
+ "stateMutability": "nonpayable"
241
+ },
242
+ {
243
+ "type": "event",
244
+ "name": "Initialized",
245
+ "inputs": [
246
+ {
247
+ "name": "version",
248
+ "type": "uint64",
249
+ "indexed": false,
250
+ "internalType": "uint64"
251
+ }
252
+ ],
253
+ "anonymous": false
254
+ },
255
+ {
256
+ "type": "event",
257
+ "name": "OwnerUpdated",
258
+ "inputs": [
259
+ {
260
+ "name": "caller",
261
+ "type": "address",
262
+ "indexed": true,
263
+ "internalType": "address"
264
+ },
265
+ {
266
+ "name": "prevOwner",
267
+ "type": "address",
268
+ "indexed": true,
269
+ "internalType": "address"
270
+ },
271
+ {
272
+ "name": "newOwner",
273
+ "type": "address",
274
+ "indexed": true,
275
+ "internalType": "address"
276
+ }
277
+ ],
278
+ "anonymous": false
279
+ },
280
+ {
281
+ "type": "event",
282
+ "name": "ZoraHookRegistered",
283
+ "inputs": [
284
+ {
285
+ "name": "hook",
286
+ "type": "address",
287
+ "indexed": true,
288
+ "internalType": "address"
289
+ },
290
+ {
291
+ "name": "tag",
292
+ "type": "string",
293
+ "indexed": false,
294
+ "internalType": "string"
295
+ },
296
+ {
297
+ "name": "version",
298
+ "type": "string",
299
+ "indexed": false,
300
+ "internalType": "string"
301
+ }
302
+ ],
303
+ "anonymous": false
304
+ },
305
+ {
306
+ "type": "event",
307
+ "name": "ZoraHookRemoved",
308
+ "inputs": [
309
+ {
310
+ "name": "hook",
311
+ "type": "address",
312
+ "indexed": true,
313
+ "internalType": "address"
314
+ },
315
+ {
316
+ "name": "tag",
317
+ "type": "string",
318
+ "indexed": false,
319
+ "internalType": "string"
320
+ },
321
+ {
322
+ "name": "version",
323
+ "type": "string",
324
+ "indexed": false,
325
+ "internalType": "string"
326
+ }
327
+ ],
328
+ "anonymous": false
329
+ },
330
+ {
331
+ "type": "error",
332
+ "name": "AlreadyOwner",
333
+ "inputs": []
334
+ },
335
+ {
336
+ "type": "error",
337
+ "name": "ArrayLengthMismatch",
338
+ "inputs": []
339
+ },
340
+ {
341
+ "type": "error",
342
+ "name": "InvalidInitialization",
343
+ "inputs": []
344
+ },
345
+ {
346
+ "type": "error",
347
+ "name": "NotInitializing",
348
+ "inputs": []
349
+ },
350
+ {
351
+ "type": "error",
352
+ "name": "NotOwner",
353
+ "inputs": []
354
+ },
355
+ {
356
+ "type": "error",
357
+ "name": "OneOwnerRequired",
358
+ "inputs": []
359
+ },
360
+ {
361
+ "type": "error",
362
+ "name": "OnlyOwner",
363
+ "inputs": []
364
+ },
365
+ {
366
+ "type": "error",
367
+ "name": "OwnerCannotBeAddressZero",
368
+ "inputs": []
369
+ },
370
+ {
371
+ "type": "error",
372
+ "name": "UseRevokeOwnershipToRemoveSelf",
373
+ "inputs": []
374
+ }
375
+ ]
@@ -18,7 +18,7 @@
18
18
  "internalType": "address[]"
19
19
  },
20
20
  {
21
- "name": "upgradeGate",
21
+ "name": "upgradeGate_",
22
22
  "type": "address",
23
23
  "internalType": "contract IHooksUpgradeGate"
24
24
  }
@@ -10,5 +10,6 @@
10
10
  "ZORA_FACTORY": "0x777777751622c0d3258f214F9DF38E35BF45baF3",
11
11
  "ZORA_FACTORY_IMPL": "0x0e2ea62E5377D46FeF114A60AfBE3d5eA7490577",
12
12
  "ZORA_V4_COIN_HOOK": "0x9ea932730A7787000042e34390B8E435dD839040",
13
- "ZORA_V4_COIN_HOOK_SALT": "0x0000000000000000000000000000000000000000000000000000000000002fa2"
13
+ "ZORA_V4_COIN_HOOK_SALT": "0x0000000000000000000000000000000000000000000000000000000000002fa2",
14
+ "ZORA_HOOK_REGISTRY": "0x777777C4c14b133858c3982D41Dbf02509fc18d7"
14
15
  }