@pbkware/fielded-text-web 0.1.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 (482) hide show
  1. package/dist/api/ft-reader.js +59 -0
  2. package/dist/api/ft-reader.js.map +1 -0
  3. package/dist/api/ft-serialization.js +147 -0
  4. package/dist/api/ft-serialization.js.map +1 -0
  5. package/dist/api/ft-writer-settings.js +31 -0
  6. package/dist/api/ft-writer-settings.js.map +1 -0
  7. package/dist/api/ft-writer.js +22 -0
  8. package/dist/api/ft-writer.js.map +1 -0
  9. package/dist/factory/ft-field-factory.js +86 -0
  10. package/dist/factory/ft-field-factory.js.map +1 -0
  11. package/dist/factory/ft-meta-constructor.js +16 -0
  12. package/dist/factory/ft-meta-constructor.js.map +1 -0
  13. package/dist/factory/ft-meta-factory.js +30 -0
  14. package/dist/factory/ft-meta-factory.js.map +1 -0
  15. package/dist/factory/ft-sequence-constructor.js +11 -0
  16. package/dist/factory/ft-sequence-constructor.js.map +1 -0
  17. package/dist/factory/ft-sequence-factory.js +18 -0
  18. package/dist/factory/ft-sequence-factory.js.map +1 -0
  19. package/dist/factory/ft-sequence-item-constructor.js +11 -0
  20. package/dist/factory/ft-sequence-item-constructor.js.map +1 -0
  21. package/dist/factory/ft-sequence-item-factory.js +18 -0
  22. package/dist/factory/ft-sequence-item-factory.js.map +1 -0
  23. package/dist/factory/ft-sequence-redirect-constructor.js +13 -0
  24. package/dist/factory/ft-sequence-redirect-constructor.js.map +1 -0
  25. package/dist/factory/ft-sequence-redirect-factory.js +176 -0
  26. package/dist/factory/ft-sequence-redirect-factory.js.map +1 -0
  27. package/dist/factory/ft-substitution-constructor.js +23 -0
  28. package/dist/factory/ft-substitution-constructor.js.map +1 -0
  29. package/dist/factory/ft-substitution-factory.js +37 -0
  30. package/dist/factory/ft-substitution-factory.js.map +1 -0
  31. package/dist/fields/definitions/ft-boolean-field-definition.js +36 -0
  32. package/dist/fields/definitions/ft-boolean-field-definition.js.map +1 -0
  33. package/dist/fields/definitions/ft-date-time-field-definition.js +39 -0
  34. package/dist/fields/definitions/ft-date-time-field-definition.js.map +1 -0
  35. package/dist/fields/definitions/ft-decimal-field-definition.js +32 -0
  36. package/dist/fields/definitions/ft-decimal-field-definition.js.map +1 -0
  37. package/dist/fields/definitions/ft-field-definition-list.js +26 -0
  38. package/dist/fields/definitions/ft-field-definition-list.js.map +1 -0
  39. package/dist/fields/definitions/ft-field-definition.js +245 -0
  40. package/dist/fields/definitions/ft-field-definition.js.map +1 -0
  41. package/dist/fields/definitions/ft-float-field-definition.js +32 -0
  42. package/dist/fields/definitions/ft-float-field-definition.js.map +1 -0
  43. package/dist/fields/definitions/ft-generic-field-definition.js +30 -0
  44. package/dist/fields/definitions/ft-generic-field-definition.js.map +1 -0
  45. package/dist/fields/definitions/ft-integer-field-definition.js +33 -0
  46. package/dist/fields/definitions/ft-integer-field-definition.js.map +1 -0
  47. package/dist/fields/definitions/ft-string-field-definition.js +21 -0
  48. package/dist/fields/definitions/ft-string-field-definition.js.map +1 -0
  49. package/dist/fields/instances/ft-boolean-field.js +38 -0
  50. package/dist/fields/instances/ft-boolean-field.js.map +1 -0
  51. package/dist/fields/instances/ft-date-time-field.js +35 -0
  52. package/dist/fields/instances/ft-date-time-field.js.map +1 -0
  53. package/dist/fields/instances/ft-decimal-field.js +35 -0
  54. package/dist/fields/instances/ft-decimal-field.js.map +1 -0
  55. package/dist/fields/instances/ft-field-list.js +56 -0
  56. package/dist/fields/instances/ft-field-list.js.map +1 -0
  57. package/dist/fields/instances/ft-field.js +561 -0
  58. package/dist/fields/instances/ft-field.js.map +1 -0
  59. package/dist/fields/instances/ft-float-field.js +35 -0
  60. package/dist/fields/instances/ft-float-field.js.map +1 -0
  61. package/dist/fields/instances/ft-generic-field.js +173 -0
  62. package/dist/fields/instances/ft-generic-field.js.map +1 -0
  63. package/dist/fields/instances/ft-integer-field.js +35 -0
  64. package/dist/fields/instances/ft-integer-field.js.map +1 -0
  65. package/dist/fields/instances/ft-string-field.js +34 -0
  66. package/dist/fields/instances/ft-string-field.js.map +1 -0
  67. package/dist/index.d.ts +3483 -0
  68. package/dist/index.js +133 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/meta/fields/ft-boolean-meta-field.js +65 -0
  71. package/dist/meta/fields/ft-boolean-meta-field.js.map +1 -0
  72. package/dist/meta/fields/ft-date-time-meta-field.js +55 -0
  73. package/dist/meta/fields/ft-date-time-meta-field.js.map +1 -0
  74. package/dist/meta/fields/ft-decimal-meta-field.js +55 -0
  75. package/dist/meta/fields/ft-decimal-meta-field.js.map +1 -0
  76. package/dist/meta/fields/ft-float-meta-field.js +55 -0
  77. package/dist/meta/fields/ft-float-meta-field.js.map +1 -0
  78. package/dist/meta/fields/ft-generic-meta-field.js +32 -0
  79. package/dist/meta/fields/ft-generic-meta-field.js.map +1 -0
  80. package/dist/meta/fields/ft-integer-meta-field.js +55 -0
  81. package/dist/meta/fields/ft-integer-meta-field.js.map +1 -0
  82. package/dist/meta/fields/ft-meta-field-list.js +183 -0
  83. package/dist/meta/fields/ft-meta-field-list.js.map +1 -0
  84. package/dist/meta/fields/ft-meta-field.js +351 -0
  85. package/dist/meta/fields/ft-meta-field.js.map +1 -0
  86. package/dist/meta/fields/ft-string-meta-field.js +27 -0
  87. package/dist/meta/fields/ft-string-meta-field.js.map +1 -0
  88. package/dist/meta/ft-meta-defaults.js +152 -0
  89. package/dist/meta/ft-meta-defaults.js.map +1 -0
  90. package/dist/meta/ft-meta.js +391 -0
  91. package/dist/meta/ft-meta.js.map +1 -0
  92. package/dist/meta/sequences/core/ft-meta-sequence-item-list.js +82 -0
  93. package/dist/meta/sequences/core/ft-meta-sequence-item-list.js.map +1 -0
  94. package/dist/meta/sequences/core/ft-meta-sequence-item.js +62 -0
  95. package/dist/meta/sequences/core/ft-meta-sequence-item.js.map +1 -0
  96. package/dist/meta/sequences/core/ft-meta-sequence-list.js +164 -0
  97. package/dist/meta/sequences/core/ft-meta-sequence-list.js.map +1 -0
  98. package/dist/meta/sequences/core/ft-meta-sequence.js +96 -0
  99. package/dist/meta/sequences/core/ft-meta-sequence.js.map +1 -0
  100. package/dist/meta/sequences/redirects/ft-boolean-meta-sequence-redirect.js +40 -0
  101. package/dist/meta/sequences/redirects/ft-boolean-meta-sequence-redirect.js.map +1 -0
  102. package/dist/meta/sequences/redirects/ft-case-insensitive-string-meta-sequence-redirect.js +40 -0
  103. package/dist/meta/sequences/redirects/ft-case-insensitive-string-meta-sequence-redirect.js.map +1 -0
  104. package/dist/meta/sequences/redirects/ft-date-meta-sequence-redirect.js +45 -0
  105. package/dist/meta/sequences/redirects/ft-date-meta-sequence-redirect.js.map +1 -0
  106. package/dist/meta/sequences/redirects/ft-exact-date-time-meta-sequence-redirect.js +40 -0
  107. package/dist/meta/sequences/redirects/ft-exact-date-time-meta-sequence-redirect.js.map +1 -0
  108. package/dist/meta/sequences/redirects/ft-exact-decimal-meta-sequence-redirect.js +40 -0
  109. package/dist/meta/sequences/redirects/ft-exact-decimal-meta-sequence-redirect.js.map +1 -0
  110. package/dist/meta/sequences/redirects/ft-exact-float-meta-sequence-redirect.js +40 -0
  111. package/dist/meta/sequences/redirects/ft-exact-float-meta-sequence-redirect.js.map +1 -0
  112. package/dist/meta/sequences/redirects/ft-exact-integer-meta-sequence-redirect.js +40 -0
  113. package/dist/meta/sequences/redirects/ft-exact-integer-meta-sequence-redirect.js.map +1 -0
  114. package/dist/meta/sequences/redirects/ft-exact-string-meta-sequence-redirect.js +40 -0
  115. package/dist/meta/sequences/redirects/ft-exact-string-meta-sequence-redirect.js.map +1 -0
  116. package/dist/meta/sequences/redirects/ft-meta-sequence-redirect-list.js +85 -0
  117. package/dist/meta/sequences/redirects/ft-meta-sequence-redirect-list.js.map +1 -0
  118. package/dist/meta/sequences/redirects/ft-meta-sequence-redirect.js +68 -0
  119. package/dist/meta/sequences/redirects/ft-meta-sequence-redirect.js.map +1 -0
  120. package/dist/meta/sequences/redirects/ft-null-meta-sequence-redirect.js +21 -0
  121. package/dist/meta/sequences/redirects/ft-null-meta-sequence-redirect.js.map +1 -0
  122. package/dist/meta/substitutions/ft-meta-substitution-list.js +51 -0
  123. package/dist/meta/substitutions/ft-meta-substitution-list.js.map +1 -0
  124. package/dist/meta-serialization/format/ft-json-meta-serialization.js +283 -0
  125. package/dist/meta-serialization/format/ft-json-meta-serialization.js.map +1 -0
  126. package/dist/meta-serialization/format/ft-xml-meta-serialization.js +706 -0
  127. package/dist/meta-serialization/format/ft-xml-meta-serialization.js.map +1 -0
  128. package/dist/meta-serialization/format/meta-serializer-options.js +12 -0
  129. package/dist/meta-serialization/format/meta-serializer-options.js.map +1 -0
  130. package/dist/meta-serialization/ft-meta-serialization.js +59 -0
  131. package/dist/meta-serialization/ft-meta-serialization.js.map +1 -0
  132. package/dist/meta-serialization/styles/ft-boolean-styles-meta-serialization.js +83 -0
  133. package/dist/meta-serialization/styles/ft-boolean-styles-meta-serialization.js.map +1 -0
  134. package/dist/meta-serialization/styles/ft-date-time-styles-meta-serialization.js +54 -0
  135. package/dist/meta-serialization/styles/ft-date-time-styles-meta-serialization.js.map +1 -0
  136. package/dist/meta-serialization/styles/ft-number-styles-meta-serialization.js +199 -0
  137. package/dist/meta-serialization/styles/ft-number-styles-meta-serialization.js.map +1 -0
  138. package/dist/meta-serialization/types/boolean-meta-serialization.js +39 -0
  139. package/dist/meta-serialization/types/boolean-meta-serialization.js.map +1 -0
  140. package/dist/meta-serialization/types/char-meta-serialization.js +32 -0
  141. package/dist/meta-serialization/types/char-meta-serialization.js.map +1 -0
  142. package/dist/meta-serialization/types/date-time-meta-serialization.js +227 -0
  143. package/dist/meta-serialization/types/date-time-meta-serialization.js.map +1 -0
  144. package/dist/meta-serialization/types/decimal-meta-serialization.js +12 -0
  145. package/dist/meta-serialization/types/decimal-meta-serialization.js.map +1 -0
  146. package/dist/meta-serialization/types/enums/data-type-meta-serialisation.js +55 -0
  147. package/dist/meta-serialization/types/enums/data-type-meta-serialisation.js.map +1 -0
  148. package/dist/meta-serialization/types/enums/end-of-line-auto-write-type-meta-serialization.js +50 -0
  149. package/dist/meta-serialization/types/enums/end-of-line-auto-write-type-meta-serialization.js.map +1 -0
  150. package/dist/meta-serialization/types/enums/end-of-line-type-meta-serialization.js +49 -0
  151. package/dist/meta-serialization/types/enums/end-of-line-type-meta-serialization.js.map +1 -0
  152. package/dist/meta-serialization/types/enums/heading-constraint-meta-serialization.js +55 -0
  153. package/dist/meta-serialization/types/enums/heading-constraint-meta-serialization.js.map +1 -0
  154. package/dist/meta-serialization/types/enums/last-line-ended-type-meta-serialization.js +48 -0
  155. package/dist/meta-serialization/types/enums/last-line-ended-type-meta-serialization.js.map +1 -0
  156. package/dist/meta-serialization/types/enums/pad-alignment-meta-serialization.js +52 -0
  157. package/dist/meta-serialization/types/enums/pad-alignment-meta-serialization.js.map +1 -0
  158. package/dist/meta-serialization/types/enums/pad-char-type-meta-serialization.js +52 -0
  159. package/dist/meta-serialization/types/enums/pad-char-type-meta-serialization.js.map +1 -0
  160. package/dist/meta-serialization/types/enums/quoted-type-meta-serialization.js +52 -0
  161. package/dist/meta-serialization/types/enums/quoted-type-meta-serialization.js.map +1 -0
  162. package/dist/meta-serialization/types/enums/sequence-invokation-delay-meta-serialization.js +47 -0
  163. package/dist/meta-serialization/types/enums/sequence-invokation-delay-meta-serialization.js.map +1 -0
  164. package/dist/meta-serialization/types/enums/sequence-redirect-type-meta-serialisation.js +88 -0
  165. package/dist/meta-serialization/types/enums/sequence-redirect-type-meta-serialisation.js.map +1 -0
  166. package/dist/meta-serialization/types/enums/substitution-type-meta-serialization.js +47 -0
  167. package/dist/meta-serialization/types/enums/substitution-type-meta-serialization.js.map +1 -0
  168. package/dist/meta-serialization/types/enums/truncate-type-meta-serialization.js +56 -0
  169. package/dist/meta-serialization/types/enums/truncate-type-meta-serialization.js.map +1 -0
  170. package/dist/meta-serialization/types/float-meta-serialization.js +99 -0
  171. package/dist/meta-serialization/types/float-meta-serialization.js.map +1 -0
  172. package/dist/meta-serialization/types/integer-float-meta-serialization.js +52 -0
  173. package/dist/meta-serialization/types/integer-float-meta-serialization.js.map +1 -0
  174. package/dist/meta-serialization/types/integer-meta-serialization.js +50 -0
  175. package/dist/meta-serialization/types/integer-meta-serialization.js.map +1 -0
  176. package/dist/meta-serialization/types/string-meta-serialization.js +35 -0
  177. package/dist/meta-serialization/types/string-meta-serialization.js.map +1 -0
  178. package/dist/meta-serialization/utils/implicit-explicit-index-sorter.js +57 -0
  179. package/dist/meta-serialization/utils/implicit-explicit-index-sorter.js.map +1 -0
  180. package/dist/meta-serialization/utils/meta-serialization-redirect-sequence-resolver.js +33 -0
  181. package/dist/meta-serialization/utils/meta-serialization-redirect-sequence-resolver.js.map +1 -0
  182. package/dist/meta-serialization/utils/meta-serialization-sequence-name-resolver.js +67 -0
  183. package/dist/meta-serialization/utils/meta-serialization-sequence-name-resolver.js.map +1 -0
  184. package/dist/meta-serialization/utils/sequence-item-field-indices.js +70 -0
  185. package/dist/meta-serialization/utils/sequence-item-field-indices.js.map +1 -0
  186. package/dist/sequences/core/ft-sequence-invokation-list.js +91 -0
  187. package/dist/sequences/core/ft-sequence-invokation-list.js.map +1 -0
  188. package/dist/sequences/core/ft-sequence-invokation.js +143 -0
  189. package/dist/sequences/core/ft-sequence-invokation.js.map +1 -0
  190. package/dist/sequences/core/ft-sequence-item-list.js +34 -0
  191. package/dist/sequences/core/ft-sequence-item-list.js.map +1 -0
  192. package/dist/sequences/core/ft-sequence-item.js +46 -0
  193. package/dist/sequences/core/ft-sequence-item.js.map +1 -0
  194. package/dist/sequences/core/ft-sequence-list.js +62 -0
  195. package/dist/sequences/core/ft-sequence-list.js.map +1 -0
  196. package/dist/sequences/core/ft-sequence.js +59 -0
  197. package/dist/sequences/core/ft-sequence.js.map +1 -0
  198. package/dist/sequences/redirects/ft-boolean-sequence-redirect.js +33 -0
  199. package/dist/sequences/redirects/ft-boolean-sequence-redirect.js.map +1 -0
  200. package/dist/sequences/redirects/ft-case-insensitive-string-sequence-redirect.js +33 -0
  201. package/dist/sequences/redirects/ft-case-insensitive-string-sequence-redirect.js.map +1 -0
  202. package/dist/sequences/redirects/ft-date-sequence-redirect.js +37 -0
  203. package/dist/sequences/redirects/ft-date-sequence-redirect.js.map +1 -0
  204. package/dist/sequences/redirects/ft-exact-date-time-sequence-redirect.js +33 -0
  205. package/dist/sequences/redirects/ft-exact-date-time-sequence-redirect.js.map +1 -0
  206. package/dist/sequences/redirects/ft-exact-decimal-sequence-redirect.js +33 -0
  207. package/dist/sequences/redirects/ft-exact-decimal-sequence-redirect.js.map +1 -0
  208. package/dist/sequences/redirects/ft-exact-float-sequence-redirect.js +33 -0
  209. package/dist/sequences/redirects/ft-exact-float-sequence-redirect.js.map +1 -0
  210. package/dist/sequences/redirects/ft-exact-integer-sequence-redirect.js +33 -0
  211. package/dist/sequences/redirects/ft-exact-integer-sequence-redirect.js.map +1 -0
  212. package/dist/sequences/redirects/ft-exact-string-sequence-redirect.js +33 -0
  213. package/dist/sequences/redirects/ft-exact-string-sequence-redirect.js.map +1 -0
  214. package/dist/sequences/redirects/ft-null-sequence-redirect.js +20 -0
  215. package/dist/sequences/redirects/ft-null-sequence-redirect.js.map +1 -0
  216. package/dist/sequences/redirects/ft-sequence-redirect-list.js +35 -0
  217. package/dist/sequences/redirects/ft-sequence-redirect-list.js.map +1 -0
  218. package/dist/sequences/redirects/ft-sequence-redirect.js +47 -0
  219. package/dist/sequences/redirects/ft-sequence-redirect.js.map +1 -0
  220. package/dist/serialization/char-reader.js +178 -0
  221. package/dist/serialization/char-reader.js.map +1 -0
  222. package/dist/serialization/declaration-parser.js +176 -0
  223. package/dist/serialization/declaration-parser.js.map +1 -0
  224. package/dist/serialization/delimited-field-parser.js +278 -0
  225. package/dist/serialization/delimited-field-parser.js.map +1 -0
  226. package/dist/serialization/embedded-meta-parser.js +129 -0
  227. package/dist/serialization/embedded-meta-parser.js.map +1 -0
  228. package/dist/serialization/fixed-width-field-parser.js +196 -0
  229. package/dist/serialization/fixed-width-field-parser.js.map +1 -0
  230. package/dist/serialization/formatting/ft-boolean-field-formatter.js +113 -0
  231. package/dist/serialization/formatting/ft-boolean-field-formatter.js.map +1 -0
  232. package/dist/serialization/formatting/ft-date-time-field-formatter.js +54 -0
  233. package/dist/serialization/formatting/ft-date-time-field-formatter.js.map +1 -0
  234. package/dist/serialization/formatting/ft-decimal-field-formatter.js +46 -0
  235. package/dist/serialization/formatting/ft-decimal-field-formatter.js.map +1 -0
  236. package/dist/serialization/formatting/ft-declared-parameters-formatter.js +52 -0
  237. package/dist/serialization/formatting/ft-declared-parameters-formatter.js.map +1 -0
  238. package/dist/serialization/formatting/ft-field-formatter.js +15 -0
  239. package/dist/serialization/formatting/ft-field-formatter.js.map +1 -0
  240. package/dist/serialization/formatting/ft-float-field-formatter.js +46 -0
  241. package/dist/serialization/formatting/ft-float-field-formatter.js.map +1 -0
  242. package/dist/serialization/formatting/ft-integer-field-formatter.js +47 -0
  243. package/dist/serialization/formatting/ft-integer-field-formatter.js.map +1 -0
  244. package/dist/serialization/formatting/ft-string-field-formatter.js +14 -0
  245. package/dist/serialization/formatting/ft-string-field-formatter.js.map +1 -0
  246. package/dist/serialization/ft-declared-parameters.js +199 -0
  247. package/dist/serialization/ft-declared-parameters.js.map +1 -0
  248. package/dist/serialization/ft-serialization-reader.js +865 -0
  249. package/dist/serialization/ft-serialization-reader.js.map +1 -0
  250. package/dist/serialization/ft-serialization-writer.js +633 -0
  251. package/dist/serialization/ft-serialization-writer.js.map +1 -0
  252. package/dist/serialization/ft-text-reader.js +48 -0
  253. package/dist/serialization/ft-text-reader.js.map +1 -0
  254. package/dist/serialization/ft-text-writer.js +46 -0
  255. package/dist/serialization/ft-text-writer.js.map +1 -0
  256. package/dist/serialization/heading-line-record-parser.js +253 -0
  257. package/dist/serialization/heading-line-record-parser.js.map +1 -0
  258. package/dist/serialization/line-parser.js +205 -0
  259. package/dist/serialization/line-parser.js.map +1 -0
  260. package/dist/serialization/serialization-core.js +551 -0
  261. package/dist/serialization/serialization-core.js.map +1 -0
  262. package/dist/substitutions/ft-substitution-list.js +54 -0
  263. package/dist/substitutions/ft-substitution-list.js.map +1 -0
  264. package/dist/tsdoc-metadata.json +11 -0
  265. package/dist/types/enums/ft-boolean-styles.js +12 -0
  266. package/dist/types/enums/ft-boolean-styles.js.map +1 -0
  267. package/dist/types/enums/ft-data-type.js +12 -0
  268. package/dist/types/enums/ft-data-type.js.map +1 -0
  269. package/dist/types/enums/ft-end-of-line-auto-write-type.js +10 -0
  270. package/dist/types/enums/ft-end-of-line-auto-write-type.js.map +1 -0
  271. package/dist/types/enums/ft-end-of-line-type.js +9 -0
  272. package/dist/types/enums/ft-end-of-line-type.js.map +1 -0
  273. package/dist/types/enums/ft-heading-constraint.js +11 -0
  274. package/dist/types/enums/ft-heading-constraint.js.map +1 -0
  275. package/dist/types/enums/ft-last-line-ended-type.js +9 -0
  276. package/dist/types/enums/ft-last-line-ended-type.js.map +1 -0
  277. package/dist/types/enums/ft-line-type.js +13 -0
  278. package/dist/types/enums/ft-line-type.js.map +1 -0
  279. package/dist/types/enums/ft-meta-element-type.js +12 -0
  280. package/dist/types/enums/ft-meta-element-type.js.map +1 -0
  281. package/dist/types/enums/ft-meta-reference-type.js +10 -0
  282. package/dist/types/enums/ft-meta-reference-type.js.map +1 -0
  283. package/dist/types/enums/ft-meta-serialization-format.js +15 -0
  284. package/dist/types/enums/ft-meta-serialization-format.js.map +1 -0
  285. package/dist/types/enums/ft-pad-alignment.js +9 -0
  286. package/dist/types/enums/ft-pad-alignment.js.map +1 -0
  287. package/dist/types/enums/ft-pad-char-type.js +9 -0
  288. package/dist/types/enums/ft-pad-char-type.js.map +1 -0
  289. package/dist/types/enums/ft-quoted-type.js +9 -0
  290. package/dist/types/enums/ft-quoted-type.js.map +1 -0
  291. package/dist/types/enums/ft-read-record-result.js +9 -0
  292. package/dist/types/enums/ft-read-record-result.js.map +1 -0
  293. package/dist/types/enums/ft-sequence-invokation-delay.js +8 -0
  294. package/dist/types/enums/ft-sequence-invokation-delay.js.map +1 -0
  295. package/dist/types/enums/ft-sequence-redirect-type.js +15 -0
  296. package/dist/types/enums/ft-sequence-redirect-type.js.map +1 -0
  297. package/dist/types/enums/ft-substitution-type.js +12 -0
  298. package/dist/types/enums/ft-substitution-type.js.map +1 -0
  299. package/dist/types/enums/ft-truncate-type.js +11 -0
  300. package/dist/types/enums/ft-truncate-type.js.map +1 -0
  301. package/dist/types/errors/ft-internal-error.js +14 -0
  302. package/dist/types/errors/ft-internal-error.js.map +1 -0
  303. package/dist/types/errors/ft-serialization-error.js +49 -0
  304. package/dist/types/errors/ft-serialization-error.js.map +1 -0
  305. package/dist/types/errors/ft-serialization-exception.js +78 -0
  306. package/dist/types/errors/ft-serialization-exception.js.map +1 -0
  307. package/dist/types/events/ft-field-heading-ready-event-args.js +2 -0
  308. package/dist/types/events/ft-field-heading-ready-event-args.js.map +1 -0
  309. package/dist/types/events/ft-field-value-ready-event-args.js +2 -0
  310. package/dist/types/events/ft-field-value-ready-event-args.js.map +1 -0
  311. package/dist/types/events/ft-heading-line-finished-event-args.js +2 -0
  312. package/dist/types/events/ft-heading-line-finished-event-args.js.map +1 -0
  313. package/dist/types/events/ft-heading-line-started-event-args.js +2 -0
  314. package/dist/types/events/ft-heading-line-started-event-args.js.map +1 -0
  315. package/dist/types/events/ft-record-finished-event-args.js +2 -0
  316. package/dist/types/events/ft-record-finished-event-args.js.map +1 -0
  317. package/dist/types/events/ft-record-started-event-args.js +2 -0
  318. package/dist/types/events/ft-record-started-event-args.js.map +1 -0
  319. package/dist/types/events/ft-sequence-redirected-event-args.js +2 -0
  320. package/dist/types/events/ft-sequence-redirected-event-args.js.map +1 -0
  321. package/package.json +84 -0
  322. package/src/api/ft-reader.ts +106 -0
  323. package/src/api/ft-serialization.ts +216 -0
  324. package/src/api/ft-writer-settings.ts +76 -0
  325. package/src/api/ft-writer.ts +26 -0
  326. package/src/factory/ft-field-factory.ts +94 -0
  327. package/src/factory/ft-meta-constructor.ts +16 -0
  328. package/src/factory/ft-meta-factory.ts +34 -0
  329. package/src/factory/ft-sequence-constructor.ts +11 -0
  330. package/src/factory/ft-sequence-factory.ts +22 -0
  331. package/src/factory/ft-sequence-item-constructor.ts +11 -0
  332. package/src/factory/ft-sequence-item-factory.ts +22 -0
  333. package/src/factory/ft-sequence-redirect-constructor.ts +19 -0
  334. package/src/factory/ft-sequence-redirect-factory.ts +197 -0
  335. package/src/factory/ft-substitution-constructor.ts +24 -0
  336. package/src/factory/ft-substitution-factory.ts +43 -0
  337. package/src/fields/definitions/ft-boolean-field-definition.ts +49 -0
  338. package/src/fields/definitions/ft-date-time-field-definition.ts +52 -0
  339. package/src/fields/definitions/ft-decimal-field-definition.ts +43 -0
  340. package/src/fields/definitions/ft-field-definition-list.ts +33 -0
  341. package/src/fields/definitions/ft-field-definition.ts +276 -0
  342. package/src/fields/definitions/ft-float-field-definition.ts +43 -0
  343. package/src/fields/definitions/ft-generic-field-definition.ts +49 -0
  344. package/src/fields/definitions/ft-integer-field-definition.ts +44 -0
  345. package/src/fields/definitions/ft-string-field-definition.ts +26 -0
  346. package/src/fields/instances/ft-boolean-field.ts +49 -0
  347. package/src/fields/instances/ft-date-time-field.ts +44 -0
  348. package/src/fields/instances/ft-decimal-field.ts +44 -0
  349. package/src/fields/instances/ft-field-list.ts +68 -0
  350. package/src/fields/instances/ft-field.ts +691 -0
  351. package/src/fields/instances/ft-float-field.ts +44 -0
  352. package/src/fields/instances/ft-generic-field.ts +219 -0
  353. package/src/fields/instances/ft-integer-field.ts +44 -0
  354. package/src/fields/instances/ft-string-field.ts +40 -0
  355. package/src/index.ts +185 -0
  356. package/src/meta/fields/ft-boolean-meta-field.ts +79 -0
  357. package/src/meta/fields/ft-date-time-meta-field.ts +68 -0
  358. package/src/meta/fields/ft-decimal-meta-field.ts +68 -0
  359. package/src/meta/fields/ft-float-meta-field.ts +68 -0
  360. package/src/meta/fields/ft-generic-meta-field.ts +38 -0
  361. package/src/meta/fields/ft-integer-meta-field.ts +68 -0
  362. package/src/meta/fields/ft-meta-field-list.ts +208 -0
  363. package/src/meta/fields/ft-meta-field.ts +399 -0
  364. package/src/meta/fields/ft-string-meta-field.ts +34 -0
  365. package/src/meta/ft-meta-defaults.ts +151 -0
  366. package/src/meta/ft-meta.ts +453 -0
  367. package/src/meta/sequences/core/ft-meta-sequence-item-list.ts +97 -0
  368. package/src/meta/sequences/core/ft-meta-sequence-item.ts +78 -0
  369. package/src/meta/sequences/core/ft-meta-sequence-list.ts +203 -0
  370. package/src/meta/sequences/core/ft-meta-sequence.ts +127 -0
  371. package/src/meta/sequences/redirects/ft-boolean-meta-sequence-redirect.ts +49 -0
  372. package/src/meta/sequences/redirects/ft-case-insensitive-string-meta-sequence-redirect.ts +49 -0
  373. package/src/meta/sequences/redirects/ft-date-meta-sequence-redirect.ts +54 -0
  374. package/src/meta/sequences/redirects/ft-exact-date-time-meta-sequence-redirect.ts +49 -0
  375. package/src/meta/sequences/redirects/ft-exact-decimal-meta-sequence-redirect.ts +49 -0
  376. package/src/meta/sequences/redirects/ft-exact-float-meta-sequence-redirect.ts +49 -0
  377. package/src/meta/sequences/redirects/ft-exact-integer-meta-sequence-redirect.ts +49 -0
  378. package/src/meta/sequences/redirects/ft-exact-string-meta-sequence-redirect.ts +49 -0
  379. package/src/meta/sequences/redirects/ft-meta-sequence-redirect-list.ts +99 -0
  380. package/src/meta/sequences/redirects/ft-meta-sequence-redirect.ts +89 -0
  381. package/src/meta/sequences/redirects/ft-null-meta-sequence-redirect.ts +25 -0
  382. package/src/meta/substitutions/ft-meta-substitution-list.ts +54 -0
  383. package/src/meta-serialization/format/ft-json-meta-serialization.ts +288 -0
  384. package/src/meta-serialization/format/ft-xml-meta-serialization.ts +885 -0
  385. package/src/meta-serialization/format/meta-serializer-options.ts +21 -0
  386. package/src/meta-serialization/ft-meta-serialization.ts +60 -0
  387. package/src/meta-serialization/styles/ft-boolean-styles-meta-serialization.ts +88 -0
  388. package/src/meta-serialization/styles/ft-date-time-styles-meta-serialization.ts +50 -0
  389. package/src/meta-serialization/styles/ft-number-styles-meta-serialization.ts +212 -0
  390. package/src/meta-serialization/types/boolean-meta-serialization.ts +36 -0
  391. package/src/meta-serialization/types/char-meta-serialization.ts +28 -0
  392. package/src/meta-serialization/types/date-time-meta-serialization.ts +220 -0
  393. package/src/meta-serialization/types/decimal-meta-serialization.ts +13 -0
  394. package/src/meta-serialization/types/enums/data-type-meta-serialisation.ts +52 -0
  395. package/src/meta-serialization/types/enums/end-of-line-auto-write-type-meta-serialization.ts +47 -0
  396. package/src/meta-serialization/types/enums/end-of-line-type-meta-serialization.ts +46 -0
  397. package/src/meta-serialization/types/enums/heading-constraint-meta-serialization.ts +52 -0
  398. package/src/meta-serialization/types/enums/last-line-ended-type-meta-serialization.ts +45 -0
  399. package/src/meta-serialization/types/enums/meta-element-type-meta-serialization.ts +36 -0
  400. package/src/meta-serialization/types/enums/pad-alignment-meta-serialization.ts +54 -0
  401. package/src/meta-serialization/types/enums/pad-char-type-meta-serialization.ts +54 -0
  402. package/src/meta-serialization/types/enums/quoted-type-meta-serialization.ts +54 -0
  403. package/src/meta-serialization/types/enums/sequence-invokation-delay-meta-serialization.ts +44 -0
  404. package/src/meta-serialization/types/enums/sequence-redirect-type-meta-serialisation.ts +86 -0
  405. package/src/meta-serialization/types/enums/substitution-type-meta-serialization.ts +44 -0
  406. package/src/meta-serialization/types/enums/truncate-type-meta-serialization.ts +58 -0
  407. package/src/meta-serialization/types/float-meta-serialization.ts +96 -0
  408. package/src/meta-serialization/types/integer-float-meta-serialization.ts +46 -0
  409. package/src/meta-serialization/types/integer-meta-serialization.ts +44 -0
  410. package/src/meta-serialization/types/string-meta-serialization.ts +32 -0
  411. package/src/meta-serialization/utils/implicit-explicit-index-sorter.ts +61 -0
  412. package/src/meta-serialization/utils/meta-serialization-redirect-sequence-resolver.ts +43 -0
  413. package/src/meta-serialization/utils/meta-serialization-sequence-name-resolver.ts +85 -0
  414. package/src/meta-serialization/utils/sequence-item-field-indices.ts +76 -0
  415. package/src/sequences/core/ft-sequence-invokation-list.ts +109 -0
  416. package/src/sequences/core/ft-sequence-invokation.ts +166 -0
  417. package/src/sequences/core/ft-sequence-item-list.ts +40 -0
  418. package/src/sequences/core/ft-sequence-item.ts +59 -0
  419. package/src/sequences/core/ft-sequence-list.ts +73 -0
  420. package/src/sequences/core/ft-sequence.ts +75 -0
  421. package/src/sequences/redirects/ft-boolean-sequence-redirect.ts +42 -0
  422. package/src/sequences/redirects/ft-case-insensitive-string-sequence-redirect.ts +46 -0
  423. package/src/sequences/redirects/ft-date-sequence-redirect.ts +48 -0
  424. package/src/sequences/redirects/ft-exact-date-time-sequence-redirect.ts +46 -0
  425. package/src/sequences/redirects/ft-exact-decimal-sequence-redirect.ts +46 -0
  426. package/src/sequences/redirects/ft-exact-float-sequence-redirect.ts +46 -0
  427. package/src/sequences/redirects/ft-exact-integer-sequence-redirect.ts +46 -0
  428. package/src/sequences/redirects/ft-exact-string-sequence-redirect.ts +46 -0
  429. package/src/sequences/redirects/ft-null-sequence-redirect.ts +27 -0
  430. package/src/sequences/redirects/ft-sequence-redirect-list.ts +42 -0
  431. package/src/sequences/redirects/ft-sequence-redirect.ts +68 -0
  432. package/src/serialization/char-reader.ts +203 -0
  433. package/src/serialization/declaration-parser.ts +203 -0
  434. package/src/serialization/delimited-field-parser.ts +296 -0
  435. package/src/serialization/embedded-meta-parser.ts +147 -0
  436. package/src/serialization/fixed-width-field-parser.ts +220 -0
  437. package/src/serialization/formatting/ft-boolean-field-formatter.ts +114 -0
  438. package/src/serialization/formatting/ft-date-time-field-formatter.ts +61 -0
  439. package/src/serialization/formatting/ft-decimal-field-formatter.ts +52 -0
  440. package/src/serialization/formatting/ft-declared-parameters-formatter.ts +60 -0
  441. package/src/serialization/formatting/ft-field-formatter.ts +18 -0
  442. package/src/serialization/formatting/ft-float-field-formatter.ts +52 -0
  443. package/src/serialization/formatting/ft-integer-field-formatter.ts +53 -0
  444. package/src/serialization/formatting/ft-string-field-formatter.ts +15 -0
  445. package/src/serialization/formatting/index.ts +7 -0
  446. package/src/serialization/ft-declared-parameters.ts +232 -0
  447. package/src/serialization/ft-serialization-reader.ts +953 -0
  448. package/src/serialization/ft-serialization-writer.ts +760 -0
  449. package/src/serialization/ft-text-reader.ts +64 -0
  450. package/src/serialization/ft-text-writer.ts +61 -0
  451. package/src/serialization/heading-line-record-parser.ts +285 -0
  452. package/src/serialization/line-parser.ts +231 -0
  453. package/src/serialization/serialization-core.ts +632 -0
  454. package/src/substitutions/ft-substitution-list.ts +60 -0
  455. package/src/types/enums/ft-boolean-styles.ts +17 -0
  456. package/src/types/enums/ft-data-type.ts +21 -0
  457. package/src/types/enums/ft-end-of-line-auto-write-type.ts +14 -0
  458. package/src/types/enums/ft-end-of-line-type.ts +13 -0
  459. package/src/types/enums/ft-heading-constraint.ts +15 -0
  460. package/src/types/enums/ft-last-line-ended-type.ts +13 -0
  461. package/src/types/enums/ft-line-type.ts +17 -0
  462. package/src/types/enums/ft-meta-element-type.ts +16 -0
  463. package/src/types/enums/ft-meta-reference-type.ts +14 -0
  464. package/src/types/enums/ft-meta-serialization-format.ts +19 -0
  465. package/src/types/enums/ft-pad-alignment.ts +13 -0
  466. package/src/types/enums/ft-pad-char-type.ts +13 -0
  467. package/src/types/enums/ft-quoted-type.ts +13 -0
  468. package/src/types/enums/ft-read-record-result.ts +13 -0
  469. package/src/types/enums/ft-sequence-invokation-delay.ts +12 -0
  470. package/src/types/enums/ft-sequence-redirect-type.ts +19 -0
  471. package/src/types/enums/ft-substitution-type.ts +16 -0
  472. package/src/types/enums/ft-truncate-type.ts +15 -0
  473. package/src/types/errors/ft-internal-error.ts +15 -0
  474. package/src/types/errors/ft-serialization-error.ts +53 -0
  475. package/src/types/errors/ft-serialization-exception.ts +86 -0
  476. package/src/types/events/ft-field-heading-ready-event-args.ts +9 -0
  477. package/src/types/events/ft-field-value-ready-event-args.ts +9 -0
  478. package/src/types/events/ft-heading-line-finished-event-args.ts +6 -0
  479. package/src/types/events/ft-heading-line-started-event-args.ts +6 -0
  480. package/src/types/events/ft-record-finished-event-args.ts +6 -0
  481. package/src/types/events/ft-record-started-event-args.ts +6 -0
  482. package/src/types/events/ft-sequence-redirected-event-args.ts +9 -0
