@knpkv/confluence-to-markdown 0.2.0 → 0.4.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 (336) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/LICENSE +21 -0
  3. package/README.md +282 -14
  4. package/dist/ConfluenceAuth.d.ts +76 -0
  5. package/dist/ConfluenceAuth.d.ts.map +1 -0
  6. package/dist/ConfluenceAuth.js +356 -0
  7. package/dist/ConfluenceAuth.js.map +1 -0
  8. package/dist/ConfluenceClient.d.ts +26 -2
  9. package/dist/ConfluenceClient.d.ts.map +1 -1
  10. package/dist/ConfluenceClient.js +98 -92
  11. package/dist/ConfluenceClient.js.map +1 -1
  12. package/dist/ConfluenceConfig.d.ts +4 -24
  13. package/dist/ConfluenceConfig.d.ts.map +1 -1
  14. package/dist/ConfluenceConfig.js +45 -7
  15. package/dist/ConfluenceConfig.js.map +1 -1
  16. package/dist/ConfluenceError.d.ts +89 -6
  17. package/dist/ConfluenceError.d.ts.map +1 -1
  18. package/dist/ConfluenceError.js +88 -5
  19. package/dist/ConfluenceError.js.map +1 -1
  20. package/dist/GitError.d.ts +103 -0
  21. package/dist/GitError.d.ts.map +1 -0
  22. package/dist/GitError.js +85 -0
  23. package/dist/GitError.js.map +1 -0
  24. package/dist/GitService.d.ts +175 -0
  25. package/dist/GitService.d.ts.map +1 -0
  26. package/dist/GitService.js +431 -0
  27. package/dist/GitService.js.map +1 -0
  28. package/dist/LocalFileSystem.d.ts +29 -4
  29. package/dist/LocalFileSystem.d.ts.map +1 -1
  30. package/dist/LocalFileSystem.js +80 -6
  31. package/dist/LocalFileSystem.js.map +1 -1
  32. package/dist/MarkdownConverter.d.ts +49 -2
  33. package/dist/MarkdownConverter.d.ts.map +1 -1
  34. package/dist/MarkdownConverter.js +73 -111
  35. package/dist/MarkdownConverter.js.map +1 -1
  36. package/dist/SchemaConverterError.d.ts +108 -0
  37. package/dist/SchemaConverterError.d.ts.map +1 -0
  38. package/dist/SchemaConverterError.js +84 -0
  39. package/dist/SchemaConverterError.js.map +1 -0
  40. package/dist/Schemas.d.ts +225 -1
  41. package/dist/Schemas.d.ts.map +1 -1
  42. package/dist/Schemas.js +155 -6
  43. package/dist/Schemas.js.map +1 -1
  44. package/dist/SyncEngine.d.ts +30 -20
  45. package/dist/SyncEngine.d.ts.map +1 -1
  46. package/dist/SyncEngine.js +566 -117
  47. package/dist/SyncEngine.js.map +1 -1
  48. package/dist/ast/BlockNode.d.ts +468 -0
  49. package/dist/ast/BlockNode.d.ts.map +1 -0
  50. package/dist/ast/BlockNode.js +319 -0
  51. package/dist/ast/BlockNode.js.map +1 -0
  52. package/dist/ast/Document.d.ts +244 -0
  53. package/dist/ast/Document.d.ts.map +1 -0
  54. package/dist/ast/Document.js +69 -0
  55. package/dist/ast/Document.js.map +1 -0
  56. package/dist/ast/InlineNode.d.ts +477 -0
  57. package/dist/ast/InlineNode.d.ts.map +1 -0
  58. package/dist/ast/InlineNode.js +263 -0
  59. package/dist/ast/InlineNode.js.map +1 -0
  60. package/dist/ast/MacroNode.d.ts +267 -0
  61. package/dist/ast/MacroNode.d.ts.map +1 -0
  62. package/dist/ast/MacroNode.js +164 -0
  63. package/dist/ast/MacroNode.js.map +1 -0
  64. package/dist/ast/index.d.ts +10 -0
  65. package/dist/ast/index.d.ts.map +1 -0
  66. package/dist/ast/index.js +14 -0
  67. package/dist/ast/index.js.map +1 -0
  68. package/dist/bin.js +33 -149
  69. package/dist/bin.js.map +1 -1
  70. package/dist/commands/auth.d.ts +15 -0
  71. package/dist/commands/auth.d.ts.map +1 -0
  72. package/dist/commands/auth.js +86 -0
  73. package/dist/commands/auth.js.map +1 -0
  74. package/dist/commands/clone.d.ts +12 -0
  75. package/dist/commands/clone.d.ts.map +1 -0
  76. package/dist/commands/clone.js +93 -0
  77. package/dist/commands/clone.js.map +1 -0
  78. package/dist/commands/delete.d.ts +13 -0
  79. package/dist/commands/delete.d.ts.map +1 -0
  80. package/dist/commands/delete.js +48 -0
  81. package/dist/commands/delete.js.map +1 -0
  82. package/dist/commands/errorHandler.d.ts +14 -0
  83. package/dist/commands/errorHandler.d.ts.map +1 -0
  84. package/dist/commands/errorHandler.js +33 -0
  85. package/dist/commands/errorHandler.js.map +1 -0
  86. package/dist/commands/git.d.ts +22 -0
  87. package/dist/commands/git.d.ts.map +1 -0
  88. package/dist/commands/git.js +72 -0
  89. package/dist/commands/git.js.map +1 -0
  90. package/dist/commands/index.d.ts +11 -0
  91. package/dist/commands/index.d.ts.map +1 -0
  92. package/dist/commands/index.js +11 -0
  93. package/dist/commands/index.js.map +1 -0
  94. package/dist/commands/layers.d.ts +31 -0
  95. package/dist/commands/layers.d.ts.map +1 -0
  96. package/dist/commands/layers.js +137 -0
  97. package/dist/commands/layers.js.map +1 -0
  98. package/dist/commands/new.d.ts +9 -0
  99. package/dist/commands/new.d.ts.map +1 -0
  100. package/dist/commands/new.js +80 -0
  101. package/dist/commands/new.js.map +1 -0
  102. package/dist/commands/pageTree.d.ts +18 -0
  103. package/dist/commands/pageTree.d.ts.map +1 -0
  104. package/dist/commands/pageTree.js +20 -0
  105. package/dist/commands/pageTree.js.map +1 -0
  106. package/dist/commands/shared.d.ts +15 -0
  107. package/dist/commands/shared.d.ts.map +1 -0
  108. package/dist/commands/shared.js +27 -0
  109. package/dist/commands/shared.js.map +1 -0
  110. package/dist/commands/sync.d.ts +15 -0
  111. package/dist/commands/sync.d.ts.map +1 -0
  112. package/dist/commands/sync.js +101 -0
  113. package/dist/commands/sync.js.map +1 -0
  114. package/dist/index.d.ts +10 -1
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +14 -0
  117. package/dist/index.js.map +1 -1
  118. package/dist/internal/NodeLayers.d.ts +7 -0
  119. package/dist/internal/NodeLayers.d.ts.map +1 -0
  120. package/dist/internal/NodeLayers.js +19 -0
  121. package/dist/internal/NodeLayers.js.map +1 -0
  122. package/dist/internal/frontmatter.d.ts +10 -0
  123. package/dist/internal/frontmatter.d.ts.map +1 -1
  124. package/dist/internal/frontmatter.js +16 -0
  125. package/dist/internal/frontmatter.js.map +1 -1
  126. package/dist/internal/gitCommands.d.ts +78 -0
  127. package/dist/internal/gitCommands.d.ts.map +1 -0
  128. package/dist/internal/gitCommands.js +156 -0
  129. package/dist/internal/gitCommands.js.map +1 -0
  130. package/dist/internal/hashUtils.d.ts +42 -1
  131. package/dist/internal/hashUtils.d.ts.map +1 -1
  132. package/dist/internal/hashUtils.js +38 -2
  133. package/dist/internal/hashUtils.js.map +1 -1
  134. package/dist/internal/oauthServer.d.ts +55 -0
  135. package/dist/internal/oauthServer.d.ts.map +1 -0
  136. package/dist/internal/oauthServer.js +110 -0
  137. package/dist/internal/oauthServer.js.map +1 -0
  138. package/dist/internal/pathUtils.d.ts +21 -4
  139. package/dist/internal/pathUtils.d.ts.map +1 -1
  140. package/dist/internal/pathUtils.js +24 -13
  141. package/dist/internal/pathUtils.js.map +1 -1
  142. package/dist/internal/tokenStorage.d.ts +75 -0
  143. package/dist/internal/tokenStorage.d.ts.map +1 -0
  144. package/dist/internal/tokenStorage.js +149 -0
  145. package/dist/internal/tokenStorage.js.map +1 -0
  146. package/dist/internal/userCache.d.ts +42 -0
  147. package/dist/internal/userCache.d.ts.map +1 -0
  148. package/dist/internal/userCache.js +51 -0
  149. package/dist/internal/userCache.js.map +1 -0
  150. package/dist/parsers/ConfluenceParser.d.ts +26 -0
  151. package/dist/parsers/ConfluenceParser.d.ts.map +1 -0
  152. package/dist/parsers/ConfluenceParser.js +792 -0
  153. package/dist/parsers/ConfluenceParser.js.map +1 -0
  154. package/dist/parsers/MarkdownParser.d.ts +26 -0
  155. package/dist/parsers/MarkdownParser.d.ts.map +1 -0
  156. package/dist/parsers/MarkdownParser.js +873 -0
  157. package/dist/parsers/MarkdownParser.js.map +1 -0
  158. package/dist/parsers/index.d.ts +8 -0
  159. package/dist/parsers/index.d.ts.map +1 -0
  160. package/dist/parsers/index.js +8 -0
  161. package/dist/parsers/index.js.map +1 -0
  162. package/dist/schemas/ConfluenceSchema.d.ts +21 -0
  163. package/dist/schemas/ConfluenceSchema.d.ts.map +1 -0
  164. package/dist/schemas/ConfluenceSchema.js +38 -0
  165. package/dist/schemas/ConfluenceSchema.js.map +1 -0
  166. package/dist/schemas/ConversionSchema.d.ts +35 -0
  167. package/dist/schemas/ConversionSchema.d.ts.map +1 -0
  168. package/dist/schemas/ConversionSchema.js +208 -0
  169. package/dist/schemas/ConversionSchema.js.map +1 -0
  170. package/dist/schemas/MarkdownSchema.d.ts +21 -0
  171. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  172. package/dist/schemas/MarkdownSchema.js +38 -0
  173. package/dist/schemas/MarkdownSchema.js.map +1 -0
  174. package/dist/schemas/hast/HastFromHtml.d.ts +27 -0
  175. package/dist/schemas/hast/HastFromHtml.d.ts.map +1 -0
  176. package/dist/schemas/hast/HastFromHtml.js +107 -0
  177. package/dist/schemas/hast/HastFromHtml.js.map +1 -0
  178. package/dist/schemas/hast/HastSchema.d.ts +195 -0
  179. package/dist/schemas/hast/HastSchema.d.ts.map +1 -0
  180. package/dist/schemas/hast/HastSchema.js +183 -0
  181. package/dist/schemas/hast/HastSchema.js.map +1 -0
  182. package/dist/schemas/hast/index.d.ts +9 -0
  183. package/dist/schemas/hast/index.d.ts.map +1 -0
  184. package/dist/schemas/hast/index.js +3 -0
  185. package/dist/schemas/hast/index.js.map +1 -0
  186. package/dist/schemas/index.d.ts +14 -0
  187. package/dist/schemas/index.d.ts.map +1 -0
  188. package/dist/schemas/index.js +16 -0
  189. package/dist/schemas/index.js.map +1 -0
  190. package/dist/schemas/mdast/MdastFromMarkdown.d.ts +30 -0
  191. package/dist/schemas/mdast/MdastFromMarkdown.d.ts.map +1 -0
  192. package/dist/schemas/mdast/MdastFromMarkdown.js +79 -0
  193. package/dist/schemas/mdast/MdastFromMarkdown.js.map +1 -0
  194. package/dist/schemas/mdast/MdastSchema.d.ts +385 -0
  195. package/dist/schemas/mdast/MdastSchema.d.ts.map +1 -0
  196. package/dist/schemas/mdast/MdastSchema.js +266 -0
  197. package/dist/schemas/mdast/MdastSchema.js.map +1 -0
  198. package/dist/schemas/mdast/index.d.ts +10 -0
  199. package/dist/schemas/mdast/index.d.ts.map +1 -0
  200. package/dist/schemas/mdast/index.js +4 -0
  201. package/dist/schemas/mdast/index.js.map +1 -0
  202. package/dist/schemas/mdast/mdastToString.d.ts +13 -0
  203. package/dist/schemas/mdast/mdastToString.d.ts.map +1 -0
  204. package/dist/schemas/mdast/mdastToString.js +85 -0
  205. package/dist/schemas/mdast/mdastToString.js.map +1 -0
  206. package/dist/schemas/nodes/block/BlockSchema.d.ts +43 -0
  207. package/dist/schemas/nodes/block/BlockSchema.d.ts.map +1 -0
  208. package/dist/schemas/nodes/block/BlockSchema.js +634 -0
  209. package/dist/schemas/nodes/block/BlockSchema.js.map +1 -0
  210. package/dist/schemas/nodes/block/index.d.ts +7 -0
  211. package/dist/schemas/nodes/block/index.d.ts.map +1 -0
  212. package/dist/schemas/nodes/block/index.js +7 -0
  213. package/dist/schemas/nodes/block/index.js.map +1 -0
  214. package/dist/schemas/nodes/index.d.ts +9 -0
  215. package/dist/schemas/nodes/index.d.ts.map +1 -0
  216. package/dist/schemas/nodes/index.js +12 -0
  217. package/dist/schemas/nodes/index.js.map +1 -0
  218. package/dist/schemas/nodes/inline/InlineSchema.d.ts +48 -0
  219. package/dist/schemas/nodes/inline/InlineSchema.d.ts.map +1 -0
  220. package/dist/schemas/nodes/inline/InlineSchema.js +436 -0
  221. package/dist/schemas/nodes/inline/InlineSchema.js.map +1 -0
  222. package/dist/schemas/nodes/inline/index.d.ts +7 -0
  223. package/dist/schemas/nodes/inline/index.d.ts.map +1 -0
  224. package/dist/schemas/nodes/inline/index.js +7 -0
  225. package/dist/schemas/nodes/inline/index.js.map +1 -0
  226. package/dist/schemas/nodes/macro/MacroSchema.d.ts +27 -0
  227. package/dist/schemas/nodes/macro/MacroSchema.d.ts.map +1 -0
  228. package/dist/schemas/nodes/macro/MacroSchema.js +162 -0
  229. package/dist/schemas/nodes/macro/MacroSchema.js.map +1 -0
  230. package/dist/schemas/nodes/macro/index.d.ts +7 -0
  231. package/dist/schemas/nodes/macro/index.d.ts.map +1 -0
  232. package/dist/schemas/nodes/macro/index.js +7 -0
  233. package/dist/schemas/nodes/macro/index.js.map +1 -0
  234. package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts +24 -0
  235. package/dist/schemas/preprocessing/ConfluencePreprocessor.d.ts.map +1 -0
  236. package/dist/schemas/preprocessing/ConfluencePreprocessor.js +351 -0
  237. package/dist/schemas/preprocessing/ConfluencePreprocessor.js.map +1 -0
  238. package/dist/schemas/preprocessing/index.d.ts +8 -0
  239. package/dist/schemas/preprocessing/index.d.ts.map +1 -0
  240. package/dist/schemas/preprocessing/index.js +2 -0
  241. package/dist/schemas/preprocessing/index.js.map +1 -0
  242. package/dist/serializers/ConfluenceSerializer.d.ts +30 -0
  243. package/dist/serializers/ConfluenceSerializer.d.ts.map +1 -0
  244. package/dist/serializers/ConfluenceSerializer.js +551 -0
  245. package/dist/serializers/ConfluenceSerializer.js.map +1 -0
  246. package/dist/serializers/MarkdownSerializer.d.ts +34 -0
  247. package/dist/serializers/MarkdownSerializer.d.ts.map +1 -0
  248. package/dist/serializers/MarkdownSerializer.js +355 -0
  249. package/dist/serializers/MarkdownSerializer.js.map +1 -0
  250. package/dist/serializers/index.d.ts +8 -0
  251. package/dist/serializers/index.d.ts.map +1 -0
  252. package/dist/serializers/index.js +8 -0
  253. package/dist/serializers/index.js.map +1 -0
  254. package/package.json +27 -16
  255. package/src/ConfluenceAuth.ts +571 -0
  256. package/src/ConfluenceClient.ts +188 -156
  257. package/src/ConfluenceConfig.ts +63 -7
  258. package/src/ConfluenceError.ts +110 -14
  259. package/src/GitError.ts +92 -0
  260. package/src/GitService.ts +859 -0
  261. package/src/LocalFileSystem.ts +179 -9
  262. package/src/MarkdownConverter.ts +126 -122
  263. package/src/SchemaConverterError.ts +108 -0
  264. package/src/Schemas.ts +223 -6
  265. package/src/SyncEngine.ts +745 -162
  266. package/src/ast/BlockNode.ts +425 -0
  267. package/src/ast/Document.ts +90 -0
  268. package/src/ast/InlineNode.ts +323 -0
  269. package/src/ast/MacroNode.ts +245 -0
  270. package/src/ast/index.ts +83 -0
  271. package/src/bin.ts +50 -249
  272. package/src/commands/auth.ts +117 -0
  273. package/src/commands/clone.ts +145 -0
  274. package/src/commands/delete.ts +57 -0
  275. package/src/commands/errorHandler.ts +32 -0
  276. package/src/commands/git.ts +114 -0
  277. package/src/commands/index.ts +10 -0
  278. package/src/commands/layers.ts +211 -0
  279. package/src/commands/new.ts +99 -0
  280. package/src/commands/pageTree.ts +40 -0
  281. package/src/commands/shared.ts +35 -0
  282. package/src/commands/sync.ts +129 -0
  283. package/src/index.ts +21 -1
  284. package/src/internal/NodeLayers.ts +21 -0
  285. package/src/internal/frontmatter.ts +21 -0
  286. package/src/internal/gitCommands.ts +229 -0
  287. package/src/internal/hashUtils.ts +65 -3
  288. package/src/internal/oauthServer.ts +199 -0
  289. package/src/internal/pathUtils.ts +34 -17
  290. package/src/internal/tokenStorage.ts +240 -0
  291. package/src/internal/userCache.ts +90 -0
  292. package/src/parsers/ConfluenceParser.ts +950 -0
  293. package/src/parsers/MarkdownParser.ts +1198 -0
  294. package/src/parsers/index.ts +8 -0
  295. package/src/schemas/ConfluenceSchema.ts +56 -0
  296. package/src/schemas/ConversionSchema.ts +318 -0
  297. package/src/schemas/MarkdownSchema.ts +56 -0
  298. package/src/schemas/hast/HastFromHtml.ts +153 -0
  299. package/src/schemas/hast/HastSchema.ts +274 -0
  300. package/src/schemas/hast/index.ts +35 -0
  301. package/src/schemas/index.ts +20 -0
  302. package/src/schemas/mdast/MdastFromMarkdown.ts +118 -0
  303. package/src/schemas/mdast/MdastSchema.ts +566 -0
  304. package/src/schemas/mdast/index.ts +59 -0
  305. package/src/schemas/mdast/mdastToString.ts +102 -0
  306. package/src/schemas/nodes/block/BlockSchema.ts +773 -0
  307. package/src/schemas/nodes/block/index.ts +13 -0
  308. package/src/schemas/nodes/index.ts +20 -0
  309. package/src/schemas/nodes/inline/InlineSchema.ts +523 -0
  310. package/src/schemas/nodes/inline/index.ts +14 -0
  311. package/src/schemas/nodes/macro/MacroSchema.ts +226 -0
  312. package/src/schemas/nodes/macro/index.ts +6 -0
  313. package/src/schemas/preprocessing/ConfluencePreprocessor.ts +446 -0
  314. package/src/schemas/preprocessing/index.ts +8 -0
  315. package/src/serializers/ConfluenceSerializer.ts +717 -0
  316. package/src/serializers/MarkdownSerializer.ts +493 -0
  317. package/src/serializers/index.ts +8 -0
  318. package/test/GitService.test.ts +209 -0
  319. package/test/MarkdownConverter.test.ts +37 -3
  320. package/test/Schemas.test.ts +97 -2
  321. package/test/ast/BlockNode.test.ts +265 -0
  322. package/test/ast/Document.test.ts +126 -0
  323. package/test/ast/InlineNode.test.ts +161 -0
  324. package/test/fixtures/integration-test.html.fixture +103 -0
  325. package/test/fixtures/integration-test.md.expected +257 -0
  326. package/test/integration.test.ts +269 -0
  327. package/test/oauthServer.test.ts +50 -0
  328. package/test/parsers/ConfluenceParser.test.ts +283 -0
  329. package/test/schemas/ConfluencePreprocessor.test.ts +180 -0
  330. package/test/schemas/ConversionSchema.test.ts +159 -0
  331. package/test/schemas/HastSchema.test.ts +138 -0
  332. package/test/schemas/MdastSchema.test.ts +145 -0
  333. package/test/schemas/nodes/block/BlockSchema.test.ts +173 -0
  334. package/test/schemas/nodes/inline/InlineSchema.test.ts +198 -0
  335. package/test/schemas/nodes/macro/MacroSchema.test.ts +142 -0
  336. package/test/tokenStorage.test.ts +99 -0
