react-native-nitro-xlsx 0.2.5 → 0.2.6

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 (395) hide show
  1. package/NitroXlsx.podspec +26 -27
  2. package/Package.swift +31 -10
  3. package/README.md +1 -1
  4. package/android/CMakeLists.txt +20 -27
  5. package/package.json +2 -2
  6. package/scripts/run-cpp-tests.sh +1 -1
  7. package/thirdparty/OpenXLSX/.clang-format +118 -0
  8. package/thirdparty/OpenXLSX/.clang-tidy +28 -0
  9. package/thirdparty/OpenXLSX/.gitignore +130 -0
  10. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
  11. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
  12. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
  13. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
  14. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
  15. package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
  16. package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
  17. package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
  18. package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
  19. package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
  20. package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
  21. package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
  22. package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
  23. package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
  24. package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
  25. package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
  26. package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
  27. package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
  28. package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
  29. package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
  30. package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
  31. package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
  32. package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
  33. package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
  34. package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
  35. package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
  36. package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
  37. package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
  38. package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
  39. package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
  40. package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
  41. package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
  42. package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
  43. package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
  44. package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
  45. package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
  46. package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
  47. package/thirdparty/OpenXLSX/LICENSE.md +29 -0
  48. package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
  49. package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
  50. package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
  51. package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
  52. package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
  53. package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
  54. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
  55. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
  56. package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
  57. package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
  58. package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
  59. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
  60. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
  61. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
  62. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
  63. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
  64. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
  65. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
  66. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
  67. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
  68. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
  69. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
  70. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
  71. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
  72. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
  73. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
  74. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
  75. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
  76. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
  77. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
  78. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
  79. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
  80. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
  81. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
  82. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
  83. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
  84. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
  85. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
  86. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
  87. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
  88. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
  89. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
  90. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
  91. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
  92. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
  93. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
  94. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
  95. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
  96. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
  97. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
  98. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
  99. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
  100. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
  101. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
  102. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
  103. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
  104. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
  105. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
  106. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
  107. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
  108. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
  109. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
  110. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
  111. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
  112. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
  113. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
  114. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
  115. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
  116. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
  117. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
  118. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
  119. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
  120. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
  121. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
  122. package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
  123. package/thirdparty/OpenXLSX/README.md +1279 -0
  124. package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
  125. package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
  126. package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
  127. package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
  128. package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
  129. package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
  130. package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
  131. package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
  132. package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
  133. package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
  134. package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
  135. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
  136. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
  137. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
  138. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
  139. package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
  140. package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
  141. package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
  142. package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
  143. package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
  144. package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
  145. package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
  146. package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
  147. package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
  148. package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
  149. package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
  150. package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
  151. package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
  152. package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
  153. package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
  154. package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
  155. package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
  156. package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
  157. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
  158. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
  159. package/thirdparty/OpenXLSX/vcpkg.json +24 -0
  160. package/thirdparty/README.md +42 -0
  161. package/thirdparty/miniz/.clang-format +47 -0
  162. package/thirdparty/miniz/.travis.yml +2 -0
  163. package/thirdparty/miniz/CMakeLists.txt +333 -0
  164. package/thirdparty/miniz/CMakePresets.json +31 -0
  165. package/thirdparty/miniz/ChangeLog.md +272 -0
  166. package/thirdparty/miniz/Config.cmake.in +1 -0
  167. package/thirdparty/miniz/LICENSE +22 -0
  168. package/thirdparty/miniz/amalgamate.sh +57 -0
  169. package/thirdparty/miniz/examples/example1.c +105 -0
  170. package/thirdparty/miniz/examples/example2.c +164 -0
  171. package/thirdparty/miniz/examples/example3.c +269 -0
  172. package/thirdparty/miniz/examples/example4.c +102 -0
  173. package/thirdparty/miniz/examples/example5.c +327 -0
  174. package/thirdparty/miniz/examples/example6.c +189 -0
  175. package/thirdparty/miniz/meson.build +21 -0
  176. package/thirdparty/miniz/miniz.c +646 -0
  177. package/thirdparty/miniz/miniz.h +615 -0
  178. package/thirdparty/miniz/miniz.pc.in +13 -0
  179. package/thirdparty/miniz/miniz_common.h +89 -0
  180. package/thirdparty/miniz/miniz_export.h +20 -0
  181. package/thirdparty/miniz/miniz_tdef.c +1602 -0
  182. package/thirdparty/miniz/miniz_tdef.h +199 -0
  183. package/thirdparty/miniz/miniz_tinfl.c +778 -0
  184. package/thirdparty/miniz/miniz_tinfl.h +150 -0
  185. package/thirdparty/miniz/miniz_zip.c +4895 -0
  186. package/thirdparty/miniz/miniz_zip.h +454 -0
  187. package/thirdparty/miniz/readme.md +46 -0
  188. package/thirdparty/miniz/test.sh +36 -0
  189. package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
  190. package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
  191. package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
  192. package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
  193. package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
  194. package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
  195. package/thirdparty/miniz/tests/fuzz_main.c +55 -0
  196. package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
  197. package/thirdparty/miniz/tests/main.cpp +185 -0
  198. package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
  199. package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
  200. package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
  201. package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
  202. package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
  203. package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
  204. package/thirdparty/miniz/tests/timer.cpp +152 -0
  205. package/thirdparty/miniz/tests/timer.h +40 -0
  206. package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
  207. package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
  208. package/thirdparty/miniz/tests/zip.dict +9 -0
  209. package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
  210. package/thirdparty/pugixml/.codecov.yml +7 -0
  211. package/thirdparty/pugixml/.gitattributes +1 -0
  212. package/thirdparty/pugixml/CMakeLists.txt +330 -0
  213. package/thirdparty/pugixml/LICENSE.md +24 -0
  214. package/thirdparty/pugixml/Makefile +98 -0
  215. package/thirdparty/pugixml/README.md +81 -0
  216. package/thirdparty/pugixml/SECURITY.md +9 -0
  217. package/thirdparty/pugixml/appveyor.yml +50 -0
  218. package/thirdparty/pugixml/docs/config.adoc +7 -0
  219. package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
  220. package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
  221. package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
  222. package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
  223. package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
  224. package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
  225. package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
  226. package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
  227. package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
  228. package/thirdparty/pugixml/docs/manual.adoc +3326 -0
  229. package/thirdparty/pugixml/docs/manual.html +6395 -0
  230. package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
  231. package/thirdparty/pugixml/docs/quickstart.html +1107 -0
  232. package/thirdparty/pugixml/docs/samples/character.xml +8 -0
  233. package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
  234. package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
  235. package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
  236. package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
  237. package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
  238. package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
  239. package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
  240. package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
  241. package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
  242. package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
  243. package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
  244. package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
  245. package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
  246. package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
  247. package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
  248. package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
  249. package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
  250. package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
  251. package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
  252. package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
  253. package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
  254. package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
  255. package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
  256. package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
  257. package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
  258. package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
  259. package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
  260. package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
  261. package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
  262. package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
  263. package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
  264. package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
  265. package/thirdparty/pugixml/readme.txt +50 -0
  266. package/thirdparty/pugixml/scripts/archive.py +54 -0
  267. package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
  268. package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
  269. package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
  270. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
  271. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
  272. package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
  273. package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
  274. package/thirdparty/pugixml/scripts/premake4.lua +92 -0
  275. package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
  276. package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
  277. package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
  278. package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
  279. package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
  280. package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
  281. package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
  282. package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
  283. package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
  284. package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
  285. package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
  286. package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
  287. package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
  288. package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
  289. package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
  290. package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
  291. package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
  292. package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
  293. package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
  294. package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
  295. package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
  296. package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
  297. package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
  298. package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
  299. package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
  300. package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
  301. package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
  302. package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
  303. package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
  304. package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
  305. package/thirdparty/pugixml/tests/allocator.cpp +175 -0
  306. package/thirdparty/pugixml/tests/allocator.hpp +10 -0
  307. package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
  308. package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
  309. package/thirdparty/pugixml/tests/data/empty.xml +0 -0
  310. package/thirdparty/pugixml/tests/data/large.xml +1 -0
  311. package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
  312. package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
  313. package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
  314. package/thirdparty/pugixml/tests/data/small.xml +1 -0
  315. package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
  316. package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
  317. package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
  318. package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
  319. package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
  320. package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
  321. package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
  322. package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
  323. package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
  324. package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
  325. package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
  326. package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
  327. package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
  328. package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
  329. package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
  330. package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
  331. package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
  332. package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
  333. package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
  334. package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
  335. package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
  336. package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
  337. package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
  338. package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
  339. package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
  340. package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
  341. package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
  342. package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
  343. package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
  344. package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
  345. package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
  346. package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
  347. package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
  348. package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
  349. package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
  350. package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
  351. package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
  352. package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
  353. package/thirdparty/pugixml/tests/helpers.hpp +114 -0
  354. package/thirdparty/pugixml/tests/main.cpp +218 -0
  355. package/thirdparty/pugixml/tests/test.cpp +220 -0
  356. package/thirdparty/pugixml/tests/test.hpp +175 -0
  357. package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
  358. package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
  359. package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
  360. package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
  361. package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
  362. package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
  363. package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
  364. package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
  365. package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
  366. package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
  367. package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
  368. package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
  369. package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
  370. package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
  371. package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
  372. package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
  373. package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
  374. package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
  375. package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
  376. package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
  377. package/thirdparty/pugixml/tests/test_version.cpp +5 -0
  378. package/thirdparty/pugixml/tests/test_write.cpp +757 -0
  379. package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
  380. package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
  381. package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
  382. package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
  383. package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
  384. package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
  385. package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
  386. package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
  387. package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
  388. package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
  389. package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
  390. package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
  391. package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
  392. package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
  393. package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
  394. package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
  395. package/scripts/prepare-openxlsx.js +0 -126