@@ -0,0 +1,885 @@
1
+ import { CommaText } from '@pbkware/js-utils';
2
+ import XMLBuilder from 'fast-xml-builder';
3
+ import { XMLParser } from 'fast-xml-parser';
4
+ import { FtFieldFactory } from '../../factory/ft-field-factory.js';
5
+ import { FtBooleanMetaField } from '../../meta/fields/ft-boolean-meta-field.js';
6
+ import { FtDateTimeMetaField } from '../../meta/fields/ft-date-time-meta-field.js';
7
+ import { FtDecimalMetaField } from '../../meta/fields/ft-decimal-meta-field.js';
8
+ import { FtFloatMetaField } from '../../meta/fields/ft-float-meta-field.js';
9
+ import { FtIntegerMetaField } from '../../meta/fields/ft-integer-meta-field.js';
10
+ import { FtMetaFieldList } from '../../meta/fields/ft-meta-field-list.js';
11
+ import { FtMetaField } from '../../meta/fields/ft-meta-field.js';
12
+ import { FtStringMetaField } from '../../meta/fields/ft-string-meta-field.js';
13
+ import { FtMetaDefaults } from '../../meta/ft-meta-defaults.js';
14
+ import { FtMeta } from '../../meta/ft-meta.js';
15
+ import { FtMetaSequenceItem } from '../../meta/sequences/core/ft-meta-sequence-item.js';
16
+ import { FtMetaSequence } from '../../meta/sequences/core/ft-meta-sequence.js';
17
+ import { FtBooleanMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-boolean-meta-sequence-redirect.js';
18
+ import { FtCaseInsensitiveStringMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-case-insensitive-string-meta-sequence-redirect.js';
19
+ import { FtDateMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-date-meta-sequence-redirect.js';
20
+ import { FtExactDateTimeMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-exact-date-time-meta-sequence-redirect.js';
21
+ import { FtExactDecimalMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-exact-decimal-meta-sequence-redirect.js';
22
+ import { FtExactFloatMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-exact-float-meta-sequence-redirect.js';
23
+ import { FtExactIntegerMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-exact-integer-meta-sequence-redirect.js';
24
+ import { FtExactStringMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-exact-string-meta-sequence-redirect.js';
25
+ import { FtMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-meta-sequence-redirect.js';
26
+ import { FtNullMetaSequenceRedirect } from '../../meta/sequences/redirects/ft-null-meta-sequence-redirect.js';
27
+ import { FtMetaSubstitution } from '../../meta/substitutions/ft-meta-substitution-list.js';
28
+ import { FtDataType } from '../../types/enums/ft-data-type.js';
29
+ import { FtSequenceRedirectType } from '../../types/enums/ft-sequence-redirect-type.js';
30
+ import { FtAssertError, FtUnreachableCaseError } from '../../types/errors/ft-internal-error.js';
31
+ import { FtBooleanStylesMetaSerialization } from '../styles/ft-boolean-styles-meta-serialization.js';
32
+ import { FtDateTimeStylesMetaSerialization } from '../styles/ft-date-time-styles-meta-serialization.js';
33
+ import { FtNumberStylesMetaSerialization } from '../styles/ft-number-styles-meta-serialization.js';
34
+ import { BooleanMetaSerialization } from '../types/boolean-meta-serialization.js';
35
+ import { CharMetaSerialization } from '../types/char-meta-serialization.js';
36
+ import { DateTimeMetaSerialization } from '../types/date-time-meta-serialization.js';
37
+ import { DecimalMetaSerialization } from '../types/decimal-meta-serialization.js';
38
+ import { DataTypeMetaSerialization } from '../types/enums/data-type-meta-serialisation.js';
39
+ import { EndOfLineAutoWriteTypeMetaSerialization } from '../types/enums/end-of-line-auto-write-type-meta-serialization.js';
40
+ import { EndOfLineTypeMetaSerialization } from '../types/enums/end-of-line-type-meta-serialization.js';
41
+ import { HeadingConstraintMetaSerialization } from '../types/enums/heading-constraint-meta-serialization.js';
42
+ import { LastLineEndedTypeMetaSerialization } from '../types/enums/last-line-ended-type-meta-serialization.js';
43
+ import { PadAlignmentMetaSerialization } from '../types/enums/pad-alignment-meta-serialization.js';
44
+ import { PadCharTypeMetaSerialization } from '../types/enums/pad-char-type-meta-serialization.js';
45
+ import { QuotedTypeMetaSerialization } from '../types/enums/quoted-type-meta-serialization.js';
46
+ import { SequenceInvokationDelayMetaSerialization } from '../types/enums/sequence-invokation-delay-meta-serialization.js';
47
+ import { SequenceRedirectTypeMetaSerialization } from '../types/enums/sequence-redirect-type-meta-serialisation.js';
48
+ import { SubstitutionTypeMetaSerialization } from '../types/enums/substitution-type-meta-serialization.js';
49
+ import { TruncateTypeMetaSerialization } from '../types/enums/truncate-type-meta-serialization.js';
50
+ import { FloatMetaSerialization } from '../types/float-meta-serialization.js';
51
+ import { IntegerFloatMetaSerialization } from '../types/integer-float-meta-serialization.js';
52
+ import { IntegerMetaSerialization } from '../types/integer-meta-serialization.js';
53
+ import { StringMetaSerialization } from '../types/string-meta-serialization.js';
54
+ import { ImplicitExplicitIndexSortRec } from '../utils/implicit-explicit-index-sorter.js';
55
+ import { MetaSerializationRedirectSequenceResolver } from '../utils/meta-serialization-redirect-sequence-resolver.js';
56
+ import { MetaSerializationSequenceNameResolver } from '../utils/meta-serialization-sequence-name-resolver.js';
57
+ import { SequenceItemFieldIndexSerialization } from '../utils/sequence-item-field-indices.js';
58
+ import { FtMetaSerializerOptions } from './meta-serializer-options.js';
59
+
60
+ /**
61
+ * Serializes and deserializes FtMeta to/from XML format.
62
+ * Compatible with the C# XmlMetaSerializationWriter/Reader implementation.
63
+ *
64
+ * Note: The "\@_" prefix is used by fast-xml-parser to distinguish XML attributes
65
+ * from XML elements. Properties starting with "\@_" become XML attributes when
66
+ * serialized, and XML attributes are prefixed with "\@_" when deserialized.
67
+ * @public
68
+ */
69
+ export class FtXmlMetaSerialization {
70
+ /**
71
+ * Serialize an FtMeta object to XML string.
72
+ */
73
+ serialize(meta: FtMeta, options?: FtMetaSerializerOptions): string {
74
+ const explicitIndices = options?.explicitIndices ?? FtMetaSerializerOptions.DEFAULT_EXPLICIT_INDICES;
75
+
76
+ const rootObj: Record<'FieldedText', Record<string, unknown>> = {
77
+ FieldedText: {
78
+ '@_Culture': StringMetaSerialization.serialize(meta.culture.name, FtMetaDefaults.Root.CultureName),
79
+ '@_DelimiterChar': CharMetaSerialization.serialize(meta.delimiterChar, FtMetaDefaults.Root.DelimiterChar),
80
+ '@_QuoteChar': CharMetaSerialization.serialize(meta.quoteChar, FtMetaDefaults.Root.QuoteChar),
81
+ '@_LineCommentChar': CharMetaSerialization.serialize(meta.lineCommentChar, FtMetaDefaults.Root.LineCommentChar),
82
+ '@_EndOfLineType': EndOfLineTypeMetaSerialization.serialize(meta.endOfLineType),
83
+ '@_EndOfLineChar': CharMetaSerialization.serialize(meta.endOfLineChar, FtMetaDefaults.Root.EndOfLineChar),
84
+ '@_EndOfLineAutoWriteType': EndOfLineAutoWriteTypeMetaSerialization.serialize(meta.endOfLineAutoWriteType),
85
+ '@_LastLineEndedType': LastLineEndedTypeMetaSerialization.serialize(meta.lastLineEndedType),
86
+ '@_AllowEndOfLineCharInQuotes': BooleanMetaSerialization.serialize(
87
+ meta.allowEndOfLineCharInQuotes,
88
+ FtMetaDefaults.Root.AllowEndOfLineCharInQuotes,
89
+ ),
90
+ '@_IgnoreBlankLines': BooleanMetaSerialization.serialize(meta.ignoreBlankLines, FtMetaDefaults.Root.IgnoreBlankLines),
91
+ '@_IgnoreExtraChars': BooleanMetaSerialization.serialize(meta.ignoreExtraChars, FtMetaDefaults.Root.IgnoreExtraChars),
92
+ '@_AllowIncompleteRecords': BooleanMetaSerialization.serialize(meta.allowIncompleteRecords, FtMetaDefaults.Root.AllowIncompleteRecords),
93
+ '@_StuffedEmbeddedQuotes': BooleanMetaSerialization.serialize(meta.stuffedEmbeddedQuotes, FtMetaDefaults.Root.StuffedEmbeddedQuotes),
94
+ '@_SubstitutionChar': CharMetaSerialization.serialize(meta.substitutionChar, FtMetaDefaults.Root.SubstitutionChar),
95
+ '@_HeadingLineCount': IntegerFloatMetaSerialization.serialize(meta.headingLineCount, false, FtMetaDefaults.Root.HeadingLineCount),
96
+ '@_MainHeadingLineIndex': IntegerFloatMetaSerialization.serialize(meta.mainHeadingLineIndex, false, FtMetaDefaults.Root.MainHeadingLineIndex),
97
+ '@_HeadingConstraint': HeadingConstraintMetaSerialization.serialize(meta.headingConstraint, undefined),
98
+ '@_HeadingQuotedType': QuotedTypeMetaSerialization.serialize(meta.headingQuotedType, true, undefined),
99
+ '@_HeadingAlwaysWriteOptionalQuote': BooleanMetaSerialization.serialize(
100
+ meta.headingAlwaysWriteOptionalQuote,
101
+ FtMetaDefaults.Root.HeadingAlwaysWriteOptionalQuote,
102
+ ),
103
+ '@_HeadingWritePrefixSpace': BooleanMetaSerialization.serialize(meta.headingWritePrefixSpace, FtMetaDefaults.Root.HeadingWritePrefixSpace),
104
+ '@_HeadingPadAlignment': PadAlignmentMetaSerialization.serialize(meta.headingPadAlignment, true, undefined),
105
+ '@_HeadingPadCharType': PadCharTypeMetaSerialization.serialize(meta.headingPadCharType, true, undefined),
106
+ '@_HeadingPadChar': CharMetaSerialization.serialize(meta.headingPadChar, FtMetaDefaults.Root.HeadingPadChar),
107
+ '@_HeadingTruncateType': TruncateTypeMetaSerialization.serialize(meta.headingTruncateType, true, undefined),
108
+ '@_HeadingTruncateChar': CharMetaSerialization.serialize(meta.headingTruncateChar, FtMetaDefaults.Root.HeadingTruncateChar),
109
+ '@_HeadingEndOfValueChar': CharMetaSerialization.serialize(meta.headingEndOfValueChar, FtMetaDefaults.Root.HeadingEndOfValueChar),
110
+ },
111
+ };
112
+
113
+ // Add substitutions
114
+ const substitutionList = meta.substitutionList;
115
+ const substitutionCount = substitutionList.count;
116
+ if (substitutionCount > 0) {
117
+ const substitutionObjs = new Array<Record<string, unknown>>(substitutionCount);
118
+ for (let i = 0; i < substitutionCount; i++) {
119
+ const sub = substitutionList.get(i);
120
+ substitutionObjs[i] = this.serializeSubstitution(sub);
121
+ }
122
+ rootObj.FieldedText.Substitution = substitutionObjs;
123
+ }
124
+
125
+ const metaFieldList = meta.fieldList;
126
+ const metaFieldCount = metaFieldList.count;
127
+
128
+ // Add fields
129
+ if (metaFieldCount > 0) {
130
+ const fieldObjs = new Array<Record<string, unknown>>(metaFieldCount);
131
+ for (let i = 0; i < metaFieldCount; i++) {
132
+ const field = metaFieldList.get(i);
133
+ const index = explicitIndices ? i : undefined;
134
+ fieldObjs[i] = this.serializeField(field, index, meta);
135
+ }
136
+ rootObj.FieldedText.Field = fieldObjs;
137
+ }
138
+
139
+ // Add sequences
140
+ const metaSequenceList = meta.sequenceList;
141
+ const metaSequenceCount = metaSequenceList.count;
142
+ if (metaSequenceCount > 0) {
143
+ const seqObjs = new Array<Record<string, unknown>>(metaSequenceCount);
144
+
145
+ for (let i = 0; i < metaSequenceCount; i++) {
146
+ const seq = metaSequenceList.get(i);
147
+ seqObjs[i] = this.serializeSequence(explicitIndices, seq, metaFieldList);
148
+ }
149
+ rootObj.FieldedText.Sequence = seqObjs;
150
+ }
151
+
152
+ const indent = options?.indent ?? FtMetaSerializerOptions.DEFAULT_INDENT;
153
+ const indentChars = options?.indentChars ?? FtMetaSerializerOptions.DEFAULT_INDENT_CHARS;
154
+ // Note: fast-xml-parser doesn't support newLineOnAttributes, so we ignore it
155
+
156
+ const builder = new XMLBuilder({
157
+ attributeNamePrefix: '@_',
158
+ ignoreAttributes: false,
159
+ format: indent,
160
+ indentBy: indentChars,
161
+ suppressEmptyNode: false,
162
+ suppressBooleanAttributes: false,
163
+ });
164
+
165
+ const xmlContent = builder.build(rootObj);
166
+ return '<?xml version="1.0" encoding="utf-8"?>\n' + xmlContent;
167
+ }
168
+
169
+ /**
170
+ * Deserialize XML string to an FtMeta object.
171
+ */
172
+ deserialize(xml: string, warnings?: string[]): FtMeta {
173
+ const parser = new XMLParser({
174
+ attributeNamePrefix: '@_',
175
+ ignoreAttributes: false,
176
+ parseAttributeValue: false, // Keep as strings for proper type handling
177
+ isArray: (name, jpath, isLeafNode, isAttribute) => {
178
+ // These elements can appear multiple times
179
+ return name === 'Substitution' || name === 'Field' || name === 'Sequence' || name === 'Item' || name === 'Heading';
180
+ },
181
+ });
182
+
183
+ if (warnings === undefined) {
184
+ warnings = new Array<string>();
185
+ }
186
+ const result = parser.parse(xml);
187
+ const meta = new FtMeta();
188
+
189
+ const ftObj = result.FieldedText;
190
+ if (!ftObj) {
191
+ throw new Error('Invalid XML: Missing FieldedText root element');
192
+ }
193
+
194
+ // Deserialize root properties
195
+ this.deserializeRootProperties(meta, ftObj, warnings);
196
+
197
+ // Deserialize substitutions
198
+ if (ftObj.Substitution) {
199
+ const subs = Array.isArray(ftObj.Substitution) ? ftObj.Substitution : [ftObj.Substitution];
200
+ for (const subObj of subs) {
201
+ const type = SubstitutionTypeMetaSerialization.deserialize(subObj['@_Type'], warnings);
202
+ const token = StringMetaSerialization.tryDeserialize(subObj['@_Token'], warnings);
203
+ const value = StringMetaSerialization.tryDeserialize(subObj['@_Value'], warnings);
204
+ if (token === undefined || value === undefined) {
205
+ warnings.push(`Substitution: Missing required attributes. Token: ${token}, Value: ${value}`);
206
+ continue; // Skip this substitution if required attributes are missing
207
+ } else {
208
+ meta.substitutionList.new(type, token, value);
209
+ }
210
+ }
211
+ }
212
+
213
+ // Deserialize fields
214
+ if (ftObj.Field) {
215
+ const headingLineCount = meta.headingLineCount;
216
+ const fieldObjs = Array.isArray(ftObj.Field) ? ftObj.Field : [ftObj.Field];
217
+ const fieldCount = fieldObjs.length;
218
+ const fieldSortRecs = new Array<ImplicitExplicitIndexSortRec<FtMetaField>>(fieldCount);
219
+ for (let i = 0; i < fieldCount; i++) {
220
+ const fieldSortRec = this.deserializeField(fieldObjs[i], headingLineCount, meta, warnings);
221
+ fieldSortRec.implicitIndex = i;
222
+ fieldSortRecs[i] = fieldSortRec;
223
+ }
224
+ fieldSortRecs.sort((left, right) => ImplicitExplicitIndexSortRec.compare(left, right));
225
+ ImplicitExplicitIndexSortRec.checkSortedArray(fieldSortRecs, 'Field', warnings);
226
+ meta.fieldList.set(fieldSortRecs.map((rec) => rec.target));
227
+ }
228
+
229
+ const resolvedOrderedFieldList = meta.fieldList; // Field orders are resolved so can be used to resolve field references in sequences
230
+
231
+ // Deserialize sequences
232
+ const objSequence = ftObj.Sequence;
233
+ if (objSequence) {
234
+ const objSequences = Array.isArray(objSequence) ? objSequence : [objSequence];
235
+ const sequenceCount = objSequences.length;
236
+ const sequenceNameResolver = new MetaSerializationSequenceNameResolver();
237
+ const redirectSequenceResolver = new MetaSerializationRedirectSequenceResolver(sequenceNameResolver);
238
+
239
+ const redirectNames = new Array<MetaSerializationRedirectSequenceResolver.Rec>(sequenceCount); // We need to collect redirect names first before we can resolve them, so we create records with redirect names and resolve after deserializing all sequences
240
+ const sequenceNameRecs = new Array<MetaSerializationSequenceNameResolver.Rec>(sequenceCount);
241
+
242
+ for (let i = 0; i < sequenceCount; i++) {
243
+ const seqObj = objSequences[i];
244
+ const sequenceNameRec = this.deserializeSequence(seqObj, resolvedOrderedFieldList, redirectSequenceResolver, warnings);
245
+ sequenceNameResolver.add(sequenceNameRec);
246
+ }
247
+
248
+ redirectSequenceResolver.resolve(warnings);
249
+ const sequences = sequenceNameResolver.resolve(warnings);
250
+ meta.sequenceList.set(sequences);
251
+ }
252
+
253
+ return meta;
254
+ }
255
+
256
+ private serializeSubstitution(sub: FtMetaSubstitution): Record<string, unknown> {
257
+ return {
258
+ '@_Token': StringMetaSerialization.serialize(sub.token),
259
+ '@_Type': SubstitutionTypeMetaSerialization.serialize(sub.type),
260
+ '@_Value': StringMetaSerialization.serialize(sub.value),
261
+ };
262
+ }
263
+
264
+ private serializeField(field: FtMetaField, index: number | undefined, meta: FtMeta): Record<string, unknown> {
265
+ const fieldId = field.id;
266
+ const fieldHeadings = field.headings;
267
+ const obj: Record<string, unknown> = {
268
+ '@_DataType': DataTypeMetaSerialization.serialize(field.dataType),
269
+ '@_Index': index === undefined ? undefined : IntegerFloatMetaSerialization.serialize(index, false),
270
+ '@_Id': fieldId === undefined ? undefined : IntegerFloatMetaSerialization.serialize(fieldId, true, FtMetaDefaults.Field.Id),
271
+ '@_Name': StringMetaSerialization.serialize(field.name, FtMetaDefaults.Field.Name),
272
+ '@_FixedWidth': BooleanMetaSerialization.serialize(field.fixedWidth, FtMetaDefaults.Field.FixedWidth),
273
+ '@_Width': IntegerFloatMetaSerialization.serialize(field.width, false, FtMetaDefaults.Field.Width),
274
+ '@_Constant': BooleanMetaSerialization.serialize(field.constant, FtMetaDefaults.Field.Constant),
275
+ '@_Null': BooleanMetaSerialization.serialize(field.null, FtMetaDefaults.Field.Null),
276
+ '@_ValueQuotedType': QuotedTypeMetaSerialization.serialize(field.valueQuotedType, false, undefined),
277
+ '@_ValueAlwaysWriteOptionalQuote': BooleanMetaSerialization.serialize(field.valueAlwaysWriteOptionalQuote, false),
278
+ '@_ValueWritePrefixSpace': BooleanMetaSerialization.serialize(field.valueWritePrefixSpace, false),
279
+ '@_ValuePadAlignment': PadAlignmentMetaSerialization.serialize(field.valuePadAlignment, false, undefined),
280
+ '@_ValuePadCharType': PadCharTypeMetaSerialization.serialize(field.valuePadCharType, false, undefined),
281
+ '@_ValuePadChar': CharMetaSerialization.serialize(field.valuePadChar, FtMetaDefaults.Field.ValuePadChar),
282
+ '@_ValueTruncateType': TruncateTypeMetaSerialization.serialize(field.valueTruncateType, false, undefined),
283
+ '@_ValueTruncateChar': CharMetaSerialization.serialize(field.valueTruncateChar, FtMetaDefaults.Field.ValueTruncateChar),
284
+ '@_ValueEndOfValueChar': CharMetaSerialization.serialize(field.valueEndOfValueChar, FtMetaDefaults.Field.ValueEndOfValueChar),
285
+ '@_ValueNullChar': CharMetaSerialization.serialize(field.valueNullChar, FtMetaDefaults.Field.ValueNullChar),
286
+ '@_HeadingConstraint': HeadingConstraintMetaSerialization.serialize(field.headingConstraint, meta.headingConstraint),
287
+ '@_HeadingQuotedType': QuotedTypeMetaSerialization.serialize(field.headingQuotedType, true, meta.headingQuotedType),
288
+ '@_HeadingAlwaysWriteOptionalQuote': BooleanMetaSerialization.serialize(
289
+ field.headingAlwaysWriteOptionalQuote,
290
+ meta.headingAlwaysWriteOptionalQuote,
291
+ ),
292
+ '@_HeadingWritePrefixSpace': BooleanMetaSerialization.serialize(field.headingWritePrefixSpace, meta.headingWritePrefixSpace),
293
+ '@_HeadingPadAlignment': PadAlignmentMetaSerialization.serialize(field.headingPadAlignment, true, meta.headingPadAlignment),
294
+ '@_HeadingPadCharType': PadCharTypeMetaSerialization.serialize(field.headingPadCharType, true, meta.headingPadCharType),
295
+ '@_HeadingPadChar': CharMetaSerialization.serialize(field.headingPadChar, meta.headingPadChar),
296
+ '@_HeadingTruncateType': TruncateTypeMetaSerialization.serialize(field.headingTruncateType, true, meta.headingTruncateType),
297
+ '@_HeadingTruncateChar': CharMetaSerialization.serialize(field.headingTruncateChar, meta.headingTruncateChar),
298
+ '@_HeadingEndOfValueChar': CharMetaSerialization.serialize(field.headingEndOfValueChar, meta.headingEndOfValueChar),
299
+ '@_Headings': fieldHeadings.length === 0 ? undefined : StringMetaSerialization.serialize(CommaText.fromStringArray(fieldHeadings)),
300
+ };
301
+
302
+ // Type-specific properties
303
+ const fieldDataType = field.dataType;
304
+ const valueSerializable = field.constant && !field.null;
305
+ switch (fieldDataType) {
306
+ case FtDataType.String: {
307
+ const stringField = field as FtStringMetaField;
308
+ if (valueSerializable) {
309
+ obj['@_Value'] = StringMetaSerialization.serialize(stringField.value, FtStringMetaField.DEFAULT_VALUE);
310
+ }
311
+ break;
312
+ }
313
+ case FtDataType.Boolean: {
314
+ const booleanField = field as FtBooleanMetaField;
315
+ obj['@_Styles'] = FtBooleanStylesMetaSerialization.serialize(booleanField.styles);
316
+ obj['@_TrueText'] = StringMetaSerialization.serialize(booleanField.trueText, FtBooleanMetaField.DEFAULT_TRUE_TEXT);
317
+ obj['@_FalseText'] = StringMetaSerialization.serialize(booleanField.falseText, FtBooleanMetaField.DEFAULT_FALSE_TEXT);
318
+ if (valueSerializable) {
319
+ obj['@_Value'] = BooleanMetaSerialization.serialize(booleanField.value, FtBooleanMetaField.DEFAULT_VALUE);
320
+ }
321
+ break;
322
+ }
323
+ case FtDataType.Integer: {
324
+ const integerField = field as FtIntegerMetaField;
325
+ obj['@_Format'] = StringMetaSerialization.serialize(integerField.format, FtIntegerMetaField.DEFAULT_FORMAT);
326
+ obj['@_Styles'] = FtNumberStylesMetaSerialization.serialize(integerField.styles, fieldDataType);
327
+ if (valueSerializable) {
328
+ obj['@_Value'] = IntegerMetaSerialization.serialize(integerField.value, FtIntegerMetaField.DEFAULT_VALUE);
329
+ }
330
+ break;
331
+ }
332
+ case FtDataType.Float: {
333
+ const floatField = field as FtFloatMetaField;
334
+ obj['@_Format'] = StringMetaSerialization.serialize(floatField.format, FtFloatMetaField.DEFAULT_FORMAT);
335
+ obj['@_Styles'] = FtNumberStylesMetaSerialization.serialize(floatField.styles, fieldDataType);
336
+ if (valueSerializable) {
337
+ obj['@_Value'] = FloatMetaSerialization.serialize(floatField.value, FtFloatMetaField.DEFAULT_VALUE);
338
+ }
339
+ break;
340
+ }
341
+ case FtDataType.Decimal: {
342
+ const decimalField = field as FtDecimalMetaField;
343
+ obj['@_Format'] = StringMetaSerialization.serialize(decimalField.format, FtDecimalMetaField.DEFAULT_FORMAT);
344
+ obj['@_Styles'] = FtNumberStylesMetaSerialization.serialize(decimalField.styles, fieldDataType);
345
+ if (valueSerializable) {
346
+ obj['@_Value'] = DecimalMetaSerialization.serialize(decimalField.value, FtDecimalMetaField.DEFAULT_VALUE);
347
+ }
348
+ break;
349
+ }
350
+ case FtDataType.DateTime: {
351
+ const dateTimeField = field as FtDateTimeMetaField;
352
+ obj['@_Format'] = StringMetaSerialization.serialize(dateTimeField.format, FtDateTimeMetaField.DEFAULT_FORMAT);
353
+ obj['@_Styles'] = FtDateTimeStylesMetaSerialization.serialize(dateTimeField.styles);
354
+ if (valueSerializable) {
355
+ obj['@_Value'] = DateTimeMetaSerialization.serialize(dateTimeField.value, FtDateTimeMetaField.DEFAULT_VALUE);
356
+ }
357
+ break;
358
+ }
359
+ }
360
+
361
+ return obj;
362
+ }
363
+
364
+ private serializeSequence(explicitIndices: boolean, seq: FtMetaSequence, metaFieldList: FtMetaFieldList) {
365
+ // If explicitIndices is true, we can optimise serialization by including by specifying items using Meta field indices up until an item has redirects.
366
+ const { commaTextFieldIndices, count: fieldIndicesCount } = explicitIndices
367
+ ? SequenceItemFieldIndexSerialization.serializeUpToRedirect(seq, metaFieldList)
368
+ : { commaTextFieldIndices: undefined, count: 0 };
369
+ const seqObj: Record<string, unknown> = {
370
+ '@_Name': StringMetaSerialization.serialize(seq.name),
371
+ '@_Root': BooleanMetaSerialization.serialize(seq.root, FtMetaDefaults.Sequence.Root),
372
+ '@_FieldIndices': commaTextFieldIndices,
373
+ };
374
+
375
+ const seqItemList = seq.itemList;
376
+ const seqItemCount = seqItemList.count;
377
+ if (fieldIndicesCount < seqItemCount) {
378
+ // Add sequence items not included in field indices as separate elements
379
+ const itemObjs = new Array<Record<string, unknown>>(seqItemCount - fieldIndicesCount);
380
+ for (let i = fieldIndicesCount; i < seqItemCount; i++) {
381
+ const item = seqItemList.get(i);
382
+ const explicityItemIndex = explicitIndices ? i : undefined;
383
+ itemObjs[i - fieldIndicesCount] = this.serializeSequenceItem(item, explicityItemIndex, metaFieldList);
384
+ }
385
+ seqObj.Item = itemObjs;
386
+ }
387
+ return seqObj;
388
+ }
389
+
390
+ private serializeSequenceItem(item: FtMetaSequenceItem, explicityItemIndex: number | undefined, metaFieldList: FtMetaFieldList) {
391
+ const field = item.field;
392
+ const itemObj: Record<string, unknown> = {
393
+ '@_Index': explicityItemIndex == undefined ? undefined : IntegerFloatMetaSerialization.serialize(explicityItemIndex, false),
394
+ '@_FieldIndex': SequenceItemFieldIndexSerialization.serializeField(field, metaFieldList),
395
+ };
396
+
397
+ const redirectList = item.redirectList;
398
+ const redirectCount = redirectList.count;
399
+ if (redirectCount > 0) {
400
+ const redirectObjs = new Array<Record<string, unknown>>(redirectCount);
401
+ for (let i = 0; i < redirectCount; i++) {
402
+ const redirect = redirectList.get(i);
403
+ const explicitRedirectIndex = explicityItemIndex === undefined ? undefined : i; // explicitRedirectIndex is defined when explicitIndices is true
404
+ redirectObjs[i] = this.serializeRedirect(redirect, explicitRedirectIndex, field.dataType);
405
+ }
406
+ itemObj.Redirect = redirectObjs;
407
+ }
408
+ return itemObj;
409
+ }
410
+
411
+ private serializeRedirect(redirect: FtMetaSequenceRedirect, explicityRedirectIndex: number | undefined, fieldDataType: FtDataType) {
412
+ const sequence = redirect.sequence;
413
+ if (sequence === undefined) {
414
+ throw new FtAssertError('XMSSR99312', 'Redirect sequence is undefined');
415
+ } else {
416
+ const redirectType = redirect.type;
417
+ const redirectObj: Record<string, unknown> = {
418
+ '@_Index': explicityRedirectIndex == undefined ? undefined : IntegerFloatMetaSerialization.serialize(explicityRedirectIndex, false),
419
+ '@_SequenceName': StringMetaSerialization.serialize(sequence.name),
420
+ '@_Type': SequenceRedirectTypeMetaSerialization.serialize(redirectType, fieldDataType),
421
+ '@_InvokationDelay': SequenceInvokationDelayMetaSerialization.serialize(redirect.invokationDelay),
422
+ };
423
+
424
+ let value: unknown;
425
+ switch (redirectType) {
426
+ case FtSequenceRedirectType.Null:
427
+ value = undefined; // Null redirects don't have a value
428
+ break;
429
+ case FtSequenceRedirectType.ExactString:
430
+ value = StringMetaSerialization.serialize(
431
+ (redirect as FtExactStringMetaSequenceRedirect).value,
432
+ FtExactStringMetaSequenceRedirect.DEFAULT_VALUE,
433
+ );
434
+ break;
435
+ case FtSequenceRedirectType.CaseInsensitiveString:
436
+ value = StringMetaSerialization.serialize(
437
+ (redirect as FtCaseInsensitiveStringMetaSequenceRedirect).value,
438
+ FtCaseInsensitiveStringMetaSequenceRedirect.DEFAULT_VALUE,
439
+ );
440
+ break;
441
+ case FtSequenceRedirectType.Boolean:
442
+ value = BooleanMetaSerialization.serialize((redirect as FtBooleanMetaSequenceRedirect).value, FtBooleanMetaSequenceRedirect.DEFAULT_VALUE);
443
+ break;
444
+ case FtSequenceRedirectType.ExactInteger:
445
+ value = IntegerMetaSerialization.serialize(
446
+ (redirect as FtExactIntegerMetaSequenceRedirect).value,
447
+ FtExactIntegerMetaSequenceRedirect.DEFAULT_VALUE,
448
+ );
449
+ break;
450
+ case FtSequenceRedirectType.ExactFloat:
451
+ value = FloatMetaSerialization.serialize(
452
+ (redirect as FtExactFloatMetaSequenceRedirect).value,
453
+ FtExactFloatMetaSequenceRedirect.DEFAULT_VALUE,
454
+ );
455
+ break;
456
+ case FtSequenceRedirectType.ExactDateTime:
457
+ value = DateTimeMetaSerialization.serialize(
458
+ (redirect as FtExactDateTimeMetaSequenceRedirect).value,
459
+ FtExactDateTimeMetaSequenceRedirect.DEFAULT_VALUE,
460
+ );
461
+ break;
462
+ case FtSequenceRedirectType.Date:
463
+ value = DateTimeMetaSerialization.serialize((redirect as FtDateMetaSequenceRedirect).value, FtDateMetaSequenceRedirect.DEFAULT_VALUE);
464
+ break;
465
+ case FtSequenceRedirectType.ExactDecimal:
466
+ value = DecimalMetaSerialization.serialize(
467
+ (redirect as FtExactDecimalMetaSequenceRedirect).value,
468
+ FtExactDecimalMetaSequenceRedirect.DEFAULT_VALUE,
469
+ );
470
+ break;
471
+ default:
472
+ throw new FtUnreachableCaseError('XMSSR99313', redirectType);
473
+ }
474
+
475
+ redirectObj['@_Value'] = value;
476
+
477
+ return redirectObj;
478
+ }
479
+ }
480
+
481
+ private deserializeRootProperties(meta: FtMeta, obj: Record<string, unknown>, warnings: string[]): void {
482
+ // Basic properties
483
+ meta.delimiterChar = CharMetaSerialization.deserialize(obj['@_DelimiterChar'], FtMetaDefaults.Root.DelimiterChar, warnings);
484
+ meta.quoteChar = CharMetaSerialization.deserialize(obj['@_QuoteChar'], FtMetaDefaults.Root.QuoteChar, warnings);
485
+ meta.lineCommentChar = CharMetaSerialization.deserialize(obj['@_LineCommentChar'], FtMetaDefaults.Root.LineCommentChar, warnings);
486
+ meta.endOfLineChar = CharMetaSerialization.deserialize(obj['@_EndOfLineChar'], FtMetaDefaults.Root.EndOfLineChar, warnings);
487
+ meta.substitutionChar = CharMetaSerialization.deserialize(obj['@_SubstitutionChar'], FtMetaDefaults.Root.SubstitutionChar, warnings);
488
+ meta.headingPadChar = CharMetaSerialization.deserialize(obj['@_HeadingPadChar'], FtMetaDefaults.Root.HeadingPadChar, warnings);
489
+ meta.headingTruncateChar = CharMetaSerialization.deserialize(obj['@_HeadingTruncateChar'], FtMetaDefaults.Root.HeadingTruncateChar, warnings);
490
+ meta.headingEndOfValueChar = CharMetaSerialization.deserialize(
491
+ obj['@_HeadingEndOfValueChar'],
492
+ FtMetaDefaults.Root.HeadingEndOfValueChar,
493
+ warnings,
494
+ );
495
+
496
+ // Numeric properties
497
+ meta.endOfLineType = EndOfLineTypeMetaSerialization.deserialize(obj['@_EndOfLineType'], warnings);
498
+ meta.endOfLineAutoWriteType = EndOfLineAutoWriteTypeMetaSerialization.deserialize(obj['@_EndOfLineAutoWriteType'], warnings);
499
+ meta.lastLineEndedType = LastLineEndedTypeMetaSerialization.deserialize(obj['@_LastLineEndedType'], warnings);
500
+ meta.headingLineCount = IntegerFloatMetaSerialization.deserialize(
501
+ obj['@_HeadingLineCount'],
502
+ FtMetaDefaults.Root.HeadingLineCount,
503
+ false,
504
+ warnings,
505
+ );
506
+ meta.mainHeadingLineIndex = IntegerFloatMetaSerialization.deserialize(
507
+ obj['@_MainHeadingLineIndex'],
508
+ FtMetaDefaults.Root.MainHeadingLineIndex,
509
+ false,
510
+ warnings,
511
+ );
512
+ meta.headingConstraint = HeadingConstraintMetaSerialization.deserialize(obj['@_HeadingConstraint'], undefined, warnings);
513
+ meta.headingQuotedType = QuotedTypeMetaSerialization.deserialize(obj['@_HeadingQuotedType'], true, undefined, warnings);
514
+ meta.headingPadAlignment = PadAlignmentMetaSerialization.deserialize(obj['@_HeadingPadAlignment'], true, undefined, warnings);
515
+ meta.headingPadCharType = PadCharTypeMetaSerialization.deserialize(obj['@_HeadingPadCharType'], true, undefined, warnings);
516
+ meta.headingTruncateType = TruncateTypeMetaSerialization.deserialize(obj['@_HeadingTruncateType'], true, undefined, warnings);
517
+
518
+ // Boolean properties
519
+ meta.allowEndOfLineCharInQuotes = BooleanMetaSerialization.deserialize(
520
+ obj['@_AllowEndOfLineCharInQuotes'],
521
+ FtMetaDefaults.Root.AllowEndOfLineCharInQuotes,
522
+ warnings,
523
+ );
524
+ meta.ignoreBlankLines = BooleanMetaSerialization.deserialize(obj['@_IgnoreBlankLines'], FtMetaDefaults.Root.IgnoreBlankLines, warnings);
525
+ meta.ignoreExtraChars = BooleanMetaSerialization.deserialize(obj['@_IgnoreExtraChars'], FtMetaDefaults.Root.IgnoreExtraChars, warnings);
526
+ meta.allowIncompleteRecords = BooleanMetaSerialization.deserialize(
527
+ obj['@_AllowIncompleteRecords'],
528
+ FtMetaDefaults.Root.AllowIncompleteRecords,
529
+ warnings,
530
+ );
531
+ meta.stuffedEmbeddedQuotes = BooleanMetaSerialization.deserialize(
532
+ obj['@_StuffedEmbeddedQuotes'],
533
+ FtMetaDefaults.Root.StuffedEmbeddedQuotes,
534
+ warnings,
535
+ );
536
+ meta.headingAlwaysWriteOptionalQuote = BooleanMetaSerialization.deserialize(
537
+ obj['@_HeadingAlwaysWriteOptionalQuote'],
538
+ FtMetaDefaults.Root.HeadingAlwaysWriteOptionalQuote,
539
+ warnings,
540
+ );
541
+ meta.headingWritePrefixSpace = BooleanMetaSerialization.deserialize(
542
+ obj['@_HeadingWritePrefixSpace'],
543
+ FtMetaDefaults.Root.HeadingWritePrefixSpace,
544
+ warnings,
545
+ );
546
+ }
547
+
548
+ private deserializeField(
549
+ obj: Record<string, unknown>,
550
+ headingLineCount: number,
551
+ meta: FtMeta,
552
+ warnings: string[],
553
+ ): ImplicitExplicitIndexSortRec<FtMetaField> {
554
+ const dataType = DataTypeMetaSerialization.deserialize(obj['@_DataType'], warnings);
555
+ const field = FtFieldFactory.createMetaField(dataType, headingLineCount);
556
+
557
+ field.name = StringMetaSerialization.deserialize(obj['@_Name'], FtMetaDefaults.Field.Name, warnings);
558
+ field.id = IntegerFloatMetaSerialization.deserialize(obj['@_Id'], FtMetaDefaults.Field.Id, true, warnings);
559
+ field.fixedWidth = BooleanMetaSerialization.deserialize(obj['@_FixedWidth'], FtMetaDefaults.Field.FixedWidth, warnings);
560
+ field.width = IntegerFloatMetaSerialization.deserialize(obj['@_Width'], FtMetaDefaults.Field.Width, false, warnings);
561
+ field.constant = BooleanMetaSerialization.deserialize(obj['@_Constant'], FtMetaDefaults.Field.Constant, warnings);
562
+ field.null = BooleanMetaSerialization.deserialize(obj['@_Null'], FtMetaDefaults.Field.Null, warnings);
563
+
564
+ // Value formatting properties
565
+ field.valueQuotedType = QuotedTypeMetaSerialization.deserialize(obj['@_ValueQuotedType'], false, undefined, warnings);
566
+ field.valueAlwaysWriteOptionalQuote = BooleanMetaSerialization.deserialize(
567
+ obj['@_ValueAlwaysWriteOptionalQuote'],
568
+ FtMetaDefaults.Field.ValueAlwaysWriteOptionalQuote,
569
+ warnings,
570
+ );
571
+ field.valueWritePrefixSpace = BooleanMetaSerialization.deserialize(
572
+ obj['@_ValueWritePrefixSpace'],
573
+ FtMetaDefaults.Field.ValueWritePrefixSpace,
574
+ warnings,
575
+ );
576
+ field.valuePadAlignment = PadAlignmentMetaSerialization.deserialize(obj['@_ValuePadAlignment'], false, undefined, warnings);
577
+ field.valuePadCharType = PadCharTypeMetaSerialization.deserialize(obj['@_ValuePadCharType'], false, undefined, warnings);
578
+ field.valuePadChar = CharMetaSerialization.deserialize(obj['@_ValuePadChar'], FtMetaDefaults.Field.ValuePadChar, warnings);
579
+ field.valueTruncateType = TruncateTypeMetaSerialization.deserialize(obj['@_ValueTruncateType'], false, undefined, warnings);
580
+ field.valueTruncateChar = CharMetaSerialization.deserialize(obj['@_ValueTruncateChar'], FtMetaDefaults.Field.ValueTruncateChar, warnings);
581
+ field.valueEndOfValueChar = CharMetaSerialization.deserialize(obj['@_ValueEndOfValueChar'], FtMetaDefaults.Field.ValueEndOfValueChar, warnings);
582
+
583
+ field.headingConstraint = HeadingConstraintMetaSerialization.deserialize(obj['@_HeadingConstraint'], meta.headingConstraint, warnings);
584
+ field.headingQuotedType = QuotedTypeMetaSerialization.deserialize(obj['@_HeadingQuotedType'], true, meta.headingQuotedType, warnings);
585
+ field.headingAlwaysWriteOptionalQuote = BooleanMetaSerialization.deserialize(
586
+ obj['@_HeadingAlwaysWriteOptionalQuote'],
587
+ meta.headingAlwaysWriteOptionalQuote,
588
+ warnings,
589
+ );
590
+ field.headingWritePrefixSpace = BooleanMetaSerialization.deserialize(obj['@_HeadingWritePrefixSpace'], meta.headingWritePrefixSpace, warnings);
591
+ field.headingPadAlignment = PadAlignmentMetaSerialization.deserialize(obj['@_HeadingPadAlignment'], true, meta.headingPadAlignment, warnings);
592
+ field.headingPadCharType = PadCharTypeMetaSerialization.deserialize(obj['@_HeadingPadCharType'], true, meta.headingPadCharType, warnings);
593
+ field.headingPadChar = CharMetaSerialization.deserialize(obj['@_HeadingPadChar'], meta.headingPadChar, warnings);
594
+ field.headingTruncateType = TruncateTypeMetaSerialization.deserialize(obj['@_HeadingTruncateType'], true, meta.headingTruncateType, warnings);
595
+ field.headingTruncateChar = CharMetaSerialization.deserialize(obj['@_HeadingTruncateChar'], meta.headingTruncateChar, warnings);
596
+ field.headingEndOfValueChar = CharMetaSerialization.deserialize(obj['@_HeadingEndOfValueChar'], meta.headingEndOfValueChar, warnings);
597
+
598
+ // Headings
599
+ if (headingLineCount > 0) {
600
+ const headingsCommaText = StringMetaSerialization.deserialize(obj['@_Headings'], '', warnings);
601
+ const headingsResult = CommaText.tryToStringArray(headingsCommaText, true);
602
+ if (headingsResult.isErr()) {
603
+ warnings.push(`Headings: Invalid: Field ${field.name}: Value: "${headingsCommaText}"`);
604
+ } else {
605
+ const headings = headingsResult.value;
606
+ const deserializedCount = headings.length;
607
+ if (deserializedCount !== headingLineCount) {
608
+ headings.length = headingLineCount;
609
+ if (deserializedCount < headingLineCount) {
610
+ for (let i = deserializedCount; i < headingLineCount; i++) {
611
+ headings[i] = '';
612
+ }
613
+ }
614
+ }
615
+ field.headings = headings;
616
+ }
617
+ }
618
+
619
+ const fieldDataType = field.dataType;
620
+ const valueDeserializable = field.constant && !field.null;
621
+ const deserializableValue = valueDeserializable ? obj['@_Value'] : undefined;
622
+ switch (fieldDataType) {
623
+ case FtDataType.String: {
624
+ const stringField = field as FtStringMetaField;
625
+ stringField.value = StringMetaSerialization.deserialize(deserializableValue, FtStringMetaField.DEFAULT_VALUE, warnings);
626
+ break;
627
+ }
628
+ case FtDataType.Boolean: {
629
+ const booleanField = field as FtBooleanMetaField;
630
+ booleanField.styles = FtBooleanStylesMetaSerialization.deserialize(obj['@_Styles'], warnings);
631
+ booleanField.trueText = StringMetaSerialization.deserialize(obj['@_TrueText'], FtBooleanMetaField.DEFAULT_TRUE_TEXT, warnings);
632
+ booleanField.falseText = StringMetaSerialization.deserialize(obj['@_FalseText'], FtBooleanMetaField.DEFAULT_FALSE_TEXT, warnings);
633
+ booleanField.value = BooleanMetaSerialization.deserialize(deserializableValue, FtBooleanMetaField.DEFAULT_VALUE, warnings);
634
+ break;
635
+ }
636
+ case FtDataType.Integer: {
637
+ const integerField = field as FtIntegerMetaField;
638
+ integerField.format = StringMetaSerialization.deserialize(obj['@_Format'], FtIntegerMetaField.DEFAULT_FORMAT, warnings);
639
+ integerField.styles = FtNumberStylesMetaSerialization.deserialize(obj['@_Styles'], fieldDataType, warnings);
640
+ integerField.value = IntegerMetaSerialization.deserialize(deserializableValue, FtIntegerMetaField.DEFAULT_VALUE, warnings);
641
+ break;
642
+ }
643
+ case FtDataType.Float: {
644
+ const floatField = field as FtFloatMetaField;
645
+ floatField.format = StringMetaSerialization.deserialize(obj['@_Format'], FtFloatMetaField.DEFAULT_FORMAT, warnings);
646
+ floatField.styles = FtNumberStylesMetaSerialization.deserialize(obj['@_Styles'], fieldDataType, warnings);
647
+ floatField.value = FloatMetaSerialization.deserialize(deserializableValue, FtFloatMetaField.DEFAULT_VALUE, warnings);
648
+ break;
649
+ }
650
+ case FtDataType.Decimal: {
651
+ const decimalField = field as FtDecimalMetaField;
652
+ decimalField.format = StringMetaSerialization.deserialize(obj['@_Format'], FtDecimalMetaField.DEFAULT_FORMAT, warnings);
653
+ decimalField.styles = FtNumberStylesMetaSerialization.deserialize(obj['@_Styles'], fieldDataType, warnings);
654
+ decimalField.value = DecimalMetaSerialization.deserialize(deserializableValue, FtDecimalMetaField.DEFAULT_VALUE, warnings);
655
+ break;
656
+ }
657
+ case FtDataType.DateTime: {
658
+ const dateTimeField = field as FtDateTimeMetaField;
659
+ dateTimeField.styles = FtDateTimeStylesMetaSerialization.deserialize(obj['@_Styles'], warnings);
660
+ dateTimeField.format = StringMetaSerialization.deserialize(obj['@_Format'], FtDateTimeMetaField.DEFAULT_FORMAT, warnings);
661
+ dateTimeField.value = DateTimeMetaSerialization.deserialize(deserializableValue, FtDateTimeMetaField.DEFAULT_VALUE, warnings);
662
+ break;
663
+ }
664
+ default:
665
+ throw new FtUnreachableCaseError('XMSDFP', fieldDataType);
666
+ }
667
+
668
+ const explicitIndex = IntegerFloatMetaSerialization.deserialize(obj['@_Index'], ImplicitExplicitIndexSortRec.INDEX_NOT_SET, false, warnings);
669
+ return { target: field, implicitIndex: ImplicitExplicitIndexSortRec.INDEX_NOT_SET, explicitIndex };
670
+ }
671
+
672
+ private deserializeSequence(
673
+ seqObj: Record<string, unknown>,
674
+ resolvedOrderedFieldList: FtMetaFieldList,
675
+ redirectSequenceResolver: MetaSerializationRedirectSequenceResolver,
676
+ warnings: string[],
677
+ ): MetaSerializationSequenceNameResolver.Rec {
678
+ const sequence = new FtMetaSequence();
679
+ const objName = seqObj['@_Name'];
680
+ let result: MetaSerializationSequenceNameResolver.Rec;
681
+ if (typeof objName === 'string') {
682
+ result = { sequence, name: objName };
683
+ } else {
684
+ result = { sequence, name: undefined };
685
+ if (objName === undefined) {
686
+ warnings.push('Sequence: Missing required attribute: Name');
687
+ } else {
688
+ warnings.push(`Sequence: Invalid Name attribute: ${objName}`);
689
+ }
690
+ }
691
+ sequence.name = result.name ?? '';
692
+ sequence.root = BooleanMetaSerialization.deserialize(seqObj['@_Root'], FtMetaDefaults.Sequence.Root, warnings);
693
+
694
+ // Deserialize sequence items
695
+ if (seqObj.Item) {
696
+ const itemObjs = Array.isArray(seqObj.Item) ? seqObj.Item : [seqObj.Item];
697
+ const itemCount = itemObjs.length;
698
+ const itemSortRecs = new Array<ImplicitExplicitIndexSortRec<FtMetaSequenceItem>>(itemCount);
699
+ let count = 0;
700
+ for (let i = 0; i < itemCount; i++) {
701
+ const itemSortRec = this.deserializeSequenceItem(itemObjs[i], resolvedOrderedFieldList, redirectSequenceResolver, warnings);
702
+ if (itemSortRec !== undefined) {
703
+ const index = count++;
704
+ itemSortRec.implicitIndex = index;
705
+ itemSortRecs[index] = itemSortRec;
706
+ }
707
+ }
708
+ itemSortRecs.length = count; // In case some items were skipped due to deserialization errors
709
+ itemSortRecs.sort((left, right) => ImplicitExplicitIndexSortRec.compare(left, right));
710
+ ImplicitExplicitIndexSortRec.checkSortedArray(itemSortRecs, 'Sequence Item', warnings);
711
+ sequence.setItemList(itemSortRecs.map((rec) => rec.target));
712
+ }
713
+
714
+ return result;
715
+ }
716
+
717
+ private deserializeSequenceItem(
718
+ itemObj: Record<string, unknown>,
719
+ resolvedOrderedFieldList: FtMetaFieldList,
720
+ redirectSequenceResolver: MetaSerializationRedirectSequenceResolver,
721
+ warnings: string[],
722
+ ): ImplicitExplicitIndexSortRec<FtMetaSequenceItem> | undefined {
723
+ const field = SequenceItemFieldIndexSerialization.deserializeField(itemObj['@_FieldIndex'], resolvedOrderedFieldList, warnings);
724
+ if (field === undefined) {
725
+ return undefined; // We can't deserialize this item without a valid field reference, but we can continue deserializing other items and sequences, so we return undefined and log a warning instead of throwing an error
726
+ } else {
727
+ const item = new FtMetaSequenceItem(field);
728
+
729
+ // Deserialize redirects
730
+ if (itemObj.Redirect) {
731
+ const redirectObjs = Array.isArray(itemObj.Redirect) ? itemObj.Redirect : [itemObj.Redirect];
732
+ const redirectCount = redirectObjs.length;
733
+ const redirectSortRecs = new Array<ImplicitExplicitIndexSortRec<MetaSerializationRedirectSequenceResolver.Rec>>(redirectCount);
734
+ for (let i = 0; i < redirectCount; i++) {
735
+ const redirectRec = this.deserializeRedirect(redirectObjs[i], field.dataType, warnings);
736
+ redirectRec.implicitIndex = i;
737
+ redirectSortRecs[i] = redirectRec;
738
+ }
739
+ redirectSortRecs.sort((left, right) => ImplicitExplicitIndexSortRec.compare(left, right));
740
+ ImplicitExplicitIndexSortRec.checkSortedArray(redirectSortRecs, 'Sequence Redirect', warnings);
741
+
742
+ const redirects = new Array<FtMetaSequenceRedirect>(redirectCount);
743
+ for (let i = 0; i < redirectCount; i++) {
744
+ const sortRec = redirectSortRecs[i];
745
+ const redirectNameRec = sortRec.target;
746
+ const redirect = redirectNameRec.redirect;
747
+ const sequenceName = redirectNameRec.sequenceName;
748
+ redirects[i] = redirect;
749
+
750
+ redirectSequenceResolver.add(redirect, sequenceName);
751
+ }
752
+ item.setRedirectList(redirects);
753
+ }
754
+
755
+ const explicitIndex = IntegerFloatMetaSerialization.deserialize(
756
+ itemObj['@_Index'],
757
+ ImplicitExplicitIndexSortRec.INDEX_NOT_SET,
758
+ false,
759
+ warnings,
760
+ );
761
+ return { target: item, implicitIndex: ImplicitExplicitIndexSortRec.INDEX_NOT_SET, explicitIndex };
762
+ }
763
+ }
764
+
765
+ private deserializeRedirect(
766
+ redirectObj: Record<string, unknown>,
767
+ fieldDataType: FtDataType,
768
+ warnings: string[],
769
+ ): ImplicitExplicitIndexSortRec<MetaSerializationRedirectSequenceResolver.Rec> {
770
+ const explicitIndex = IntegerFloatMetaSerialization.deserialize(
771
+ redirectObj['@_Index'],
772
+ ImplicitExplicitIndexSortRec.INDEX_NOT_SET,
773
+ false,
774
+ warnings,
775
+ );
776
+ const objSequenceName = redirectObj['@_SequenceName'];
777
+ const sequenceName = typeof objSequenceName === 'string' ? objSequenceName : undefined;
778
+ const redirectType = SequenceRedirectTypeMetaSerialization.deserialize(redirectObj['@_Type'], fieldDataType, warnings);
779
+ const invokationDelay = SequenceInvokationDelayMetaSerialization.deserialize(redirectObj['@_InvokationDelay'], warnings);
780
+
781
+ let redirect: FtMetaSequenceRedirect;
782
+ switch (redirectType) {
783
+ case FtSequenceRedirectType.Null:
784
+ redirect = new FtNullMetaSequenceRedirect();
785
+ // Null redirects don't have a value
786
+ break;
787
+ case FtSequenceRedirectType.ExactString: {
788
+ const exactStringRedirect = new FtExactStringMetaSequenceRedirect();
789
+ exactStringRedirect.value = StringMetaSerialization.deserialize(
790
+ redirectObj['@_Value'],
791
+ FtExactStringMetaSequenceRedirect.DEFAULT_VALUE,
792
+ warnings,
793
+ );
794
+ redirect = exactStringRedirect;
795
+ break;
796
+ }
797
+ case FtSequenceRedirectType.CaseInsensitiveString: {
798
+ const caseInsensitiveStringRedirect = new FtCaseInsensitiveStringMetaSequenceRedirect();
799
+ caseInsensitiveStringRedirect.value = StringMetaSerialization.deserialize(
800
+ redirectObj['@_Value'],
801
+ FtCaseInsensitiveStringMetaSequenceRedirect.DEFAULT_VALUE,
802
+ warnings,
803
+ );
804
+ redirect = caseInsensitiveStringRedirect;
805
+ break;
806
+ }
807
+ case FtSequenceRedirectType.Boolean: {
808
+ const booleanRedirect = new FtBooleanMetaSequenceRedirect();
809
+ booleanRedirect.value = BooleanMetaSerialization.deserialize(redirectObj['@_Value'], FtBooleanMetaSequenceRedirect.DEFAULT_VALUE, warnings);
810
+ redirect = booleanRedirect;
811
+ break;
812
+ }
813
+ case FtSequenceRedirectType.ExactInteger: {
814
+ const exactIntegerRedirect = new FtExactIntegerMetaSequenceRedirect();
815
+ exactIntegerRedirect.value = IntegerMetaSerialization.deserialize(
816
+ redirectObj['@_Value'],
817
+ FtExactIntegerMetaSequenceRedirect.DEFAULT_VALUE,
818
+ warnings,
819
+ );
820
+ redirect = exactIntegerRedirect;
821
+ break;
822
+ }
823
+ case FtSequenceRedirectType.ExactFloat: {
824
+ const exactFloatRedirect = new FtExactFloatMetaSequenceRedirect();
825
+ exactFloatRedirect.value = FloatMetaSerialization.deserialize(
826
+ redirectObj['@_Value'],
827
+ FtExactFloatMetaSequenceRedirect.DEFAULT_VALUE,
828
+ warnings,
829
+ );
830
+ redirect = exactFloatRedirect;
831
+ break;
832
+ }
833
+ case FtSequenceRedirectType.ExactDateTime: {
834
+ const exactDateTimeRedirect = new FtExactDateTimeMetaSequenceRedirect();
835
+ exactDateTimeRedirect.value = DateTimeMetaSerialization.deserialize(
836
+ redirectObj['@_Value'],
837
+ FtExactDateTimeMetaSequenceRedirect.DEFAULT_VALUE,
838
+ warnings,
839
+ );
840
+ redirect = exactDateTimeRedirect;
841
+ break;
842
+ }
843
+ case FtSequenceRedirectType.Date: {
844
+ const dateRedirect = new FtDateMetaSequenceRedirect();
845
+ dateRedirect.value = DateTimeMetaSerialization.deserialize(redirectObj['@_Value'], FtDateMetaSequenceRedirect.DEFAULT_VALUE, warnings);
846
+ redirect = dateRedirect;
847
+ break;
848
+ }
849
+ case FtSequenceRedirectType.ExactDecimal: {
850
+ const exactDecimalRedirect = new FtExactDecimalMetaSequenceRedirect();
851
+ exactDecimalRedirect.value = DecimalMetaSerialization.deserialize(
852
+ redirectObj['@_Value'],
853
+ FtExactDecimalMetaSequenceRedirect.DEFAULT_VALUE,
854
+ warnings,
855
+ );
856
+ redirect = exactDecimalRedirect;
857
+ break;
858
+ }
859
+ default:
860
+ throw new FtUnreachableCaseError('XMSSR99315', redirectType);
861
+ }
862
+
863
+ redirect.invokationDelay = invokationDelay;
864
+ const nameRec: MetaSerializationRedirectSequenceResolver.Rec = { redirect, sequenceName: sequenceName };
865
+
866
+ return {
867
+ target: nameRec,
868
+ implicitIndex: ImplicitExplicitIndexSortRec.INDEX_NOT_SET,
869
+ explicitIndex,
870
+ };
871
+ }
872
+ }
873
+
874
+ /** @public */
875
+ export namespace FtXmlMetaSerialization {
876
+ export function serialize(meta: FtMeta, options?: FtMetaSerializerOptions): string {
877
+ const serializer = new FtXmlMetaSerialization();
878
+ return serializer.serialize(meta, options);
879
+ }
880
+
881
+ export function deserialize(xml: string, warnings?: string[]): FtMeta {
882
+ const deserializer = new FtXmlMetaSerialization();
883
+ return deserializer.deserialize(xml, warnings);
884
+ }
885
+ }