@@ -0,0 +1,161 @@
1
+ import { describe, expect, it } from "@effect/vitest"
2
+ import * as Either from "effect/Either"
3
+ import * as Schema from "effect/Schema"
4
+ import {
5
+ Emphasis,
6
+ InlineCode,
7
+ InlineNode,
8
+ LineBreak,
9
+ Link,
10
+ Strong,
11
+ Text,
12
+ UnsupportedInline
13
+ } from "../../src/ast/InlineNode.js"
14
+
15
+ describe("InlineNode", () => {
16
+ describe("Text", () => {
17
+ it("creates text node", () => {
18
+ const text = new Text({ value: "Hello world" })
19
+ expect(text.value).toBe("Hello world")
20
+ expect(text._tag).toBe("Text")
21
+ })
22
+
23
+ it("decodes from plain object", () => {
24
+ const result = Schema.decodeUnknownEither(Text)({
25
+ _tag: "Text",
26
+ value: "test"
27
+ })
28
+ expect(Either.isRight(result)).toBe(true)
29
+ if (Either.isRight(result)) {
30
+ expect(result.right.value).toBe("test")
31
+ }
32
+ })
33
+
34
+ it("encodes to plain object", () => {
35
+ const text = new Text({ value: "hello" })
36
+ const result = Schema.encodeUnknownEither(Text)(text)
37
+ expect(Either.isRight(result)).toBe(true)
38
+ if (Either.isRight(result)) {
39
+ expect(result.right).toEqual({ _tag: "Text", value: "hello" })
40
+ }
41
+ })
42
+ })
43
+
44
+ describe("Strong", () => {
45
+ it("creates strong node with children", () => {
46
+ const strong = new Strong({
47
+ children: [new Text({ value: "bold" })]
48
+ })
49
+ expect(strong._tag).toBe("Strong")
50
+ expect(strong.children).toHaveLength(1)
51
+ })
52
+
53
+ it("decodes from plain object", () => {
54
+ const result = Schema.decodeUnknownEither(Strong)({
55
+ _tag: "Strong",
56
+ children: [{ _tag: "Text", value: "bold" }]
57
+ })
58
+ expect(Either.isRight(result)).toBe(true)
59
+ })
60
+ })
61
+
62
+ describe("Emphasis", () => {
63
+ it("creates emphasis node with children", () => {
64
+ const em = new Emphasis({
65
+ children: [new Text({ value: "italic" })]
66
+ })
67
+ expect(em._tag).toBe("Emphasis")
68
+ expect(em.children).toHaveLength(1)
69
+ })
70
+ })
71
+
72
+ describe("InlineCode", () => {
73
+ it("creates inline code node", () => {
74
+ const code = new InlineCode({ value: "const x = 1" })
75
+ expect(code._tag).toBe("InlineCode")
76
+ expect(code.value).toBe("const x = 1")
77
+ })
78
+ })
79
+
80
+ describe("Link", () => {
81
+ it("creates link with href and children", () => {
82
+ const link = new Link({
83
+ href: "https://example.com",
84
+ children: [new Text({ value: "Click" })]
85
+ })
86
+ expect(link._tag).toBe("Link")
87
+ expect(link.href).toBe("https://example.com")
88
+ expect(link.title).toBeUndefined()
89
+ })
90
+
91
+ it("creates link with optional title", () => {
92
+ const link = new Link({
93
+ href: "https://example.com",
94
+ title: "Example",
95
+ children: [new Text({ value: "Click" })]
96
+ })
97
+ expect(link.title).toBe("Example")
98
+ })
99
+ })
100
+
101
+ describe("LineBreak", () => {
102
+ it("creates line break node", () => {
103
+ const br = new LineBreak({})
104
+ expect(br._tag).toBe("LineBreak")
105
+ })
106
+ })
107
+
108
+ describe("UnsupportedInline", () => {
109
+ it("creates unsupported inline from confluence", () => {
110
+ const unknown = new UnsupportedInline({
111
+ raw: "<ac:custom/>",
112
+ source: "confluence"
113
+ })
114
+ expect(unknown._tag).toBe("UnsupportedInline")
115
+ expect(unknown.source).toBe("confluence")
116
+ })
117
+
118
+ it("creates unsupported inline from markdown", () => {
119
+ const unknown = new UnsupportedInline({
120
+ raw: "~~strike~~",
121
+ source: "markdown"
122
+ })
123
+ expect(unknown.source).toBe("markdown")
124
+ })
125
+ })
126
+
127
+ describe("InlineNode union", () => {
128
+ it("decodes Text variant", () => {
129
+ const result = Schema.decodeUnknownEither(InlineNode)({
130
+ _tag: "Text",
131
+ value: "hello"
132
+ })
133
+ expect(Either.isRight(result)).toBe(true)
134
+ })
135
+
136
+ it("decodes Strong variant", () => {
137
+ const result = Schema.decodeUnknownEither(InlineNode)({
138
+ _tag: "Strong",
139
+ children: [{ _tag: "Text", value: "bold" }]
140
+ })
141
+ expect(Either.isRight(result)).toBe(true)
142
+ })
143
+
144
+ it("decodes Link variant", () => {
145
+ const result = Schema.decodeUnknownEither(InlineNode)({
146
+ _tag: "Link",
147
+ href: "https://example.com",
148
+ children: [{ _tag: "Text", value: "link" }]
149
+ })
150
+ expect(Either.isRight(result)).toBe(true)
151
+ })
152
+
153
+ it("rejects unknown tag", () => {
154
+ const result = Schema.decodeUnknownEither(InlineNode)({
155
+ _tag: "Unknown",
156
+ value: "test"
157
+ })
158
+ expect(Either.isLeft(result)).toBe(true)
159
+ })
160
+ })
161
+ })
@@ -0,0 +1,103 @@
1
+ <ac:layout><ac:layout-section ac:type="fixed-width" ac:breakout-mode="default"><ac:layout-cell><table><thead><tr><th /><th /></tr></thead><tbody><tr><td>Owner</td><td><ac:link><ri:user ri:account-id="557058:76c20100-e45a-495d-9cb2-4d7c809e6a9b" /></ac:link></td></tr><tr><td>On this page</td><td><ac:structured-macro ac:name="toc" ac:schema-version="1" ac:macro-id="d452bad4-700f-4973-ae06-574776a14687" /></td></tr></tbody></table>
2
+ <p>Normal text</p>
3
+ <h2>Headings</h2>
4
+ <h1>Heading 1</h1>
5
+ <h2>Heading 2</h2>
6
+ <h3>Heading 3</h3>
7
+ <h4>Heading 4</h4>
8
+ <h5>Heading 5</h5>
9
+ <h6>Heading 6</h6>
10
+ <h2>Text Formatting</h2>
11
+ <h3>Basic Styles</h3>
12
+ <p><strong>Bold</strong></p>
13
+ <p><em>Italic</em></p>
14
+ <p><u>Inderline</u></p>
15
+ <p><del>Strikethrough</del></p>
16
+ <p><code>Code</code></p>
17
+ <p><sub>Subscript</sub></p>
18
+ <p><sup>Superscript</sup></p>
19
+ <h3>Quotes</h3>
20
+ <blockquote><p>Quote</p></blockquote>
21
+ <h3>Alignment</h3>
22
+ <p style="text-align: center;">Align center</p>
23
+ <p style="text-align: right;">Align right</p>
24
+ <p>Default</p>
25
+ <h2>Colors</h2>
26
+ <h3>Text Colors</h3>
27
+ <p><span style="color: rgb(151,160,175);">Gray</span></p>
28
+ <p><span style="color: rgb(255,255,255);">White</span></p>
29
+ <p><span style="color: rgb(7,71,166);">Bold blue</span></p>
30
+ <p><span style="color: rgb(76,154,255);">Blue</span></p>
31
+ <p><span style="color: rgb(179,212,255);">Subtle blue</span></p>
32
+ <p><span style="color: rgb(0,141,166);">Bold teal</span></p>
33
+ <p><span style="color: rgb(0,184,217);">Teal</span></p>
34
+ <p><span style="color: rgb(179,245,255);">Subtle blue</span></p>
35
+ <p><span style="color: rgb(0,102,68);">Bold green</span></p>
36
+ <p><span style="color: rgb(54,179,126);">Green</span></p>
37
+ <p><span style="color: rgb(171,245,209);">Subtle green</span></p>
38
+ <p><span style="color: rgb(255,153,31);">Bold orange</span></p>
39
+ <p><span style="color: rgb(255,196,0);">Yellow</span></p>
40
+ <p><span style="color: rgb(255,240,179);">Subtle yellow</span></p>
41
+ <p><span style="color: rgb(191,38,0);">Bold red</span></p>
42
+ <p><span style="color: rgb(255,86,48);">Red</span></p>
43
+ <p><span style="color: rgb(255,189,173);">Subtle red</span></p>
44
+ <p><span style="color: rgb(64,50,148);">Bold purple</span></p>
45
+ <p><span style="color: rgb(101,84,192);">Purple</span></p>
46
+ <p><span style="color: rgb(234,230,255);">Subtle purple</span></p>
47
+ <h3>Highlights</h3>
48
+ <p><span style="background-color: rgb(220,223,228);">Gray highlight</span></p>
49
+ <p><span style="background-color: rgb(198,237,251);">Teal highlight</span></p>
50
+ <p><span style="background-color: rgb(211,241,167);">Lime highlight</span></p>
51
+ <p><span style="background-color: rgb(254,222,200);">Yellow highlight</span></p>
52
+ <p><span style="background-color: rgb(253,208,236);">Magenta highlight</span></p>
53
+ <p><span style="background-color: rgb(223,216,253);">Purple highlight</span></p>
54
+ <h2>Lists</h2>
55
+ <h3>Bullet Lists</h3>
56
+ <ul><li><p>Bullet list 1</p><ul><li><p>Bullet list 1.1</p><ul><li><p>Bullet list 1.1.1</p></li></ul></li></ul></li><li><p>Bullet list 2</p></li></ul>
57
+ <h3>Numbered Lists</h3>
58
+ <ol><li><p>Numbered list 1</p><ol start="1"><li><p>Numbered list a</p><ol start="1"><li><p>Numbered list i</p></li></ol></li></ol></li><li><p>Numbered list 2</p></li></ol>
59
+ <h3>Indentation</h3>
60
+ <p style="margin-left: 30.0px;">Indent tab 1</p>
61
+ <p style="margin-left: 60.0px;">Indent tab 2</p>
62
+ <p style="margin-left: 90.0px;">Indent tab 3</p>
63
+ <h3>Action Items</h3>
64
+ <ac:task-list>
65
+ <ac:task><ac:task-id>11</ac:task-id><ac:task-uuid>bce1bc39-6cba-44f9-b1b3-6adf0634475a</ac:task-uuid><ac:task-status>incomplete</ac:task-status><ac:task-body><span class="placeholder-inline-tasks">Action Item unchecked</span></ac:task-body></ac:task>
66
+ <ac:task><ac:task-id>12</ac:task-id><ac:task-uuid>49c6a48e-cb41-4d98-ba45-64c1ecf96702</ac:task-uuid><ac:task-status>complete</ac:task-status><ac:task-body><span class="placeholder-inline-tasks">Action item checked</span></ac:task-body></ac:task>
67
+ </ac:task-list>
68
+ <h2>Links &amp; Media</h2>
69
+ <h3>Links</h3>
70
+ <p><a href="http://example.com">External link</a></p>
71
+ <p><ac:link><ac:link-body>Confluence link</ac:link-body></ac:link></p>
72
+ <h3>Images</h3>
73
+ <ac:image ac:align="center" ac:width="238" ac:alt="Atlassian_Confluence_2017_logo.svg"><ri:attachment ri:filename="Atlassian_Confluence_2017_logo.svg" ri:version-at-save="1" /></ac:image>
74
+ <h3>User Mentions</h3>
75
+ <p><ac:link><ri:user ri:account-id="557058:76c20100-e45a-495d-9cb2-4d7c809e6a9b" /></ac:link></p>
76
+ <h3>Emoticons</h3>
77
+ <p><ac:emoticon ac:emoji-shortname=":grinning:" ac:emoji-id="1f600" ac:emoji-fallback="😀" /> <ac:emoticon ac:emoji-shortname=":smiley:" ac:emoji-id="1f603" ac:emoji-fallback="😃" /> <ac:emoticon ac:emoji-shortname=":smile:" ac:emoji-id="1f604" ac:emoji-fallback="😄" /> <ac:emoticon ac:emoji-shortname=":grin:" ac:emoji-id="1f601" ac:emoji-fallback="😁" /> <ac:emoticon ac:emoji-shortname=":laughing:" ac:emoji-id="1f606" ac:emoji-fallback="😆" /> <ac:emoticon ac:emoji-shortname=":sweat_smile:" ac:emoji-id="1f605" ac:emoji-fallback="😅" /> <ac:emoticon ac:emoji-shortname=":joy:" ac:emoji-id="1f602" ac:emoji-fallback="😂" /> <ac:emoticon ac:emoji-shortname=":rofl:" ac:emoji-id="1f923" ac:emoji-fallback="🤣" /></p>
78
+ <h2>Tables</h2>
79
+ <table><thead><tr><th><strong>Header 1</strong></th><th><strong>Header 2</strong></th><th><strong>Header 3</strong></th></tr></thead><tbody><tr><td>Cell 1.1</td><td>Cell 2.1</td><td>Cell 3.1</td></tr><tr><td>Cell 1.2</td><td>Cell 2.2</td><td>Cell 3.2</td></tr></tbody></table></ac:layout-cell></ac:layout-section><ac:layout-section ac:type="two_equal" ac:breakout-mode="wide" ac:breakout-width="760"><ac:layout-cell><p>Column 1</p></ac:layout-cell><ac:layout-cell><p>Column 2</p></ac:layout-cell></ac:layout-section><ac:layout-section ac:type="fixed-width" ac:breakout-mode="default"><ac:layout-cell><h3>Code Blocks</h3>
80
+ <ac:structured-macro ac:name="code" ac:schema-version="1" ac:macro-id="84de7e03-e3b0-4884-aa7b-34cbfce6c1c1"><ac:parameter ac:name="language">typescript</ac:parameter><ac:plain-text-body><![CDATA[const typescript = {};]]></ac:plain-text-body></ac:structured-macro>
81
+ <ac:structured-macro ac:name="code" ac:schema-version="1" ac:macro-id="0d60fe56-c93c-4f6b-979b-3432c79db9ba"><ac:parameter ac:name="language">json</ac:parameter><ac:plain-text-body><![CDATA[{
82
+ "json": true
83
+ }]]></ac:plain-text-body></ac:structured-macro>
84
+ <h3>Decisions</h3>
85
+ <ac:adf-extension><ac:adf-node type="decision-list"><ac:adf-node type="decision-item"><ac:adf-attribute key="local-id">7c3012f5-3ad3-47e1-89cc-cd87267668d3</ac:adf-attribute><ac:adf-attribute key="state">DECIDED</ac:adf-attribute><ac:adf-content>Decision</ac:adf-content></ac:adf-node></ac:adf-node><ac:adf-fallback><ul class="decision-list"><li>Decision</li></ul></ac:adf-fallback></ac:adf-extension>
86
+ <hr />
87
+ <h3>Expand</h3>
88
+ <ac:structured-macro ac:name="expand" ac:schema-version="1" ac:macro-id="a1c56c2d-d8a1-4b83-8dbc-c1283a401cb8"><ac:parameter ac:name="title">Expand title</ac:parameter><ac:rich-text-body><p>Expand content</p></ac:rich-text-body></ac:structured-macro>
89
+ <h3>Dates</h3>
90
+ <p><time datetime="2026-01-01" /></p>
91
+ <h3>Status</h3>
92
+ <p><ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="ba0a4297-9ff9-4d44-bf69-3469663636f7"><ac:parameter ac:name="title">Gray</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="f220ee0c-735a-4613-bbb6-64b5f9952472"><ac:parameter ac:name="colour">Blue</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="71234fd5-5442-4557-a6de-ed762923d99d"><ac:parameter ac:name="colour">Green</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="72ac3007-9264-468e-b0f2-858465e5e9cd"><ac:parameter ac:name="colour">Yellow</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="27fafb59-40d9-44b9-979a-7b820ccc1ba6"><ac:parameter ac:name="colour">Red</ac:parameter></ac:structured-macro> <ac:structured-macro ac:name="status" ac:schema-version="1" ac:macro-id="cc376419-1aa0-4fc3-9378-4a9e0efc5a4e"><ac:parameter ac:name="colour">Purple</ac:parameter></ac:structured-macro></p>
93
+ <h3>Smart Links</h3>
94
+ <p><a href="https://knpkv-team.atlassian.net/issues/?jql=project%20in%20(LEARNJIRA)%20ORDER%20BY%20created%20DESC" data-card-appearance="block" data-datasource="{&quot;id&quot;:&quot;d8b75300-dfda-4519-b6cd-e49abbd50401&quot;,&quot;parameters&quot;:{&quot;cloudId&quot;:&quot;85fe2d49-d86f-4afa-be53-e7ec408a4d5e&quot;,&quot;jql&quot;:&quot;project in (LEARNJIRA) ORDER BY created DESC&quot;},&quot;views&quot;:[{&quot;type&quot;:&quot;table&quot;,&quot;properties&quot;:{&quot;columns&quot;:[{&quot;key&quot;:&quot;issuetype&quot;},{&quot;key&quot;:&quot;key&quot;},{&quot;key&quot;:&quot;summary&quot;},{&quot;key&quot;:&quot;assignee&quot;},{&quot;key&quot;:&quot;priority&quot;},{&quot;key&quot;:&quot;status&quot;},{&quot;key&quot;:&quot;updated&quot;}]}}]}">https://knpkv-team.atlassian.net/issues/?jql=project%20in%20(LEARNJIRA)%20ORDER%20BY%20created%20DESC</a></p>
95
+ <p><a href="https://knpkv-team.atlassian.net/wiki/search?text=Getting+started" data-card-appearance="block" data-datasource="{&quot;id&quot;:&quot;768fc736-3af4-4a8f-b27e-203602bff8ca&quot;,&quot;parameters&quot;:{&quot;cloudId&quot;:&quot;85fe2d49-d86f-4afa-be53-e7ec408a4d5e&quot;,&quot;searchString&quot;:&quot;Getting started&quot;},&quot;views&quot;:[{&quot;type&quot;:&quot;table&quot;,&quot;properties&quot;:{&quot;columns&quot;:[{&quot;key&quot;:&quot;type&quot;},{&quot;key&quot;:&quot;title&quot;},{&quot;key&quot;:&quot;space&quot;,&quot;width&quot;:243},{&quot;key&quot;:&quot;description&quot;},{&quot;key&quot;:&quot;ownedBy&quot;},{&quot;key&quot;:&quot;updatedAt&quot;}]}}]}">https://knpkv-team.atlassian.net/wiki/search?text=Getting+started</a></p>
96
+ <h3>Panels</h3>
97
+ <ac:structured-macro ac:name="info" ac:schema-version="1" ac:macro-id="5dccc7f1-ede2-43e6-926c-9c36fc4144ce"><ac:rich-text-body><p>Info panel</p></ac:rich-text-body></ac:structured-macro>
98
+ <ac:structured-macro ac:name="note" ac:schema-version="1" ac:macro-id="5884da9b-d738-45b3-9821-e8dc832e6601"><ac:rich-text-body><p>Note panel</p></ac:rich-text-body></ac:structured-macro>
99
+ <ac:structured-macro ac:name="warning" ac:schema-version="1" ac:macro-id="c1c28329-228c-42b7-8456-f2530f56f2c0"><ac:rich-text-body><p>Error panel</p></ac:rich-text-body></ac:structured-macro>
100
+ <ac:structured-macro ac:name="panel" ac:schema-version="1" ac:macro-id="fe489f67-fe69-4a52-bd26-9cc23eea815c"><ac:rich-text-body><p>Custom panel</p></ac:rich-text-body></ac:structured-macro>
101
+ <ac:structured-macro ac:name="tip" ac:schema-version="1" ac:macro-id="77ad7dce-d489-42a1-995d-0a1db3a9ef83"><ac:rich-text-body><p>Success panel</p></ac:rich-text-body></ac:structured-macro>
102
+ <ac:structured-macro ac:name="note" ac:schema-version="1" ac:macro-id="e5c6352e-cf6e-47cb-a423-a912838dcec4"><ac:rich-text-body><p>Warning panel</p></ac:rich-text-body></ac:structured-macro>
103
+ </ac:layout-cell></ac:layout-section></ac:layout>
@@ -0,0 +1,257 @@
1
+ <!--cf:layout-start-->
2
+
3
+ <!--cf:section:0;fixed-width;default;;1-->
4
+
5
+ <!--cf:cell:0;0-->
6
+
7
+ | | |
8
+ | --- | --- |
9
+ | Owner | <!--cf:user:557058:76c20100-e45a-495d-9cb2-4d7c809e6a9b--> |
10
+ | On this page | <!--cf:toc:;--> |
11
+
12
+ Normal text
13
+
14
+ ## Headings
15
+
16
+ # Heading 1
17
+
18
+ ## Heading 2
19
+
20
+ ### Heading 3
21
+
22
+ #### Heading 4
23
+
24
+ ##### Heading 5
25
+
26
+ ###### Heading 6
27
+
28
+ ## Text Formatting
29
+
30
+ ### Basic Styles
31
+
32
+ **Bold**
33
+
34
+ *Italic*
35
+
36
+ <u>Inderline</u>
37
+
38
+ ~~Strikethrough~~
39
+
40
+ `Code`
41
+
42
+ <sub>Subscript</sub>
43
+
44
+ <sup>Superscript</sup>
45
+
46
+ ### Quotes
47
+
48
+ > Quote
49
+
50
+ ### Alignment
51
+
52
+ <p style="text-align: center;">Align center</p>
53
+
54
+ <p style="text-align: right;">Align right</p>
55
+
56
+ Default
57
+
58
+ ## Colors
59
+
60
+ ### Text Colors
61
+
62
+ <span style="color: rgb(151,160,175);">Gray</span>
63
+
64
+ <span style="color: rgb(255,255,255);">White</span>
65
+
66
+ <span style="color: rgb(7,71,166);">Bold blue</span>
67
+
68
+ <span style="color: rgb(76,154,255);">Blue</span>
69
+
70
+ <span style="color: rgb(179,212,255);">Subtle blue</span>
71
+
72
+ <span style="color: rgb(0,141,166);">Bold teal</span>
73
+
74
+ <span style="color: rgb(0,184,217);">Teal</span>
75
+
76
+ <span style="color: rgb(179,245,255);">Subtle blue</span>
77
+
78
+ <span style="color: rgb(0,102,68);">Bold green</span>
79
+
80
+ <span style="color: rgb(54,179,126);">Green</span>
81
+
82
+ <span style="color: rgb(171,245,209);">Subtle green</span>
83
+
84
+ <span style="color: rgb(255,153,31);">Bold orange</span>
85
+
86
+ <span style="color: rgb(255,196,0);">Yellow</span>
87
+
88
+ <span style="color: rgb(255,240,179);">Subtle yellow</span>
89
+
90
+ <span style="color: rgb(191,38,0);">Bold red</span>
91
+
92
+ <span style="color: rgb(255,86,48);">Red</span>
93
+
94
+ <span style="color: rgb(255,189,173);">Subtle red</span>
95
+
96
+ <span style="color: rgb(64,50,148);">Bold purple</span>
97
+
98
+ <span style="color: rgb(101,84,192);">Purple</span>
99
+
100
+ <span style="color: rgb(234,230,255);">Subtle purple</span>
101
+
102
+ ### Highlights
103
+
104
+ <span style="background-color: rgb(220,223,228);">Gray highlight</span>
105
+
106
+ <span style="background-color: rgb(198,237,251);">Teal highlight</span>
107
+
108
+ <span style="background-color: rgb(211,241,167);">Lime highlight</span>
109
+
110
+ <span style="background-color: rgb(254,222,200);">Yellow highlight</span>
111
+
112
+ <span style="background-color: rgb(253,208,236);">Magenta highlight</span>
113
+
114
+ <span style="background-color: rgb(223,216,253);">Purple highlight</span>
115
+
116
+ ## Lists
117
+
118
+ ### Bullet Lists
119
+
120
+ - Bullet list 1
121
+ <ul local-id="bed75a55-f8b9-45fb-9346-7531dd9ea338"><li local-id="30852041-2521-40ed-acbb-1a8469be3c30"><p local-id="5b0cccdf-3a87-4b32-b618-910a94529992">Bullet list 1.1</p><ul local-id="453de478-a2d7-4b2f-9b93-91732877c960"><li local-id="cc32bd38-0927-42f2-b2bc-8f480ea97762"><p local-id="308bc2ca-c9b5-4734-a0ff-dea8e319184d">Bullet list 1.1.1</p></li></ul></li></ul>
122
+ - Bullet list 2
123
+
124
+ ### Numbered Lists
125
+
126
+ 1. Numbered list 1
127
+ <ol start="1" local-id="d40d0651-9647-4012-aa44-22dea36dca0f"><li local-id="16340895-0a02-4369-a4f2-7fe3f7c56112"><p local-id="d5ad263d-afe0-4ca3-8299-929fbc1c7cd0">Numbered list a</p><ol start="1" local-id="897771c4-1ff1-4b72-832b-c8d6cc79f57b"><li local-id="25120a69-d5ff-41e0-9192-35e036d752f0"><p local-id="6bd35901-285f-4f58-872f-51e4152e296b">Numbered list i</p></li></ol></li></ol>
128
+ 2. Numbered list 2
129
+
130
+ ### Indentation
131
+
132
+ <p style="margin-left: 30px;">Indent tab 1</p>
133
+
134
+ <p style="margin-left: 60px;">Indent tab 2</p>
135
+
136
+ <p style="margin-left: 90px;">Indent tab 3</p>
137
+
138
+ ### Action Items
139
+
140
+ <!--cf:tasklist:11|bce1bc39-6cba-44f9-b1b3-6adf0634475a|incomplete|Action%20Item%20unchecked;12|49c6a48e-cb41-4d98-ba45-64c1ecf96702|complete|Action%20item%20checked-->
141
+
142
+ ## Links & Media
143
+
144
+ ### Links
145
+
146
+ [External link](http://example.com)
147
+
148
+ <!--cf:link:Confluence%20link-->
149
+
150
+ ### Images
151
+
152
+ <!--cf:image:f=Atlassian_Confluence_2017_logo.svg|a=Atlassian_Confluence_2017_logo.svg|al=center|w=238-->
153
+
154
+ ### User Mentions
155
+
156
+ <!--cf:user:557058:76c20100-e45a-495d-9cb2-4d7c809e6a9b-->
157
+
158
+ ### Emoticons
159
+
160
+ <!--cf:emoticon:%3Agrinning%3A|1f600|%F0%9F%98%80--> <!--cf:emoticon:%3Asmiley%3A|1f603|%F0%9F%98%83--> <!--cf:emoticon:%3Asmile%3A|1f604|%F0%9F%98%84--> <!--cf:emoticon:%3Agrin%3A|1f601|%F0%9F%98%81--> <!--cf:emoticon:%3Alaughing%3A|1f606|%F0%9F%98%86--> <!--cf:emoticon:%3Asweat_smile%3A|1f605|%F0%9F%98%85--> <!--cf:emoticon:%3Ajoy%3A|1f602|%F0%9F%98%82--> <!--cf:emoticon:%3Arofl%3A|1f923|%F0%9F%A4%A3-->
161
+
162
+ ## Tables
163
+
164
+ | **Header 1** | **Header 2** | **Header 3** |
165
+ | --- | --- | --- |
166
+ | Cell 1.1 | Cell 2.1 | Cell 3.1 |
167
+ | Cell 1.2 | Cell 2.2 | Cell 3.2 |
168
+
169
+ <!--cf:section-end:0-->
170
+
171
+ <!--cf:section:1;two_equal;wide;760;2-->
172
+
173
+ <!--cf:cell:1;0-->
174
+
175
+ Column 1
176
+
177
+ <!--cf:cell:1;1-->
178
+
179
+ Column 2
180
+
181
+ <!--cf:section-end:1-->
182
+
183
+ <!--cf:section:2;fixed-width;default;;1-->
184
+
185
+ <!--cf:cell:2;0-->
186
+
187
+ ### Code Blocks
188
+
189
+ ```typescript
190
+ const typescript = {};
191
+ ```
192
+
193
+ ```json
194
+ {
195
+ "json": true
196
+ }
197
+ ```
198
+
199
+ ### Decisions
200
+
201
+ <!--cf:decision:7c3012f5-3ad3-47e1-89cc-cd87267668d3;DECIDED;Decision-->
202
+
203
+ ---
204
+
205
+ ### Expand
206
+
207
+ <!--cf:expand:Expand%20title:Expand%20content-->
208
+
209
+ ### Dates
210
+
211
+ <!--cf:date:2026-01-01-->
212
+
213
+ ### Status
214
+
215
+ <!--cf:status:Gray;--> <!--cf:status:;Blue--> <!--cf:status:;Green--> <!--cf:status:;Yellow--> <!--cf:status:;Red--> <!--cf:status:;Purple-->
216
+
217
+ ### Smart Links
218
+
219
+ <!--cf:smartlink:https%3A%2F%2Fknpkv-team.atlassian.net%2Fissues%2F%3Fjql%3Dproject%2520in%2520(LEARNJIRA)%2520ORDER%2520BY%2520created%2520DESC;block;%7B%22id%22%3A%22d8b75300-dfda-4519-b6cd-e49abbd50401%22%2C%22parameters%22%3A%7B%22cloudId%22%3A%2285fe2d49-d86f-4afa-be53-e7ec408a4d5e%22%2C%22jql%22%3A%22project%20in%20(LEARNJIRA)%20ORDER%20BY%20created%20DESC%22%7D%2C%22views%22%3A%5B%7B%22type%22%3A%22table%22%2C%22properties%22%3A%7B%22columns%22%3A%5B%7B%22key%22%3A%22issuetype%22%7D%2C%7B%22key%22%3A%22key%22%7D%2C%7B%22key%22%3A%22summary%22%7D%2C%7B%22key%22%3A%22assignee%22%7D%2C%7B%22key%22%3A%22priority%22%7D%2C%7B%22key%22%3A%22status%22%7D%2C%7B%22key%22%3A%22updated%22%7D%5D%7D%7D%5D%7D-->
220
+
221
+ <!--cf:smartlink:https%3A%2F%2Fknpkv-team.atlassian.net%2Fwiki%2Fsearch%3Ftext%3DGetting%2Bstarted;block;%7B%22id%22%3A%22768fc736-3af4-4a8f-b27e-203602bff8ca%22%2C%22parameters%22%3A%7B%22cloudId%22%3A%2285fe2d49-d86f-4afa-be53-e7ec408a4d5e%22%2C%22searchString%22%3A%22Getting%20started%22%7D%2C%22views%22%3A%5B%7B%22type%22%3A%22table%22%2C%22properties%22%3A%7B%22columns%22%3A%5B%7B%22key%22%3A%22type%22%7D%2C%7B%22key%22%3A%22title%22%7D%2C%7B%22key%22%3A%22space%22%2C%22width%22%3A243%7D%2C%7B%22key%22%3A%22description%22%7D%2C%7B%22key%22%3A%22ownedBy%22%7D%2C%7B%22key%22%3A%22updatedAt%22%7D%5D%7D%7D%5D%7D-->
222
+
223
+ ### Panels
224
+
225
+ :::info
226
+ Info panel
227
+ :::
228
+
229
+ :::note
230
+ Note panel
231
+ :::
232
+
233
+ :::warning
234
+ Error panel
235
+ :::
236
+
237
+ :::panel
238
+ Custom panel
239
+ :::
240
+
241
+ :::tip
242
+ Success panel
243
+ :::
244
+
245
+ :::note
246
+ Warning panel
247
+ :::
248
+
249
+ ### Other
250
+
251
+ Hello 3
252
+
253
+ <!--cf:section-end:2-->
254
+
255
+ <!--cf:layout-end-->
256
+
257
+ <!--cf:raw:PGFjOmxheW91dD48YWM6bGF5b3V0LXNlY3Rpb24gYWM6dHlwZT0iZml4ZWQtd2lkdGgiIGFjOmJyZWFrb3V0LW1vZGU9ImRlZmF1bHQiPjxhYzpsYXlvdXQtY2VsbD48dGFibGU+PHRoZWFkPjx0cj48dGggLz48dGggLz48L3RyPjwvdGhlYWQ+PHRib2R5Pjx0cj48dGQ+T3duZXI8L3RkPjx0ZD48YWM6bGluaz48cmk6dXNlciByaTphY2NvdW50LWlkPSI1NTcwNTg6NzZjMjAxMDAtZTQ1YS00OTVkLTljYjItNGQ3YzgwOWU2YTliIiAvPjwvYWM6bGluaz48L3RkPjwvdHI+PHRyPjx0ZD5PbiB0aGlzIHBhZ2U8L3RkPjx0ZD48YWM6c3RydWN0dXJlZC1tYWNybyBhYzpuYW1lPSJ0b2MiIGFjOnNjaGVtYS12ZXJzaW9uPSIxIiBhYzptYWNyby1pZD0iZDQ1MmJhZDQtNzAwZi00OTczLWFlMDYtNTc0Nzc2YTE0Njg3IiAvPjwvdGQ+PC90cj48L3Rib2R5PjwvdGFibGU+CjxwPk5vcm1hbCB0ZXh0PC9wPgo8aDI+SGVhZGluZ3M8L2gyPgo8aDE+SGVhZGluZyAxPC9oMT4KPGgyPkhlYWRpbmcgMjwvaDI+CjxoMz5IZWFkaW5nIDM8L2gzPgo8aDQ+SGVhZGluZyA0PC9oND4KPGg1PkhlYWRpbmcgNTwvaDU+CjxoNj5IZWFkaW5nIDY8L2g2Pgo8aDI+VGV4dCBGb3JtYXR0aW5nPC9oMj4KPGgzPkJhc2ljIFN0eWxlczwvaDM+CjxwPjxzdHJvbmc+Qm9sZDwvc3Ryb25nPjwvcD4KPHA+PGVtPkl0YWxpYzwvZW0+PC9wPgo8cD48dT5JbmRlcmxpbmU8L3U+PC9wPgo8cD48ZGVsPlN0cmlrZXRocm91Z2g8L2RlbD48L3A+CjxwPjxjb2RlPkNvZGU8L2NvZGU+PC9wPgo8cD48c3ViPlN1YnNjcmlwdDwvc3ViPjwvcD4KPHA+PHN1cD5TdXBlcnNjcmlwdDwvc3VwPjwvcD4KPGgzPlF1b3RlczwvaDM+CjxibG9ja3F1b3RlPjxwPlF1b3RlPC9wPjwvYmxvY2txdW90ZT4KPGgzPkFsaWdubWVudDwvaDM+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij5BbGlnbiBjZW50ZXI8L3A+CjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiByaWdodDsiPkFsaWduIHJpZ2h0PC9wPgo8cD5EZWZhdWx0PC9wPgo8aDI+Q29sb3JzPC9oMj4KPGgzPlRleHQgQ29sb3JzPC9oMz4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMTUxLDE2MCwxNzUpOyI+R3JheTwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDI1NSwyNTUsMjU1KTsiPldoaXRlPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoNyw3MSwxNjYpOyI+Qm9sZCBibHVlPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoNzYsMTU0LDI1NSk7Ij5CbHVlPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMTc5LDIxMiwyNTUpOyI+U3VidGxlIGJsdWU8L3NwYW4+PC9wPgo8cD48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigwLDE0MSwxNjYpOyI+Qm9sZCB0ZWFsPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMCwxODQsMjE3KTsiPlRlYWw8L3NwYW4+PC9wPgo8cD48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigxNzksMjQ1LDI1NSk7Ij5TdWJ0bGUgYmx1ZTwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDAsMTAyLDY4KTsiPkJvbGQgZ3JlZW48L3NwYW4+PC9wPgo8cD48c3BhbiBzdHlsZT0iY29sb3I6IHJnYig1NCwxNzksMTI2KTsiPkdyZWVuPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMTcxLDI0NSwyMDkpOyI+U3VidGxlIGdyZWVuPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMjU1LDE1MywzMSk7Ij5Cb2xkIG9yYW5nZTwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDI1NSwxOTYsMCk7Ij5ZZWxsb3c8L3NwYW4+PC9wPgo8cD48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigyNTUsMjQwLDE3OSk7Ij5TdWJ0bGUgeWVsbG93PC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMTkxLDM4LDApOyI+Qm9sZCByZWQ8L3NwYW4+PC9wPgo8cD48c3BhbiBzdHlsZT0iY29sb3I6IHJnYigyNTUsODYsNDgpOyI+UmVkPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMjU1LDE4OSwxNzMpOyI+U3VidGxlIHJlZDwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDY0LDUwLDE0OCk7Ij5Cb2xkIHB1cnBsZTwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJjb2xvcjogcmdiKDEwMSw4NCwxOTIpOyI+UHVycGxlPC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImNvbG9yOiByZ2IoMjM0LDIzMCwyNTUpOyI+U3VidGxlIHB1cnBsZTwvc3Bhbj48L3A+CjxoMz5IaWdobGlnaHRzPC9oMz4KPHA+PHNwYW4gc3R5bGU9ImJhY2tncm91bmQtY29sb3I6IHJnYigyMjAsMjIzLDIyOCk7Ij5HcmF5IGhpZ2hsaWdodDwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMTk4LDIzNywyNTEpOyI+VGVhbCBoaWdobGlnaHQ8L3NwYW4+PC9wPgo8cD48c3BhbiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjogcmdiKDIxMSwyNDEsMTY3KTsiPkxpbWUgaGlnaGxpZ2h0PC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImJhY2tncm91bmQtY29sb3I6IHJnYigyNTQsMjIyLDIwMCk7Ij5ZZWxsb3cgaGlnaGxpZ2h0PC9zcGFuPjwvcD4KPHA+PHNwYW4gc3R5bGU9ImJhY2tncm91bmQtY29sb3I6IHJnYigyNTMsMjA4LDIzNik7Ij5NYWdlbnRhIGhpZ2hsaWdodDwvc3Bhbj48L3A+CjxwPjxzcGFuIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjIzLDIxNiwyNTMpOyI+UHVycGxlIGhpZ2hsaWdodDwvc3Bhbj48L3A+CjxoMj5MaXN0czwvaDI+CjxoMz5CdWxsZXQgTGlzdHM8L2gzPgo8dWw+PGxpPjxwPkJ1bGxldCBsaXN0IDE8L3A+PHVsIGxvY2FsLWlkPSJiZWQ3NWE1NS1mOGI5LTQ1ZmItOTM0Ni03NTMxZGQ5ZWEzMzgiPjxsaSBsb2NhbC1pZD0iMzA4NTIwNDEtMjUyMS00MGVkLWFjYmItMWE4NDY5YmUzYzMwIj48cCBsb2NhbC1pZD0iNWIwY2NjZGYtM2E4Ny00YjMyLWI2MTgtOTEwYTk0NTI5OTkyIj5CdWxsZXQgbGlzdCAxLjE8L3A+PHVsIGxvY2FsLWlkPSI0NTNkZTQ3OC1hMmQ3LTRiMmYtOWI5My05MTczMjg3N2M5NjAiPjxsaSBsb2NhbC1pZD0iY2MzMmJkMzgtMDkyNy00MmYyLWIyYmMtOGY0ODBlYTk3NzYyIj48cCBsb2NhbC1pZD0iMzA4YmMyY2EtYzliNS00NzM0LWEwZmYtZGVhOGUzMTkxODRkIj5CdWxsZXQgbGlzdCAxLjEuMTwvcD48L2xpPjwvdWw+PC9saT48L3VsPjwvbGk+PGxpPjxwPkJ1bGxldCBsaXN0IDI8L3A+PC9saT48L3VsPgo8aDM+TnVtYmVyZWQgTGlzdHM8L2gzPgo8b2w+PGxpPjxwPk51bWJlcmVkIGxpc3QgMTwvcD48b2wgc3RhcnQ9IjEiIGxvY2FsLWlkPSJkNDBkMDY1MS05NjQ3LTQwMTItYWE0NC0yMmRlYTM2ZGNhMGYiPjxsaSBsb2NhbC1pZD0iMTYzNDA4OTUtMGEwMi00MzY5LWE0ZjItN2ZlM2Y3YzU2MTEyIj48cCBsb2NhbC1pZD0iZDVhZDI2M2QtYWZlMC00Y2EzLTgyOTktOTI5ZmJjMWM3Y2QwIj5OdW1iZXJlZCBsaXN0IGE8L3A+PG9sIHN0YXJ0PSIxIiBsb2NhbC1pZD0iODk3NzcxYzQtMWZmMS00YjcyLTgzMmItYzhkNmNjNzlmNTdiIj48bGkgbG9jYWwtaWQ9IjI1MTIwYTY5LWQ1ZmYtNDFlMC05MTkyLTM1ZTAzNmQ3NTJmMCI+PHAgbG9jYWwtaWQ9IjZiZDM1OTAxLTI4NWYtNGY1OC04NzJmLTUxZTQxNTJlMjk2YiI+TnVtYmVyZWQgbGlzdCBpPC9wPjwvbGk+PC9vbD48L2xpPjwvb2w+PC9saT48bGk+PHA+TnVtYmVyZWQgbGlzdCAyPC9wPjwvbGk+PC9vbD4KPGgzPkluZGVudGF0aW9uPC9oMz4KPHAgc3R5bGU9Im1hcmdpbi1sZWZ0OiAzMC4wcHg7Ij5JbmRlbnQgdGFiIDE8L3A+CjxwIHN0eWxlPSJtYXJnaW4tbGVmdDogNjAuMHB4OyI+SW5kZW50IHRhYiAyPC9wPgo8cCBzdHlsZT0ibWFyZ2luLWxlZnQ6IDkwLjBweDsiPkluZGVudCB0YWIgMzwvcD4KPGgzPkFjdGlvbiBJdGVtczwvaDM+CjxhYzp0YXNrLWxpc3Q+CjxhYzp0YXNrPjxhYzp0YXNrLWlkPjQzPC9hYzp0YXNrLWlkPjxhYzp0YXNrLXV1aWQ+Yjk0ZTUzMzQtNzRkYy00Yjk1LWJkNmYtYTAzMGMxZGY3MDY4PC9hYzp0YXNrLXV1aWQ+PGFjOnRhc2stc3RhdHVzPmluY29tcGxldGU8L2FjOnRhc2stc3RhdHVzPjxhYzp0YXNrLWJvZHk+PHNwYW4gY2xhc3M9InBsYWNlaG9sZGVyLWlubGluZS10YXNrcyI+QWN0aW9uIEl0ZW0gdW5jaGVja2VkPC9zcGFuPjwvYWM6dGFzay1ib2R5PjwvYWM6dGFzaz4KPGFjOnRhc2s+PGFjOnRhc2staWQ+NDQ8L2FjOnRhc2staWQ+PGFjOnRhc2stdXVpZD5mN2YzNDBlMS03MmNmLTQ2NWItYTE3YS00NDA0OGY1M2I0ZjU8L2FjOnRhc2stdXVpZD48YWM6dGFzay1zdGF0dXM+Y29tcGxldGU8L2FjOnRhc2stc3RhdHVzPjxhYzp0YXNrLWJvZHk+PHNwYW4gY2xhc3M9InBsYWNlaG9sZGVyLWlubGluZS10YXNrcyI+QWN0aW9uIGl0ZW0gY2hlY2tlZDwvc3Bhbj48L2FjOnRhc2stYm9keT48L2FjOnRhc2s+CjwvYWM6dGFzay1saXN0Pgo8aDI+TGlua3MgJmFtcDsgTWVkaWE8L2gyPgo8aDM+TGlua3M8L2gzPgo8cD48YSBocmVmPSJodHRwOi8vZXhhbXBsZS5jb20iPkxpbms8L2E+PC9wPgo8aDM+SW1hZ2VzPC9oMz4KPGFjOmltYWdlIGFjOmFsaWduPSJjZW50ZXIiIGFjOndpZHRoPSIyNTAiIGFjOmFsdD0iQXRsYXNzaWFuX0NvbmZsdWVuY2VfMjAxN19sb2dvLnN2ZyI+PHJpOmF0dGFjaG1lbnQgcmk6ZmlsZW5hbWU9IkF0bGFzc2lhbl9Db25mbHVlbmNlXzIwMTdfbG9nby5zdmciIHJpOnZlcnNpb24tYXQtc2F2ZT0iMSIgLz48L2FjOmltYWdlPgo8aDM+VXNlciBNZW50aW9uczwvaDM+CjxwPjxhYzpsaW5rPjxyaTp1c2VyIHJpOmFjY291bnQtaWQ9IjU1NzA1ODo3NmMyMDEwMC1lNDVhLTQ5NWQtOWNiMi00ZDdjODA5ZTZhOWIiIC8+PC9hYzpsaW5rPjwvcD4KPGgzPkVtb3RpY29uczwvaDM+CjxwPjxhYzplbW90aWNvbiBhYzplbW9qaS1zaG9ydG5hbWU9IjpncmlubmluZzoiIGFjOmVtb2ppLWlkPSIxZjYwMCIgYWM6ZW1vamktZmFsbGJhY2s9IvCfmIAiIC8+IDxhYzplbW90aWNvbiBhYzplbW9qaS1zaG9ydG5hbWU9IjpzbWlsZXk6IiBhYzplbW9qaS1pZD0iMWY2MDMiIGFjOmVtb2ppLWZhbGxiYWNrPSLwn5iDIiAvPiA8YWM6ZW1vdGljb24gYWM6ZW1vamktc2hvcnRuYW1lPSI6c21pbGU6IiBhYzplbW9qaS1pZD0iMWY2MDQiIGFjOmVtb2ppLWZhbGxiYWNrPSLwn5iEIiAvPiA8YWM6ZW1vdGljb24gYWM6ZW1vamktc2hvcnRuYW1lPSI6Z3JpbjoiIGFjOmVtb2ppLWlkPSIxZjYwMSIgYWM6ZW1vamktZmFsbGJhY2s9IvCfmIEiIC8+IDxhYzplbW90aWNvbiBhYzplbW9qaS1zaG9ydG5hbWU9IjpsYXVnaGluZzoiIGFjOmVtb2ppLWlkPSIxZjYwNiIgYWM6ZW1vamktZmFsbGJhY2s9IvCfmIYiIC8+IDxhYzplbW90aWNvbiBhYzplbW9qaS1zaG9ydG5hbWU9Ijpzd2VhdF9zbWlsZToiIGFjOmVtb2ppLWlkPSIxZjYwNSIgYWM6ZW1vamktZmFsbGJhY2s9IvCfmIUiIC8+IDxhYzplbW90aWNvbiBhYzplbW9qaS1zaG9ydG5hbWU9Ijpqb3k6IiBhYzplbW9qaS1pZD0iMWY2MDIiIGFjOmVtb2ppLWZhbGxiYWNrPSLwn5iCIiAvPiA8YWM6ZW1vdGljb24gYWM6ZW1vamktc2hvcnRuYW1lPSI6cm9mbDoiIGFjOmVtb2ppLWlkPSIxZjkyMyIgYWM6ZW1vamktZmFsbGJhY2s9IvCfpKMiIC8+PC9wPgo8aDI+VGFibGVzPC9oMj4KPHRhYmxlPjx0aGVhZD48dHI+PHRoPjxzdHJvbmc+SGVhZGVyIDE8L3N0cm9uZz48L3RoPjx0aD48c3Ryb25nPkhlYWRlciAyPC9zdHJvbmc+PC90aD48dGg+PHN0cm9uZz5IZWFkZXIgMzwvc3Ryb25nPjwvdGg+PC90cj48L3RoZWFkPjx0Ym9keT48dHI+PHRkPkNlbGwgMS4xPC90ZD48dGQ+Q2VsbCAyLjE8L3RkPjx0ZD5DZWxsIDMuMTwvdGQ+PC90cj48dHI+PHRkPkNlbGwgMS4yPC90ZD48dGQ+Q2VsbCAyLjI8L3RkPjx0ZD5DZWxsIDMuMjwvdGQ+PC90cj48L3Rib2R5PjwvdGFibGU+PC9hYzpsYXlvdXQtY2VsbD48L2FjOmxheW91dC1zZWN0aW9uPjxhYzpsYXlvdXQtc2VjdGlvbiBhYzp0eXBlPSJ0d29fZXF1YWwiIGFjOmJyZWFrb3V0LW1vZGU9IndpZGUiIGFjOmJyZWFrb3V0LXdpZHRoPSI3NjAiPjxhYzpsYXlvdXQtY2VsbD48cD5Db2x1bW4gMTwvcD48L2FjOmxheW91dC1jZWxsPjxhYzpsYXlvdXQtY2VsbD48cD5Db2x1bW4gMjwvcD48L2FjOmxheW91dC1jZWxsPjwvYWM6bGF5b3V0LXNlY3Rpb24+PGFjOmxheW91dC1zZWN0aW9uIGFjOnR5cGU9ImZpeGVkLXdpZHRoIiBhYzpicmVha291dC1tb2RlPSJkZWZhdWx0Ij48YWM6bGF5b3V0LWNlbGw+PGgzPkNvZGUgQmxvY2tzPC9oMz4KPGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0iY29kZSIgYWM6c2NoZW1hLXZlcnNpb249IjEiIGFjOm1hY3JvLWlkPSI4NGRlN2UwMy1lM2IwLTQ4ODQtYWE3Yi0zNGNiZmNlNmMxYzEiPjxhYzpwYXJhbWV0ZXIgYWM6bmFtZT0ibGFuZ3VhZ2UiPnR5cGVzY3JpcHQ8L2FjOnBhcmFtZXRlcj48YWM6cGxhaW4tdGV4dC1ib2R5PjwhW0NEQVRBW2NvbnN0IHR5cGVzY3JpcHQgPSB7fTtdXT48L2FjOnBsYWluLXRleHQtYm9keT48L2FjOnN0cnVjdHVyZWQtbWFjcm8+CjxhYzpzdHJ1Y3R1cmVkLW1hY3JvIGFjOm5hbWU9ImNvZGUiIGFjOnNjaGVtYS12ZXJzaW9uPSIxIiBhYzptYWNyby1pZD0iMGQ2MGZlNTYtYzkzYy00ZjZiLTk3OWItMzQzMmM3OWRiOWJhIj48YWM6cGFyYW1ldGVyIGFjOm5hbWU9Imxhbmd1YWdlIj5qc29uPC9hYzpwYXJhbWV0ZXI+PGFjOnBsYWluLXRleHQtYm9keT48IVtDREFUQVt7CiAgImpzb24iOiB0cnVlCn1dXT48L2FjOnBsYWluLXRleHQtYm9keT48L2FjOnN0cnVjdHVyZWQtbWFjcm8+CjxoMz5EZWNpc2lvbnM8L2gzPgo8YWM6YWRmLWV4dGVuc2lvbj48YWM6YWRmLW5vZGUgdHlwZT0iZGVjaXNpb24tbGlzdCI+PGFjOmFkZi1ub2RlIHR5cGU9ImRlY2lzaW9uLWl0ZW0iPjxhYzphZGYtYXR0cmlidXRlIGtleT0ibG9jYWwtaWQiPjdjMzAxMmY1LTNhZDMtNDdlMS04OWNjLWNkODcyNjc2NjhkMzwvYWM6YWRmLWF0dHJpYnV0ZT48YWM6YWRmLWF0dHJpYnV0ZSBrZXk9InN0YXRlIj5ERUNJREVEPC9hYzphZGYtYXR0cmlidXRlPjxhYzphZGYtY29udGVudD5EZWNpc2lvbjwvYWM6YWRmLWNvbnRlbnQ+PC9hYzphZGYtbm9kZT48L2FjOmFkZi1ub2RlPjxhYzphZGYtZmFsbGJhY2s+PHVsIGNsYXNzPSJkZWNpc2lvbi1saXN0Ij48bGk+RGVjaXNpb248L2xpPjwvdWw+PC9hYzphZGYtZmFsbGJhY2s+PC9hYzphZGYtZXh0ZW5zaW9uPgo8aHIgLz4KPGgzPkV4cGFuZDwvaDM+CjxhYzpzdHJ1Y3R1cmVkLW1hY3JvIGFjOm5hbWU9ImV4cGFuZCIgYWM6c2NoZW1hLXZlcnNpb249IjEiIGFjOm1hY3JvLWlkPSJhMWM1NmMyZC1kOGExLTRiODMtOGRiYy1jMTI4M2E0MDFjYjgiPjxhYzpwYXJhbWV0ZXIgYWM6bmFtZT0idGl0bGUiPkV4cGFuZCB0aXRsZTwvYWM6cGFyYW1ldGVyPjxhYzpyaWNoLXRleHQtYm9keT48cD5FeHBhbmQgY29udGVudDwvcD48L2FjOnJpY2gtdGV4dC1ib2R5PjwvYWM6c3RydWN0dXJlZC1tYWNybz4KPGgzPkRhdGVzPC9oMz4KPHA+PHRpbWUgZGF0ZXRpbWU9IjIwMjYtMDEtMDEiIC8+PC9wPgo8aDM+U3RhdHVzPC9oMz4KPHA+PGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0ic3RhdHVzIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9ImJhMGE0Mjk3LTlmZjktNGQ0NC1iZjY5LTM0Njk2NjM2MzZmNyI+PGFjOnBhcmFtZXRlciBhYzpuYW1lPSJ0aXRsZSI+R3JheTwvYWM6cGFyYW1ldGVyPjwvYWM6c3RydWN0dXJlZC1tYWNybz4gPGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0ic3RhdHVzIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9ImYyMjBlZTBjLTczNWEtNDYxMy1iYmI2LTY0YjVmOTk1MjQ3MiI+PGFjOnBhcmFtZXRlciBhYzpuYW1lPSJjb2xvdXIiPkJsdWU8L2FjOnBhcmFtZXRlcj48L2FjOnN0cnVjdHVyZWQtbWFjcm8+IDxhYzpzdHJ1Y3R1cmVkLW1hY3JvIGFjOm5hbWU9InN0YXR1cyIgYWM6c2NoZW1hLXZlcnNpb249IjEiIGFjOm1hY3JvLWlkPSI3MTIzNGZkNS01NDQyLTQ1NTctYTZkZS1lZDc2MjkyM2Q5OWQiPjxhYzpwYXJhbWV0ZXIgYWM6bmFtZT0iY29sb3VyIj5HcmVlbjwvYWM6cGFyYW1ldGVyPjwvYWM6c3RydWN0dXJlZC1tYWNybz4gPGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0ic3RhdHVzIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9IjcyYWMzMDA3LTkyNjQtNDY4ZS1iMGYyLTg1ODQ2NWU1ZTljZCI+PGFjOnBhcmFtZXRlciBhYzpuYW1lPSJjb2xvdXIiPlllbGxvdzwvYWM6cGFyYW1ldGVyPjwvYWM6c3RydWN0dXJlZC1tYWNybz4gPGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0ic3RhdHVzIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9IjI3ZmFmYjU5LTQwZDktNDRiOS05NzlhLTdiODIwY2NjMWJhNiI+PGFjOnBhcmFtZXRlciBhYzpuYW1lPSJjb2xvdXIiPlJlZDwvYWM6cGFyYW1ldGVyPjwvYWM6c3RydWN0dXJlZC1tYWNybz4gPGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0ic3RhdHVzIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9ImNjMzc2NDE5LTFhYTAtNGZjMy05Mzc4LTRhOWUwZWZjNWE0ZSI+PGFjOnBhcmFtZXRlciBhYzpuYW1lPSJjb2xvdXIiPlB1cnBsZTwvYWM6cGFyYW1ldGVyPjwvYWM6c3RydWN0dXJlZC1tYWNybz48L3A+CjxoMz5TbWFydCBMaW5rczwvaDM+CjxwPjxhIGhyZWY9Imh0dHBzOi8va25wa3YtdGVhbS5hdGxhc3NpYW4ubmV0L2lzc3Vlcy8/anFsPXByb2plY3QlMjBpbiUyMChMRUFSTkpJUkEpJTIwT1JERVIlMjBCWSUyMGNyZWF0ZWQlMjBERVNDIiBkYXRhLWNhcmQtYXBwZWFyYW5jZT0iYmxvY2siIGRhdGEtZGF0YXNvdXJjZT0ieyZxdW90O2lkJnF1b3Q7OiZxdW90O2Q4Yjc1MzAwLWRmZGEtNDUxOS1iNmNkLWU0OWFiYmQ1MDQwMSZxdW90OywmcXVvdDtwYXJhbWV0ZXJzJnF1b3Q7OnsmcXVvdDtjbG91ZElkJnF1b3Q7OiZxdW90Ozg1ZmUyZDQ5LWQ4NmYtNGFmYS1iZTUzLWU3ZWM0MDhhNGQ1ZSZxdW90OywmcXVvdDtqcWwmcXVvdDs6JnF1b3Q7cHJvamVjdCBpbiAoTEVBUk5KSVJBKSBPUkRFUiBCWSBjcmVhdGVkIERFU0MmcXVvdDt9LCZxdW90O3ZpZXdzJnF1b3Q7Olt7JnF1b3Q7dHlwZSZxdW90OzomcXVvdDt0YWJsZSZxdW90OywmcXVvdDtwcm9wZXJ0aWVzJnF1b3Q7OnsmcXVvdDtjb2x1bW5zJnF1b3Q7Olt7JnF1b3Q7a2V5JnF1b3Q7OiZxdW90O2lzc3VldHlwZSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDtrZXkmcXVvdDt9LHsmcXVvdDtrZXkmcXVvdDs6JnF1b3Q7c3VtbWFyeSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDthc3NpZ25lZSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDtwcmlvcml0eSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDtzdGF0dXMmcXVvdDt9LHsmcXVvdDtrZXkmcXVvdDs6JnF1b3Q7dXBkYXRlZCZxdW90O31dfX1dfSI+aHR0cHM6Ly9rbnBrdi10ZWFtLmF0bGFzc2lhbi5uZXQvaXNzdWVzLz9qcWw9cHJvamVjdCUyMGluJTIwKExFQVJOSklSQSklMjBPUkRFUiUyMEJZJTIwY3JlYXRlZCUyMERFU0M8L2E+PC9wPgo8cD48YSBocmVmPSJodHRwczovL2tucGt2LXRlYW0uYXRsYXNzaWFuLm5ldC93aWtpL3NlYXJjaD90ZXh0PUdldHRpbmcrc3RhcnRlZCIgZGF0YS1jYXJkLWFwcGVhcmFuY2U9ImJsb2NrIiBkYXRhLWRhdGFzb3VyY2U9InsmcXVvdDtpZCZxdW90OzomcXVvdDs3NjhmYzczNi0zYWY0LTRhOGYtYjI3ZS0yMDM2MDJiZmY4Y2EmcXVvdDssJnF1b3Q7cGFyYW1ldGVycyZxdW90Ozp7JnF1b3Q7Y2xvdWRJZCZxdW90OzomcXVvdDs4NWZlMmQ0OS1kODZmLTRhZmEtYmU1My1lN2VjNDA4YTRkNWUmcXVvdDssJnF1b3Q7c2VhcmNoU3RyaW5nJnF1b3Q7OiZxdW90O0dldHRpbmcgc3RhcnRlZCZxdW90O30sJnF1b3Q7dmlld3MmcXVvdDs6W3smcXVvdDt0eXBlJnF1b3Q7OiZxdW90O3RhYmxlJnF1b3Q7LCZxdW90O3Byb3BlcnRpZXMmcXVvdDs6eyZxdW90O2NvbHVtbnMmcXVvdDs6W3smcXVvdDtrZXkmcXVvdDs6JnF1b3Q7dHlwZSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDt0aXRsZSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDtzcGFjZSZxdW90OywmcXVvdDt3aWR0aCZxdW90OzoyNDN9LHsmcXVvdDtrZXkmcXVvdDs6JnF1b3Q7ZGVzY3JpcHRpb24mcXVvdDt9LHsmcXVvdDtrZXkmcXVvdDs6JnF1b3Q7b3duZWRCeSZxdW90O30seyZxdW90O2tleSZxdW90OzomcXVvdDt1cGRhdGVkQXQmcXVvdDt9XX19XX0iPmh0dHBzOi8va25wa3YtdGVhbS5hdGxhc3NpYW4ubmV0L3dpa2kvc2VhcmNoP3RleHQ9R2V0dGluZytzdGFydGVkPC9hPjwvcD4KPGgzPlBhbmVsczwvaDM+CjxhYzpzdHJ1Y3R1cmVkLW1hY3JvIGFjOm5hbWU9ImluZm8iIGFjOnNjaGVtYS12ZXJzaW9uPSIxIiBhYzptYWNyby1pZD0iNWRjY2M3ZjEtZWRlMi00M2U2LTkyNmMtOWMzNmZjNDE0NGNlIj48YWM6cmljaC10ZXh0LWJvZHk+PHA+SW5mbyBwYW5lbDwvcD48L2FjOnJpY2gtdGV4dC1ib2R5PjwvYWM6c3RydWN0dXJlZC1tYWNybz4KPGFjOnN0cnVjdHVyZWQtbWFjcm8gYWM6bmFtZT0ibm90ZSIgYWM6c2NoZW1hLXZlcnNpb249IjEiIGFjOm1hY3JvLWlkPSI1ODg0ZGE5Yi1kNzM4LTQ1YjMtOTgyMS1lOGRjODMyZTY2MDEiPjxhYzpyaWNoLXRleHQtYm9keT48cD5Ob3RlIHBhbmVsPC9wPjwvYWM6cmljaC10ZXh0LWJvZHk+PC9hYzpzdHJ1Y3R1cmVkLW1hY3JvPgo8YWM6c3RydWN0dXJlZC1tYWNybyBhYzpuYW1lPSJ3YXJuaW5nIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9ImMxYzI4MzI5LTIyOGMtNDJiNy04NDU2LWYyNTMwZjU2ZjJjMCI+PGFjOnJpY2gtdGV4dC1ib2R5PjxwPkVycm9yIHBhbmVsPC9wPjwvYWM6cmljaC10ZXh0LWJvZHk+PC9hYzpzdHJ1Y3R1cmVkLW1hY3JvPgo8YWM6c3RydWN0dXJlZC1tYWNybyBhYzpuYW1lPSJwYW5lbCIgYWM6c2NoZW1hLXZlcnNpb249IjEiIGFjOm1hY3JvLWlkPSJmZTQ4OWY2Ny1mZTY5LTRhNTItYmQyNi05Y2MyM2VlYTgxNWMiPjxhYzpyaWNoLXRleHQtYm9keT48cD5DdXN0b20gcGFuZWw8L3A+PC9hYzpyaWNoLXRleHQtYm9keT48L2FjOnN0cnVjdHVyZWQtbWFjcm8+CjxhYzpzdHJ1Y3R1cmVkLW1hY3JvIGFjOm5hbWU9InRpcCIgYWM6c2NoZW1hLXZlcnNpb249IjEiIGFjOm1hY3JvLWlkPSI3N2FkN2RjZS1kNDg5LTQyYTEtOTk1ZC0wYTFkYjNhOWVmODMiPjxhYzpyaWNoLXRleHQtYm9keT48cD5TdWNjZXNzIHBhbmVsPC9wPjwvYWM6cmljaC10ZXh0LWJvZHk+PC9hYzpzdHJ1Y3R1cmVkLW1hY3JvPgo8YWM6c3RydWN0dXJlZC1tYWNybyBhYzpuYW1lPSJub3RlIiBhYzpzY2hlbWEtdmVyc2lvbj0iMSIgYWM6bWFjcm8taWQ9ImU1YzYzNTJlLWNmNmUtNDdjYi1hNDIzLWE5MTI4MzhkY2VjNCI+PGFjOnJpY2gtdGV4dC1ib2R5PjxwPldhcm5pbmcgcGFuZWw8L3A+PC9hYzpyaWNoLXRleHQtYm9keT48L2FjOnN0cnVjdHVyZWQtbWFjcm8+CjxoMz5PdGhlcjwvaDM+CjxwPkhlbGxvIDM8L3A+PC9hYzpsYXlvdXQtY2VsbD48L2FjOmxheW91dC1zZWN0aW9uPjwvYWM6bGF5b3V0Pg==-->