@@ -0,0 +1,1678 @@
1
+ /*
2
+
3
+ ____ ____ ___ ____ ____ ____ ___
4
+ 6MMMMb `MM( )M' `MM' 6MMMMb\`MM( )M'
5
+ 8P Y8 `MM. d' MM 6M' ` `MM. d'
6
+ 6M Mb __ ____ ____ ___ __ `MM. d' MM MM `MM. d'
7
+ MM MM `M6MMMMb 6MMMMb `MM 6MMb `MM. d' MM YM. `MM. d'
8
+ MM MM MM' `Mb 6M' `Mb MMM9 `Mb `MMd MM YMMMMb `MMd
9
+ MM MM MM MM MM MM MM' MM dMM. MM `Mb dMM.
10
+ MM MM MM MM MMMMMMMM MM MM d'`MM. MM MM d'`MM.
11
+ YM M9 MM MM MM MM MM d' `MM. MM MM d' `MM.
12
+ 8b d8 MM. ,M9 YM d9 MM MM d' `MM. MM / L ,M9 d' `MM.
13
+ YMMMM9 MMYMMM9 YMMMM9 _MM_ _MM_M(_ _)MM_ _MMMMMMM MYMMMM9 _M(_ _)MM_
14
+ MM
15
+ MM
16
+ _MM_
17
+
18
+ Copyright (c) 2018, Kenneth Troldal Balslev
19
+
20
+ All rights reserved.
21
+
22
+ Redistribution and use in source and binary forms, with or without
23
+ modification, are permitted provided that the following conditions are met:
24
+ - Redistributions of source code must retain the above copyright
25
+ notice, this list of conditions and the following disclaimer.
26
+ - Redistributions in binary form must reproduce the above copyright
27
+ notice, this list of conditions and the following disclaimer in the
28
+ documentation and/or other materials provided with the distribution.
29
+ - Neither the name of the author nor the
30
+ names of any contributors may be used to endorse or promote products
31
+ derived from this software without specific prior written permission.
32
+
33
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
+
44
+ */
45
+
46
+ // ===== External Includes ===== //
47
+ #include <algorithm>
48
+ #include <iostream>
49
+ #if defined(_WIN32)
50
+ #include <random> // TBD: is this still needed for anything? For what?
51
+ #else
52
+ #include <unistd.h> // unlink
53
+ #endif
54
+ #include <vector> // std::vector
55
+
56
+ // ===== OpenXLSX Includes ===== //
57
+ #include "detail/OpenXLSXFileSystemTools.hpp" // pathExists, GenerateRandomNameInSamePath
58
+ #include "XLContentTypes.hpp"
59
+ #include "XLDocument.hpp"
60
+ #include "XLSheet.hpp"
61
+ #include "XLStyles.hpp"
62
+ #include "XLXmlParser.hpp" // pugixml wrapper
63
+ #include "utilities/XLUtilities.hpp"
64
+
65
+ using namespace OpenXLSX;
66
+
67
+ namespace OpenXLSX {
68
+ // define variable that depends on pugixml header file
69
+ const unsigned int pugi_parse_settings = pugi::parse_default | pugi::parse_ws_pcdata; // TBD: | pugi::parse_comments
70
+ } // namespace OpenXLSX
71
+
72
+ namespace
73
+ {
74
+ constexpr int templateSize = 7714;
75
+ constexpr unsigned char templateData[7714] = {
76
+ 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xb5, 0x55, 0x30, 0x23, 0xf4, 0x00, 0x00, 0x00,
77
+ 0x4c, 0x02, 0x00, 0x00, 0x0b, 0x00, 0x08, 0x02, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x2e, 0x72, 0x65, 0x6c, 0x73, 0x20, 0xa2, 0x04,
78
+ 0x02, 0x28, 0xa0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x92, 0x4d, 0x4f, 0xc3, 0x30, 0x0c, 0x86, 0xef, 0x48, 0xfc,
102
+ 0x87, 0xc8, 0xf7, 0xd5, 0xdd, 0x90, 0x10, 0x42, 0x4b, 0x77, 0x41, 0x48, 0xbb, 0x21, 0x54, 0x7e, 0x80, 0x49, 0xdc, 0x0f, 0xb5, 0x8d,
103
+ 0xa3, 0x24, 0x1b, 0xdd, 0xbf, 0x27, 0x1c, 0x10, 0x54, 0x1a, 0x83, 0x03, 0x47, 0x7f, 0xbd, 0x7e, 0xfc, 0xca, 0xdb, 0xdd, 0x3c, 0x8d,
104
+ 0xea, 0xc8, 0x21, 0xf6, 0xe2, 0x34, 0xac, 0x8b, 0x12, 0x14, 0x3b, 0x23, 0xb6, 0x77, 0xad, 0x86, 0x97, 0xfa, 0x71, 0x75, 0x07, 0x2a,
105
+ 0x26, 0x72, 0x96, 0x46, 0x71, 0xac, 0xe1, 0xc4, 0x11, 0x76, 0xd5, 0xf5, 0xd5, 0xf6, 0x99, 0x47, 0x4a, 0x79, 0x28, 0x76, 0xbd, 0x8f,
106
+ 0x2a, 0xab, 0xb8, 0xa8, 0xa1, 0x4b, 0xc9, 0xdf, 0x23, 0x46, 0xd3, 0xf1, 0x44, 0xb1, 0x10, 0xcf, 0x2e, 0x57, 0x1a, 0x09, 0x13, 0xa5,
107
+ 0x1c, 0x86, 0x16, 0x3d, 0x99, 0x81, 0x5a, 0xc6, 0x4d, 0x59, 0xde, 0x62, 0xf8, 0xae, 0x01, 0xd5, 0x42, 0x53, 0xed, 0xad, 0x86, 0xb0,
108
+ 0xb7, 0x37, 0xa0, 0xea, 0x93, 0xcf, 0x9b, 0x7f, 0xd7, 0x96, 0xa6, 0xe9, 0x0d, 0x3f, 0x88, 0x39, 0x4c, 0xec, 0xd2, 0x99, 0x15, 0xc8,
109
+ 0x73, 0x62, 0x67, 0xd9, 0xae, 0x7c, 0xc8, 0x6c, 0x21, 0xf5, 0xf9, 0x1a, 0x55, 0x53, 0x68, 0x39, 0x69, 0xb0, 0x62, 0x9e, 0x72, 0x3a,
110
+ 0x22, 0x79, 0x5f, 0x64, 0x6c, 0xc0, 0xf3, 0x44, 0x9b, 0xbf, 0x13, 0xfd, 0x7c, 0x2d, 0x4e, 0x9c, 0xc8, 0x52, 0x22, 0x34, 0x12, 0xf8,
111
+ 0x32, 0xcf, 0x47, 0xc7, 0x25, 0xa0, 0xf5, 0x7f, 0x5a, 0xb4, 0x34, 0xf1, 0xcb, 0x9d, 0x79, 0xc4, 0x37, 0x09, 0xc3, 0xab, 0xc8, 0xf0,
112
+ 0xc9, 0x82, 0x8b, 0x1f, 0xa8, 0xde, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08,
113
+ 0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x88, 0xbc, 0xe2, 0x5d, 0x03, 0x00, 0x00, 0x35, 0x08, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x78,
114
+ 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0xac, 0x55, 0x6d, 0x6f, 0xa3, 0x38, 0x10, 0xfe,
115
+ 0x7e, 0xd2, 0xfd, 0x07, 0xc4, 0x77, 0x8a, 0x4d, 0xcc, 0x4b, 0x50, 0xe9, 0x2a, 0x90, 0xa0, 0xab, 0xb4, 0x5d, 0x55, 0x6d, 0xb6, 0xfb,
116
+ 0xf1, 0xe4, 0x80, 0x29, 0x56, 0x01, 0x73, 0xc6, 0x34, 0xa9, 0xaa, 0xfd, 0xef, 0x3b, 0x76, 0x42, 0xda, 0x6e, 0x57, 0xa7, 0x5c, 0xf7,
117
+ 0xaa, 0xd4, 0xc6, 0x9e, 0xe1, 0xf1, 0x33, 0x33, 0xcf, 0x98, 0xf3, 0x4f, 0xbb, 0xb6, 0xb1, 0x1e, 0x99, 0x1c, 0xb8, 0xe8, 0x12, 0x1b,
118
+ 0x9f, 0x21, 0xdb, 0x62, 0x5d, 0x21, 0x4a, 0xde, 0xdd, 0x27, 0xf6, 0xd7, 0x75, 0xee, 0x44, 0xb6, 0x35, 0x28, 0xda, 0x95, 0xb4, 0x11,
119
+ 0x1d, 0x4b, 0xec, 0x27, 0x36, 0xd8, 0x9f, 0x2e, 0xfe, 0xfc, 0xe3, 0x7c, 0x2b, 0xe4, 0xc3, 0x46, 0x88, 0x07, 0x0b, 0x00, 0xba, 0x21,
120
+ 0xb1, 0x6b, 0xa5, 0xfa, 0xd8, 0x75, 0x87, 0xa2, 0x66, 0x2d, 0x1d, 0xce, 0x44, 0xcf, 0x3a, 0xb0, 0x54, 0x42, 0xb6, 0x54, 0xc1, 0x52,
121
+ 0xde, 0xbb, 0x43, 0x2f, 0x19, 0x2d, 0x87, 0x9a, 0x31, 0xd5, 0x36, 0xae, 0x87, 0x50, 0xe0, 0xb6, 0x94, 0x77, 0xf6, 0x1e, 0x21, 0x96,
122
+ 0xa7, 0x60, 0x88, 0xaa, 0xe2, 0x05, 0x5b, 0x8a, 0x62, 0x6c, 0x59, 0xa7, 0xf6, 0x20, 0x92, 0x35, 0x54, 0x01, 0xfd, 0xa1, 0xe6, 0xfd,
123
+ 0x30, 0xa1, 0xb5, 0xc5, 0x29, 0x70, 0x2d, 0x95, 0x0f, 0x63, 0xef, 0x14, 0xa2, 0xed, 0x01, 0x62, 0xc3, 0x1b, 0xae, 0x9e, 0x0c, 0xa8,
124
+ 0x6d, 0xb5, 0x45, 0x7c, 0x79, 0xdf, 0x09, 0x49, 0x37, 0x0d, 0x84, 0xbd, 0xc3, 0xbe, 0xb5, 0x93, 0xf0, 0x0b, 0xe0, 0x1f, 0x23, 0x18,
125
+ 0xbc, 0xe9, 0x24, 0x30, 0xbd, 0x3b, 0xaa, 0xe5, 0x85, 0x14, 0x83, 0xa8, 0xd4, 0x19, 0x40, 0xbb, 0x7b, 0xd2, 0xef, 0xe2, 0xc7, 0xc8,
126
+ 0xc5, 0xf8, 0x4d, 0x0a, 0x76, 0xef, 0x73, 0x70, 0x1a, 0x12, 0x71, 0x25, 0x7b, 0xe4, 0xba, 0x86, 0x47, 0x56, 0x32, 0xf8, 0x20, 0xab,
127
+ 0xe0, 0x88, 0x15, 0xbc, 0x80, 0x61, 0xf4, 0xdb, 0x68, 0x18, 0xa4, 0x65, 0xb4, 0x12, 0x43, 0xf2, 0x3e, 0x88, 0xe6, 0x1f, 0xb9, 0x79,
128
+ 0xf6, 0xc5, 0x79, 0xc5, 0x1b, 0x76, 0xb7, 0x97, 0xae, 0x45, 0xfb, 0xfe, 0x0b, 0x6d, 0x75, 0xa5, 0x1a, 0xdb, 0x6a, 0xe8, 0xa0, 0x56,
129
+ 0x25, 0x57, 0xac, 0x4c, 0xec, 0x10, 0x96, 0x62, 0xcb, 0xde, 0x6c, 0xc8, 0xb1, 0x4f, 0x47, 0xde, 0x80, 0x15, 0xa3, 0x08, 0x7b, 0xb6,
130
+ 0x7b, 0x71, 0x94, 0xf3, 0xb5, 0xb4, 0x4a, 0x56, 0xd1, 0xb1, 0x51, 0x6b, 0x10, 0xf2, 0x04, 0x0f, 0x8e, 0x41, 0x30, 0xf7, 0x7c, 0xed,
131
+ 0x09, 0xc2, 0x58, 0x34, 0x8a, 0xc9, 0x8e, 0x2a, 0x96, 0x89, 0x4e, 0x81, 0x0e, 0x0f, 0x71, 0xfd, 0xae, 0xe6, 0x0c, 0x76, 0x56, 0x0b,
132
+ 0x50, 0xb8, 0x75, 0xc3, 0xfe, 0x19, 0xb9, 0x64, 0xd0, 0x58, 0xa0, 0x2f, 0x88, 0x15, 0x46, 0x5a, 0xc4, 0x74, 0x33, 0x5c, 0x53, 0x55,
133
+ 0x5b, 0xa3, 0x6c, 0x12, 0xdb, 0xfd, 0x3a, 0x40, 0xf0, 0xee, 0x5a, 0x8a, 0x06, 0xba, 0xd3, 0x5d, 0xb2, 0x47, 0xd6, 0x88, 0xde, 0xf4,
134
+ 0xc5, 0x86, 0x77, 0x5e, 0xe1, 0xbe, 0x52, 0x28, 0x7d, 0xdf, 0x0e, 0xff, 0x41, 0xa3, 0xb4, 0xd0, 0x81, 0xbb, 0x10, 0xf9, 0x9e, 0xdd,
135
+ 0xfe, 0xf9, 0xe7, 0x2c, 0x00, 0x49, 0x19, 0x4f, 0x3a, 0xbc, 0x56, 0xd2, 0x82, 0xe7, 0xcb, 0xe5, 0x67, 0xa8, 0xc5, 0x2d, 0x7d, 0x84,
136
+ 0xca, 0x40, 0xfd, 0xcb, 0x43, 0xe3, 0x5e, 0x42, 0xea, 0xa3, 0xbf, 0x9f, 0x17, 0xd9, 0x6c, 0xb6, 0x08, 0xf2, 0xd4, 0xc1, 0x01, 0x9a,
137
+ 0x39, 0x5e, 0x40, 0xb0, 0xb3, 0x20, 0x28, 0x77, 0xd2, 0x30, 0x0b, 0x73, 0x2f, 0x45, 0xab, 0x60, 0x1e, 0x7d, 0x87, 0x28, 0x64, 0x10,
138
+ 0x17, 0x82, 0x8e, 0xaa, 0x3e, 0x54, 0x5b, 0x63, 0x26, 0x36, 0x21, 0xbf, 0x30, 0x5d, 0xd1, 0xdd, 0x64, 0xc1, 0x28, 0x1e, 0x79, 0xf9,
139
+ 0x72, 0xfe, 0x33, 0x3a, 0xfc, 0x39, 0x7a, 0xfe, 0x69, 0x98, 0x6c, 0xdf, 0x75, 0xa4, 0xfa, 0x5e, 0xbb, 0xe3, 0x6c, 0x3b, 0xbc, 0xe8,
140
+ 0x42, 0x2f, 0xad, 0xdd, 0x37, 0xde, 0x95, 0x62, 0x9b, 0xd8, 0x5e, 0x18, 0x41, 0x34, 0x4f, 0xd3, 0x12, 0xfb, 0x01, 0x2c, 0xb7, 0xc6,
141
+ 0xf8, 0x8d, 0x97, 0xaa, 0x06, 0x8f, 0x08, 0x91, 0xe3, 0xde, 0x5f, 0x8c, 0xdf, 0xd7, 0xc0, 0x18, 0x87, 0x44, 0x6f, 0x82, 0xfe, 0x35,
142
+ 0xb3, 0xc4, 0x7e, 0xce, 0x73, 0x32, 0x4f, 0x23, 0xbc, 0x70, 0xb0, 0x17, 0x2e, 0x9c, 0x94, 0x90, 0x0c, 0x12, 0x40, 0x52, 0x27, 0xcf,
143
+ 0x51, 0x3e, 0x5b, 0xe5, 0x51, 0x9e, 0xe5, 0x73, 0xc3, 0xc8, 0x7d, 0x45, 0xc9, 0xdc, 0xa0, 0x40, 0xcd, 0xcc, 0x56, 0x67, 0x54, 0x7f,
144
+ 0xab, 0x6f, 0x55, 0x0c, 0x57, 0xb5, 0x9e, 0x75, 0x76, 0xe1, 0x59, 0xc6, 0xfa, 0x0c, 0x79, 0x59, 0x62, 0x53, 0xbd, 0xe9, 0xb5, 0x82,
145
+ 0x36, 0x05, 0xa8, 0x5c, 0x4f, 0xc6, 0x31, 0xc2, 0xc8, 0x9b, 0x6b, 0x0f, 0xb6, 0x53, 0x9f, 0x07, 0x65, 0x66, 0x10, 0x18, 0x07, 0x7a,
146
+ 0x98, 0xa0, 0x45, 0x88, 0xe6, 0xc4, 0x41, 0xab, 0x99, 0xef, 0x90, 0x68, 0xee, 0x39, 0x11, 0x99, 0x79, 0x4e, 0x46, 0x96, 0xde, 0xca,
147
+ 0x0f, 0x57, 0xcb, 0x55, 0xea, 0xeb, 0xfa, 0xe8, 0x2f, 0x40, 0xfc, 0x7f, 0xdc, 0x83, 0x46, 0xe7, 0xf1, 0xf4, 0x69, 0xd1, 0x2c, 0x6b,
148
+ 0x2a, 0xd5, 0x5a, 0xd2, 0xe2, 0x01, 0x3e, 0x48, 0x37, 0xac, 0x4a, 0xe9, 0x00, 0x4a, 0xda, 0x07, 0x04, 0x7c, 0x5f, 0x93, 0x4d, 0xfd,
149
+ 0x28, 0x45, 0x33, 0xa0, 0x48, 0x72, 0x9c, 0x3b, 0x04, 0xcf, 0x91, 0x93, 0xa6, 0x01, 0x71, 0xfc, 0x65, 0x3e, 0xf3, 0x43, 0xbc, 0xcc,
150
+ 0x56, 0x7e, 0xfe, 0x42, 0x56, 0x87, 0x5f, 0x7d, 0xf0, 0x16, 0x8a, 0x5c, 0xf3, 0x36, 0xa3, 0x6a, 0x84, 0x0e, 0xd5, 0xcd, 0x69, 0xd6,
151
+ 0xb1, 0x1e, 0xf3, 0xc3, 0xee, 0x71, 0xb3, 0xda, 0x6f, 0x1c, 0xea, 0xf4, 0xa6, 0xe9, 0xe2, 0x9b, 0xa5, 0xce, 0xfb, 0xe1, 0xed, 0x7f,
152
+ 0x73, 0xbc, 0x85, 0xe8, 0x1b, 0x76, 0xa2, 0x73, 0x7e, 0x77, 0xa2, 0x63, 0xf6, 0xe5, 0x6a, 0x7d, 0x65, 0xb4, 0xf1, 0xcb, 0x00, 0x5c,
153
+ 0x93, 0x60, 0x3d, 0x1a, 0x59, 0xb8, 0x53, 0x59, 0x2e, 0x7e, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14,
154
+ 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xf0, 0x08, 0x58, 0xf4, 0xa5, 0x02, 0x00, 0x00, 0x52, 0x06, 0x00, 0x00, 0x0d,
155
+ 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0xa4, 0x55, 0x6d, 0x6b, 0xdb, 0x30,
156
+ 0x10, 0xfe, 0x3e, 0xd8, 0x7f, 0x10, 0xfa, 0xee, 0xca, 0x76, 0xe3, 0x2c, 0x09, 0xb6, 0xcb, 0xd2, 0xd4, 0x50, 0xe8, 0xc6, 0xa0, 0x1d,
157
+ 0xec, 0xab, 0x62, 0xcb, 0x89, 0xa8, 0x5e, 0x8c, 0x24, 0x67, 0xce, 0xc6, 0xfe, 0xfb, 0x4e, 0x76, 0x5e, 0x1c, 0x3a, 0xb6, 0xd1, 0x7e,
158
+ 0x89, 0x4e, 0xe7, 0xd3, 0x73, 0xcf, 0xdd, 0x73, 0x52, 0xd2, 0x9b, 0x4e, 0x0a, 0xb4, 0x63, 0xc6, 0x72, 0xad, 0x32, 0x1c, 0x5d, 0x85,
159
+ 0x18, 0x31, 0x55, 0xea, 0x8a, 0xab, 0x4d, 0x86, 0xbf, 0x3e, 0x15, 0xc1, 0x0c, 0x23, 0xeb, 0xa8, 0xaa, 0xa8, 0xd0, 0x8a, 0x65, 0x78,
160
+ 0xcf, 0x2c, 0xbe, 0xc9, 0xdf, 0xbf, 0x4b, 0xad, 0xdb, 0x0b, 0xf6, 0xb8, 0x65, 0xcc, 0x21, 0x80, 0x50, 0x36, 0xc3, 0x5b, 0xe7, 0x9a,
161
+ 0x05, 0x21, 0xb6, 0xdc, 0x32, 0x49, 0xed, 0x95, 0x6e, 0x98, 0x82, 0x2f, 0xb5, 0x36, 0x92, 0x3a, 0xd8, 0x9a, 0x0d, 0xb1, 0x8d, 0x61,
162
+ 0xb4, 0xb2, 0xfe, 0x90, 0x14, 0x24, 0x0e, 0xc3, 0x29, 0x91, 0x94, 0x2b, 0x3c, 0x20, 0x2c, 0x64, 0xf9, 0x3f, 0x20, 0x92, 0x9a, 0xe7,
163
+ 0xb6, 0x09, 0x4a, 0x2d, 0x1b, 0xea, 0xf8, 0x9a, 0x0b, 0xee, 0xf6, 0x3d, 0x16, 0x46, 0xb2, 0x5c, 0xdc, 0x6f, 0x94, 0x36, 0x74, 0x2d,
164
+ 0x80, 0x6a, 0x17, 0x4d, 0x68, 0x89, 0xba, 0x68, 0x6a, 0x62, 0xd4, 0x99, 0x63, 0x92, 0xde, 0xfb, 0x22, 0x8f, 0xe4, 0xa5, 0xd1, 0x56,
165
+ 0xd7, 0xee, 0x0a, 0x70, 0x89, 0xae, 0x6b, 0x5e, 0xb2, 0x97, 0x74, 0xe7, 0x64, 0x4e, 0x68, 0x79, 0x46, 0x02, 0xe4, 0xd7, 0x21, 0x45,
166
+ 0x09, 0x09, 0xe3, 0x8b, 0xda, 0x3b, 0xf3, 0x4a, 0xa4, 0x09, 0x31, 0x6c, 0xc7, 0xbd, 0x7c, 0x38, 0x4f, 0x6b, 0xad, 0x9c, 0x45, 0xa5,
167
+ 0x6e, 0x95, 0x03, 0x31, 0x81, 0xa8, 0x6f, 0xc1, 0xe2, 0x59, 0xe9, 0xef, 0xaa, 0xf0, 0x9f, 0xbc, 0x73, 0x88, 0xca, 0x53, 0xfb, 0x03,
168
+ 0xed, 0xa8, 0x00, 0x4f, 0x8c, 0x49, 0x9e, 0x96, 0x5a, 0x68, 0x83, 0x1c, 0x48, 0x07, 0x9d, 0x8b, 0xbc, 0x47, 0x51, 0xc9, 0x86, 0x88,
169
+ 0x5b, 0x2a, 0xf8, 0xda, 0x70, 0xef, 0xac, 0xa9, 0xe4, 0x62, 0x3f, 0xb8, 0xfb, 0x73, 0xbd, 0xda, 0x87, 0x38, 0xc9, 0xa1, 0xf7, 0x3e,
170
+ 0x8a, 0x78, 0x1e, 0x87, 0xc5, 0xc2, 0x21, 0x2e, 0xc4, 0x89, 0x55, 0xec, 0x09, 0x80, 0x23, 0x4f, 0x41, 0x3e, 0xc7, 0x8c, 0x2a, 0x60,
171
+ 0x83, 0x0e, 0xf6, 0xd3, 0xbe, 0x81, 0xf4, 0x0a, 0x26, 0x6d, 0x80, 0xe9, 0xe3, 0xfe, 0x11, 0xbd, 0x31, 0x74, 0x1f, 0xc5, 0xc9, 0xe8,
172
+ 0x00, 0xe9, 0x13, 0xe6, 0xe9, 0x5a, 0x9b, 0x0a, 0x26, 0xfb, 0xdc, 0x8f, 0xa3, 0x2b, 0x4f, 0x05, 0xab, 0x1d, 0x10, 0x35, 0x7c, 0xb3,
173
+ 0xf5, 0xab, 0xd3, 0x0d, 0xfc, 0xae, 0xb5, 0x73, 0xa0, 0x7e, 0x9e, 0x56, 0x9c, 0x6e, 0xb4, 0xa2, 0xc2, 0x97, 0x32, 0x80, 0x9c, 0x0c,
174
+ 0x28, 0xa7, 0x64, 0x42, 0x3c, 0xfa, 0xe9, 0xff, 0x56, 0x5f, 0x60, 0x77, 0x35, 0x52, 0xad, 0x2c, 0xa4, 0xbb, 0xaf, 0x32, 0x0c, 0xf7,
175
+ 0xc8, 0x37, 0xe1, 0x68, 0x42, 0x21, 0x07, 0x73, 0xc0, 0x1b, 0x36, 0x1e, 0x7f, 0x8c, 0x36, 0x60, 0xbf, 0x19, 0x16, 0x75, 0xf5, 0x25,
176
+ 0x3e, 0x20, 0x8e, 0x68, 0x5f, 0x90, 0x3e, 0xa5, 0x47, 0x5e, 0xef, 0x0c, 0x7f, 0xf6, 0xd7, 0x55, 0xc0, 0xe4, 0x1c, 0x20, 0xd0, 0xba,
177
+ 0xe5, 0xc2, 0x71, 0xf5, 0x07, 0xc2, 0x80, 0x59, 0x75, 0xe7, 0x16, 0x84, 0x5e, 0x01, 0xe7, 0xaf, 0x5e, 0xdf, 0x9c, 0x53, 0x16, 0xe8,
178
+ 0x44, 0xc5, 0x6a, 0xda, 0x0a, 0xf7, 0x74, 0xfa, 0x98, 0xe1, 0xb3, 0xfd, 0x89, 0x55, 0xbc, 0x95, 0xf1, 0x29, 0xea, 0x0b, 0xdf, 0x69,
179
+ 0xd7, 0x43, 0x64, 0xf8, 0x6c, 0x3f, 0x78, 0xa5, 0xa2, 0xa9, 0xcf, 0xc1, 0x3a, 0xf7, 0x60, 0x61, 0xbc, 0x60, 0x45, 0xad, 0xe1, 0x19,
180
+ 0xfe, 0x79, 0xb7, 0xfc, 0x30, 0x5f, 0xdd, 0x15, 0x71, 0x30, 0x0b, 0x97, 0xb3, 0x60, 0x72, 0xcd, 0x92, 0x60, 0x9e, 0x2c, 0x57, 0x41,
181
+ 0x32, 0xb9, 0x5d, 0xae, 0x56, 0xc5, 0x3c, 0x8c, 0xc3, 0xdb, 0x5f, 0xa3, 0x07, 0xe0, 0x0d, 0xd7, 0xbf, 0x7f, 0xaf, 0xf2, 0x14, 0x2e,
182
+ 0xd6, 0xc2, 0x0a, 0x78, 0x24, 0xcc, 0xa1, 0xd8, 0x43, 0x89, 0x8f, 0x67, 0x5f, 0x86, 0x47, 0x9b, 0x81, 0x7e, 0x3f, 0xa3, 0x40, 0x7b,
183
+ 0xcc, 0x7d, 0x1e, 0x4f, 0xc3, 0x8f, 0x49, 0x14, 0x06, 0xc5, 0x75, 0x18, 0x05, 0x93, 0x29, 0x9d, 0x05, 0xb3, 0xe9, 0x75, 0x12, 0x14,
184
+ 0x49, 0x14, 0xaf, 0xa6, 0x93, 0xe5, 0x5d, 0x52, 0x24, 0x23, 0xee, 0xc9, 0x2b, 0x9f, 0x89, 0x90, 0x44, 0xd1, 0xf0, 0xe0, 0x78, 0xf2,
185
+ 0xc9, 0xc2, 0x71, 0xc9, 0x04, 0x57, 0x47, 0xad, 0x8e, 0x0a, 0x8d, 0xbd, 0x20, 0x12, 0x6c, 0xff, 0x52, 0x04, 0x39, 0x2a, 0x41, 0xce,
186
+ 0x7f, 0x06, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00,
187
+ 0x00, 0x21, 0x00, 0xc1, 0x17, 0x10, 0xbe, 0x4e, 0x07, 0x00, 0x00, 0xc6, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f,
188
+ 0x74, 0x68, 0x65, 0x6d, 0x65, 0x2f, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x31, 0x2e, 0x78, 0x6d, 0x6c, 0xec, 0x59, 0xcd, 0x8b, 0x1b, 0x37,
189
+ 0x14, 0xbf, 0x17, 0xfa, 0x3f, 0x0c, 0x73, 0x77, 0xfc, 0x35, 0xe3, 0x8f, 0x25, 0xde, 0xe0, 0xcf, 0x6c, 0x93, 0xdd, 0x24, 0x64, 0x9d,
190
+ 0x94, 0x1c, 0xb5, 0xb6, 0xec, 0x51, 0x56, 0x33, 0x32, 0x92, 0xbc, 0x1b, 0x13, 0x02, 0x25, 0x39, 0xf5, 0x52, 0x28, 0xa4, 0xa5, 0x97,
191
+ 0x42, 0x6f, 0x3d, 0x94, 0xd2, 0x40, 0x03, 0x0d, 0xbd, 0xf4, 0x8f, 0x09, 0x24, 0xb4, 0xe9, 0x1f, 0xd1, 0x27, 0xcd, 0xd8, 0x23, 0xad,
192
+ 0xe5, 0x24, 0x9b, 0x6c, 0x4a, 0x5a, 0x76, 0x0d, 0x8b, 0x47, 0xfe, 0xbd, 0xa7, 0xa7, 0xf7, 0x9e, 0x7e, 0x7a, 0xf3, 0x74, 0xf1, 0xd2,
193
+ 0xbd, 0x98, 0x7a, 0x47, 0x98, 0x0b, 0xc2, 0x92, 0x96, 0x5f, 0xbe, 0x50, 0xf2, 0x3d, 0x9c, 0x8c, 0xd8, 0x98, 0x24, 0xd3, 0x96, 0x7f,
194
+ 0x6b, 0x38, 0x28, 0x34, 0x7c, 0x4f, 0x48, 0x94, 0x8c, 0x11, 0x65, 0x09, 0x6e, 0xf9, 0x0b, 0x2c, 0xfc, 0x4b, 0xdb, 0x9f, 0x7e, 0x72,
195
+ 0x11, 0x6d, 0xc9, 0x08, 0xc7, 0xd8, 0x03, 0xf9, 0x44, 0x6c, 0xa1, 0x96, 0x1f, 0x49, 0x39, 0xdb, 0x2a, 0x16, 0xc5, 0x08, 0x86, 0x91,
196
+ 0xb8, 0xc0, 0x66, 0x38, 0x81, 0xdf, 0x26, 0x8c, 0xc7, 0x48, 0xc2, 0x23, 0x9f, 0x16, 0xc7, 0x1c, 0x1d, 0x83, 0xde, 0x98, 0x16, 0x2b,
197
+ 0xa5, 0x52, 0xad, 0x18, 0x23, 0x92, 0xf8, 0x5e, 0x82, 0x62, 0x50, 0x7b, 0x7d, 0x32, 0x21, 0x23, 0xec, 0x0d, 0x95, 0x4a, 0x7f, 0x7b,
198
+ 0xa9, 0xbc, 0x4f, 0xe1, 0x31, 0x91, 0x42, 0x0d, 0x8c, 0x28, 0xdf, 0x57, 0xaa, 0xb1, 0x25, 0xa1, 0xb1, 0xe3, 0xc3, 0xb2, 0x42, 0x88,
199
+ 0x85, 0xe8, 0x52, 0xee, 0x1d, 0x21, 0xda, 0xf2, 0x61, 0x9e, 0x31, 0x3b, 0x1e, 0xe2, 0x7b, 0xd2, 0xf7, 0x28, 0x12, 0x12, 0x7e, 0x68,
200
+ 0xf9, 0x25, 0xfd, 0xe7, 0x17, 0xb7, 0x2f, 0x16, 0xd1, 0x56, 0x26, 0x44, 0xe5, 0x06, 0x59, 0x43, 0x6e, 0xa0, 0xff, 0x32, 0xb9, 0x4c,
201
+ 0x60, 0x7c, 0x58, 0xd1, 0x73, 0xf2, 0xe9, 0xc1, 0x6a, 0xd2, 0x20, 0x08, 0x83, 0x5a, 0x7b, 0xa5, 0x5f, 0x03, 0xa8, 0x5c, 0xc7, 0xf5,
202
+ 0xeb, 0xfd, 0x5a, 0xbf, 0xb6, 0xd2, 0xa7, 0x01, 0x68, 0x34, 0x82, 0x95, 0xa6, 0xb6, 0xd8, 0x3a, 0xeb, 0x95, 0x6e, 0x90, 0x61, 0x0d,
203
+ 0x50, 0xfa, 0xd5, 0xa1, 0xbb, 0x57, 0xef, 0x55, 0xcb, 0x16, 0xde, 0xd0, 0x5f, 0x5d, 0xb3, 0xb9, 0x1d, 0xaa, 0x8f, 0x85, 0xd7, 0xa0,
204
+ 0x54, 0x7f, 0xb0, 0x86, 0x1f, 0x0c, 0xba, 0xe0, 0x45, 0x0b, 0xaf, 0x41, 0x29, 0x3e, 0x5c, 0xc3, 0x87, 0x9d, 0x66, 0xa7, 0x67, 0xeb,
205
+ 0xd7, 0xa0, 0x14, 0x5f, 0x5b, 0xc3, 0xd7, 0x4b, 0xed, 0x5e, 0x50, 0xb7, 0xf4, 0x6b, 0x50, 0x44, 0x49, 0x72, 0xb8, 0x86, 0x2e, 0x85,
206
+ 0xb5, 0x6a, 0x77, 0xb9, 0xda, 0x15, 0x64, 0xc2, 0xe8, 0x8e, 0x13, 0xde, 0x0c, 0x83, 0x41, 0xbd, 0x92, 0x29, 0xcf, 0x51, 0x90, 0x0d,
207
+ 0xab, 0xec, 0x52, 0x53, 0x4c, 0x58, 0x22, 0x37, 0xe5, 0x5a, 0x8c, 0xee, 0x32, 0x3e, 0x00, 0x80, 0x02, 0x52, 0x24, 0x49, 0xe2, 0xc9,
208
+ 0xc5, 0x0c, 0x4f, 0xd0, 0x08, 0xb2, 0xb8, 0x8b, 0x28, 0x39, 0xe0, 0xc4, 0xdb, 0x25, 0xd3, 0x08, 0x12, 0x6f, 0x86, 0x12, 0x26, 0x60,
209
+ 0xb8, 0x54, 0x29, 0x0d, 0x4a, 0x55, 0xf8, 0xaf, 0x3e, 0x81, 0xfe, 0xa6, 0x23, 0x8a, 0xb6, 0x30, 0x32, 0xa4, 0x95, 0x5d, 0x60, 0x89,
210
+ 0x58, 0x1b, 0x52, 0xf6, 0x78, 0x62, 0xc4, 0xc9, 0x4c, 0xb6, 0xfc, 0x2b, 0xa0, 0xd5, 0x37, 0x20, 0x2f, 0x9e, 0x3d, 0x7b, 0xfe, 0xf0,
211
+ 0xe9, 0xf3, 0x87, 0xbf, 0x3d, 0x7f, 0xf4, 0xe8, 0xf9, 0xc3, 0x5f, 0xb2, 0xb9, 0xb5, 0x2a, 0x4b, 0x6e, 0x07, 0x25, 0x53, 0x53, 0xee,
212
+ 0xd5, 0x8f, 0x5f, 0xff, 0xfd, 0xfd, 0x17, 0xde, 0x5f, 0xbf, 0xfe, 0xf0, 0xea, 0xf1, 0x37, 0xe9, 0xd4, 0x27, 0xf1, 0xc2, 0xc4, 0xbf,
213
+ 0xfc, 0xf9, 0xcb, 0x97, 0xbf, 0xff, 0xf1, 0x3a, 0xf5, 0xb0, 0xe2, 0xdc, 0x15, 0x2f, 0xbe, 0x7d, 0xf2, 0xf2, 0xe9, 0x93, 0x17, 0xdf,
214
+ 0x7d, 0xf5, 0xe7, 0x4f, 0x8f, 0x1d, 0xda, 0xdb, 0x1c, 0x1d, 0x98, 0xf0, 0x21, 0x89, 0xb1, 0xf0, 0xae, 0xe1, 0x63, 0xef, 0x26, 0x8b,
215
+ 0x61, 0x81, 0x0e, 0xfb, 0xf1, 0x01, 0x3f, 0x9d, 0xc4, 0x30, 0x42, 0xc4, 0x92, 0x40, 0x11, 0xe8, 0x76, 0xa8, 0xee, 0xcb, 0xc8, 0x02,
216
+ 0x5e, 0x5b, 0x20, 0xea, 0xc2, 0x75, 0xb0, 0xed, 0xc2, 0xdb, 0x1c, 0x58, 0xc6, 0x05, 0xbc, 0x3c, 0xbf, 0x6b, 0xd9, 0xba, 0x1f, 0xf1,
217
+ 0xb9, 0x24, 0x8e, 0x99, 0xaf, 0x46, 0xb1, 0x05, 0xdc, 0x63, 0x8c, 0x76, 0x18, 0x77, 0x3a, 0xe0, 0xaa, 0x9a, 0xcb, 0xf0, 0xf0, 0x70,
218
+ 0x9e, 0x4c, 0xdd, 0x93, 0xf3, 0xb9, 0x89, 0xbb, 0x89, 0xd0, 0x91, 0x6b, 0xee, 0x2e, 0x4a, 0xac, 0x00, 0xf7, 0xe7, 0x33, 0xa0, 0x57,
219
+ 0xe2, 0x52, 0xd9, 0x8d, 0xb0, 0x65, 0xe6, 0x0d, 0x8a, 0x12, 0x89, 0xa6, 0x38, 0xc1, 0xd2, 0x53, 0xbf, 0xb1, 0x43, 0x8c, 0x1d, 0xab,
220
+ 0xbb, 0x43, 0x88, 0xe5, 0xd7, 0x3d, 0x32, 0xe2, 0x4c, 0xb0, 0x89, 0xf4, 0xee, 0x10, 0xaf, 0x83, 0x88, 0xd3, 0x25, 0x43, 0x72, 0x60,
221
+ 0x25, 0x52, 0x2e, 0xb4, 0x43, 0x62, 0x88, 0xcb, 0xc2, 0x65, 0x20, 0x84, 0xda, 0xf2, 0xcd, 0xde, 0x6d, 0xaf, 0xc3, 0xa8, 0x6b, 0xd5,
222
+ 0x3d, 0x7c, 0x64, 0x23, 0x61, 0x5b, 0x20, 0xea, 0x30, 0x7e, 0x88, 0xa9, 0xe5, 0xc6, 0xcb, 0x68, 0x2e, 0x51, 0xec, 0x52, 0x39, 0x44,
223
+ 0x31, 0x35, 0x1d, 0xbe, 0x8b, 0x64, 0xe4, 0x32, 0x72, 0x7f, 0xc1, 0x47, 0x26, 0xae, 0x2f, 0x24, 0x44, 0x7a, 0x8a, 0x29, 0xf3, 0xfa,
224
+ 0x63, 0x2c, 0x84, 0x4b, 0xe6, 0x3a, 0x87, 0xf5, 0x1a, 0x41, 0xbf, 0x0a, 0x0c, 0xe3, 0x0e, 0xfb, 0x1e, 0x5d, 0xc4, 0x36, 0x92, 0x4b,
225
+ 0x72, 0xe8, 0xd2, 0xb9, 0x8b, 0x18, 0x33, 0x91, 0x3d, 0x76, 0xd8, 0x8d, 0x50, 0x3c, 0x73, 0xda, 0x4c, 0x92, 0xc8, 0xc4, 0x7e, 0x26,
226
+ 0x0e, 0x21, 0x45, 0x91, 0x77, 0x83, 0x49, 0x17, 0x7c, 0x8f, 0xd9, 0x3b, 0x44, 0x3d, 0x43, 0x1c, 0x50, 0xb2, 0x31, 0xdc, 0xb7, 0x09,
227
+ 0xb6, 0xc2, 0xfd, 0x66, 0x22, 0xb8, 0x05, 0xe4, 0x6a, 0x9a, 0x94, 0x27, 0x88, 0xfa, 0x65, 0xce, 0x1d, 0xb1, 0xbc, 0x8c, 0x99, 0xbd,
228
+ 0x1f, 0x17, 0x74, 0x82, 0xb0, 0x8b, 0x65, 0xda, 0x3c, 0xb6, 0xd8, 0xb5, 0xcd, 0x89, 0x33, 0x3b, 0x3a, 0xf3, 0xa9, 0x95, 0xda, 0xbb,
229
+ 0x18, 0x53, 0x74, 0x8c, 0xc6, 0x18, 0x7b, 0xb7, 0x3e, 0x73, 0x58, 0xd0, 0x61, 0x33, 0xcb, 0xe7, 0xb9, 0xd1, 0x57, 0x22, 0x60, 0x95,
230
+ 0x1d, 0xec, 0x4a, 0xac, 0x2b, 0xc8, 0xce, 0x55, 0xf5, 0x9c, 0x60, 0x01, 0x65, 0x92, 0xaa, 0x6b, 0xd6, 0x29, 0x72, 0x97, 0x08, 0x2b,
231
+ 0x65, 0xf7, 0xf1, 0x94, 0x6d, 0xb0, 0x67, 0x6f, 0x71, 0x82, 0x78, 0x16, 0x28, 0x89, 0x11, 0xdf, 0xa4, 0xf9, 0x1a, 0x44, 0xdd, 0x4a,
232
+ 0x5d, 0x38, 0xe5, 0x9c, 0x54, 0x7a, 0x9d, 0x8e, 0x0e, 0x4d, 0xe0, 0x35, 0x02, 0xe5, 0x1f, 0xe4, 0x8b, 0xd3, 0x29, 0xd7, 0x05, 0xe8,
233
+ 0x30, 0x92, 0xbb, 0xbf, 0x49, 0xeb, 0x8d, 0x08, 0x59, 0x67, 0x97, 0x7a, 0x16, 0xee, 0x7c, 0x5d, 0x70, 0x2b, 0x7e, 0x6f, 0xb3, 0xc7,
234
+ 0x60, 0x5f, 0xde, 0x3d, 0xed, 0xbe, 0x04, 0x19, 0x7c, 0x6a, 0x19, 0x20, 0xf6, 0xb7, 0xf6, 0xcd, 0x10, 0x51, 0x6b, 0x82, 0x3c, 0x61,
235
+ 0x86, 0x08, 0x0a, 0x0c, 0x17, 0xdd, 0x82, 0x88, 0x15, 0xfe, 0x5c, 0x44, 0x9d, 0xab, 0x5a, 0x6c, 0xee, 0x94, 0x9b, 0xd8, 0x9b, 0x36,
236
+ 0x0f, 0x03, 0x14, 0x46, 0x56, 0xbd, 0x13, 0x93, 0xe4, 0x8d, 0xc5, 0xcf, 0x89, 0xb2, 0x27, 0xfc, 0x77, 0xca, 0x1e, 0x77, 0x01, 0x73,
237
+ 0x06, 0x05, 0x8f, 0x5b, 0xf1, 0xfb, 0x94, 0x3a, 0x9b, 0x28, 0x65, 0xe7, 0x44, 0x81, 0xb3, 0x09, 0xf7, 0x1f, 0x2c, 0x6b, 0x7a, 0x68,
238
+ 0x9e, 0xdc, 0xc0, 0x70, 0x92, 0xac, 0x73, 0xd6, 0x79, 0x55, 0x73, 0x5e, 0xd5, 0xf8, 0xff, 0xfb, 0xaa, 0x66, 0xd3, 0x5e, 0x3e, 0xaf,
239
+ 0x65, 0xce, 0x6b, 0x99, 0xf3, 0x5a, 0xc6, 0xf5, 0xf6, 0xf5, 0x41, 0x6a, 0x99, 0xbc, 0x7c, 0x81, 0xca, 0x26, 0xef, 0xf2, 0xe8, 0x9e,
240
+ 0x4f, 0xbc, 0xb1, 0xe5, 0x33, 0x21, 0x94, 0xee, 0xcb, 0x05, 0xc5, 0xbb, 0x42, 0x77, 0x7d, 0x04, 0xbc, 0xd1, 0x8c, 0x07, 0x30, 0xa8,
241
+ 0xdb, 0x51, 0xba, 0x27, 0xb9, 0x6a, 0x01, 0xce, 0x22, 0xf8, 0x9a, 0x35, 0x98, 0x2c, 0xdc, 0x94, 0x23, 0x2d, 0xe3, 0x71, 0x26, 0x3f,
242
+ 0x27, 0x32, 0xda, 0x8f, 0xd0, 0x0c, 0x5a, 0x43, 0x65, 0xdd, 0xc0, 0x9c, 0x8a, 0x4c, 0xf5, 0x54, 0x78, 0x33, 0x26, 0xa0, 0x63, 0xa4,
243
+ 0x87, 0x75, 0x2b, 0x15, 0x9f, 0xd0, 0xad, 0xfb, 0x4e, 0xf3, 0x78, 0x8f, 0x8d, 0xd3, 0x4e, 0x67, 0xb9, 0xac, 0xba, 0x9a, 0xa9, 0x0b,
244
+ 0x05, 0x92, 0xf9, 0x78, 0x29, 0x5c, 0x8d, 0x43, 0x97, 0x4a, 0xa6, 0xe8, 0x5a, 0x3d, 0xef, 0xde, 0xad, 0xd4, 0xeb, 0x7e, 0xe8, 0x54,
245
+ 0x77, 0x59, 0x97, 0x06, 0x28, 0xd9, 0xd3, 0x18, 0x61, 0x4c, 0x66, 0x1b, 0x51, 0x75, 0x18, 0x51, 0x5f, 0x0e, 0x42, 0x14, 0x5e, 0x67,
246
+ 0x84, 0x5e, 0xd9, 0x99, 0x58, 0xd1, 0x74, 0x58, 0xd1, 0x50, 0xea, 0x97, 0xa1, 0x5a, 0x46, 0x71, 0xe5, 0x0a, 0x30, 0x6d, 0x15, 0x15,
247
+ 0x78, 0xe5, 0xf6, 0xe0, 0x45, 0xbd, 0xe5, 0x87, 0x41, 0xda, 0x41, 0x86, 0x66, 0x1c, 0x94, 0xe7, 0x63, 0x15, 0xa7, 0xb4, 0x99, 0xbc,
248
+ 0x8c, 0xae, 0x0a, 0xce, 0x99, 0x46, 0x7a, 0x93, 0x33, 0xa9, 0x99, 0x01, 0x50, 0x62, 0x2f, 0x33, 0x20, 0x8f, 0x74, 0x53, 0xd9, 0xba,
249
+ 0x71, 0x79, 0x6a, 0x75, 0x69, 0xaa, 0xbd, 0x45, 0xa4, 0x2d, 0x23, 0x8c, 0x74, 0xb3, 0x8d, 0x30, 0xd2, 0x30, 0x82, 0x17, 0xe1, 0x2c,
250
+ 0x3b, 0xcd, 0x96, 0xfb, 0x59, 0xc6, 0xba, 0x99, 0x87, 0xd4, 0x32, 0x4f, 0xb9, 0x62, 0xb9, 0x1b, 0x72, 0x33, 0xea, 0x8d, 0x0f, 0x11,
251
+ 0x6b, 0x45, 0x22, 0x27, 0xb8, 0x81, 0x26, 0x26, 0x53, 0xd0, 0xc4, 0x3b, 0x6e, 0xf9, 0xb5, 0x6a, 0x08, 0xb7, 0x2a, 0x23, 0x34, 0x6b,
252
+ 0xf9, 0x13, 0xe8, 0x18, 0xc3, 0xd7, 0x78, 0x06, 0xb9, 0x23, 0xd4, 0x5b, 0x17, 0xa2, 0x53, 0xb8, 0x76, 0x19, 0x49, 0x9e, 0x6e, 0xf8,
253
+ 0x77, 0x61, 0x96, 0x19, 0x17, 0xb2, 0x87, 0x44, 0x94, 0x3a, 0x5c, 0x93, 0x4e, 0xca, 0x06, 0x31, 0x91, 0x98, 0x7b, 0x94, 0xc4, 0x2d,
254
+ 0x5f, 0x2d, 0x7f, 0x95, 0x0d, 0x34, 0xd1, 0x1c, 0xa2, 0x6d, 0x2b, 0x57, 0x80, 0x10, 0x3e, 0x5a, 0xe3, 0x9a, 0x40, 0x2b, 0x1f, 0x9b,
255
+ 0x71, 0x10, 0x74, 0x3b, 0xc8, 0x78, 0x32, 0xc1, 0x23, 0x69, 0x86, 0xdd, 0x18, 0x51, 0x9e, 0x4e, 0x1f, 0x81, 0xe1, 0x53, 0xae, 0x70,
256
+ 0xfe, 0xaa, 0xc5, 0xdf, 0x1d, 0xac, 0x24, 0xd9, 0x1c, 0xc2, 0xbd, 0x1f, 0x8d, 0x8f, 0xbd, 0x03, 0x3a, 0xe7, 0x37, 0x11, 0xa4, 0x58,
257
+ 0x58, 0x2f, 0x2b, 0x07, 0x8e, 0x89, 0x80, 0x8b, 0x83, 0x72, 0xea, 0xcd, 0x31, 0x81, 0x9b, 0xb0, 0x15, 0x91, 0xe5, 0xf9, 0x77, 0xe2,
258
+ 0x60, 0xca, 0x68, 0xd7, 0xbc, 0x8a, 0xd2, 0x39, 0x94, 0x8e, 0x23, 0x3a, 0x8b, 0x50, 0x76, 0xa2, 0x98, 0x64, 0x9e, 0xc2, 0x35, 0x89,
259
+ 0xae, 0xcc, 0xd1, 0x4f, 0x2b, 0x1f, 0x18, 0x4f, 0xd9, 0x9a, 0xc1, 0xa1, 0xeb, 0x2e, 0x3c, 0x98, 0xaa, 0x03, 0xf6, 0xbd, 0x4f, 0xdd,
260
+ 0x37, 0x1f, 0xd5, 0xca, 0x73, 0x06, 0x69, 0xe6, 0x67, 0xa6, 0xc5, 0x2a, 0xea, 0xd4, 0x74, 0x93, 0xe9, 0x87, 0x3b, 0xe4, 0x0d, 0xab,
261
+ 0xf2, 0x43, 0xd4, 0xb2, 0x2a, 0xa5, 0x6e, 0xfd, 0x4e, 0x2d, 0x72, 0xae, 0x6b, 0x2e, 0xb9, 0x0e, 0x12, 0xd5, 0x79, 0x4a, 0xbc, 0xe1,
262
+ 0xd4, 0x7d, 0x8b, 0x03, 0xc1, 0x30, 0x2d, 0x9f, 0xcc, 0x32, 0x4d, 0x59, 0xbc, 0x4e, 0xc3, 0x8a, 0xb3, 0xb3, 0x51, 0xdb, 0xb4, 0x33,
263
+ 0x2c, 0x08, 0x0c, 0x4f, 0xd4, 0x36, 0xf8, 0x6d, 0x75, 0x46, 0x38, 0x3d, 0xf1, 0xae, 0x27, 0x3f, 0xc8, 0x9d, 0xcc, 0x5a, 0x75, 0x40,
264
+ 0x2c, 0xeb, 0x4a, 0x9d, 0xf8, 0xfa, 0xca, 0xdc, 0xbc, 0xd5, 0x66, 0x07, 0x77, 0x81, 0x3c, 0x7a, 0x70, 0x7f, 0x38, 0xa7, 0x52, 0xe8,
265
+ 0x50, 0x42, 0x6f, 0x97, 0x23, 0x28, 0xfa, 0xd2, 0x1b, 0xc8, 0x94, 0x36, 0x60, 0x8b, 0xdc, 0x93, 0x59, 0x8d, 0x08, 0xdf, 0xbc, 0x39,
266
+ 0x27, 0x2d, 0xff, 0x7e, 0x29, 0x6c, 0x07, 0xdd, 0x4a, 0xd8, 0x2d, 0x94, 0x1a, 0x61, 0xbf, 0x10, 0x54, 0x83, 0x52, 0xa1, 0x11, 0xb6,
267
+ 0xab, 0x85, 0x76, 0x18, 0x56, 0xcb, 0xfd, 0xb0, 0x5c, 0xea, 0x75, 0x2a, 0x0f, 0xe0, 0x60, 0x91, 0x51, 0x5c, 0x0e, 0xd3, 0xeb, 0xfa,
268
+ 0x01, 0x5c, 0x61, 0xd0, 0x45, 0x76, 0x69, 0xaf, 0xc7, 0xd7, 0x2e, 0xee, 0xe3, 0xe5, 0x2d, 0xcd, 0x85, 0x11, 0x8b, 0x8b, 0x4c, 0x5f,
269
+ 0xcc, 0x17, 0xb5, 0xe1, 0xfa, 0xe2, 0xbe, 0x5c, 0xd9, 0x7c, 0x71, 0xef, 0x11, 0x20, 0x9d, 0xfb, 0xb5, 0xca, 0xa0, 0x59, 0x6d, 0x76,
270
+ 0x6a, 0x85, 0x66, 0xb5, 0x3d, 0x28, 0x04, 0xbd, 0x4e, 0xa3, 0xd0, 0xec, 0xd6, 0x3a, 0x85, 0x5e, 0xad, 0x5b, 0xef, 0x0d, 0x7a, 0xdd,
271
+ 0xb0, 0xd1, 0x1c, 0x3c, 0xf0, 0xbd, 0x23, 0x0d, 0x0e, 0xda, 0xd5, 0x6e, 0x50, 0xeb, 0x37, 0x0a, 0xb5, 0x72, 0xb7, 0x5b, 0x08, 0x6a,
272
+ 0x25, 0x65, 0x7e, 0xa3, 0x59, 0xa8, 0x07, 0x95, 0x4a, 0x3b, 0xa8, 0xb7, 0x1b, 0xfd, 0xa0, 0xfd, 0x20, 0x2b, 0x63, 0x60, 0xe5, 0x29,
273
+ 0x7d, 0x64, 0xbe, 0x00, 0xf7, 0x6a, 0xbb, 0xb6, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00,
274
+ 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xff, 0x6b, 0x0c, 0xe9, 0xcd, 0x01, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x00, 0x18, 0x00,
275
+ 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x68, 0x65, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x65, 0x65, 0x74, 0x31,
276
+ 0x2e, 0x78, 0x6d, 0x6c, 0x9c, 0x93, 0x4d, 0x8b, 0xdb, 0x30, 0x10, 0x86, 0xef, 0x85, 0xfe, 0x07, 0xa1, 0xbb, 0x2d, 0xdb, 0xf1, 0x3a,
277
+ 0x89, 0x89, 0xb3, 0x6c, 0x36, 0x0d, 0xdd, 0x43, 0xa1, 0xf4, 0xf3, 0x2c, 0xcb, 0x63, 0x5b, 0xc4, 0x92, 0x8c, 0xa4, 0x6c, 0x12, 0x4a,
278
+ 0xff, 0x7b, 0xc7, 0x0e, 0xf1, 0x16, 0x72, 0x09, 0x0b, 0x16, 0x68, 0xc6, 0x9a, 0x67, 0x66, 0xa4, 0x77, 0x56, 0x8f, 0x27, 0xd5, 0x91,
279
+ 0x57, 0xb0, 0x4e, 0x1a, 0x5d, 0xd0, 0x38, 0x8c, 0x28, 0x01, 0x2d, 0x4c, 0x25, 0x75, 0x53, 0xd0, 0x9f, 0x3f, 0x76, 0xc1, 0x82, 0x12,
280
+ 0xe7, 0xb9, 0xae, 0x78, 0x67, 0x34, 0x14, 0xf4, 0x0c, 0x8e, 0x3e, 0xae, 0x3f, 0x7e, 0x58, 0x1d, 0x8d, 0xdd, 0xbb, 0x16, 0xc0, 0x13,
281
+ 0x24, 0x68, 0x57, 0xd0, 0xd6, 0xfb, 0x3e, 0x67, 0xcc, 0x89, 0x16, 0x14, 0x77, 0xa1, 0xe9, 0x41, 0xe3, 0x9f, 0xda, 0x58, 0xc5, 0x3d,
282
+ 0x9a, 0xb6, 0x61, 0xae, 0xb7, 0xc0, 0xab, 0x31, 0x48, 0x75, 0x2c, 0x89, 0xa2, 0x8c, 0x29, 0x2e, 0x35, 0xbd, 0x10, 0x72, 0x7b, 0x0f,
283
+ 0xc3, 0xd4, 0xb5, 0x14, 0xb0, 0x35, 0xe2, 0xa0, 0x40, 0xfb, 0x0b, 0xc4, 0x42, 0xc7, 0x3d, 0xd6, 0xef, 0x5a, 0xd9, 0xbb, 0x2b, 0x4d,
284
+ 0x89, 0x7b, 0x70, 0x8a, 0xdb, 0xfd, 0xa1, 0x0f, 0x84, 0x51, 0x3d, 0x22, 0x4a, 0xd9, 0x49, 0x7f, 0x1e, 0xa1, 0x94, 0x28, 0x91, 0xbf,
285
+ 0x34, 0xda, 0x58, 0x5e, 0x76, 0xd8, 0xf7, 0x29, 0x4e, 0xb9, 0x20, 0x27, 0x8b, 0x5f, 0x82, 0x6b, 0x76, 0x4d, 0x33, 0xfa, 0x6f, 0x32,
286
+ 0x29, 0x29, 0xac, 0x71, 0xa6, 0xf6, 0x21, 0x92, 0xd9, 0xa5, 0xe6, 0xdb, 0xf6, 0x97, 0x6c, 0xc9, 0xb8, 0x98, 0x48, 0xb7, 0xfd, 0xdf,
287
+ 0x85, 0x89, 0x53, 0x66, 0xe1, 0x55, 0x0e, 0x0f, 0xf8, 0x86, 0x4a, 0xde, 0x57, 0x52, 0xfc, 0x30, 0xb1, 0x92, 0x37, 0xd8, 0xec, 0x9d,
288
+ 0xb0, 0x6c, 0x82, 0x0d, 0xd7, 0x65, 0xf3, 0x83, 0xac, 0x0a, 0xfa, 0x27, 0x4a, 0x97, 0xbb, 0x4d, 0xbc, 0x49, 0x83, 0xe4, 0x29, 0x8b,
289
+ 0x83, 0x34, 0x4b, 0x67, 0xc1, 0x62, 0x11, 0x67, 0xc1, 0x62, 0x33, 0xcf, 0x3e, 0x3d, 0xcf, 0xb2, 0xdd, 0x36, 0xdd, 0xfc, 0xa5, 0xeb,
290
+ 0x55, 0x25, 0xf1, 0x85, 0x87, 0xae, 0x88, 0x85, 0xba, 0xa0, 0x4f, 0x31, 0x65, 0xeb, 0xd5, 0x28, 0x9e, 0x5f, 0x12, 0x8e, 0xee, 0xbf,
291
+ 0x3d, 0xf1, 0xbc, 0xfc, 0x0e, 0x1d, 0x08, 0x0f, 0x98, 0x20, 0xa6, 0x64, 0xd0, 0x66, 0x69, 0xcc, 0x7e, 0x38, 0xf8, 0x82, 0xae, 0x68,
292
+ 0x08, 0x65, 0x37, 0xb1, 0xbb, 0x51, 0x9b, 0x5f, 0x2d, 0x29, 0xb9, 0x83, 0x67, 0xd3, 0xfd, 0x96, 0x95, 0x6f, 0x11, 0x80, 0x33, 0x50,
293
+ 0x41, 0xcd, 0x0f, 0x9d, 0xff, 0x66, 0x8e, 0x9f, 0x41, 0x36, 0xad, 0x47, 0x6f, 0x86, 0x3d, 0x0c, 0x22, 0xc8, 0xab, 0xf3, 0x16, 0x9c,
294
+ 0x40, 0xf5, 0x21, 0x38, 0x4c, 0xa6, 0xaa, 0xb6, 0xdc, 0x73, 0x4c, 0xd3, 0xf3, 0x06, 0xbe, 0x70, 0xdb, 0x48, 0xed, 0x48, 0x07, 0xf5,
295
+ 0x78, 0x68, 0x4e, 0x89, 0xbd, 0x50, 0xa2, 0x10, 0xf7, 0xde, 0xf4, 0x43, 0xe8, 0xfc, 0x81, 0x92, 0xd2, 0x78, 0x6f, 0xd4, 0xd5, 0x6a,
296
+ 0x71, 0x3c, 0x00, 0x65, 0x10, 0x85, 0x78, 0x61, 0xb5, 0x31, 0xfe, 0x6a, 0x0c, 0xe5, 0x4f, 0x03, 0xb7, 0xfe, 0x07, 0x00, 0x00, 0xff,
297
+ 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xc2, 0x5e, 0x59, 0x08, 0x90,
298
+ 0x01, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x10, 0x00, 0x08, 0x01, 0x64, 0x6f, 0x63, 0x50, 0x72, 0x6f, 0x70, 0x73, 0x2f, 0x61, 0x70,
299
+ 0x70, 0x2e, 0x78, 0x6d, 0x6c, 0x20, 0xa2, 0x04, 0x01, 0x28, 0xa0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
305
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x92, 0x4d, 0x6f, 0xdb, 0x30, 0x0c, 0x86, 0xef, 0x03, 0xfa, 0x1f, 0x0c, 0xdd, 0x1b, 0x39, 0x6d,
312
+ 0x51, 0x0c, 0x81, 0xac, 0x62, 0x48, 0x57, 0xf4, 0xb0, 0x62, 0x01, 0x92, 0x76, 0x67, 0x4e, 0xa6, 0x63, 0xa1, 0xb2, 0x24, 0x88, 0xac,
313
+ 0x91, 0xec, 0xd7, 0x4f, 0xb6, 0xd1, 0xd4, 0xd9, 0x76, 0xda, 0x8d, 0x1f, 0x2f, 0x5e, 0x3e, 0xa2, 0xa8, 0xee, 0x0e, 0x9d, 0x2b, 0x7a,
314
+ 0x4c, 0x64, 0x83, 0xaf, 0xc4, 0x72, 0x51, 0x8a, 0x02, 0xbd, 0x09, 0xb5, 0xf5, 0xfb, 0x4a, 0x3c, 0xef, 0x1e, 0x2e, 0x3f, 0x8b, 0x82,
315
+ 0x18, 0x7c, 0x0d, 0x2e, 0x78, 0xac, 0xc4, 0x11, 0x49, 0xdc, 0xe9, 0x8b, 0x4f, 0x6a, 0x93, 0x42, 0xc4, 0xc4, 0x16, 0xa9, 0xc8, 0x16,
316
+ 0x9e, 0x2a, 0xd1, 0x32, 0xc7, 0x95, 0x94, 0x64, 0x5a, 0xec, 0x80, 0x16, 0xb9, 0xed, 0x73, 0xa7, 0x09, 0xa9, 0x03, 0xce, 0x69, 0xda,
317
+ 0xcb, 0xd0, 0x34, 0xd6, 0xe0, 0x7d, 0x30, 0x6f, 0x1d, 0x7a, 0x96, 0x57, 0x65, 0x79, 0x2b, 0xf1, 0xc0, 0xe8, 0x6b, 0xac, 0x2f, 0xe3,
318
+ 0xc9, 0x50, 0x4c, 0x8e, 0xab, 0x9e, 0xff, 0xd7, 0xb4, 0x0e, 0x66, 0xe0, 0xa3, 0x97, 0xdd, 0x31, 0x66, 0x60, 0xad, 0xbe, 0xc4, 0xe8,
319
+ 0xac, 0x01, 0xce, 0xaf, 0xd4, 0x4f, 0xd6, 0xa4, 0x40, 0xa1, 0xe1, 0xe2, 0x09, 0x8c, 0xf5, 0x1c, 0xa8, 0x2d, 0xbe, 0x1e, 0x0c, 0x3a,
320
+ 0x25, 0xe7, 0x32, 0x95, 0x39, 0xb7, 0x68, 0xde, 0x92, 0xe5, 0xa3, 0x2e, 0x95, 0x9c, 0xa7, 0x6a, 0x6b, 0xc0, 0xe1, 0x3a, 0x8f, 0xd0,
321
+ 0x0d, 0x38, 0x42, 0x25, 0x3f, 0x0a, 0xea, 0x11, 0x61, 0x58, 0xdf, 0x06, 0x6c, 0x22, 0xad, 0x7a, 0x5e, 0xf5, 0x68, 0x38, 0xa4, 0x82,
322
+ 0xec, 0xaf, 0xbc, 0xc0, 0x2b, 0x51, 0xfc, 0x04, 0xc2, 0x01, 0xac, 0x12, 0x3d, 0x24, 0x0b, 0x9e, 0x33, 0xe0, 0x20, 0x9b, 0x92, 0x31,
323
+ 0x76, 0x91, 0x38, 0xe9, 0x1f, 0x21, 0xbd, 0x52, 0x8b, 0xc8, 0xa4, 0x64, 0x16, 0x4c, 0xc5, 0x31, 0x9c, 0x6b, 0xe7, 0xb1, 0xbd, 0xd1,
324
+ 0xcb, 0x51, 0x90, 0x83, 0x73, 0xe1, 0x60, 0x30, 0x81, 0xe4, 0xc6, 0x39, 0xe2, 0xce, 0xb2, 0x43, 0xfa, 0xde, 0x6c, 0x20, 0xf1, 0x3f,
325
+ 0x88, 0x97, 0x73, 0xe2, 0x91, 0x61, 0xe2, 0x9d, 0x70, 0xb6, 0x03, 0xdf, 0x34, 0x73, 0xce, 0x37, 0x3e, 0x39, 0x4f, 0xfa, 0xc3, 0x7b,
326
+ 0x1d, 0xba, 0x08, 0xfe, 0x98, 0x1b, 0xa7, 0xe8, 0x9b, 0xf5, 0xaf, 0xf4, 0x1c, 0x77, 0xe1, 0x1e, 0x18, 0xdf, 0xd7, 0x79, 0x5e, 0x54,
327
+ 0xdb, 0x16, 0x12, 0xd6, 0xf9, 0x07, 0x4e, 0xeb, 0x3e, 0x15, 0xd4, 0x63, 0xde, 0x64, 0x72, 0x83, 0xc9, 0xba, 0x05, 0xbf, 0xc7, 0xfa,
328
+ 0x5d, 0xf3, 0x77, 0x63, 0x38, 0x83, 0x97, 0xe9, 0xd6, 0xf5, 0xf2, 0x76, 0x51, 0x5e, 0x97, 0xf9, 0x5f, 0x67, 0x35, 0x25, 0x3f, 0xae,
329
+ 0x5a, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21,
330
+ 0x00, 0xbd, 0xde, 0xac, 0xb8, 0x45, 0x01, 0x00, 0x00, 0x6f, 0x02, 0x00, 0x00, 0x11, 0x00, 0x08, 0x01, 0x64, 0x6f, 0x63, 0x50, 0x72,
331
+ 0x6f, 0x70, 0x73, 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x78, 0x6d, 0x6c, 0x20, 0xa2, 0x04, 0x01, 0x28, 0xa0, 0x00, 0x01, 0x00, 0x00,
332
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x92, 0x5f, 0x4b, 0xc3, 0x30, 0x14, 0xc5, 0xdf, 0x05,
344
+ 0xbf, 0x43, 0xc9, 0x7b, 0x9b, 0x66, 0x1b, 0x63, 0x96, 0xb6, 0x83, 0x29, 0x7b, 0xd1, 0x81, 0xe0, 0x44, 0xf1, 0x2d, 0x24, 0x77, 0x5b,
345
+ 0xb0, 0xf9, 0x43, 0x12, 0xd7, 0xed, 0xdb, 0x9b, 0xb6, 0x5b, 0xad, 0xd4, 0x17, 0x1f, 0x93, 0x73, 0xee, 0x2f, 0xe7, 0x5c, 0x92, 0x2f,
346
+ 0x4f, 0xb2, 0x8a, 0x8e, 0x60, 0x9d, 0xd0, 0xaa, 0x40, 0x24, 0x49, 0x51, 0x04, 0x8a, 0x69, 0x2e, 0xd4, 0xbe, 0x40, 0xaf, 0xdb, 0x75,
347
+ 0xbc, 0x40, 0x91, 0xf3, 0x54, 0x71, 0x5a, 0x69, 0x05, 0x05, 0x3a, 0x83, 0x43, 0xcb, 0xf2, 0xf6, 0x26, 0x67, 0x26, 0x63, 0xda, 0xc2,
348
+ 0xb3, 0xd5, 0x06, 0xac, 0x17, 0xe0, 0xa2, 0x40, 0x52, 0x2e, 0x63, 0xa6, 0x40, 0x07, 0xef, 0x4d, 0x86, 0xb1, 0x63, 0x07, 0x90, 0xd4,
349
+ 0x25, 0xc1, 0xa1, 0x82, 0xb8, 0xd3, 0x56, 0x52, 0x1f, 0x8e, 0x76, 0x8f, 0x0d, 0x65, 0x9f, 0x74, 0x0f, 0x78, 0x92, 0xa6, 0x73, 0x2c,
350
+ 0xc1, 0x53, 0x4e, 0x3d, 0xc5, 0x0d, 0x30, 0x36, 0x3d, 0x11, 0x5d, 0x90, 0x9c, 0xf5, 0x48, 0xf3, 0x65, 0xab, 0x16, 0xc0, 0x19, 0x86,
351
+ 0x0a, 0x24, 0x28, 0xef, 0x30, 0x49, 0x08, 0xfe, 0xf1, 0x7a, 0xb0, 0xd2, 0xfd, 0x39, 0xd0, 0x2a, 0x03, 0xa7, 0x14, 0xfe, 0x6c, 0x42,
352
+ 0xa7, 0x4b, 0xdc, 0x21, 0x9b, 0xb3, 0x4e, 0xec, 0xdd, 0x27, 0x27, 0x7a, 0x63, 0x5d, 0xd7, 0x49, 0x3d, 0x6d, 0x63, 0x84, 0xfc, 0x04,
353
+ 0xbf, 0x6f, 0x9e, 0x5e, 0xda, 0xaa, 0xb1, 0x50, 0xcd, 0xae, 0x18, 0xa0, 0x32, 0xe7, 0x2c, 0x63, 0x16, 0xa8, 0xd7, 0xb6, 0x7c, 0x04,
354
+ 0xa5, 0xc0, 0x1f, 0xa2, 0x15, 0xad, 0x5c, 0x05, 0xc7, 0x1c, 0x0f, 0xb4, 0x66, 0x8f, 0x15, 0x75, 0x7e, 0x13, 0x56, 0xbe, 0x13, 0xc0,
355
+ 0x57, 0xe7, 0xb1, 0x7d, 0x6c, 0x09, 0xf4, 0xb6, 0x4c, 0xf7, 0x04, 0xf0, 0x28, 0xc4, 0xcb, 0xba, 0x32, 0x57, 0xe5, 0x6d, 0x7a, 0xff,
356
+ 0xb0, 0x5d, 0xa3, 0x72, 0x92, 0x92, 0xbb, 0x38, 0x5d, 0xc4, 0x64, 0xbe, 0x4d, 0xd3, 0x6c, 0x3a, 0xcb, 0xc8, 0xec, 0xa3, 0x49, 0xf0,
357
+ 0x6b, 0xbe, 0x89, 0xdb, 0x5d, 0xc8, 0x4b, 0x8e, 0xff, 0x10, 0x27, 0xf3, 0x01, 0xf1, 0x0a, 0x28, 0x73, 0x3c, 0xfa, 0x22, 0xe5, 0x37,
358
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x9a, 0xab, 0x0f, 0x4f, 0x5e,
359
+ 0xff, 0xec, 0xaa, 0x93, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x73, 0x68, 0x61, 0x72,
360
+ 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0x35, 0x8d, 0x41, 0x0a, 0xc2, 0x30, 0x10, 0x45, 0xf7,
361
+ 0x82, 0x77, 0x08, 0xb3, 0xd7, 0xa9, 0x2e, 0x44, 0x24, 0x49, 0x17, 0x82, 0x27, 0xd0, 0x03, 0x84, 0x76, 0x6c, 0x03, 0xcd, 0xa4, 0x66,
362
+ 0xa6, 0xa2, 0xb7, 0x37, 0x5d, 0xb8, 0xf8, 0xf0, 0x1f, 0x9f, 0xcf, 0xb3, 0xed, 0x27, 0x4d, 0xe6, 0x4d, 0x45, 0x62, 0x66, 0x07, 0x87,
363
+ 0x7d, 0x03, 0x86, 0xb8, 0xcb, 0x7d, 0xe4, 0xc1, 0xc1, 0xe3, 0x7e, 0xdb, 0x9d, 0xc1, 0x88, 0x06, 0xee, 0xc3, 0x94, 0x99, 0x1c, 0x7c,
364
+ 0x49, 0xa0, 0xf5, 0xdb, 0x8d, 0x15, 0x51, 0x53, 0xbf, 0x2c, 0x0e, 0x46, 0xd5, 0xf9, 0x82, 0x28, 0xdd, 0x48, 0x29, 0xc8, 0x3e, 0xcf,
365
+ 0xc4, 0x75, 0x79, 0xe6, 0x92, 0x82, 0x56, 0x2c, 0x03, 0xca, 0x5c, 0x28, 0xf4, 0x32, 0x12, 0x69, 0x9a, 0xf0, 0xd8, 0x34, 0x27, 0x4c,
366
+ 0x21, 0x32, 0x98, 0x2e, 0x2f, 0xac, 0xd5, 0x0b, 0x66, 0xe1, 0xf8, 0x5a, 0xe8, 0xfa, 0x67, 0x6f, 0x25, 0x7a, 0xab, 0xde, 0xe2, 0x9a,
367
+ 0xb5, 0x63, 0x35, 0x56, 0xf1, 0x0f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x99, 0x64, 0xef, 0x50, 0xd9, 0x19,
368
+ 0xd7, 0x73, 0x3f, 0x01, 0x00, 0x00, 0x7e, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x5b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
369
+ 0x5f, 0x54, 0x79, 0x70, 0x65, 0x73, 0x5d, 0x2e, 0x78, 0x6d, 0x6c, 0xad, 0x93, 0xcd, 0x4e, 0xc3, 0x30, 0x10, 0x84, 0xef, 0x3c, 0x45,
370
+ 0xe4, 0x2b, 0x4a, 0xdc, 0x72, 0x40, 0x08, 0x35, 0xed, 0x81, 0x9f, 0x23, 0x54, 0xa2, 0x3c, 0x80, 0xb1, 0x37, 0x8d, 0xd5, 0xf8, 0x47,
371
+ 0xbb, 0x6e, 0x69, 0xdf, 0x9e, 0x4d, 0x52, 0x21, 0x40, 0x55, 0x03, 0xb4, 0x97, 0x58, 0xf1, 0xce, 0xcc, 0x37, 0x3e, 0xec, 0x64, 0xb6,
372
+ 0x75, 0x4d, 0xb6, 0x01, 0x24, 0x1b, 0x7c, 0x29, 0xc6, 0xc5, 0x48, 0x64, 0xe0, 0x75, 0x30, 0xd6, 0x2f, 0x4b, 0xf1, 0xba, 0x78, 0xcc,
373
+ 0x6f, 0xc4, 0x6c, 0x3a, 0x59, 0xec, 0x22, 0x50, 0xc6, 0x52, 0x4f, 0xa5, 0xa8, 0x53, 0x8a, 0xb7, 0x52, 0x92, 0xae, 0xc1, 0x29, 0x2a,
374
+ 0x42, 0x04, 0xcf, 0x93, 0x2a, 0xa0, 0x53, 0x89, 0x7f, 0x71, 0x29, 0xa3, 0xd2, 0x2b, 0xb5, 0x04, 0x79, 0x35, 0x1a, 0x5d, 0x4b, 0x1d,
375
+ 0x7c, 0x02, 0x9f, 0xf2, 0xd4, 0x66, 0x88, 0xe9, 0xe4, 0x1e, 0x2a, 0xb5, 0x6e, 0x52, 0xf6, 0xb0, 0xe5, 0xeb, 0x1e, 0x8b, 0xd0, 0x90,
376
+ 0xc8, 0xee, 0x7a, 0x61, 0xcb, 0x2a, 0x85, 0x8a, 0xb1, 0xb1, 0x5a, 0x25, 0x9e, 0xcb, 0x8d, 0x37, 0x3f, 0x28, 0xf9, 0x9e, 0x50, 0xb0,
377
+ 0xb3, 0xd3, 0x50, 0x6d, 0x23, 0x5d, 0xb2, 0x40, 0xc8, 0x83, 0x04, 0x9e, 0x1c, 0x01, 0xec, 0x7d, 0xcf, 0x1b, 0x40, 0xb4, 0x06, 0xb2,
378
+ 0xb9, 0xc2, 0xf4, 0xa4, 0x1c, 0xab, 0xe4, 0xb6, 0x91, 0xef, 0x01, 0x57, 0x6f, 0x21, 0xac, 0x0a, 0x96, 0xfd, 0xad, 0x65, 0xa8, 0x2a,
379
+ 0xab, 0xc1, 0x04, 0xbd, 0x76, 0x6c, 0x29, 0x28, 0x22, 0x28, 0x43, 0x35, 0x40, 0x72, 0x4d, 0xd1, 0x9d, 0x85, 0x53, 0xd6, 0x5f, 0x0e,
380
+ 0xf3, 0x3b, 0x31, 0xc9, 0xee, 0x18, 0x9f, 0xb9, 0xc8, 0x67, 0xfe, 0x40, 0x8f, 0x54, 0x83, 0x83, 0xfe, 0x7b, 0x7a, 0x85, 0x2e, 0x66,
381
+ 0x00, 0x48, 0x69, 0xd7, 0x00, 0x9d, 0x8c, 0xfa, 0xfe, 0xda, 0x3e, 0x74, 0x88, 0x5c, 0x2b, 0x04, 0xf3, 0x92, 0x90, 0xd7, 0xe0, 0xec,
382
+ 0x05, 0xbe, 0x64, 0x1f, 0xed, 0xc1, 0xfe, 0x39, 0x86, 0x48, 0x52, 0x07, 0x84, 0xb6, 0xc4, 0xff, 0x56, 0xa4, 0x75, 0xe7, 0x11, 0x79,
383
+ 0x8a, 0xc9, 0xc2, 0xef, 0x88, 0x1c, 0x7d, 0xf2, 0xab, 0xa1, 0xdd, 0x3e, 0x03, 0xe6, 0x00, 0x5b, 0xb6, 0x79, 0x34, 0xbd, 0xf8, 0x00,
384
+ 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0xa7, 0x64, 0xef, 0x50, 0x59, 0xaf, 0xf9, 0x51, 0xdc, 0x00, 0x00, 0x00,
385
+ 0xa8, 0x02, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x62,
386
+ 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x72, 0x65, 0x6c, 0x73, 0xad, 0x92, 0xcd, 0x6a, 0xc3, 0x30, 0x10, 0x84, 0xef, 0x7d,
387
+ 0x0a, 0xb1, 0xf7, 0x5a, 0x76, 0x5a, 0x4a, 0x29, 0x51, 0x72, 0x29, 0x85, 0x5c, 0xdb, 0xf4, 0x01, 0x84, 0xbc, 0xb6, 0x4c, 0x6c, 0x49,
388
+ 0xec, 0x6e, 0x7f, 0xf2, 0xf6, 0x11, 0x0e, 0x24, 0x31, 0x84, 0x90, 0x83, 0x4f, 0x62, 0x46, 0xda, 0x99, 0x4f, 0xb0, 0xcb, 0xf5, 0xff,
389
+ 0xd0, 0xab, 0x5f, 0x24, 0xee, 0x62, 0x30, 0x50, 0x15, 0x25, 0x28, 0x0c, 0x2e, 0xd6, 0x5d, 0x68, 0x0d, 0x7c, 0x6f, 0x3f, 0x1e, 0x5f,
390
+ 0x61, 0xbd, 0x5a, 0x7e, 0x62, 0x6f, 0x25, 0xbf, 0x60, 0xdf, 0x25, 0x56, 0x79, 0x24, 0xb0, 0x01, 0x2f, 0x92, 0xde, 0xb4, 0x66, 0xe7,
391
+ 0x71, 0xb0, 0x5c, 0xc4, 0x84, 0x21, 0xdf, 0x34, 0x91, 0x06, 0x2b, 0x59, 0x52, 0xab, 0x93, 0x75, 0x3b, 0xdb, 0xa2, 0x5e, 0x94, 0xe5,
392
+ 0x8b, 0xa6, 0xcb, 0x0c, 0x98, 0x66, 0xaa, 0x4d, 0x6d, 0x80, 0x36, 0xf5, 0x33, 0xa8, 0xed, 0x3e, 0xe1, 0x3d, 0xd9, 0xb1, 0x69, 0x3a,
393
+ 0x87, 0xef, 0xd1, 0xfd, 0x0c, 0x18, 0xe4, 0x4a, 0x85, 0x66, 0x6f, 0x09, 0xeb, 0x2f, 0xa1, 0xfc, 0x17, 0xce, 0xc1, 0x96, 0x5a, 0x14,
394
+ 0x03, 0x13, 0xbb, 0xc8, 0xa9, 0xa0, 0xaf, 0xc3, 0x3c, 0xcd, 0x0a, 0x23, 0xfb, 0x1e, 0x2f, 0x28, 0x46, 0x7d, 0xb3, 0x7e, 0x31, 0x67,
395
+ 0xbd, 0xe4, 0x59, 0x3c, 0xb7, 0x8f, 0xf2, 0x68, 0x56, 0xb7, 0x18, 0xaa, 0x39, 0x19, 0xfe, 0x22, 0xed, 0xd8, 0x23, 0xca, 0x99, 0xe3,
396
+ 0x64, 0xb1, 0x1e, 0x8f, 0x13, 0x8c, 0x9e, 0x6c, 0xdc, 0xea, 0xe1, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00,
397
+ 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xb5, 0x55, 0x30, 0x23, 0xf4, 0x00, 0x00, 0x00, 0x4c, 0x02, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
398
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x2e, 0x72,
399
+ 0x65, 0x6c, 0x73, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x47, 0x88, 0xbc,
400
+ 0xe2, 0x5d, 0x03, 0x00, 0x00, 0x35, 0x08, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401
+ 0x00, 0x25, 0x03, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b,
402
+ 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xf0, 0x08, 0x58, 0xf4, 0xa5, 0x02, 0x00, 0x00,
403
+ 0x52, 0x06, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x06, 0x00, 0x00,
404
+ 0x78, 0x6c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06,
405
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xc1, 0x17, 0x10, 0xbe, 0x4e, 0x07, 0x00, 0x00, 0xc6, 0x20, 0x00, 0x00, 0x13, 0x00, 0x00,
406
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x09, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x74, 0x68, 0x65, 0x6d,
407
+ 0x65, 0x2f, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x31, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00,
408
+ 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xff, 0x6b, 0x0c, 0xe9, 0xcd, 0x01, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
409
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x10, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x73,
410
+ 0x68, 0x65, 0x65, 0x74, 0x73, 0x2f, 0x73, 0x68, 0x65, 0x65, 0x74, 0x31, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00,
411
+ 0x14, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xc2, 0x5e, 0x59, 0x08, 0x90, 0x01, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00,
412
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x13, 0x00, 0x00, 0x64, 0x6f, 0x63, 0x50,
413
+ 0x72, 0x6f, 0x70, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x14, 0x00, 0x06, 0x00,
414
+ 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0xbd, 0xde, 0xac, 0xb8, 0x45, 0x01, 0x00, 0x00, 0x6f, 0x02, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
415
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0x15, 0x00, 0x00, 0x64, 0x6f, 0x63, 0x50, 0x72, 0x6f, 0x70, 0x73,
416
+ 0x2f, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x9a,
417
+ 0xab, 0x0f, 0x4f, 0x5e, 0xff, 0xec, 0xaa, 0x93, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0xb6, 0x81, 0x43, 0x18, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x74,
419
+ 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0x99,
420
+ 0x64, 0xef, 0x50, 0xd9, 0x19, 0xd7, 0x73, 0x3f, 0x01, 0x00, 0x00, 0x7e, 0x04, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0xb6, 0x81, 0x08, 0x19, 0x00, 0x00, 0x5b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x54, 0x79,
422
+ 0x70, 0x65, 0x73, 0x5d, 0x2e, 0x78, 0x6d, 0x6c, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x02, 0x00, 0x08, 0x00, 0xa7, 0x64,
423
+ 0xef, 0x50, 0x59, 0xaf, 0xf9, 0x51, 0xdc, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424
+ 0x01, 0x00, 0x00, 0x00, 0xb6, 0x81, 0x78, 0x1a, 0x00, 0x00, 0x78, 0x6c, 0x2f, 0x5f, 0x72, 0x65, 0x6c, 0x73, 0x2f, 0x77, 0x6f, 0x72,
425
+ 0x6b, 0x62, 0x6f, 0x6f, 0x6b, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x72, 0x65, 0x6c, 0x73, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00,
426
+ 0x0a, 0x00, 0x0a, 0x00, 0x80, 0x02, 0x00, 0x00, 0x8c, 0x1b, 0x00, 0x00, 0x00, 0x00
427
+ };
428
+ } // namespace
429
+
430
+ XLDocument::XLDocument(const IZipArchive& zipArchive) : m_xmlSavingDeclaration{}, m_archive(zipArchive) {}
431
+
432
+ /**
433
+ * @details An alternative constructor, taking a std::string with the path to the .xlsx package as an argument.
434
+ */
435
+ XLDocument::XLDocument(const std::string& docPath, const IZipArchive& zipArchive)
436
+ : m_xmlSavingDeclaration{}, m_archive(zipArchive)
437
+ {
438
+ open(docPath);
439
+ }
440
+
441
+ /**
442
+ * @details explicit default move constructor
443
+ */
444
+ XLDocument::XLDocument(XLDocument&& other) noexcept = default;
445
+
446
+ /**
447
+ * @details The destructor calls the closeDocument method before the object is destroyed.
448
+ */
449
+ XLDocument::~XLDocument()
450
+ {
451
+ if (isOpen()) close();// 2024-05-31 prevent double-close if document has been manually closed before
452
+ }
453
+
454
+ /**
455
+ * @details explicit default move assignment operator
456
+ */
457
+ XLDocument& XLDocument::operator=(XLDocument&& other) noexcept = default;
458
+
459
+ /**
460
+ * @details disable m_suppressWarnings
461
+ */
462
+ void XLDocument::showWarnings() { m_suppressWarnings = false; }
463
+
464
+ /**
465
+ * @details enable m_suppressWarnings
466
+ */
467
+ void XLDocument::suppressWarnings() { m_suppressWarnings = true; }
468
+
469
+ /**
470
+ * @details The openDocument method opens the .xlsx package in the following manner:
471
+ * - Check if a document is already open. If yes, close it.
472
+ * - Create a temporary folder for the contents of the .xlsx package
473
+ * - Unzip the contents of the package to the temporary folder.
474
+ * - load the contents into the data structure for manipulation.
475
+ */
476
+ void XLDocument::open(const std::string& fileName)
477
+ {
478
+ // Check if a document is already open. If yes, close it.
479
+ if (m_archive.isOpen()) close(); // TBD: consider throwing if a file is already open.
480
+ m_filePath = fileName;
481
+ m_archive.open(m_filePath);
482
+
483
+ // ===== Add and open the Relationships and [Content_Types] files for the document level.
484
+ std::string relsFilename = "_rels/.rels";
485
+ m_data.emplace_back(this, "[Content_Types].xml");
486
+ m_data.emplace_back(this, relsFilename);
487
+
488
+ m_contentTypes = XLContentTypes(getXmlData("[Content_Types].xml"));
489
+ m_docRelationships = XLRelationships(getXmlData(relsFilename), relsFilename);
490
+ std::string workbookPath = "xl/workbook.xml";
491
+ bool workbookAdded = false;
492
+ for (auto& item : m_docRelationships.relationships()) {
493
+ if (item.type() == XLRelationshipType::Workbook) {
494
+ workbookPath = item.target();
495
+ if( workbookPath[ 0 ] == '/' ) workbookPath = workbookPath.substr(1); // NON STANDARD FORMATS: strip leading '/'
496
+ m_data.emplace_back(this, workbookPath, item.id(), XLContentType::Workbook);
497
+ workbookAdded = true;
498
+ break;
499
+ }
500
+ }
501
+
502
+ // ===== Determine workbook relationships path based on workbookPath, and construct m_wbkRelationships
503
+ size_t pos = workbookPath.find_last_of('/');
504
+ if( pos == std::string::npos ) {
505
+ using namespace std::literals::string_literals;
506
+ throw XLInputError(std::string("workbook path from "s + relsFilename + " has no folder name: "s) + workbookPath);
507
+ }
508
+ std::string workbookRelsFilename = std::string("xl/_rels/") + workbookPath.substr(pos + 1) + std::string(".rels");
509
+ m_data.emplace_back(this, workbookRelsFilename); // m_data.emplace_back(this, "xl/_rels/workbook.xml.rels");
510
+ m_wbkRelationships = XLRelationships(getXmlData(workbookRelsFilename), workbookRelsFilename);
511
+
512
+ // ===== Create xl/styles.xml if missing
513
+ if (!m_archive.hasEntry("xl/styles.xml")) execCommand(XLCommand(XLCommandType::AddStyles));
514
+
515
+ // ===== Create xl/sharedStrings.xml from scratch if missing
516
+ if (!m_archive.hasEntry("xl/sharedStrings.xml")) execCommand(XLCommand(XLCommandType::AddSharedStrings));
517
+
518
+ // ===== Add remaining spreadsheet elements to the vector of XLXmlData objects.
519
+ for (auto& item : m_contentTypes.getContentItems()) {
520
+ // ===== 2024-07-26 BUGFIX: ignore content item entries for relationship files, that have already been read above
521
+ if (item.path().substr(1) == relsFilename) continue; // always ignore relsFilename - would have thrown above if not found
522
+ if (item.path().substr(1) == workbookRelsFilename) continue; // always ignore workbookRelsFilename - would have thrown
523
+
524
+ // ===== Test if item is not in a known and handled subfolder (e.g. /customXml/*)
525
+ if (size_t pos = item.path().substr(1).find_first_of('/'); pos != std::string::npos) {
526
+ std::string subdirectory = item.path().substr(1, pos);
527
+ if (subdirectory != "xl" && subdirectory != "docProps") continue; // ignore items in unhandled subfolders
528
+ }
529
+
530
+ bool isWorkbookPath = (item.path().substr(1) == workbookPath); // determine once, use thrice
531
+ if (!isWorkbookPath && item.path().substr(0, 4) == "/xl/") {
532
+ if ((item.path().substr(4, 7) == "comment")
533
+ ||(item.path().substr(4, 12) == "tables/table")
534
+ ||(item.path().substr(4, 19) == "drawings/vmlDrawing")
535
+ ||(item.path().substr(4, 22) == "worksheets/_rels/sheet")
536
+ ) {
537
+ // no-op - worksheet dependencies will be loaded on access through the worksheet
538
+ }
539
+ else if ((item.path().substr(4, 16) == "worksheets/sheet")
540
+ ||(item.path().substr(4) == "sharedStrings.xml")
541
+ ||(item.path().substr(4) == "styles.xml")
542
+ ||(item.path().substr(4, 11) == "theme/theme"))
543
+ {
544
+ m_data.emplace_back(/* parentDoc */ this,
545
+ /* xmlPath */ item.path().substr(1),
546
+ /* xmlID */ m_wbkRelationships.relationshipByTarget(item.path().substr(4)).id(),
547
+ /* xmlType */ item.type());
548
+ }
549
+ else {
550
+ if( !m_suppressWarnings )
551
+ std::cout << "ignoring currently unhandled workbook item " << item.path() << std::endl;
552
+ }
553
+ }
554
+ else if (!isWorkbookPath || !workbookAdded) { // do not re-add workbook if it was previously added via m_docRelationships
555
+ if (isWorkbookPath) { // if workbook is found but workbook relationship did not exist in m_docRelationships
556
+ workbookAdded = true; // 2024-09-30 bugfix: was set to true after checking item.path() == workbookPath, not item.path().substr(1) as above
557
+ std::cerr << "adding missing workbook relationship to _rels/.rels" << std::endl;
558
+ m_docRelationships.addRelationship(XLRelationshipType::Workbook, workbookPath); // Pull request #185: Fix missing workbook relationship
559
+ }
560
+ m_data.emplace_back(/* parentDoc */ this,
561
+ /* xmlPath */ item.path().substr(1),
562
+ /* xmlID */ m_docRelationships.relationshipByTarget(item.path().substr(1)).id(),
563
+ /* xmlType */ item.type());
564
+ }
565
+ }
566
+
567
+ // ===== Read shared strings table.
568
+ XMLDocument* sharedStrings = getXmlData("xl/sharedStrings.xml")->getXmlDocument();
569
+ if (not sharedStrings->document_element().attribute("uniqueCount").empty())
570
+ sharedStrings->document_element().remove_attribute(
571
+ "uniqueCount"); // pull request #192 -> remove count & uniqueCount as they are optional
572
+ if (not sharedStrings->document_element().attribute("count").empty())
573
+ sharedStrings->document_element().remove_attribute(
574
+ "count"); // pull request #192 -> remove count & uniqueCount as they are optional
575
+
576
+ XMLNode node =
577
+ sharedStrings->document_element().first_child_of_type(pugi::node_element); // pull request #186: Skip non-element nodes in sst.
578
+ while (not node.empty()) {
579
+ // ===== Validate si node name.
580
+ using namespace std::literals::string_literals;
581
+ if (node.name() != "si"s) throw XLInputError("xl/sharedStrings.xml sst node name \""s + node.name() + "\" is not \"si\""s);
582
+
583
+ // ===== 2024-09-01 Refactored code to tolerate a mix of <t> and <r> tags within a shared string entry.
584
+ // This simplifies the loop while not doing any harm (obsolete inner loops for rich text and text elements removed).
585
+
586
+ // ===== Find first node_element child of si node.
587
+ XMLNode elem = node.first_child_of_type(pugi::node_element);
588
+ std::string result{}; // assemble a shared string entry here
589
+ while (not elem.empty()) {
590
+ // 2024-09-01: support a string composed of multiple <t> nodes in the same way as rich text <r> nodes, because LibreOffice accepts it
591
+
592
+ std::string elementName = elem.name(); // assign name to a string once, for string comparisons using operator==
593
+ if (elementName == "t") // If elem is a regular string
594
+ result += elem.text().get(); // append the tag value to result
595
+ else if (elementName == "r") // If elem is rich text
596
+ result += elem.child("t").text().get(); // append the <t> node value to result
597
+ // ===== Ignore phonetic property tags
598
+ else if (elementName == "rPh" || elementName == "phoneticPr") {}
599
+ else // For all other (unexpected) tags, throw an exception
600
+ throw XLInputError("xl/sharedStrings.xml si node \""s + elementName + "\" is none of \"r\", \"t\", \"rPh\", \"phoneticPr\""s);
601
+
602
+ elem = elem.next_sibling_of_type(pugi::node_element); // advance to next child of <si>
603
+ }
604
+ // ===== Append an empty string even if elem.empty(), to keep the index aligned with the <si> tag index in the shared strings table <sst>
605
+ m_sharedStringCache.emplace_back(result); // 2024-09-01 TBC BUGFIX: previously, a shared strings table entry that had neither <t> nor
606
+ /**/ // <r> nodes would not have appended to m_sharedStringCache, causing an index misalignment
607
+
608
+ node = node.next_sibling_of_type(pugi::node_element);
609
+ }
610
+
611
+ // ===== Open the workbook and document property items
612
+ m_workbook = XLWorkbook(getXmlData(workbookPath));
613
+ // 2024-05-31: moved XLWorkbook object creation up in code worksheets info can be used for XLAppProperties generation from scratch
614
+
615
+ // ===== 2024-06-03: creating core and extended properties if they do not exist
616
+ execCommand(XLCommand(XLCommandType::CheckAndFixCoreProperties)); // checks & fixes consistency of docProps/core.xml related data
617
+ execCommand(XLCommand(XLCommandType::CheckAndFixExtendedProperties)); // checks & fixes consistency of docProps/app.xml related data
618
+
619
+ if (!hasXmlData("docProps/core.xml") || !hasXmlData("docProps/app.xml"))
620
+ throw XLInternalError("Failed to repair docProps (core.xml and/or app.xml)");
621
+
622
+ m_coreProperties = XLProperties(getXmlData("docProps/core.xml"));
623
+ m_appProperties = XLAppProperties(getXmlData("docProps/app.xml"), m_workbook.xmlDocument());
624
+ // ===== 2024-09-02: ensure that all worksheets are contained in app.xml <TitlesOfParts> and reflected in <HeadingPairs> value for Worksheets
625
+ m_appProperties.alignWorksheets(m_workbook.sheetNames());
626
+
627
+ m_sharedStrings = XLSharedStrings(getXmlData("xl/sharedStrings.xml"), &m_sharedStringCache);
628
+ m_styles = XLStyles(getXmlData("xl/styles.xml"), m_suppressWarnings); // 2024-10-14: forward supress warnings setting to XLStyles
629
+ }
630
+
631
+
632
+ /**
633
+ * @details Create a new document. This is done by saving the data in XLTemplate.h in binary format.
634
+ */
635
+ void XLDocument::create(const std::string& fileName, bool forceOverwrite)
636
+ {
637
+ // 2024-07-26: prevent silent overwriting of existing files
638
+ if (!forceOverwrite && pathExists(fileName)) { // 2026-04-19 pathExists now uses nowide::stat on Windows and should be safe with unicode characters
639
+ using namespace std::literals::string_literals;
640
+ throw XLException("XLDocument::create: refusing to overwrite existing file "s + fileName);
641
+ }
642
+
643
+ std::string tempFileName = GenerateRandomNameInSamePath(fileName, 20);
644
+
645
+ // 2026-05-17 BUGFIX issue #399: use nowide for tempFileName as well, because *path* may contain unicode encoded characters
646
+ // NOTE / TODO: in the future, try to open an archive from memory, without the de-tour via a temporary file
647
+
648
+ // ===== Create a temporary output file
649
+ FILE *outfile = OpenXLSX::fopen(tempFileName, "wb");
650
+ if (outfile == nullptr) {
651
+ using namespace std::literals::string_literals;
652
+ throw XLException("XLDocument::create: could not create empty archive template with temp name "s + tempFileName);
653
+ }
654
+
655
+ // ===== Stream the binary data for an empty workbook to the output file.
656
+ // ===== Casting, in particular reinterpret_cast, is discouraged, but in this case it is unfortunately unavoidable.
657
+ fwrite( templateData, templateSize, 1, outfile );
658
+ fclose( outfile );
659
+
660
+ open(tempFileName); // open the template archive from the temporary file
661
+ m_filePath = fileName; // re-configure the document file path to point to the desired fileName
662
+
663
+ // 2025-05-04: the created (empty) archive is no longer saved implicitly, to remove the XLDocument dependency on nowide::ofstream
664
+ // Instead, OpenXLSX shall rely on the underlying zip implementation (Zippy.hpp or LibZip.hpp) to support Unicode filenames
665
+ // NOTE: LibZip currently does not support Unicode filenames on Windows (no use of nowide), status of miniz is unknown
666
+ OpenXLSX::remove(tempFileName); // delete the temporary file used for archive creation
667
+ }
668
+
669
+ /**
670
+ * @details Legacy function to create a new document
671
+ * @deprecated use instead XLDocument::create(const std::string& fileName, bool forceOverwrite)
672
+ * @warning This deprecated function overwrites an existing file without prompt
673
+ */
674
+ void XLDocument::create(const std::string& fileName) { create( fileName, XLForceOverwrite ); }
675
+
676
+ /**
677
+ * @details The document is closed by deleting the temporary folder structure.
678
+ */
679
+ void XLDocument::close()
680
+ {
681
+ if (m_archive.isValid()) m_archive.close();
682
+ // m_suppressWarnings shall remain in the configured setting
683
+
684
+ m_filePath.clear();
685
+
686
+ m_xmlSavingDeclaration = XLXmlSavingDeclaration();
687
+
688
+ m_data.clear();
689
+ m_sharedStringCache.clear(); // 2024-12-18 BUGFIX: clear shared strings cache - addresses issue #283
690
+ m_sharedStrings = XLSharedStrings(); //
691
+
692
+ m_docRelationships = XLRelationships();
693
+ m_wbkRelationships = XLRelationships();
694
+ m_contentTypes = XLContentTypes();
695
+ m_appProperties = XLAppProperties();
696
+ m_coreProperties = XLProperties();
697
+ m_styles = XLStyles();
698
+ m_workbook = XLWorkbook();
699
+ // m_archive = IZipArchive(); // keep IZipArchive class intact throughout close/open
700
+ }
701
+
702
+ /**
703
+ * @details Save the document with the same name. The existing file will be overwritten.
704
+ */
705
+ void XLDocument::save() { saveAs(m_filePath, XLForceOverwrite); }
706
+
707
+ /**
708
+ * @details Save the document with a new name. If present, the 'calcChain.xml file will be ignored. The reason for this
709
+ * is that changes to the document may invalidate the calcChain.xml file. Deleting will force Excel to re-create the
710
+ * file. This will happen automatically, without the user noticing.
711
+ */
712
+ void XLDocument::saveAs(const std::string& fileName, bool forceOverwrite)
713
+ {
714
+ // 2024-07-26: prevent silent overwriting of existing files
715
+ if (!forceOverwrite && pathExists(fileName)) {
716
+ using namespace std::literals::string_literals;
717
+ throw XLException("XLDocument::saveAs: refusing to overwrite existing file "s + fileName);
718
+ }
719
+
720
+ m_filePath = fileName;
721
+
722
+ // ===== Delete the calcChain.xml file in order to force re-calculation of the sheet
723
+ // TODO: Is this the best way to do it? Maybe there is a flag that can be set, that forces re-calculalion.
724
+ execCommand(XLCommand(XLCommandType::ResetCalcChain));
725
+
726
+ // ===== Add all xml items to archive and save the archive.
727
+ for (auto& item : m_data) {
728
+ bool xmlIsStandalone = m_xmlSavingDeclaration.standalone_as_bool();
729
+ if ((item.getXmlPath() == "docProps/core.xml")
730
+ ||(item.getXmlPath() == "docProps/app.xml"))
731
+ xmlIsStandalone = XLXmlStandalone;
732
+ m_archive.addEntry(item.getXmlPath(),
733
+ item.getRawData(XLXmlSavingDeclaration(m_xmlSavingDeclaration.version(), m_xmlSavingDeclaration.encoding(),xmlIsStandalone)));
734
+ }
735
+ m_archive.save(m_filePath);
736
+ }
737
+
738
+ /**
739
+ * @details Legacy function to save the document with a new name
740
+ * @deprecated use instead void XLDocument::saveAs(const std::string& fileName, bool forceOverwrite)
741
+ * @warning This deprecated function overwrites an existing file without prompt
742
+ */
743
+ void XLDocument::saveAs(const std::string& fileName) { saveAs( fileName, XLForceOverwrite ); }
744
+
745
+ /**
746
+ * @details
747
+ */
748
+ std::string XLDocument::name() const
749
+ {
750
+ size_t pos = m_filePath.find_last_of('/');
751
+ if (pos != std::string::npos)
752
+ return m_filePath.substr(pos + 1);
753
+ else
754
+ return m_filePath;
755
+ }
756
+
757
+ /**
758
+ * @details
759
+ */
760
+ const std::string& XLDocument::path() const { return m_filePath; }
761
+
762
+ /**
763
+ * @details Get a const pointer to the underlying XLWorkbook object.
764
+ */
765
+ XLWorkbook XLDocument::workbook() const { return m_workbook; }
766
+
767
+ /**
768
+ * @details Get the value for a property.
769
+ */
770
+ std::string XLDocument::property(XLProperty prop) const
771
+ {
772
+ switch (prop) {
773
+ case XLProperty::Application:
774
+ return m_appProperties.property("Application");
775
+ case XLProperty::AppVersion:
776
+ return m_appProperties.property("AppVersion");
777
+ case XLProperty::Category:
778
+ return m_coreProperties.property("cp:category");
779
+ case XLProperty::Company:
780
+ return m_appProperties.property("Company");
781
+ case XLProperty::CreationDate:
782
+ return m_coreProperties.property("dcterms:created");
783
+ case XLProperty::Creator:
784
+ return m_coreProperties.property("dc:creator");
785
+ case XLProperty::Description:
786
+ return m_coreProperties.property("dc:description");
787
+ case XLProperty::DocSecurity:
788
+ return m_appProperties.property("DocSecurity");
789
+ case XLProperty::HyperlinkBase:
790
+ return m_appProperties.property("HyperlinkBase");
791
+ case XLProperty::HyperlinksChanged:
792
+ return m_appProperties.property("HyperlinksChanged");
793
+ case XLProperty::Keywords:
794
+ return m_coreProperties.property("cp:keywords");
795
+ case XLProperty::LastModifiedBy:
796
+ return m_coreProperties.property("cp:lastModifiedBy");
797
+ case XLProperty::LastPrinted:
798
+ return m_coreProperties.property("cp:lastPrinted");
799
+ case XLProperty::LinksUpToDate:
800
+ return m_appProperties.property("LinksUpToDate");
801
+ case XLProperty::Manager:
802
+ return m_appProperties.property("Manager");
803
+ case XLProperty::ModificationDate:
804
+ return m_coreProperties.property("dcterms:modified");
805
+ case XLProperty::ScaleCrop:
806
+ return m_appProperties.property("ScaleCrop");
807
+ case XLProperty::SharedDoc:
808
+ return m_appProperties.property("SharedDoc");
809
+ case XLProperty::Subject:
810
+ return m_coreProperties.property("dc:subject");
811
+ case XLProperty::Title:
812
+ return m_coreProperties.property("dc:title");
813
+ default:
814
+ return ""; // To silence compiler warning.
815
+ }
816
+ }
817
+
818
+ /**
819
+ * @brief extract an integer major version v1 and minor version v2 from a string
820
+ * @details trims all whitespaces from begin and end of versionString and attempts to extract two integers from the format
821
+ * [0-9]{1,2}\.[0-9]{1,4} (Example: 14.123)
822
+ * @param versionString the string to process
823
+ * @param majorVersion by reference: store the major version here
824
+ * @param minorVersion by reference: store the minor version here
825
+ * @return true if string adheres to format & version numbers could be extracted
826
+ * @return false in case of failure
827
+ */
828
+ bool getAppVersion(const std::string& versionString, int& majorVersion, int& minorVersion)
829
+ {
830
+ // ===== const expressions for hardcoded version limits
831
+ constexpr int minMajorV = 0, maxMajorV = 99; // allowed value range for major version number
832
+ constexpr int minMinorV = 0, maxMinorV = 9999; // " for minor "
833
+
834
+ const size_t begin = versionString.find_first_not_of(" \t");
835
+ const size_t dotPos = versionString.find_first_of('.');
836
+
837
+ // early failure if string is only blanks or does not contain a dot
838
+ if (begin == std::string::npos || dotPos == std::string::npos) return false;
839
+
840
+ const size_t end = versionString.find_last_not_of(" \t");
841
+ if (begin != std::string::npos && dotPos != std::string::npos) {
842
+ const std::string strMajorVersion = versionString.substr(begin, dotPos - begin);
843
+ const std::string strMinorVersion = versionString.substr(dotPos + 1, end - dotPos);
844
+ try {
845
+ size_t pos;
846
+ majorVersion = std::stoi(strMajorVersion, &pos);
847
+ if (pos != strMajorVersion.length()) throw 1;
848
+ minorVersion = std::stoi(strMinorVersion, &pos);
849
+ if (pos != strMinorVersion.length()) throw 1;
850
+ }
851
+ catch (...) {
852
+ return false; // conversion failed or did not convert the full string
853
+ }
854
+ }
855
+ if (majorVersion < minMajorV || majorVersion > maxMajorV || minorVersion < minMinorV ||
856
+ minorVersion > maxMinorV) // final range check
857
+ return false;
858
+
859
+ return true;
860
+ }
861
+
862
+ /**
863
+ * @details Set the value for a property.
864
+ *
865
+ * If the property is a datetime, it must be in the W3CDTF format, i.e. YYYY-MM-DDTHH:MM:SSZ. Also, the time should
866
+ * be GMT. Creating a time point in this format can be done as follows:
867
+ * ```cpp
868
+ * #include <iostream>
869
+ * #include <iomanip>
870
+ * #include <ctime>
871
+ * #include <sstream>
872
+ *
873
+ * // other stuff here
874
+ *
875
+ * std::time_t t = std::time(nullptr);
876
+ * std::tm tm = *std::gmtime(&t);
877
+ *
878
+ * std::stringstream ss;
879
+ * ss << std::put_time(&tm, "%FT%TZ");
880
+ * auto datetime = ss.str();
881
+ *
882
+ * // datetime now is a string with the datetime in the right format.
883
+ *
884
+ * ```
885
+ */
886
+ void XLDocument::setProperty(XLProperty prop, const std::string& value) // NOLINT
887
+ {
888
+ switch (prop) {
889
+ case XLProperty::Application:
890
+ m_appProperties.setProperty("Application", value);
891
+ break;
892
+ case XLProperty::AppVersion: // ===== 2025-05-02 done: section cleaned up, pull request #174: Fixing discarding return value of
893
+ // function with 'nodiscard' attribute
894
+ int minorVersion, majorVersion;
895
+ // ===== Check for the format "XX.XXXX", with X being a number.
896
+ if (!getAppVersion(value, majorVersion, minorVersion)) throw XLPropertyError("Invalid property value: " + std::string(value));
897
+ m_appProperties.setProperty("AppVersion",
898
+ std::to_string(majorVersion) + "." +
899
+ std::to_string(minorVersion)); // re-assemble version string for a clean property setting
900
+ break;
901
+
902
+ case XLProperty::Category:
903
+ m_coreProperties.setProperty("cp:category", value);
904
+ break;
905
+ case XLProperty::Company:
906
+ m_appProperties.setProperty("Company", value);
907
+ break;
908
+ case XLProperty::CreationDate:
909
+ m_coreProperties.setProperty("dcterms:created", value);
910
+ break;
911
+ case XLProperty::Creator:
912
+ m_coreProperties.setProperty("dc:creator", value);
913
+ break;
914
+ case XLProperty::Description:
915
+ m_coreProperties.setProperty("dc:description", value);
916
+ break;
917
+ case XLProperty::DocSecurity:
918
+ if (value == "0" || value == "1" || value == "2" || value == "4" || value == "8")
919
+ m_appProperties.setProperty("DocSecurity", value);
920
+ else
921
+ throw XLPropertyError("Invalid property value");
922
+ break;
923
+
924
+ case XLProperty::HyperlinkBase:
925
+ m_appProperties.setProperty("HyperlinkBase", value);
926
+ break;
927
+ case XLProperty::HyperlinksChanged:
928
+ if (value == "true" || value == "false")
929
+ m_appProperties.setProperty("HyperlinksChanged", value);
930
+ else
931
+ throw XLPropertyError("Invalid property value");
932
+
933
+ break;
934
+
935
+ case XLProperty::Keywords:
936
+ m_coreProperties.setProperty("cp:keywords", value);
937
+ break;
938
+ case XLProperty::LastModifiedBy:
939
+ m_coreProperties.setProperty("cp:lastModifiedBy", value);
940
+ break;
941
+ case XLProperty::LastPrinted:
942
+ m_coreProperties.setProperty("cp:lastPrinted", value);
943
+ break;
944
+ case XLProperty::LinksUpToDate:
945
+ if (value == "true" || value == "false")
946
+ m_appProperties.setProperty("LinksUpToDate", value);
947
+ else
948
+ throw XLPropertyError("Invalid property value");
949
+ break;
950
+
951
+ case XLProperty::Manager:
952
+ m_appProperties.setProperty("Manager", value);
953
+ break;
954
+ case XLProperty::ModificationDate:
955
+ m_coreProperties.setProperty("dcterms:modified", value);
956
+ break;
957
+ case XLProperty::ScaleCrop:
958
+ if (value == "true" || value == "false")
959
+ m_appProperties.setProperty("ScaleCrop", value);
960
+ else
961
+ throw XLPropertyError("Invalid property value");
962
+ break;
963
+
964
+ case XLProperty::SharedDoc:
965
+ if (value == "true" || value == "false")
966
+ m_appProperties.setProperty("SharedDoc", value);
967
+ else
968
+ throw XLPropertyError("Invalid property value");
969
+ break;
970
+
971
+ case XLProperty::Subject:
972
+ m_coreProperties.setProperty("dc:subject", value);
973
+ break;
974
+ case XLProperty::Title:
975
+ m_coreProperties.setProperty("dc:title", value);
976
+ break;
977
+ }
978
+ }
979
+
980
+ /**
981
+ * @details Delete a property
982
+ */
983
+ void XLDocument::deleteProperty(XLProperty theProperty) { setProperty(theProperty, ""); }
984
+
985
+ /**
986
+ * @details
987
+ */
988
+ XLDocument::operator bool() const
989
+ {
990
+ return m_archive.isValid(); // NOLINT
991
+ }
992
+
993
+ /**
994
+ * @details
995
+ */
996
+ bool XLDocument::isOpen() const { return this->operator bool(); }
997
+
998
+ /**
999
+ * @details fetch a reference to m_styles
1000
+ */
1001
+ XLStyles& XLDocument::styles() { return m_styles; }
1002
+
1003
+
1004
+ /**
1005
+ * @details determine - without creation - whether the document contains a sheet relationships file for sheet with sheetXmlNo
1006
+ */
1007
+ bool XLDocument::hasSheetRelationships(uint16_t sheetXmlNo) const
1008
+ {
1009
+ using namespace std::literals::string_literals;
1010
+ return m_archive.hasEntry("xl/worksheets/_rels/sheet"s + std::to_string(sheetXmlNo) + ".xml.rels"s);
1011
+ }
1012
+
1013
+ /**
1014
+ * @details determine - without creation - whether the document contains a VML drawing file for sheet with sheetXmlNo
1015
+ */
1016
+ bool XLDocument::hasSheetVmlDrawing(uint16_t sheetXmlNo) const
1017
+ {
1018
+ using namespace std::literals::string_literals;
1019
+ return m_archive.hasEntry("xl/drawings/vmlDrawing"s + std::to_string(sheetXmlNo) + ".vml"s);
1020
+ }
1021
+
1022
+ /**
1023
+ * @details determine - without creation - whether the document contains a comments file for sheet with sheetXmlNo
1024
+ */
1025
+ bool XLDocument::hasSheetComments(uint16_t sheetXmlNo) const
1026
+ {
1027
+ using namespace std::literals::string_literals;
1028
+ return m_archive.hasEntry("xl/comments"s + std::to_string(sheetXmlNo) + ".xml"s);
1029
+ }
1030
+
1031
+ /**
1032
+ * @details determine - without creation - whether the document contains a table(s) file for sheet with sheetXmlNo
1033
+ */
1034
+ bool XLDocument::hasSheetTables(uint16_t sheetXmlNo) const
1035
+ {
1036
+ using namespace std::literals::string_literals;
1037
+ return m_archive.hasEntry("xl/tables/table"s + std::to_string(sheetXmlNo) + ".xml"s);
1038
+ }
1039
+
1040
+ /**
1041
+ * @details return an XLRelationships item for sheet with sheetXmlNo - create the underlying XML and add it to the archive if needed
1042
+ */
1043
+ XLRelationships XLDocument::sheetRelationships(uint16_t sheetXmlNo)
1044
+ {
1045
+ using namespace std::literals::string_literals;
1046
+ std::string relsFilename = "xl/worksheets/_rels/sheet"s + std::to_string(sheetXmlNo) + ".xml.rels"s;
1047
+
1048
+ if (!m_archive.hasEntry(relsFilename)) {
1049
+ // ===== Create the sheet relationships file within the archive
1050
+ m_archive.addEntryAndCommit(relsFilename, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); // empty XML file, class constructor will do the rest
1051
+ m_contentTypes.addOverride("/" + relsFilename, XLContentType::Relationships); // add content types entry
1052
+ }
1053
+ constexpr const bool DO_NOT_THROW = true;
1054
+ XLXmlData *xmlData = getXmlData(relsFilename, DO_NOT_THROW);
1055
+ if (xmlData == nullptr) // if not yet managed: add the sheet relationships file to the managed files
1056
+ xmlData = &m_data.emplace_back(this, relsFilename, "", XLContentType::Relationships);
1057
+
1058
+ return XLRelationships(xmlData, relsFilename);
1059
+ }
1060
+
1061
+ /**
1062
+ * @details return an XLVmlDrawing item for sheet with sheetXmlNo - create the underlying XML and add it to the archive if needed
1063
+ */
1064
+ XLVmlDrawing XLDocument::sheetVmlDrawing(uint16_t sheetXmlNo)
1065
+ {
1066
+ using namespace std::literals::string_literals;
1067
+ std::string vmlDrawingFilename = "xl/drawings/vmlDrawing"s + std::to_string(sheetXmlNo) + ".vml"s;
1068
+
1069
+ if (!m_archive.hasEntry(vmlDrawingFilename)) {
1070
+ // ===== Create the sheet drawing file within the archive
1071
+ m_archive.addEntryAndCommit(vmlDrawingFilename, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); // empty XML file, class constructor will do the rest
1072
+ m_contentTypes.addOverride("/" + vmlDrawingFilename, XLContentType::VMLDrawing); // add content types entry
1073
+ }
1074
+ constexpr const bool DO_NOT_THROW = true;
1075
+ XLXmlData *xmlData = getXmlData(vmlDrawingFilename, DO_NOT_THROW);
1076
+ if (xmlData == nullptr) // if not yet managed: add the sheet drawing file to the managed files
1077
+ xmlData = &m_data.emplace_back(this, vmlDrawingFilename, "", XLContentType::VMLDrawing);
1078
+
1079
+ return XLVmlDrawing(xmlData);
1080
+ }
1081
+
1082
+ /**
1083
+ * @details return an XLComments item for sheet with sheetXmlNo - create the underlying XML and add it to the archive if needed
1084
+ */
1085
+ XLComments XLDocument::sheetComments(uint16_t sheetXmlNo)
1086
+ {
1087
+ using namespace std::literals::string_literals;
1088
+ std::string commentsFilename = "xl/comments"s + std::to_string(sheetXmlNo) + ".xml"s;
1089
+
1090
+ if (!m_archive.hasEntry(commentsFilename)) {
1091
+ // ===== Create the sheet comments file within the archive
1092
+ m_archive.addEntryAndCommit(commentsFilename, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); // empty XML file, class constructor will do the rest
1093
+ m_contentTypes.addOverride("/" + commentsFilename, XLContentType::Comments); // add content types entry
1094
+ }
1095
+ constexpr const bool DO_NOT_THROW = true;
1096
+ XLXmlData *xmlData = getXmlData(commentsFilename, DO_NOT_THROW);
1097
+ if (xmlData == nullptr) // if not yet managed: add the sheet comments file to the managed files
1098
+ xmlData = &m_data.emplace_back(this, commentsFilename, "", XLContentType::Comments);
1099
+
1100
+ return XLComments(xmlData);
1101
+ }
1102
+
1103
+ /**
1104
+ * @details return an XLTables item for sheet with sheetXmlNo - create the underlying XML and add it to the archive if needed
1105
+ */
1106
+ XLTables XLDocument::sheetTables(uint16_t sheetXmlNo)
1107
+ {
1108
+ using namespace std::literals::string_literals;
1109
+ std::string tablesFilename = "xl/tables/table"s + std::to_string(sheetXmlNo) + ".xml"s;
1110
+
1111
+ if (!m_archive.hasEntry(tablesFilename)) {
1112
+ // ===== Create the sheet tables file within the archive
1113
+ m_archive.addEntryAndCommit(tablesFilename, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); // empty XML file, class constructor will do the rest
1114
+ m_contentTypes.addOverride("/" + tablesFilename, XLContentType::Table); // add content types entry
1115
+ }
1116
+ constexpr const bool DO_NOT_THROW = true;
1117
+ XLXmlData *xmlData = getXmlData(tablesFilename, DO_NOT_THROW);
1118
+ if (xmlData == nullptr) // if not yet managed: add the sheet tables file to the managed files
1119
+ xmlData = &m_data.emplace_back(this, tablesFilename, "", XLContentType::Table);
1120
+
1121
+ return XLTables(xmlData);
1122
+ }
1123
+
1124
+ /**
1125
+ * @details Worksheet names cannot:
1126
+ * Be blank.
1127
+ * Contain more than 31 characters.
1128
+ * Contain any of the following characters: / \ ? * : [ ]
1129
+ * For example, 02/17/2016 would not be a valid worksheet name, but 02-17-2016 would work fine.
1130
+ * Begin or end with an apostrophe ('), but they can be used in between text or numbers in a name.
1131
+ * Be named "History". This is a reserved word Excel uses internally.
1132
+ */
1133
+ constexpr const bool THROW_ON_INVALID = true;
1134
+ bool XLDocument::validateSheetName(std::string sheetName, bool throwOnInvalid)
1135
+ {
1136
+ using namespace std::literals::string_literals;
1137
+ bool valid = true;
1138
+
1139
+ try {
1140
+ if (sheetName.length() > 31)
1141
+ throw "contain more than 31 characters"s;
1142
+
1143
+ size_t pos = 0;
1144
+ while (sheetName[pos] == ' ' || sheetName[pos] == '\t') ++pos; // aborts on sheetName[ sheetName.length() ], guaranteed to be \0
1145
+ if (pos == sheetName.length())
1146
+ throw "be blank"s;
1147
+
1148
+ if (sheetName.front() == '\'' || sheetName.back() == '\'')
1149
+ throw "begin or end with an apostrophe (')"s;
1150
+
1151
+ if (sheetName == "History")
1152
+ throw "be named \"History\" (Excel reserves this word for internal use)"s;
1153
+
1154
+ for (pos = 0; pos < sheetName.length(); ++pos) {
1155
+ switch (sheetName[pos]) {
1156
+ // test for disallowed characters:
1157
+ case '/': [[fallthrough]];
1158
+ case '\\': [[fallthrough]];
1159
+ case '?': [[fallthrough]];
1160
+ case '*': [[fallthrough]];
1161
+ case ':': [[fallthrough]];
1162
+ case '[': [[fallthrough]];
1163
+ case ']':
1164
+ throw "contain any of the following characters: / \\ ? * : [ ]"s;
1165
+ default: ; // no-op
1166
+ }
1167
+ }
1168
+ // if execution gets here, sheetName is valid
1169
+ }
1170
+ catch( std::string const & err ) {
1171
+ if (throwOnInvalid)
1172
+ throw XLInputError("Sheet name \""s + sheetName + "\" violates naming rules: sheet name can not "s + err);
1173
+ valid = false;
1174
+ }
1175
+ return valid;
1176
+ }
1177
+
1178
+ /**
1179
+ * @details return value defaults to true, false only where the XLCommandType implements it
1180
+ */
1181
+ bool XLDocument::execCommand(const XLCommand& command)
1182
+ {
1183
+ switch (command.type()) {
1184
+ case XLCommandType::SetSheetName:
1185
+ validateSheetName(command.getParam<std::string>("newName"), THROW_ON_INVALID);
1186
+ m_appProperties.setSheetName(command.getParam<std::string>("sheetName"), command.getParam<std::string>("newName"));
1187
+ m_workbook.setSheetName(command.getParam<std::string>("sheetID"), command.getParam<std::string>("newName"));
1188
+ break;
1189
+
1190
+ case XLCommandType::SetSheetColor:
1191
+ // TODO: To be implemented
1192
+ break;
1193
+
1194
+ case XLCommandType::SetSheetVisibility:
1195
+ m_workbook.setSheetVisibility(command.getParam<std::string>("sheetID"), command.getParam<std::string>("sheetVisibility"));
1196
+ break;
1197
+
1198
+ case XLCommandType::SetSheetIndex: {
1199
+ XLQuery qry(XLQueryType::QuerySheetName);
1200
+ const auto sheetName = execQuery(qry.setParam("sheetID", command.getParam<std::string>("sheetID"))).result<std::string>();
1201
+ m_workbook.setSheetIndex(sheetName, command.getParam<uint16_t>("sheetIndex"));
1202
+ } break;
1203
+
1204
+ case XLCommandType::SetSheetActive:
1205
+ return m_workbook.setSheetActive(command.getParam<std::string>("sheetID"));
1206
+ // break;
1207
+
1208
+ case XLCommandType::ResetCalcChain: {
1209
+ m_archive.deleteEntry("xl/calcChain.xml");
1210
+ const auto item =
1211
+ std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& theItem) { return theItem.getXmlPath() == "xl/calcChain.xml"; });
1212
+
1213
+ if (item != m_data.end()) m_data.erase(item);
1214
+ } break;
1215
+ case XLCommandType::CheckAndFixCoreProperties: { // does nothing if core properties are in good shape
1216
+ // ===== If _rels/.rels has no entry for docProps/core.xml
1217
+ if (!m_docRelationships.targetExists("docProps/core.xml"))
1218
+ m_docRelationships.addRelationship(XLRelationshipType::CoreProperties, "docProps/core.xml"); // Fix m_docRelationships
1219
+
1220
+ // ===== If docProps/core.xml is missing
1221
+ if (!m_archive.hasEntry("docProps/core.xml"))
1222
+ m_archive.addEntryAndCommit("docProps/core.xml", "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); // create empty docProps/core.xml
1223
+ // ===== XLProperties constructor will take care of adding template content
1224
+
1225
+ // ===== If [Content Types].xml has no relationship for docProps/core.xml
1226
+ if (!hasXmlData("docProps/core.xml")) {
1227
+ m_contentTypes.addOverride("/docProps/core.xml", XLContentType::CoreProperties); // add content types entry
1228
+ m_data.emplace_back( // store new entry in m_data
1229
+ /* parentDoc */ this,
1230
+ /* xmlPath */ "docProps/core.xml",
1231
+ /* xmlID */ m_docRelationships.relationshipByTarget("docProps/core.xml").id(),
1232
+ /* xmlType */ XLContentType::CoreProperties);
1233
+ }
1234
+ } break;
1235
+ case XLCommandType::CheckAndFixExtendedProperties: { // does nothing if extended properties are in good shape
1236
+ // ===== If _rels/.rels has no entry for docProps/app.xml
1237
+ if (!m_docRelationships.targetExists("docProps/app.xml"))
1238
+ m_docRelationships.addRelationship(XLRelationshipType::ExtendedProperties, "docProps/app.xml"); // Fix m_docRelationships
1239
+
1240
+ // ===== If docProps/app.xml is missing
1241
+ if (!m_archive.hasEntry("docProps/app.xml"))
1242
+ m_archive.addEntryAndCommit("docProps/app.xml", "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); // create empty docProps/app.xml
1243
+ // ===== XLAppProperties constructor will take care of adding template content
1244
+
1245
+ // ===== If [Content Types].xml has no relationship for docProps/app.xml
1246
+ if (!hasXmlData("docProps/app.xml")) {
1247
+ m_contentTypes.addOverride("/docProps/app.xml", XLContentType::ExtendedProperties); // add content types entry
1248
+ m_data.emplace_back( // store new entry in m_data
1249
+ /* parentDoc */ this,
1250
+ /* xmlPath */ "docProps/app.xml",
1251
+ /* xmlID */ m_docRelationships.relationshipByTarget("docProps/app.xml").id(),
1252
+ /* xmlType */ XLContentType::ExtendedProperties);
1253
+ }
1254
+ } break;
1255
+ case XLCommandType::AddSharedStrings: {
1256
+ m_contentTypes.addOverride("/xl/sharedStrings.xml", XLContentType::SharedStrings);
1257
+ m_wbkRelationships.addRelationship(XLRelationshipType::SharedStrings, "sharedStrings.xml");
1258
+ // ===== Add empty archive entry for shared strings, XLSharedStrings constructor will create a default document when no document element is found
1259
+ m_archive.addEntryAndCommit("xl/sharedStrings.xml", "");
1260
+ } break;
1261
+ case XLCommandType::AddWorksheet: {
1262
+ validateSheetName(command.getParam<std::string>("sheetName"), THROW_ON_INVALID);
1263
+ const std::string emptyWorksheet {
1264
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
1265
+ "<worksheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\""
1266
+ " xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\""
1267
+ " xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" mc:Ignorable=\"x14ac\""
1268
+ " xmlns:x14ac=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac\">"
1269
+ "<dimension ref=\"A1\"/>"
1270
+ "<sheetViews>"
1271
+ "<sheetView workbookViewId=\"0\"/>"
1272
+ "</sheetViews>"
1273
+ "<sheetFormatPr baseColWidth=\"10\" defaultRowHeight=\"16\" x14ac:dyDescent=\"0.2\"/>"
1274
+ "<sheetData/>"
1275
+ "<pageMargins left=\"0.7\" right=\"0.7\" top=\"0.75\" bottom=\"0.75\" header=\"0.3\" footer=\"0.3\"/>"
1276
+ "</worksheet>"
1277
+ };
1278
+ m_contentTypes.addOverride(command.getParam<std::string>("sheetPath"), XLContentType::Worksheet);
1279
+ m_wbkRelationships.addRelationship(XLRelationshipType::Worksheet, command.getParam<std::string>("sheetPath").substr(4));
1280
+ m_appProperties.appendSheetName(command.getParam<std::string>("sheetName"));
1281
+ m_archive.addEntryAndCommit(command.getParam<std::string>("sheetPath").substr(1), emptyWorksheet);
1282
+ m_data.emplace_back(
1283
+ /* parentDoc */ this,
1284
+ /* xmlPath */ command.getParam<std::string>("sheetPath").substr(1),
1285
+ /* xmlID */ m_wbkRelationships.relationshipByTarget(command.getParam<std::string>("sheetPath").substr(4)).id(),
1286
+ /* xmlType */ XLContentType::Worksheet);
1287
+ } break;
1288
+ case XLCommandType::AddChartsheet:
1289
+ // TODO: To be implemented
1290
+ break;
1291
+ case XLCommandType::DeleteSheet: {
1292
+ m_appProperties.deleteSheetName(command.getParam<std::string>("sheetName"));
1293
+ std::string sheetPath = m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).target();
1294
+ if (sheetPath.substr(0, 4) != "/xl/") sheetPath = "/xl/" + sheetPath; // 2024-12-15: respect absolute sheet path
1295
+ m_archive.deleteEntry(sheetPath.substr(1));
1296
+ m_contentTypes.deleteOverride(sheetPath);
1297
+ m_wbkRelationships.deleteRelationship(command.getParam<std::string>("sheetID"));
1298
+ m_data.erase(std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) {
1299
+ return item.getXmlPath() == sheetPath.substr(1);
1300
+ }));
1301
+ } break;
1302
+ case XLCommandType::CloneSheet: {
1303
+ validateSheetName(command.getParam<std::string>("cloneName"), THROW_ON_INVALID);
1304
+ const auto internalID = m_workbook.createInternalSheetID();
1305
+ const auto sheetPath = "/xl/worksheets/sheet" + std::to_string(internalID) + ".xml";
1306
+ if (m_workbook.sheetExists(command.getParam<std::string>("cloneName")))
1307
+ throw XLInternalError("Sheet named \"" + command.getParam<std::string>("cloneName") + "\" already exists.");
1308
+
1309
+ // ===== 2024-12-15: handle absolute sheet path: ensure relative sheet path
1310
+ std::string sheetToClonePath = m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).target();
1311
+ if (sheetToClonePath.substr(0, 4) == "/xl/") sheetToClonePath = sheetToClonePath.substr(4);
1312
+
1313
+ if (m_wbkRelationships.relationshipById(command.getParam<std::string>("sheetID")).type() == XLRelationshipType::Worksheet) {
1314
+ m_contentTypes.addOverride(sheetPath, XLContentType::Worksheet);
1315
+ m_wbkRelationships.addRelationship(XLRelationshipType::Worksheet, sheetPath.substr(4));
1316
+ m_appProperties.appendSheetName(command.getParam<std::string>("cloneName"));
1317
+ m_archive.addEntryAndCommit(sheetPath.substr(1),
1318
+ std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& data) {
1319
+ return data.getXmlPath().substr(3) == sheetToClonePath; // 2024-12-15: ensure relative sheet path
1320
+ })->getRawData());
1321
+ m_data.emplace_back(
1322
+ /* parentDoc */ this,
1323
+ /* xmlPath */ sheetPath.substr(1),
1324
+ /* xmlID */ m_wbkRelationships.relationshipByTarget(sheetPath.substr(4)).id(),
1325
+ /* xmlType */ XLContentType::Worksheet);
1326
+ }
1327
+ else {
1328
+ m_contentTypes.addOverride(sheetPath, XLContentType::Chartsheet);
1329
+ m_wbkRelationships.addRelationship(XLRelationshipType::Chartsheet, sheetPath.substr(4));
1330
+ m_appProperties.appendSheetName(command.getParam<std::string>("cloneName"));
1331
+ m_archive.addEntryAndCommit(sheetPath.substr(1),
1332
+ std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& data) {
1333
+ return data.getXmlPath().substr(3) == sheetToClonePath; // 2024-12-15: ensure relative sheet path
1334
+ })->getRawData());
1335
+ m_data.emplace_back(
1336
+ /* parentDoc */ this,
1337
+ /* xmlPath */ sheetPath.substr(1),
1338
+ /* xmlID */ m_wbkRelationships.relationshipByTarget(sheetPath.substr(4)).id(),
1339
+ /* xmlType */ XLContentType::Chartsheet);
1340
+ }
1341
+
1342
+ m_workbook.prepareSheetMetadata(command.getParam<std::string>("cloneName"), internalID);
1343
+ } break;
1344
+ case XLCommandType::AddStyles: {
1345
+ m_contentTypes.addOverride("/xl/styles.xml", XLContentType::Styles);
1346
+ m_wbkRelationships.addRelationship(XLRelationshipType::Styles, "styles.xml");
1347
+ // ===== Add empty archive entry for styles, XLStyles constructor will create a default document when no document element is found
1348
+ m_archive.addEntryAndCommit("xl/styles.xml", "");
1349
+ } break;
1350
+ }
1351
+
1352
+ return true; // default: command claims success unless otherwise implemented in switch-clauses
1353
+ }
1354
+
1355
+ /**
1356
+ * @details
1357
+ */
1358
+ XLQuery XLDocument::execQuery(const XLQuery& query) const
1359
+ {
1360
+ switch (query.type()) {
1361
+ case XLQueryType::QuerySheetName:
1362
+ return XLQuery(query).setResult(m_workbook.sheetName(query.getParam<std::string>("sheetID")));
1363
+
1364
+ case XLQueryType::QuerySheetIndex: { // 2025-01-13: implemented query - previously no index was determined at all
1365
+ std::string queriedSheetName = m_workbook.sheetName(query.getParam<std::string>("sheetID"));
1366
+ for( uint16_t sheetIndex = 1; sheetIndex <= workbook().sheetCount(); ++sheetIndex ) {
1367
+ if (workbook().sheet(sheetIndex).name() == queriedSheetName)
1368
+ return XLQuery(query).setResult(std::to_string(sheetIndex));
1369
+ }
1370
+
1371
+ { // if loop failed to locate queriedSheetName:
1372
+ using namespace std::literals::string_literals;
1373
+ throw XLInternalError("Could not determine a sheet index for sheet named \"" + queriedSheetName + "\"");
1374
+ }
1375
+ }
1376
+ case XLQueryType::QuerySheetVisibility:
1377
+ return XLQuery(query).setResult(m_workbook.sheetVisibility(query.getParam<std::string>("sheetID")));
1378
+
1379
+ case XLQueryType::QuerySheetType: {
1380
+ const XLRelationshipType t = m_wbkRelationships.relationshipById(query.getParam<std::string>("sheetID")).type();
1381
+ if (t == XLRelationshipType::Worksheet)
1382
+ return XLQuery(query).setResult(XLContentType::Worksheet);
1383
+ if (t == XLRelationshipType::Chartsheet)
1384
+ return XLQuery(query).setResult(XLContentType::Chartsheet);
1385
+ return XLQuery(query).setResult(XLContentType::Unknown);
1386
+ }
1387
+ case XLQueryType::QuerySheetIsActive:
1388
+ return XLQuery(query).setResult(m_workbook.sheetIsActive(query.getParam<std::string>("sheetID")));
1389
+
1390
+ case XLQueryType::QuerySheetID:
1391
+ return XLQuery(query).setResult(m_workbook.sheetVisibility(query.getParam<std::string>("sheetID")));
1392
+
1393
+ case XLQueryType::QuerySheetRelsID:
1394
+ return XLQuery(query).setResult(
1395
+ m_wbkRelationships.relationshipByTarget(query.getParam<std::string>("sheetPath").substr(4)).id());
1396
+
1397
+ case XLQueryType::QuerySheetRelsTarget:
1398
+ // ===== 2024-12-15: XLRelationshipItem::target() returns the unmodified Relationship "Target" property
1399
+ // - can be absolute or relative and must be handled by the caller
1400
+ // The only invocation as of today is in XLWorkbook::sheet(const std::string& sheetName) and handles this
1401
+ return XLQuery(query).setResult(m_wbkRelationships.relationshipById(query.getParam<std::string>("sheetID")).target());
1402
+
1403
+ case XLQueryType::QuerySharedStrings:
1404
+ return XLQuery(query).setResult(m_sharedStrings);
1405
+
1406
+ case XLQueryType::QueryXmlData: {
1407
+ const auto result = std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) {
1408
+ return item.getXmlPath() == query.getParam<std::string>("xmlPath");
1409
+ });
1410
+ if (result == m_data.end())
1411
+ throw XLInternalError("Path does not exist in zip archive (" + query.getParam<std::string>("xmlPath") + ")");
1412
+ return XLQuery(query).setResult(&*result);
1413
+ }
1414
+ default:
1415
+ throw XLInternalError("XLDocument::execQuery: unknown query type " + std::to_string(static_cast<uint8_t>(query.type())));
1416
+ }
1417
+
1418
+ return query; // Needed in order to suppress compiler warning
1419
+ }
1420
+
1421
+ /**
1422
+ * @details
1423
+ */
1424
+ XLQuery XLDocument::execQuery(const XLQuery& query) { return static_cast<const XLDocument&>(*this).execQuery(query); }
1425
+
1426
+ /**
1427
+ * @details assign savingDeclaration to m_xmlSavingDeclaration
1428
+ */
1429
+ void XLDocument::setSavingDeclaration(XLXmlSavingDeclaration const& savingDeclaration) { m_xmlSavingDeclaration = savingDeclaration; }
1430
+
1431
+ /**
1432
+ * @details iterate over all worksheets, all rows, all columns and re-create the shared strings table in that order based on first use
1433
+ */
1434
+ void XLDocument::cleanupSharedStrings()
1435
+ {
1436
+ int32_t oldStringCount = m_sharedStringCache.size();
1437
+ std::vector< int32_t > indexMap(oldStringCount, -1); // indexMap[ oldIndex ] :== newIndex, -1 = not yet assigned
1438
+ int32_t newStringCount = 1; // reserve index 0 for empty string, count here +1 for each unique shared string index that is in use in the worksheet
1439
+
1440
+ unsigned int worksheetCount = m_workbook.worksheetCount();
1441
+ for (unsigned int wIndex = 1; wIndex <= worksheetCount; ++wIndex) {
1442
+ XLWorksheet wks = m_workbook.worksheet(wIndex);
1443
+ XLCellRange cellRange = wks.range();
1444
+ for (XLCellIterator cellIt = cellRange.begin(); cellIt != cellRange.end(); ++cellIt) {
1445
+ if (!cellIt.cellExists()) continue; // prevent cell creation by access for non-existing cells
1446
+
1447
+ // ===== Cell exists: check for shared strings & update index as needed
1448
+ XLCell& cell = *cellIt;
1449
+ if (cell.value().type() == XLValueType::String) {
1450
+ XLCellValueProxy val = cell.value();
1451
+ int32_t si = val.stringIndex();
1452
+ if (indexMap[si] == -1) { // shared string was not yet flagged as "in use"
1453
+ if (m_sharedStringCache[si].length() > 0) // if shared string is not empty
1454
+ indexMap[si] = newStringCount++; // add this shared string to the end of the new cache being rewritten and increment the counter
1455
+ else // else
1456
+ indexMap[si] = 0; // assign the hardcoded index 0 reserved for the empty string in newStringCache
1457
+ }
1458
+ if (indexMap[si] != si) // if the index changed
1459
+ val.setStringIndex(indexMap[si]); // then update it for the cell
1460
+ }
1461
+ }
1462
+ }
1463
+
1464
+ // ===== After all cells have been reindexed, newStringCount is now the exact amount of remaining strings,
1465
+ // and indexMap now contains the mapping to applied for reindexing.
1466
+
1467
+ // ===== Create a new shared strings cache.
1468
+ std::vector<std::string> newStringCache(newStringCount); // store the re-indexed strings here
1469
+ // NOTE: newStringCache is vector because m_sharedStringCache may eventually be changed from std::deque to something else (std::map) for performance
1470
+
1471
+ newStringCache[0] = ""; // store empty string in first position
1472
+ for (int32_t oldIdx = 0; oldIdx < oldStringCount; ++oldIdx) { // "steal" all std::strings that are still in use from existing string cache
1473
+ if (int32_t newIdx = indexMap[oldIdx]; newIdx > 0) // if string is still in use
1474
+ newStringCache[newIdx] = std::move(m_sharedStringCache[oldIdx]); // NOTE: std::move invalidates the shared string cache -> not thread safe
1475
+ }
1476
+ m_sharedStringCache.clear(); // TBD: is this safe with strings that were std::move assigned to newStringCache?
1477
+ // refill m_sharedStringCache cache from newStringCache
1478
+ std::move(
1479
+ newStringCache.begin(),
1480
+ newStringCache.end(),
1481
+ std::back_inserter(m_sharedStringCache)
1482
+ );
1483
+ if (static_cast<int32_t>(newStringCache.size()) != m_sharedStrings.rewriteXmlFromCache())
1484
+ throw XLInternalError("XLDocument::cleanupSharedStrings: failed to rewrite shared string table - document would be corrupted");
1485
+ }
1486
+
1487
+ //----------------------------------------------------------------------------------------------------------------------
1488
+ // Protected Member Functions
1489
+ //----------------------------------------------------------------------------------------------------------------------
1490
+
1491
+ /**
1492
+ * @details
1493
+ */
1494
+ std::string XLDocument::extractXmlFromArchive(const std::string& path)
1495
+ {
1496
+ return (m_archive.hasEntry(path) ? m_archive.getEntry(path) : "");
1497
+ }
1498
+
1499
+ /**
1500
+ * @details
1501
+ */
1502
+ XLXmlData* XLDocument::getXmlData(const std::string& path, bool doNotThrow)
1503
+ {
1504
+ // avoid duplication of code: use const_cast to invoke the const function overload and return a non-const value
1505
+ return const_cast<XLXmlData *>(const_cast<XLDocument const *>(this)->getXmlData(path, doNotThrow));
1506
+ }
1507
+
1508
+ /**
1509
+ * @details
1510
+ */
1511
+ const XLXmlData* XLDocument::getXmlData(const std::string& path, bool doNotThrow) const
1512
+ {
1513
+ std::list<XLXmlData>::iterator result = std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) { return item.getXmlPath() == path; });
1514
+ if (result == m_data.end()) {
1515
+ if (doNotThrow) return nullptr; // use with caution
1516
+ else throw XLInternalError("Path " + path + " does not exist in zip archive.");
1517
+ }
1518
+ return &*result;
1519
+ }
1520
+
1521
+ /**
1522
+ * @details
1523
+ */
1524
+ bool XLDocument::hasXmlData(const std::string& path) const
1525
+ {
1526
+ return std::find_if(m_data.begin(), m_data.end(), [&](const XLXmlData& item) { return item.getXmlPath() == path; }) != m_data.end();
1527
+ }
1528
+
1529
+
1530
+ namespace OpenXLSX
1531
+ {
1532
+ //----------------------------------------------------------------------------------------------------------------------
1533
+ // Global utility functions
1534
+ //----------------------------------------------------------------------------------------------------------------------
1535
+
1536
+ /**
1537
+ * @brief Return a hexadecimal digit as character that is the equivalent of value
1538
+ * @param value The number to convert, must be 0 <= value <= 15
1539
+ * @return 0 if value > 15, otherwise the hex digit equivalent to value, as a character
1540
+ */
1541
+ char hexDigit(unsigned int value)
1542
+ {
1543
+ if (value > 0xf) return 0;
1544
+ if (value < 0xa) return value + '0'; // return value as number digit
1545
+ return (value - 0xa) + 'a'; // return value as letter digit
1546
+ }
1547
+
1548
+ /**
1549
+ * @details create a hex string from data - this function does the
1550
+ */
1551
+ std::string BinaryAsHexString(const void *data, const size_t size)
1552
+ {
1553
+ // ===== Allocate memory for string assembly - each byte takes two hex digits = 2 characters in string
1554
+ std::string strAssemble(size * 2, 0); // zero-initialize (alternative would be to default-construct a string and .reserve(size * 2);
1555
+
1556
+ const uint8_t *dataBytePtr = reinterpret_cast< const uint8_t * >( data );
1557
+ // ===== assemble a string of hex digits
1558
+ for (size_t pos = 0; pos < size * 2; ++pos) {
1559
+ int valueByte = dataBytePtr[pos / 2];
1560
+ int valueHalfByte = (valueByte & (pos & 1 ? 0x0f : 0xf0)) >> (pos & 1 ? 0 : 4);
1561
+ strAssemble[pos] = hexDigit(valueHalfByte); // convert each half-byte into a hex digit
1562
+ }
1563
+ return strAssemble;
1564
+ }
1565
+
1566
+ /**
1567
+ * @details apply the XLSX password hashing algorithm to password
1568
+ */
1569
+ uint16_t ExcelPasswordHash (std::string password)
1570
+ {
1571
+ uint16_t wPasswordHash = 0;
1572
+ uint16_t cchPassword = static_cast<uint16_t>(password.length());
1573
+
1574
+ for (uint16_t pos = 0; pos < cchPassword; ++pos) {
1575
+ uint32_t byteHash = password[pos] << ((pos + 1) % 15);
1576
+ byteHash = (byteHash >> 15) | (byteHash & 0x7fff);
1577
+ wPasswordHash ^= static_cast<uint16_t>(byteHash);
1578
+ }
1579
+ wPasswordHash ^= cchPassword ^ 0xce4b;
1580
+ // wPasswordHash ^= (0x8000 | ('N' << 8) | 'K'); // 'N' = 0x4e, 'K' = 0x4b, 0x8000 | 0x4e000 | 0x004b == 0xce4b, XOR'ed above
1581
+
1582
+ return wPasswordHash;
1583
+ }
1584
+
1585
+ /**
1586
+ * @details same as ExcelPasswordHash but return the result as a hex string
1587
+ */
1588
+ std::string ExcelPasswordHashAsString (std::string password)
1589
+ {
1590
+ uint16_t pw = ExcelPasswordHash(password);
1591
+ uint8_t hashData[2];
1592
+ hashData[0] = pw >> 8; // MSB first
1593
+ hashData[1] = pw & 0xff; // LSB second
1594
+ return BinaryAsHexString(hashData, 2);
1595
+ }
1596
+
1597
+ /**
1598
+ * @brief local function: split a path into a vector of strings each containing a subdirectory (or finally: a filename) - ignore leading and trailing slashes
1599
+ * @param path split this path by '/' characters
1600
+ * @param eliminateDots if true (default), will ignore "." entries and will pop a subdirectory from the vector for each ".." entry
1601
+ * @return a vector of non-empty subdirectories
1602
+ * @throw XLInternalError upon invalid path - e.g. containing "//" or trying to escape via ".." beyond the context of path
1603
+ */
1604
+ constexpr const bool DISASSEMBLE_PATH_ELIMINATE_DOTS = true; // helper constants for code readability
1605
+ constexpr const bool DISASSEMBLE_PATH_KEEP_DOTS = false; //
1606
+ std::vector<std::string> disassemblePath(std::string const& path, bool eliminateDots = DISASSEMBLE_PATH_ELIMINATE_DOTS)
1607
+ {
1608
+ std::vector< std::string > result;
1609
+ size_t startpos = (path[ 0 ] == '/' ? 1 : 0); // skip a leading slash
1610
+ size_t pos;
1611
+ do {
1612
+ pos = path.find( '/', startpos );
1613
+ if (pos == startpos)
1614
+ throw XLInternalError("eliminateDotAndDotDotFromPath: path must not contain two subsequent forward slashes");
1615
+ else {
1616
+ std::string dirEntry = path.substr(startpos, pos - startpos); // get folder name
1617
+ if (dirEntry.length() > 0 ) {
1618
+ if (eliminateDots) {
1619
+ // handle . and .. folders
1620
+ if (dirEntry == ".") {} // no-op
1621
+ else if (dirEntry == "..") {
1622
+ if (result.size() > 0)
1623
+ result.pop_back(); // remove previous folder from result
1624
+ else throw std::string( "eliminateDotAndDotDotFromPath: no remaining directory to exit with .." );
1625
+ }
1626
+ else result.push_back(dirEntry);
1627
+ }
1628
+ else result.push_back(dirEntry);
1629
+ }
1630
+ startpos = pos + 1;
1631
+ }
1632
+ } while (pos != std::string::npos);
1633
+
1634
+ return result;
1635
+ }
1636
+
1637
+ /**
1638
+ * @details
1639
+ */
1640
+ std::string getPathARelativeToPathB(std::string const& pathA, std::string const& pathB)
1641
+ {
1642
+ size_t startpos = 0;
1643
+ while (pathA[startpos] == pathB[startpos]) ++startpos; // find position where pathA and pathB differ
1644
+ while (startpos > 0 && pathA[startpos - 1] != '/') --startpos; // then iterate back to last slash before that position
1645
+ if(startpos == 0)
1646
+ throw XLInternalError("getPathARelativeToPathB: pathA and pathB have no common beginning");
1647
+
1648
+ std::vector<std::string> dirEntriesB = disassemblePath(pathB.substr(startpos)); // disassemble unique part of pathB into a vector of strings
1649
+ if (dirEntriesB.size() > 0 && pathB.back() != '/') dirEntriesB.pop_back(); // a filename in pathB isn't needed for the relative path generation
1650
+
1651
+ std::string result(""); // assemble result:
1652
+ for (auto it = dirEntriesB.rbegin(); it != dirEntriesB.rend(); ++it) // for each subdirectory unique to pathB
1653
+ result += "../"; // add one ../ to escape it
1654
+ result += pathA.substr(startpos); // finally, append unique part of pathA
1655
+
1656
+ return result;
1657
+ }
1658
+
1659
+ /**
1660
+ * @details
1661
+ */
1662
+ std::string eliminateDotAndDotDotFromPath(const std::string& path)
1663
+ {
1664
+ std::vector< std::string > dirEntries = disassemblePath( path ); // disassemble path into a vector of strings with subdirectory names
1665
+
1666
+ // assemble path from dirEntries
1667
+ std::string result = path.front() == '/' ? "/" : "";
1668
+ if( dirEntries.size() > 0 ) {
1669
+ auto it = dirEntries.begin();
1670
+ result += *it;
1671
+ while( ++it != dirEntries.end() ) { result += "/" + *it; } // concatenate dirnames
1672
+ }
1673
+
1674
+ // in return value: avoid appending a trailing slash if a path was already reduced to "/"
1675
+ return ((result.length() > 1 || result.front() != '/') && path.back() == '/') ? result + "/" : result;
1676
+ }
1677
+
1678
+ } // namespace OpenXLSX