@q9labsai/chalk-whiteboard 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/README.md +39 -0
  2. package/dist/chunk-4XG2ABSP.js +23 -0
  3. package/dist/chunk-FLUO6BVL.js +654 -0
  4. package/dist/collab/engine.d.ts +102 -0
  5. package/dist/collab/files.d.ts +65 -0
  6. package/dist/collab/index.d.ts +7 -0
  7. package/dist/collab/index.js +16 -0
  8. package/dist/collab/presence.d.ts +32 -0
  9. package/dist/collab/reducer.d.ts +2 -0
  10. package/dist/collab/syncable.d.ts +2 -0
  11. package/dist/collab/types.d.ts +2 -0
  12. package/dist/collab/wire.d.ts +29 -0
  13. package/dist/embedded/chalk-whiteboard/THIRD_PARTY_NOTICES.json +17 -0
  14. package/dist/embedded/chalk-whiteboard/asset-manifest.json +1228 -0
  15. package/dist/embedded/chalk-whiteboard/chalk.css +5 -0
  16. package/dist/embedded/chalk-whiteboard/compatibility-manifest.json +37 -0
  17. package/dist/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Bold.woff2 +0 -0
  18. package/dist/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Medium.woff2 +0 -0
  19. package/dist/embedded/chalk-whiteboard/fonts/Assistant/Assistant-Regular.woff2 +0 -0
  20. package/dist/embedded/chalk-whiteboard/fonts/Assistant/Assistant-SemiBold.woff2 +0 -0
  21. package/dist/embedded/chalk-whiteboard/fonts/Cascadia/CascadiaCode-Regular.woff2 +0 -0
  22. package/dist/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-279a7b317d12eb88de06167bd672b4b4.woff2 +0 -0
  23. package/dist/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-6e066e8de2ac57ea9283adb9c24d7f0c.woff2 +0 -0
  24. package/dist/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-dc6a8806fa96795d7b3be5026f989a17.woff2 +0 -0
  25. package/dist/embedded/chalk-whiteboard/fonts/ComicShanns/ComicShanns-Regular-fcb0fc02dcbee4c9846b3e2508668039.woff2 +0 -0
  26. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-349fac6ca4700ffec595a7150a0d1e1d.woff2 +0 -0
  27. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-3f2c5db56cc93c5a6873b1361d730c16.woff2 +0 -0
  28. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-41b173a47b57366892116a575a43e2b6.woff2 +0 -0
  29. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-623ccf21b21ef6b3a0d87738f77eb071.woff2 +0 -0
  30. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-a88b72a24fb54c9f94e3b5fdaa7481c9.woff2 +0 -0
  31. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-b9dcf9d2e50a1eaf42fc664b50a3fd0d.woff2 +0 -0
  32. package/dist/embedded/chalk-whiteboard/fonts/Excalifont/Excalifont-Regular-be310b9bcd4f1a43f571c46df7809174.woff2 +0 -0
  33. package/dist/embedded/chalk-whiteboard/fonts/Liberation/LiberationSans-Regular.woff2 +0 -0
  34. package/dist/embedded/chalk-whiteboard/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2 +0 -0
  35. package/dist/embedded/chalk-whiteboard/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2 +0 -0
  36. package/dist/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTA3j6zbXWjgevT5.woff2 +0 -0
  37. package/dist/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTQ3j6zbXWjgeg.woff2 +0 -0
  38. package/dist/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTk3j6zbXWjgevT5.woff2 +0 -0
  39. package/dist/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTo3j6zbXWjgevT5.woff2 +0 -0
  40. package/dist/embedded/chalk-whiteboard/fonts/Nunito/Nunito-Regular-XRXI3I6Li01BKofiOc5wtlZ2di8HDIkhdTs3j6zbXWjgevT5.woff2 +0 -0
  41. package/dist/embedded/chalk-whiteboard/fonts/Virgil/Virgil-Regular.woff2 +0 -0
  42. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-019d66dcad46dc156b162d267f981c20.woff2 +0 -0
  43. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-04b718e5623574919c8b0dea5f301444.woff2 +0 -0
  44. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-069e77aac84590e2e991d0a0176d34f2.woff2 +0 -0
  45. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-06c77b8c66e51ed6c63ccb502dd8b8af.woff2 +0 -0
  46. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-08e0dc436ad0ad61ba5558db0674d762.woff2 +0 -0
  47. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-093b9ef39a46ceae95a1df18a0a3a326.woff2 +0 -0
  48. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-095c169f3314805276f603a362766abd.woff2 +0 -0
  49. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-09850c4077f3fffe707905872e0e2460.woff2 +0 -0
  50. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0986d134c05864f5025962eef9f994a0.woff2 +0 -0
  51. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0b5d723fdc4e249c140f0909e87d03b4.woff2 +0 -0
  52. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0f626226ba1272e832aea87bafd9720e.woff2 +0 -0
  53. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0f7fb1e0d5015bb1371343153ecf7ce3.woff2 +0 -0
  54. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0fa55a080fcd0f9dc2e0b0058b793df8.woff2 +0 -0
  55. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-0facdf1ea213ba40261022f5d5ed4493.woff2 +0 -0
  56. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-10a7ae9a371830a80c3d844acf1c02d7.woff2 +0 -0
  57. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-112c051027b2d766c19a519f6ee1f4f7.woff2 +0 -0
  58. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-11c345711937f0ba4b8f7b6b919c8440.woff2 +0 -0
  59. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-12b52b58eb3df36804b9a654ec9ee194.woff2 +0 -0
  60. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-13ae07ed2e272d26d59bc0691cd7117a.woff2 +0 -0
  61. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-13d2887ec8ee73c43acdabc52a05af7b.woff2 +0 -0
  62. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-145aa02cdd91946e67dc934e1acffe75.woff2 +0 -0
  63. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-15dc6d811c9cd078f9086a740d5a1038.woff2 +0 -0
  64. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-173945821411c09f70c95f98d590e697.woff2 +0 -0
  65. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1b611157cd46bb184d4fa4dae2d6a2b8.woff2 +0 -0
  66. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1e6fd68f1f3902ce48ce8c69df385622.woff2 +0 -0
  67. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1ee544f0f1dac422545c505baa788992.woff2 +0 -0
  68. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-1fdc0c67ed57263a80fd108c1f6ccf24.woff2 +0 -0
  69. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-203b0e569e3b14aac86a003dc3fa523e.woff2 +0 -0
  70. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-20cc1bbf50e7efb442756cb605672c1f.woff2 +0 -0
  71. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-20e7bf72fa05de9adf7dbcc7bf51dde6.woff2 +0 -0
  72. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-21430ee05a1248901da8d0de08744d47.woff2 +0 -0
  73. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23686f7f29da6e8008c36dd3a80c83d6.woff2 +0 -0
  74. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23ad2d71b280f00b1363b95b7bea94eb.woff2 +0 -0
  75. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-23f228f3999c01983860012330e4be08.woff2 +0 -0
  76. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-24476a126f129212beb33f66853ea151.woff2 +0 -0
  77. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-24a21c1e4449222e8d1898d69ff3a404.woff2 +0 -0
  78. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-25b7f38e18f035f96cb5e547bd2bd08c.woff2 +0 -0
  79. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-29cec36cd205b211da97acabaa62f055.woff2 +0 -0
  80. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2a26d20a23b00898ce82f09d2ee47c3f.woff2 +0 -0
  81. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2adbc89c11e65905393d3dfc468b9d5b.woff2 +0 -0
  82. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2b7441d46298788ac94e610ffcc709b6.woff2 +0 -0
  83. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2b77e8ebfb2367ab2662396a60e7d320.woff2 +0 -0
  84. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2cf96d082d35ea3d8106851223ad0d16.woff2 +0 -0
  85. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2d43040e86ff03ba677f6f9c04cd0805.woff2 +0 -0
  86. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-2e33e8dc771ef5e1d9127d60a6b73679.woff2 +0 -0
  87. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-33432927cd87d40cfe393c7482bf221f.woff2 +0 -0
  88. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-353f33792a8f60dc69323ddf635a269e.woff2 +0 -0
  89. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-36925dfe329a45086cbb7fc5c20d45ac.woff2 +0 -0
  90. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3717077e38f98d89eae729b6c14e56dc.woff2 +0 -0
  91. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3756e81d3e149cf6099163ee79944fec.woff2 +0 -0
  92. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-395c35dd584b56b0789f58a0559beaf1.woff2 +0 -0
  93. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3c9de2ae0ea4bc91a510942dfa4be8d2.woff2 +0 -0
  94. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3cc70dbb64df5b21f1326cc24dee2195.woff2 +0 -0
  95. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3e1f8f654357353bf0e04ba5c34b5f7f.woff2 +0 -0
  96. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3e63ed8162808a9e425ed80a8bc79114.woff2 +0 -0
  97. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-3eaa538115d76932653c21d8dc28f207.woff2 +0 -0
  98. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4095eb84ef3874e2600247bee0b04026.woff2 +0 -0
  99. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-41521fade99856108931b4768b1b2648.woff2 +0 -0
  100. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-450da755d5bcb70906e1295e559b9602.woff2 +0 -0
  101. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-452225341522a7942f0f6aab1a5c91a3.woff2 +0 -0
  102. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4535823663ad81405188a528d8f2b1a2.woff2 +0 -0
  103. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4806e761d750087c2d734fc64596eaff.woff2 +0 -0
  104. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4a0fdb40036e87b40aa08dd30584cb85.woff2 +0 -0
  105. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4a38cc3e9cf104e69ba246d37f8cf135.woff2 +0 -0
  106. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4aca6a43e59aceee2166b0c7e4e85ef1.woff2 +0 -0
  107. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4bfaa8ffa64c5ee560aa2daba7c9cbd3.woff2 +0 -0
  108. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4dc6d5f188d5c96d44815cd1e81aa885.woff2 +0 -0
  109. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4ddc14ed3eb0c3e46364317dfc0144a3.woff2 +0 -0
  110. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4ee10ae43505e2e0bc62656ced49c0fa.woff2 +0 -0
  111. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-4f50e5136e136527280bc902c5817561.woff2 +0 -0
  112. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-51502f1206be09c565f1547c406e9558.woff2 +0 -0
  113. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-51a0e808bbc8361236ac521a119758a3.woff2 +0 -0
  114. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-52a84a22fd1369bffeaf21da2d6158dc.woff2 +0 -0
  115. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5330a2119a716e4e7224ed108b085dac.woff2 +0 -0
  116. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-543fa46ace099a7099dad69123399400.woff2 +0 -0
  117. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-544fc28abe2c5c30e62383fd4dac255f.woff2 +0 -0
  118. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-54acdfc2166ad7fcbd074f75fd4a56ba.woff2 +0 -0
  119. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5572b3513ba8df57a3d5d7303ee6b11b.woff2 +0 -0
  120. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-56467a5c8840c4d23a60b2f935114848.woff2 +0 -0
  121. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-56a32a7689abd0326e57c10c6c069bb4.woff2 +0 -0
  122. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-57862b464a55b18c7bf234ce22907d73.woff2 +0 -0
  123. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-583d166e56ba0de4b77eabb47ef67839.woff2 +0 -0
  124. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5882ffa04f32584d26109137e2da4352.woff2 +0 -0
  125. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-58fd02350d0bc52cf1ca3bb32ce9766e.woff2 +0 -0
  126. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5935a5775af3d5c6307ac667bd9ae74e.woff2 +0 -0
  127. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-59e9ff77b0efaf684bc09274fb6908c9.woff2 +0 -0
  128. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a1ce3117cfe90c48e8fb4a9a00f694d.woff2 +0 -0
  129. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a45d991244d4c7140217e1e5f5ca4f4.woff2 +0 -0
  130. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5a7fac4b8b23a6e4e5ba0c9bf1756c91.woff2 +0 -0
  131. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5b0ed6971aaab9c8ad563230bd5471a7.woff2 +0 -0
  132. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-5d2898fbc097a7e24c6f38d80587621e.woff2 +0 -0
  133. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-603aefd23e350ba7eb124273e3c9bcf1.woff2 +0 -0
  134. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-60a3089806700d379f11827ee9843b6b.woff2 +0 -0
  135. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-60a41c7e1c68f22424e6d22df544bc82.woff2 +0 -0
  136. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-642b26e2e5f5fb780b51b593dbc8c851.woff2 +0 -0
  137. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-66493ba5a8367f2928812f446f47b56a.woff2 +0 -0
  138. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-670ba603758d94268e8606f240a42e12.woff2 +0 -0
  139. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-671a2c20b1eb9e4ef8a192833940e319.woff2 +0 -0
  140. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-684d65f1793cac449dde5d59cb3c47fb.woff2 +0 -0
  141. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-69c09cc5fa3e55c74fc4821f76909cc3.woff2 +0 -0
  142. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6ae5b42180ad70b971c91e7eefb8eba2.woff2 +0 -0
  143. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6e092f71c1e634059ada0e52abadce67.woff2 +0 -0
  144. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6f3256af8454371776bc46670d33cc65.woff2 +0 -0
  145. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-6fe5c5973cc06f74b2387a631ea36b88.woff2 +0 -0
  146. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-70c2eb8d64e71a42a834eb857ea9df51.woff2 +0 -0
  147. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-70e811fd7994e61f408c923de6ddd078.woff2 +0 -0
  148. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7197d6fda6cba7c3874c53d6381ca239.woff2 +0 -0
  149. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-72252d73220fa3cd856677888cee1635.woff2 +0 -0
  150. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-72536a3d71b694a0d53dd90ddceae41e.woff2 +0 -0
  151. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-726303e0774b4e678bff8c2deb6ca603.woff2 +0 -0
  152. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-733171b4ffcd17ea1fe1c0ba627173bf.woff2 +0 -0
  153. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-739bc1a567439c7cffcd1614644593d2.woff2 +0 -0
  154. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-73e309718fd16cea44b4d54a33581811.woff2 +0 -0
  155. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7494dc504ae00ee9cd0505f990f88c5d.woff2 +0 -0
  156. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-74e2263a91439c25b91d5132ce9f4d62.woff2 +0 -0
  157. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-761d05e3cd968cf574166867998ef06a.woff2 +0 -0
  158. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7718fe60986d8b42b1be9c5ace5ccf25.woff2 +0 -0
  159. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-774d4f764a1299da5d28ec2f2ffe0d69.woff2 +0 -0
  160. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-79d494361ae093b69e74ee9dbe65bfd4.woff2 +0 -0
  161. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-79f007c1c6d07557120982951ea67998.woff2 +0 -0
  162. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7a07ddc0f0c0f5f4a9bad6ee3dda66b5.woff2 +0 -0
  163. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7ab2bed91166a9dca83a5ebfbe2a7f38.woff2 +0 -0
  164. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7ccce86603f80a099ddb0cb21d4ae3e3.woff2 +0 -0
  165. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7e4bde7e9c7f84cd34d8a845e384c746.woff2 +0 -0
  166. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7e929f262f30c8ee78bf398150b1a7cd.woff2 +0 -0
  167. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7eb9fffd1aa890d07d0f88cc82e6cfe4.woff2 +0 -0
  168. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-7f855356ab893b0d2b9c1c83b8116f0e.woff2 +0 -0
  169. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-829615148e6357d826b9242eb7fbbd1e.woff2 +0 -0
  170. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-866fa7613df6b3fd272bcfd4530c0bb9.woff2 +0 -0
  171. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-87599f94b6cc129d505b375798d0d751.woff2 +0 -0
  172. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8c2f33cee3993174f7e87c28e4bf42ee.woff2 +0 -0
  173. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8d3bcabb847b56243b16afe62adaaf21.woff2 +0 -0
  174. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8de5b863cb50dfefdd07cb11c774d579.woff2 +0 -0
  175. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8e9f97f01034820170065b2921b4fb5e.woff2 +0 -0
  176. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-8f476c4c99813d57cbe6eca4727388ad.woff2 +0 -0
  177. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-903bb6865f3452e2fda42e3a25547bc5.woff2 +0 -0
  178. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-91ddb2969bf2d31ba02ad82998d1314c.woff2 +0 -0
  179. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-938d90c10ff8c20386af7f242c05d6b0.woff2 +0 -0
  180. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-93fc8f28a33234bcadf1527cafabd502.woff2 +0 -0
  181. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-95429962233afd82db1c27df1500a28c.woff2 +0 -0
  182. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9544732d2e62d1a429674f8ee41b5d3a.woff2 +0 -0
  183. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9592bfc861f07bcb8d75c196b370e548.woff2 +0 -0
  184. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-95bfd249da4902577b4b7d76ebdd0b44.woff2 +0 -0
  185. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-968cffdc8ee679da094e77ebf50f58ef.woff2 +0 -0
  186. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-97f7f48ce90c9429bf32ae51469db74d.woff2 +0 -0
  187. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-982b630266d87db93d2539affb1275c6.woff2 +0 -0
  188. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-98f2ad84457de7f3740d9920b8fa8667.woff2 +0 -0
  189. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-99a16ef6a64934d5781933dbd9c46b2e.woff2 +0 -0
  190. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9cfb2a77a4e45025105ad29a1748b90d.woff2 +0 -0
  191. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9d81066dd2b337c938df6e90380a00dc.woff2 +0 -0
  192. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-9eb5a99df4e76ac3363453ac9ca288b1.woff2 +0 -0
  193. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a004ddfcb26e67bd6e678c8ed19e25ce.woff2 +0 -0
  194. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a0ca5df4258213d7fc9fce80f65ce760.woff2 +0 -0
  195. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a1f916d6039285c4ffb900cd654e418f.woff2 +0 -0
  196. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a203b91dad570bf05a58c3c3ddb529bf.woff2 +0 -0
  197. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a365e82ed54697a52f27adcea1315fe8.woff2 +0 -0
  198. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a4c34be6d42152e64b0df90bc4607f64.woff2 +0 -0
  199. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-a7accba310e821da5505f71c03b76bdb.woff2 +0 -0
  200. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-aa0d470430e6391eca720c7cfa44446f.woff2 +0 -0
  201. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-aa5c9ca6cf4fba00433b7aa3fa10671a.woff2 +0 -0
  202. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ac9ceb44437becc3e9c4dbfebab7fc2d.woff2 +0 -0
  203. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b1220a3c61f85cc0408deedb4c5f57a2.woff2 +0 -0
  204. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b358f7a51ece39a3247942b1feabdb29.woff2 +0 -0
  205. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b57aaedfd8ebdf3931f25119dc6a5eb2.woff2 +0 -0
  206. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b5c1596551c256e0e9cf02028595b092.woff2 +0 -0
  207. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b6d128682ee29e471486354d486a1b90.woff2 +0 -0
  208. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b6fd38ca30869792244804b04bc058da.woff2 +0 -0
  209. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b7d203b051eff504ff59ddca7576b6a9.woff2 +0 -0
  210. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-b96d9226ce77ec94ceca043d712182e6.woff2 +0 -0
  211. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ba3de316d63c7e339987b16f41a0b879.woff2 +0 -0
  212. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-bafff7a14c27403dcc6cf1432e8ea836.woff2 +0 -0
  213. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-bd77e3c7f9e0b072d96af37f73d1aa32.woff2 +0 -0
  214. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-be549ab72f0719d606a5c01e2c0219b6.woff2 +0 -0
  215. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c16ed9740b85badf16e86ea782a3062f.woff2 +0 -0
  216. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c1f94158256bb1f3bf665b053d895af9.woff2 +0 -0
  217. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c40533fdf4cc57177b12803598af7e59.woff2 +0 -0
  218. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c4a687ac4f0c2766eefc9f77ed99cddf.woff2 +0 -0
  219. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c69f61a4ab18d0488c8d1fc12e7028e8.woff2 +0 -0
  220. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c8b71798409ccc126ee264a00aadcf21.woff2 +0 -0
  221. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-c99eda15fc26a2941579560f76c3a5cf.woff2 +0 -0
  222. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cb17fc3db95f6d139afc9d31a8e93293.woff2 +0 -0
  223. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cbaaefaaf326668277aa24dfa93c4d28.woff2 +0 -0
  224. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cd145ce4a0ea18469358df53c207bc1b.woff2 +0 -0
  225. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cdbce89e82cc1ab53a2decbf5819278f.woff2 +0 -0
  226. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ce4884f96f11589608b76b726a755803.woff2 +0 -0
  227. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cf2cc71752631e579e35b0e423bf2638.woff2 +0 -0
  228. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cf6ff4e0f491ca0cf3038187a997b9b4.woff2 +0 -0
  229. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-cfb211578629b7e8153b37240de6a9d5.woff2 +0 -0
  230. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d0cf73942fea1c74edbdf0b3011f4656.woff2 +0 -0
  231. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d2666cbed13462c5dc36fa2f15c202ca.woff2 +0 -0
  232. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-d3716376641d615e2995605b29bca7b6.woff2 +0 -0
  233. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-dac48066b5883d8b4551fc584f0c2a3e.woff2 +0 -0
  234. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-dbea1af6dcd9860be40c3d18254338f5.woff2 +0 -0
  235. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e11567fd2accf9957cd0d3c2be937d87.woff2 +0 -0
  236. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e2ead7ea7da0437f085f42ffc05f8d13.woff2 +0 -0
  237. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e3fcf5180fd466c8915c4e8069491054.woff2 +0 -0
  238. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e480d9c614742d05f0e78f274f1e69e6.woff2 +0 -0
  239. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e4bca6cfa53e499cae0a6be4894a90e9.woff2 +0 -0
  240. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e51ef413167c6e14e0c0fdcc585f2fc9.woff2 +0 -0
  241. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e5f453bb04da18eed01675eeebd88bf8.woff2 +0 -0
  242. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-e656f091b9dc4709722c9f4b84d3c797.woff2 +0 -0
  243. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ec181b795ac1fb5a50d700b6e996d745.woff2 +0 -0
  244. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-ee8bae97908d5147b423f77ad0d3c1bb.woff2 +0 -0
  245. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f0f13b5c60e0af5553bd359f5513be1b.woff2 +0 -0
  246. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f2b54d4e7be0eaefe1c2c56836fa5368.woff2 +0 -0
  247. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f56414bf9bced67990def8660e306759.woff2 +0 -0
  248. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f5d079153c99a25b9be5b8583c4cc8a7.woff2 +0 -0
  249. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f6032fc06eb20480f096199713f70885.woff2 +0 -0
  250. package/dist/embedded/chalk-whiteboard/fonts/Xiaolai/Xiaolai-Regular-f8ee5d36068a42b51d0e4a1116cfcec1.woff2 +0 -0
  251. package/dist/embedded/chalk-whiteboard/index.css +1 -0
  252. package/dist/embedded/chalk-whiteboard/index.html +17 -0
  253. package/dist/embedded/chalk-whiteboard/licenses/Excalidraw.txt +21 -0
  254. package/dist/embedded/chalk-whiteboard/licenses/MathJax.txt +202 -0
  255. package/dist/embedded/chalk-whiteboard/mathjax/tex-svg.js +1 -0
  256. package/dist/embedded/chalk-whiteboard/mathjax-config.js +1 -0
  257. package/dist/embedded/chalk-whiteboard/renderer.js +4114 -0
  258. package/dist/embedded/controller.d.ts +123 -0
  259. package/dist/embedded/index.d.ts +5 -0
  260. package/dist/embedded/index.js +897 -0
  261. package/dist/embedded/manifest.d.ts +40 -0
  262. package/dist/embedded/protocol.d.ts +211 -0
  263. package/dist/embedded/renderer-bridge.d.ts +37 -0
  264. package/dist/embedded/renderer.d.ts +25 -0
  265. package/dist/engine-UMQR3O33.js +6 -0
  266. package/dist/index.d.ts +3 -0
  267. package/dist/index.js +14 -0
  268. package/dist/react/MathEditor.d.ts +17 -0
  269. package/dist/react/WhiteboardCanvas.d.ts +47 -0
  270. package/dist/react/index.d.ts +7 -0
  271. package/dist/react/index.js +625 -0
  272. package/dist/react/math-elements.d.ts +40 -0
  273. package/dist/react/mathjax-renderer.d.ts +34 -0
  274. package/package.json +97 -0
@@ -0,0 +1,897 @@
1
+ // src/embedded/controller.ts
2
+ import { sha256 } from "@noble/hashes/sha2.js";
3
+ import { bytesToHex } from "@noble/hashes/utils.js";
4
+
5
+ // src/embedded/protocol.ts
6
+ var CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION = 1;
7
+ var CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION = "0.18.1";
8
+ var CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID = "chalk-excalidraw-0.18.1-r1";
9
+ var CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES = 32 * 1024 * 1024;
10
+ function encodeEmbeddedWhiteboardMessage(message, context) {
11
+ const payloadBytes = encodedBytes(message.payload);
12
+ if (payloadBytes > CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES) {
13
+ throw new Error("embedded whiteboard message payload exceeds the bridge limit");
14
+ }
15
+ const encoded = JSON.stringify({
16
+ bridgeVersion: CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION,
17
+ rendererBuildId: CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID,
18
+ rendererGeneration: requireBoundedString(context.rendererGeneration, "renderer generation", 128),
19
+ messageId: requireBoundedString(context.nextMessageId(), "message ID", 128),
20
+ payloadBytes,
21
+ journeyId: requireBoundedString(context.journeyId, "journey ID", 256),
22
+ ...context.traceparent ? { traceparent: requireTraceparent(context.traceparent) } : {},
23
+ ...context.tracestate ? { tracestate: requireBoundedString(context.tracestate, "tracestate", 512) } : {},
24
+ type: message.type,
25
+ payload: message.payload
26
+ });
27
+ if (encodedBytes(encoded) > CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES) {
28
+ throw new Error("embedded whiteboard message exceeds the bridge limit");
29
+ }
30
+ return encoded;
31
+ }
32
+ function decodeEmbeddedWhiteboardHostMessage(value, expectedGeneration) {
33
+ return decodeEnvelope(value, expectedGeneration, hostMessageTypes);
34
+ }
35
+ function decodeEmbeddedWhiteboardRendererMessage(value, expectedGeneration) {
36
+ return decodeEnvelope(value, expectedGeneration, rendererMessageTypes);
37
+ }
38
+ var hostMessageTypes = /* @__PURE__ */ new Set(["initialize", "apply_snapshot", "apply_update", "apply_cursor", "reset_required", "set_capabilities", "set_viewport", "operation_result", "provide_file_bytes", "request_user_export", "prepare_close"]);
39
+ var rendererMessageTypes = /* @__PURE__ */ new Set(["ready", "local_update", "cursor", "camera", "request_snapshot", "clear", "file_read", "file_write", "user_export", "metric", "error", "close_ready"]);
40
+ function decodeEnvelope(value, expectedGeneration, allowedTypes) {
41
+ if (encodedBytes(value) > CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES) throw new Error("embedded whiteboard message exceeds the bridge limit");
42
+ let parsed;
43
+ try {
44
+ parsed = JSON.parse(value);
45
+ } catch {
46
+ throw new Error("embedded whiteboard message is not valid JSON");
47
+ }
48
+ if (!isRecord(parsed) || !hasOnlyEnvelopeKeys(parsed)) throw new Error("embedded whiteboard message envelope is invalid");
49
+ if (parsed.bridgeVersion !== CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION) throw new Error("embedded whiteboard bridge version is unsupported");
50
+ if (parsed.rendererBuildId !== CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID) throw new Error("embedded whiteboard renderer build is unsupported");
51
+ const rendererGeneration = requireBoundedString(parsed.rendererGeneration, "renderer generation", 128);
52
+ if (expectedGeneration && rendererGeneration !== expectedGeneration) throw new Error("embedded whiteboard renderer generation is stale");
53
+ const type = requireBoundedString(parsed.type, "message type", 64);
54
+ if (!allowedTypes.has(type)) throw new Error("embedded whiteboard message type is unsupported");
55
+ const payloadBytes = parsed.payloadBytes;
56
+ if (!Number.isSafeInteger(payloadBytes) || Number(payloadBytes) < 0 || Number(payloadBytes) !== encodedBytes(parsed.payload)) {
57
+ throw new Error("embedded whiteboard payload byte count is invalid");
58
+ }
59
+ if (Number(payloadBytes) > CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES) throw new Error("embedded whiteboard message payload exceeds the bridge limit");
60
+ return {
61
+ bridgeVersion: CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION,
62
+ rendererBuildId: CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID,
63
+ rendererGeneration,
64
+ messageId: requireBoundedString(parsed.messageId, "message ID", 128),
65
+ payloadBytes: Number(payloadBytes),
66
+ journeyId: requireBoundedString(parsed.journeyId, "journey ID", 256),
67
+ ...parsed.traceparent ? { traceparent: requireTraceparent(parsed.traceparent) } : {},
68
+ ...parsed.tracestate ? { tracestate: requireBoundedString(parsed.tracestate, "tracestate", 512) } : {},
69
+ type,
70
+ payload: parsed.payload
71
+ };
72
+ }
73
+ function hasOnlyEnvelopeKeys(value) {
74
+ const allowed = /* @__PURE__ */ new Set(["bridgeVersion", "rendererBuildId", "rendererGeneration", "messageId", "payloadBytes", "journeyId", "traceparent", "tracestate", "type", "payload"]);
75
+ return Object.keys(value).every((key) => allowed.has(key)) && ["bridgeVersion", "rendererBuildId", "rendererGeneration", "messageId", "payloadBytes", "journeyId", "type", "payload"].every((key) => Object.hasOwn(value, key));
76
+ }
77
+ function requireBoundedString(value, label, maxBytes) {
78
+ if (typeof value !== "string" || value.length === 0 || encodedBytes(value) > maxBytes) throw new Error(`embedded whiteboard ${label} is invalid`);
79
+ return value;
80
+ }
81
+ function requireTraceparent(value) {
82
+ const traceparent = requireBoundedString(value, "traceparent", 128);
83
+ const match = /^([\da-f]{2})-([\da-f]{32})-([\da-f]{16})-([\da-f]{2})$/iu.exec(traceparent);
84
+ if (!match || match[1]?.toLowerCase() === "ff" || /^0{32}$/u.test(match[2] ?? "") || /^0{16}$/u.test(match[3] ?? "")) {
85
+ throw new Error("embedded whiteboard traceparent is invalid");
86
+ }
87
+ return traceparent;
88
+ }
89
+ function isRecord(value) {
90
+ return typeof value === "object" && value !== null && !Array.isArray(value);
91
+ }
92
+ function encodedBytes(value) {
93
+ return new TextEncoder().encode(typeof value === "string" ? value : JSON.stringify(value)).byteLength;
94
+ }
95
+
96
+ // src/embedded/compatibility-manifest.json
97
+ var compatibility_manifest_default = {
98
+ schemaVersion: 1,
99
+ rendererBuildId: "chalk-excalidraw-0.18.1-r1",
100
+ excalidraw: {
101
+ package: "@excalidraw/excalidraw",
102
+ version: "0.18.1",
103
+ restoreImplementation: "@excalidraw/excalidraw@0.18.1"
104
+ },
105
+ bridge: {
106
+ current: 1,
107
+ minimum: 1,
108
+ maximum: 1,
109
+ priorCompatible: []
110
+ },
111
+ document: {
112
+ format: "excalidraw",
113
+ supportedElementTypes: ["arrow", "diamond", "ellipse", "embeddable", "frame", "freedraw", "iframe", "image", "line", "magicframe", "rectangle", "selection", "text"],
114
+ supportedSharedAppStateFields: ["viewBackgroundColor"],
115
+ preserveUnknownOptionalElementFields: true,
116
+ unknownRequiredFeaturePolicy: "read-only-update-required"
117
+ },
118
+ assets: {
119
+ fonts: ["Assistant", "Cascadia", "ComicShanns", "Excalifont", "Liberation", "Lilita", "Nunito", "Virgil", "Xiaolai"],
120
+ math: "mathjax@4.1.3",
121
+ runtimeContentDelivery: false
122
+ },
123
+ clientSkew: {
124
+ rendererBuildMustMatch: true,
125
+ initialBridgeHasNoPriorRelease: true,
126
+ newerRequiredFeaturesOpenReadOnly: true
127
+ },
128
+ security: {
129
+ networkPolicy: "offline-only",
130
+ rendererReceivesCredentials: false,
131
+ rendererReceivesSignedURLs: false
132
+ }
133
+ };
134
+
135
+ // src/embedded/manifest.ts
136
+ var chalkEmbeddedWhiteboardManifest = Object.freeze({
137
+ ...compatibility_manifest_default,
138
+ rendererBuildId: CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID,
139
+ bridge: Object.freeze({
140
+ ...compatibility_manifest_default.bridge,
141
+ current: CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION
142
+ }),
143
+ excalidraw: Object.freeze({
144
+ ...compatibility_manifest_default.excalidraw,
145
+ version: CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION
146
+ }),
147
+ entrypoint: "chalk-whiteboard/index.html",
148
+ bundledAssets: Object.freeze(["renderer.js", "index.css", "fonts/**", "mathjax/tex-svg.js", "THIRD_PARTY_NOTICES.json"])
149
+ });
150
+ var chalkEmbeddedWhiteboardSupportedElementTypes = new Set(compatibility_manifest_default.document.supportedElementTypes);
151
+
152
+ // src/embedded/controller.ts
153
+ var MAX_FILE_BYTES = 20 * 1024 * 1024;
154
+ var MAX_IMAGE_DIMENSION = 16384;
155
+ var MAX_DECODED_IMAGE_BYTES = 64 * 1024 * 1024;
156
+ var MAX_RECENT_MESSAGE_IDS = 2048;
157
+ var permittedMimeTypes = /* @__PURE__ */ new Set(["application/octet-stream", "image/gif", "image/jpeg", "image/png", "image/svg+xml", "image/webp"]);
158
+ var permittedRendererMetrics = /* @__PURE__ */ new Set(["whiteboard.bridge.backlog", "whiteboard.file.failure", "whiteboard.frame.delay_ms", "whiteboard.input.delay_ms", "whiteboard.recovery.count", "whiteboard.renderer.memory_bytes", "whiteboard.renderer.termination"]);
159
+ var permittedRendererErrorCodes = /* @__PURE__ */ new Set(["export_failed", "invalid_file_result", "invalid_host_message", "invalid_operation_result", "renderer_load_failed", "submission_failed"]);
160
+ var ChalkWhiteboardController = class {
161
+ constructor(options) {
162
+ this.options = options;
163
+ this.#canDraw = options.canDraw;
164
+ this.#canClear = options.canClear;
165
+ this.#fetch = options.fetch ?? globalThis.fetch;
166
+ this.#nextMessageId = options.nextMessageId ?? createMessageId;
167
+ }
168
+ options;
169
+ #fetch;
170
+ #nextMessageId;
171
+ #canDraw;
172
+ #canClear;
173
+ #rendererGeneration = null;
174
+ #sceneId = null;
175
+ #sceneRevision = null;
176
+ #sceneGeneration = null;
177
+ #documentCompatible = true;
178
+ #started = false;
179
+ #transportStarted = false;
180
+ #rendererMessageIds = /* @__PURE__ */ new Set();
181
+ #fileTransfers = /* @__PURE__ */ new Map();
182
+ #unsubscribeRenderer = null;
183
+ #unsubscribeTransport = null;
184
+ start() {
185
+ if (this.#started) return;
186
+ this.#started = true;
187
+ this.#unsubscribeRenderer = this.options.renderer.subscribe((message) => {
188
+ void this.#handleRendererMessage(message).catch((cause) => this.#reportHostError(cause));
189
+ });
190
+ this.#unsubscribeTransport = this.options.transport.subscribe((event) => this.#handleTransportEvent(event));
191
+ }
192
+ stop() {
193
+ if (!this.#started) return;
194
+ this.#started = false;
195
+ this.#unsubscribeRenderer?.();
196
+ this.#unsubscribeTransport?.();
197
+ this.#unsubscribeRenderer = null;
198
+ this.#unsubscribeTransport = null;
199
+ this.#rendererGeneration = null;
200
+ this.#sceneId = null;
201
+ this.#sceneRevision = null;
202
+ this.#sceneGeneration = null;
203
+ this.#documentCompatible = true;
204
+ this.#rendererMessageIds.clear();
205
+ this.#abortFileTransfers();
206
+ if (this.#transportStarted) this.options.transport.stopSceneSubscription();
207
+ this.#transportStarted = false;
208
+ }
209
+ setCapabilities(value) {
210
+ this.#canDraw = value.canDraw;
211
+ this.#canClear = value.canClear;
212
+ this.#sendEffectiveCapabilities();
213
+ }
214
+ setViewport(viewport) {
215
+ this.#send({ type: "set_viewport", payload: viewport });
216
+ }
217
+ requestUserExport(requestId, format) {
218
+ this.#send({ type: "request_user_export", payload: { requestId, format } });
219
+ }
220
+ prepareClose(reason) {
221
+ this.#send({ type: "prepare_close", payload: { reason } });
222
+ }
223
+ rendererReloaded() {
224
+ this.#rendererGeneration = null;
225
+ this.#sceneGeneration = null;
226
+ this.#rendererMessageIds.clear();
227
+ this.#abortFileTransfers();
228
+ }
229
+ async #handleRendererMessage(raw) {
230
+ const message = decodeEmbeddedWhiteboardRendererMessage(raw, this.#rendererGeneration ?? void 0);
231
+ if (message.journeyId !== this.options.journeyId) throw new Error("embedded whiteboard journey does not match its host");
232
+ if (message.type !== "ready" && this.#rendererGeneration === null) throw new Error("embedded whiteboard renderer is not ready");
233
+ if (!recordMessageId(this.#rendererMessageIds, message.messageId)) return;
234
+ switch (message.type) {
235
+ case "ready":
236
+ await this.#ready(message);
237
+ return;
238
+ case "local_update":
239
+ await this.#localUpdate(message);
240
+ return;
241
+ case "cursor": {
242
+ const payload = requireCursor(message.payload);
243
+ this.options.transport.sendCursor(payload);
244
+ return;
245
+ }
246
+ case "request_snapshot": {
247
+ const { requestId } = requireRequest(message.payload);
248
+ await this.#operation(requestId, () => this.options.transport.requestSnapshot());
249
+ return;
250
+ }
251
+ case "clear": {
252
+ const { requestId } = requireRequest(message.payload);
253
+ await this.#operation(requestId, async () => {
254
+ if (!this.#effectiveCanClear()) throw new Error("whiteboard clear is not permitted");
255
+ const commit = await this.options.transport.clear();
256
+ this.#sceneId = commit.sceneId;
257
+ this.#sceneRevision = commit.revision;
258
+ this.#sceneGeneration = createSceneGeneration();
259
+ return { ...commit, sceneGeneration: this.#sceneGeneration };
260
+ });
261
+ return;
262
+ }
263
+ case "file_write":
264
+ await this.#writeFile(message);
265
+ return;
266
+ case "file_read":
267
+ await this.#readFile(message);
268
+ return;
269
+ case "camera":
270
+ requireCamera(message.payload);
271
+ return;
272
+ case "metric":
273
+ this.options.onMetric?.(requireMetric(message.payload));
274
+ return;
275
+ case "error":
276
+ this.options.onError?.(requireRendererError(message.payload));
277
+ return;
278
+ case "user_export":
279
+ this.options.onUserExport?.(requireUserExport(message.payload));
280
+ return;
281
+ case "close_ready":
282
+ this.options.onCloseReady?.(requireCloseReady(message.payload).reason);
283
+ }
284
+ }
285
+ async #ready(message) {
286
+ const payload = requireReady(message.payload);
287
+ if (payload.excalidrawVersion !== CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION || payload.supportedBridgeVersions[0] !== 1) {
288
+ throw new Error("embedded whiteboard renderer compatibility check failed");
289
+ }
290
+ if (this.#rendererGeneration && this.#rendererGeneration !== message.rendererGeneration) {
291
+ throw new Error("embedded whiteboard renderer generation changed without a reload");
292
+ }
293
+ this.#rendererGeneration = message.rendererGeneration;
294
+ this.#send({
295
+ type: "initialize",
296
+ payload: {
297
+ canDraw: this.#effectiveCanDraw(),
298
+ canClear: this.#effectiveCanClear(),
299
+ theme: this.options.theme ?? "light",
300
+ ...this.options.localParticipantColor ? { localParticipantColor: this.options.localParticipantColor } : {}
301
+ }
302
+ });
303
+ if (!this.#transportStarted) {
304
+ await this.options.transport.startSceneSubscription();
305
+ this.#transportStarted = true;
306
+ } else {
307
+ await this.options.transport.requestSnapshot();
308
+ }
309
+ this.options.onMetric?.({
310
+ name: "whiteboard.renderer.ready",
311
+ value: 1,
312
+ attributes: { rendererBuildId: CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID }
313
+ });
314
+ }
315
+ async #localUpdate(message) {
316
+ const payload = requireLocalUpdate(message.payload);
317
+ await this.#operation(payload.requestId, async () => {
318
+ if (!this.#effectiveCanDraw()) throw new Error("whiteboard drawing is not permitted");
319
+ if (!this.#sceneId || !this.#sceneGeneration || payload.sceneId !== this.#sceneId || payload.sceneGeneration !== this.#sceneGeneration) {
320
+ throw new Error("whiteboard update belongs to a stale scene generation");
321
+ }
322
+ const commit = await this.options.transport.submitUpdate({
323
+ sceneId: payload.sceneId,
324
+ syncAll: payload.syncAll,
325
+ elements: payload.elements.map(fromWireTransportElement)
326
+ });
327
+ if (this.#sceneId !== payload.sceneId || this.#sceneGeneration !== payload.sceneGeneration || commit.sceneId !== payload.sceneId) {
328
+ throw new Error("whiteboard update committed after its scene generation changed");
329
+ }
330
+ this.#sceneRevision = commit.revision;
331
+ return commit;
332
+ });
333
+ }
334
+ async #writeFile(message) {
335
+ const payload = requireFileWrite(message.payload);
336
+ await this.#operation(payload.requestId, async () => {
337
+ if (!this.#effectiveCanDraw()) throw new Error("whiteboard file upload is not permitted");
338
+ const abortController = this.#beginFileTransfer(payload.requestId);
339
+ try {
340
+ const blob = await this.#dataURLBlob(payload.dataURL);
341
+ if (blob.size !== payload.byteLength) throw new Error("whiteboard file byte length does not match");
342
+ const validated = await validateFileBlob(blob, payload.mimeType);
343
+ if (bytesToHex(sha256(validated.bytes)) !== payload.sha256.toLowerCase()) {
344
+ throw new Error("whiteboard file digest does not match");
345
+ }
346
+ const upload = await this.options.transport.files.initiateUpload({
347
+ fileId: payload.fileId,
348
+ mimeType: validated.mimeType,
349
+ byteLength: payload.byteLength,
350
+ sha256: payload.sha256
351
+ });
352
+ const response = await this.#fetch(upload.uploadUrl, {
353
+ method: upload.method,
354
+ headers: upload.headers,
355
+ body: blob,
356
+ signal: abortController.signal
357
+ });
358
+ if (!response.ok) throw new Error(`whiteboard file upload failed with HTTP ${response.status}`);
359
+ await this.options.transport.files.finalizeUpload(upload.uploadId);
360
+ } finally {
361
+ this.#finishFileTransfer(payload.requestId, abortController);
362
+ }
363
+ });
364
+ }
365
+ async #readFile(message) {
366
+ const payload = requireFileRead(message.payload);
367
+ let abortController = null;
368
+ try {
369
+ abortController = this.#beginFileTransfer(payload.requestId);
370
+ const { downloadUrl } = await this.options.transport.files.getDownloadUrl(payload.fileId);
371
+ const response = await this.#fetch(downloadUrl, { signal: abortController.signal });
372
+ if (!response.ok) throw new Error(`whiteboard file download failed with HTTP ${response.status}`);
373
+ const blob = await boundedResponseBlob(response);
374
+ const { mimeType } = await validateFileBlob(blob, blob.type || "application/octet-stream");
375
+ const normalizedBlob = blob.type === mimeType ? blob : new Blob([blob], { type: mimeType });
376
+ const dataURL = await blobToDataURL(normalizedBlob);
377
+ this.#send({
378
+ type: "provide_file_bytes",
379
+ payload: { requestId: payload.requestId, fileId: payload.fileId, mimeType, dataURL }
380
+ });
381
+ } catch (cause) {
382
+ this.#sendOperationFailure(payload.requestId, cause);
383
+ } finally {
384
+ if (abortController) this.#finishFileTransfer(payload.requestId, abortController);
385
+ }
386
+ }
387
+ async #operation(requestId, operation) {
388
+ try {
389
+ const result = await operation();
390
+ this.#send({ type: "operation_result", payload: { requestId, ok: true, ...result === void 0 ? {} : { result } } });
391
+ } catch (cause) {
392
+ this.#sendOperationFailure(requestId, cause);
393
+ }
394
+ }
395
+ #handleTransportEvent(event) {
396
+ switch (event.type) {
397
+ case "snapshot": {
398
+ if (!isRevision(event.revision)) {
399
+ this.#reportHostError(new Error("whiteboard snapshot revision is invalid"));
400
+ return;
401
+ }
402
+ this.#updateDocumentCompatibility(event.elements);
403
+ this.#sceneId = event.sceneId;
404
+ this.#sceneRevision = event.revision;
405
+ this.#sceneGeneration = createSceneGeneration();
406
+ this.#send({
407
+ type: "apply_snapshot",
408
+ payload: {
409
+ sceneId: event.sceneId,
410
+ revision: event.revision,
411
+ sceneGeneration: this.#sceneGeneration,
412
+ elements: event.elements.map(toWireTransportElement),
413
+ ...event.appState ? { appState: event.appState } : {}
414
+ }
415
+ });
416
+ return;
417
+ }
418
+ case "update": {
419
+ if (!this.#sceneId || !this.#sceneGeneration || event.sceneId !== this.#sceneId) {
420
+ this.#invalidateSceneAndRecover(event.sceneId, "scene_changed");
421
+ return;
422
+ }
423
+ if (!isRevision(event.revision)) {
424
+ this.#invalidateSceneAndRecover(event.sceneId, "gap");
425
+ return;
426
+ }
427
+ if (this.#sceneRevision && compareRevision(event.revision, this.#sceneRevision) <= 0) return;
428
+ this.#updateDocumentCompatibility(event.elements);
429
+ this.#sceneRevision = event.revision;
430
+ this.#send({
431
+ type: "apply_update",
432
+ payload: {
433
+ sceneId: event.sceneId,
434
+ revision: event.revision,
435
+ sceneGeneration: this.#sceneGeneration,
436
+ elements: event.elements.map(toWireTransportElement)
437
+ }
438
+ });
439
+ return;
440
+ }
441
+ case "cursor":
442
+ this.#send({ type: "apply_cursor", payload: event });
443
+ return;
444
+ case "reset_required":
445
+ this.#sceneGeneration = null;
446
+ this.#send({ type: "reset_required", payload: event });
447
+ }
448
+ }
449
+ #invalidateSceneAndRecover(sceneId, reason) {
450
+ this.#sceneId = null;
451
+ this.#sceneRevision = null;
452
+ this.#sceneGeneration = null;
453
+ this.#send({ type: "reset_required", payload: { sceneId, reason } });
454
+ void this.options.transport.requestSnapshot().catch((cause) => this.#reportHostError(cause));
455
+ }
456
+ #effectiveCanDraw() {
457
+ return this.#canDraw && this.#documentCompatible;
458
+ }
459
+ #effectiveCanClear() {
460
+ return this.#canClear && this.#documentCompatible;
461
+ }
462
+ #sendEffectiveCapabilities() {
463
+ this.#send({
464
+ type: "set_capabilities",
465
+ payload: {
466
+ canDraw: this.#effectiveCanDraw(),
467
+ canClear: this.#effectiveCanClear()
468
+ }
469
+ });
470
+ }
471
+ #updateDocumentCompatibility(elements) {
472
+ const compatible = elements.every((element) => chalkEmbeddedWhiteboardSupportedElementTypes.has(element.type));
473
+ if (compatible === this.#documentCompatible) return;
474
+ this.#documentCompatible = compatible;
475
+ this.#sendEffectiveCapabilities();
476
+ this.options.onCompatibilityChange?.({
477
+ compatible,
478
+ message: compatible ? null : "This whiteboard uses a feature this app cannot edit. Update required."
479
+ });
480
+ if (!compatible) {
481
+ this.options.onError?.({
482
+ code: "update_required",
483
+ message: "This whiteboard uses a feature this app cannot edit. Update required.",
484
+ recoverable: false
485
+ });
486
+ }
487
+ }
488
+ #send(message) {
489
+ if (!this.#started || !this.#rendererGeneration) return;
490
+ this.options.renderer.postMessage(
491
+ encodeEmbeddedWhiteboardMessage(message, {
492
+ rendererGeneration: this.#rendererGeneration,
493
+ journeyId: this.options.journeyId,
494
+ ...this.options.traceparent ? { traceparent: this.options.traceparent } : {},
495
+ ...this.options.tracestate ? { tracestate: this.options.tracestate } : {},
496
+ nextMessageId: this.#nextMessageId
497
+ })
498
+ );
499
+ }
500
+ #sendOperationFailure(requestId, cause) {
501
+ const message = safeErrorMessage(cause);
502
+ this.#send({
503
+ type: "operation_result",
504
+ payload: {
505
+ requestId,
506
+ ok: false,
507
+ error: { code: "operation_failed", message, recoverable: true }
508
+ }
509
+ });
510
+ this.options.onError?.({ code: "operation_failed", message, recoverable: true });
511
+ }
512
+ #reportHostError(cause) {
513
+ const message = safeErrorMessage(cause);
514
+ this.options.onError?.({ code: "invalid_renderer_message", message, recoverable: false });
515
+ }
516
+ async #dataURLBlob(dataURL) {
517
+ if (!dataURL.startsWith("data:") || dataURL.length > Math.ceil(MAX_FILE_BYTES * 4 / 3) + 1024) {
518
+ throw new Error("whiteboard file data is invalid");
519
+ }
520
+ const separator = dataURL.indexOf(",");
521
+ if (separator < 0) throw new Error("whiteboard file data is invalid");
522
+ const metadata = dataURL.slice(5, separator).split(";");
523
+ const mimeType = normalizeMimeType(metadata[0] ?? "");
524
+ if (metadata.length !== 2 || metadata[1]?.toLowerCase() !== "base64") {
525
+ throw new Error("whiteboard file data must use base64 encoding");
526
+ }
527
+ let decoded;
528
+ try {
529
+ decoded = atob(dataURL.slice(separator + 1));
530
+ } catch {
531
+ throw new Error("whiteboard file data is not valid base64");
532
+ }
533
+ const bytes = Uint8Array.from(decoded, (character) => character.charCodeAt(0));
534
+ const blob = new Blob([bytes], { type: mimeType });
535
+ if (blob.size > MAX_FILE_BYTES) throw new Error("whiteboard file exceeds the renderer transfer limit");
536
+ return blob;
537
+ }
538
+ #beginFileTransfer(requestId) {
539
+ if (this.#fileTransfers.has(requestId)) throw new Error("whiteboard file request is already active");
540
+ const abortController = new AbortController();
541
+ this.#fileTransfers.set(requestId, abortController);
542
+ return abortController;
543
+ }
544
+ #finishFileTransfer(requestId, abortController) {
545
+ if (this.#fileTransfers.get(requestId) === abortController) this.#fileTransfers.delete(requestId);
546
+ }
547
+ #abortFileTransfers() {
548
+ for (const abortController of this.#fileTransfers.values()) abortController.abort();
549
+ this.#fileTransfers.clear();
550
+ }
551
+ };
552
+ function toWireTransportElement(element) {
553
+ return {
554
+ id: element.id,
555
+ type: element.type,
556
+ version: element.version,
557
+ version_nonce: element.versionNonce,
558
+ index: element.index,
559
+ is_deleted: element.isDeleted,
560
+ payload: element.payload
561
+ };
562
+ }
563
+ function fromWireTransportElement(element) {
564
+ return {
565
+ id: element.id,
566
+ type: element.type,
567
+ version: element.version,
568
+ versionNonce: element.version_nonce,
569
+ index: element.index,
570
+ isDeleted: element.is_deleted,
571
+ payload: element.payload
572
+ };
573
+ }
574
+ function requireReady(value) {
575
+ const record = requireRecord(value, ["excalidrawVersion", "supportedBridgeVersions"]);
576
+ if (record.excalidrawVersion !== CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION || !Array.isArray(record.supportedBridgeVersions) || record.supportedBridgeVersions.length !== 1 || record.supportedBridgeVersions[0] !== 1) {
577
+ throw new Error("embedded whiteboard ready payload is invalid");
578
+ }
579
+ return {
580
+ excalidrawVersion: CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION,
581
+ supportedBridgeVersions: [1]
582
+ };
583
+ }
584
+ function requireLocalUpdate(value) {
585
+ const record = requireRecord(value, ["requestId", "sceneId", "sceneGeneration", "syncAll", "elements"]);
586
+ if (typeof record.syncAll !== "boolean" || !Array.isArray(record.elements)) throw new Error("embedded whiteboard local update is invalid");
587
+ return {
588
+ requestId: requireString(record.requestId, "request ID"),
589
+ sceneId: requireString(record.sceneId, "scene ID"),
590
+ sceneGeneration: requireString(record.sceneGeneration, "scene generation"),
591
+ syncAll: record.syncAll,
592
+ elements: record.elements.map(requireWireElement)
593
+ };
594
+ }
595
+ function requireCursor(value) {
596
+ const record = requireRecord(value, ["x", "y"]);
597
+ if (!isFiniteNumber(record.x) || !isFiniteNumber(record.y)) throw new Error("embedded whiteboard cursor is invalid");
598
+ return { x: record.x, y: record.y };
599
+ }
600
+ function requireCamera(value) {
601
+ const record = requireRecord(value, ["scrollX", "scrollY", "zoom"]);
602
+ if (!isFiniteNumber(record.scrollX) || !isFiniteNumber(record.scrollY) || !isFiniteNumber(record.zoom) || record.zoom <= 0) {
603
+ throw new Error("embedded whiteboard camera is invalid");
604
+ }
605
+ return { scrollX: record.scrollX, scrollY: record.scrollY, zoom: record.zoom };
606
+ }
607
+ function requireRequest(value) {
608
+ const record = requireRecord(value, ["requestId"]);
609
+ return { requestId: requireString(record.requestId, "request ID") };
610
+ }
611
+ function requireFileWrite(value) {
612
+ const record = requireRecord(value, ["requestId", "fileId", "mimeType", "byteLength", "sha256", "dataURL"]);
613
+ const byteLength = record.byteLength;
614
+ const sha2562 = requireString(record.sha256, "file digest");
615
+ if (!Number.isSafeInteger(byteLength) || Number(byteLength) <= 0 || Number(byteLength) > MAX_FILE_BYTES || !/^[\da-f]{64}$/iu.test(sha2562)) {
616
+ throw new Error("embedded whiteboard file metadata is invalid");
617
+ }
618
+ return {
619
+ requestId: requireString(record.requestId, "request ID"),
620
+ fileId: requireString(record.fileId, "file ID"),
621
+ mimeType: normalizeMimeType(requireString(record.mimeType, "MIME type")),
622
+ byteLength: Number(byteLength),
623
+ sha256: sha2562.toLowerCase(),
624
+ dataURL: requireString(record.dataURL, "file data", Math.ceil(MAX_FILE_BYTES * 4 / 3) + 1024)
625
+ };
626
+ }
627
+ function requireFileRead(value) {
628
+ const record = requireRecord(value, ["requestId", "fileId"]);
629
+ return { requestId: requireString(record.requestId, "request ID"), fileId: requireString(record.fileId, "file ID") };
630
+ }
631
+ function requireMetric(value) {
632
+ const record = requireRecord(value, ["name", "value"], ["attributes"]);
633
+ if (!isFiniteNumber(record.value)) throw new Error("embedded whiteboard metric is invalid");
634
+ const name = requireString(record.name, "metric name");
635
+ if (!permittedRendererMetrics.has(name)) throw new Error("embedded whiteboard metric is unsupported");
636
+ return {
637
+ name,
638
+ value: record.value
639
+ };
640
+ }
641
+ function requireRendererError(value) {
642
+ const record = requireRecord(value, ["code", "message", "recoverable"]);
643
+ if (typeof record.recoverable !== "boolean") throw new Error("embedded whiteboard error is invalid");
644
+ const code = requireString(record.code, "error code");
645
+ if (!permittedRendererErrorCodes.has(code)) throw new Error("embedded whiteboard error code is unsupported");
646
+ return {
647
+ code,
648
+ message: `The embedded whiteboard reported ${code.replaceAll("_", " ")}.`,
649
+ recoverable: record.recoverable
650
+ };
651
+ }
652
+ function requireUserExport(value) {
653
+ const record = requireRecord(value, ["requestId", "format", "mimeType", "dataURL"]);
654
+ if (record.format !== "png" && record.format !== "svg") throw new Error("embedded whiteboard export is invalid");
655
+ return {
656
+ requestId: requireString(record.requestId, "request ID"),
657
+ format: record.format,
658
+ mimeType: normalizeMimeType(requireString(record.mimeType, "MIME type")),
659
+ dataURL: requireString(record.dataURL, "export data", CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES - 1024)
660
+ };
661
+ }
662
+ function requireCloseReady(value) {
663
+ const record = requireRecord(value, ["reason"]);
664
+ return { reason: requireString(record.reason, "close reason") };
665
+ }
666
+ function requireWireElement(value) {
667
+ const record = requireRecord(value, ["id", "type", "version", "version_nonce", "index", "is_deleted", "payload"]);
668
+ if (!Number.isSafeInteger(record.version) || Number(record.version) < 0 || !Number.isSafeInteger(record.version_nonce) || Number(record.version_nonce) < 0 || typeof record.is_deleted !== "boolean" || !isRecord2(record.payload)) {
669
+ throw new Error("embedded whiteboard element is invalid");
670
+ }
671
+ return {
672
+ id: requireString(record.id, "element ID"),
673
+ type: requireString(record.type, "element type"),
674
+ version: Number(record.version),
675
+ version_nonce: Number(record.version_nonce),
676
+ index: requireString(record.index, "element index"),
677
+ is_deleted: record.is_deleted,
678
+ payload: record.payload
679
+ };
680
+ }
681
+ function requireRecord(value, requiredKeys, optionalKeys = []) {
682
+ if (!isRecord2(value)) throw new Error("embedded whiteboard message payload is invalid");
683
+ const allowed = /* @__PURE__ */ new Set([...requiredKeys, ...optionalKeys]);
684
+ if (!requiredKeys.every((key) => Object.hasOwn(value, key)) || !Object.keys(value).every((key) => allowed.has(key))) {
685
+ throw new Error("embedded whiteboard message payload fields are invalid");
686
+ }
687
+ return value;
688
+ }
689
+ function requireString(value, label, maxBytes = 32 * 1024) {
690
+ if (typeof value !== "string" || value.length === 0 || new TextEncoder().encode(value).byteLength > maxBytes) throw new Error(`embedded whiteboard ${label} is invalid`);
691
+ return value;
692
+ }
693
+ function isRecord2(value) {
694
+ return typeof value === "object" && value !== null && !Array.isArray(value);
695
+ }
696
+ function isFiniteNumber(value) {
697
+ return typeof value === "number" && Number.isFinite(value);
698
+ }
699
+ function normalizeMimeType(value) {
700
+ const mimeType = value.split(";", 1)[0]?.trim().toLowerCase() ?? "";
701
+ if (!permittedMimeTypes.has(mimeType)) throw new Error("whiteboard file MIME type is not permitted");
702
+ return mimeType;
703
+ }
704
+ async function validateFileBlob(blob, claimedMimeType) {
705
+ if (blob.size <= 0 || blob.size > MAX_FILE_BYTES) throw new Error("whiteboard file exceeds the renderer transfer limit");
706
+ const bytes = new Uint8Array(await blob.arrayBuffer());
707
+ const claimed = normalizeMimeType(claimedMimeType);
708
+ const declared = blob.type ? normalizeMimeType(blob.type) : "application/octet-stream";
709
+ if (claimed !== "application/octet-stream" && declared !== claimed) {
710
+ throw new Error("whiteboard file declared MIME type does not match");
711
+ }
712
+ const detected = detectFileMimeType(bytes);
713
+ const mimeType = claimed === "application/octet-stream" && detected ? detected : claimed;
714
+ if (detected && mimeType !== detected) throw new Error("whiteboard file MIME signature does not match");
715
+ if (mimeType.startsWith("image/") && !detected) throw new Error("whiteboard image signature is invalid");
716
+ const dimensions = imageDimensions(bytes, mimeType);
717
+ if (mimeType.startsWith("image/") && !dimensions) throw new Error("whiteboard image dimensions are invalid");
718
+ if (dimensions) validateImageDimensions(dimensions);
719
+ if (mimeType === "image/svg+xml") validateSvg(new TextDecoder().decode(bytes));
720
+ return { bytes, mimeType };
721
+ }
722
+ async function boundedResponseBlob(response) {
723
+ const contentEncoding = response.headers.get("content-encoding");
724
+ if (contentEncoding && contentEncoding.toLowerCase() !== "identity") {
725
+ throw new Error("whiteboard file download uses an unsupported content encoding");
726
+ }
727
+ const contentLength = response.headers.get("content-length");
728
+ if (!contentLength || !/^[1-9]\d*$/u.test(contentLength)) {
729
+ throw new Error("whiteboard file download is missing a valid content length");
730
+ }
731
+ const expectedBytes = Number(contentLength);
732
+ if (!Number.isSafeInteger(expectedBytes) || expectedBytes > MAX_FILE_BYTES) {
733
+ throw new Error("whiteboard file download exceeds the renderer transfer limit");
734
+ }
735
+ const blob = await response.blob();
736
+ if (blob.size !== expectedBytes || blob.size > MAX_FILE_BYTES) {
737
+ throw new Error("whiteboard file download byte length does not match");
738
+ }
739
+ return blob;
740
+ }
741
+ function detectFileMimeType(bytes) {
742
+ if (hasBytes(bytes, [137, 80, 78, 71, 13, 10, 26, 10])) return "image/png";
743
+ if (hasBytes(bytes, [255, 216, 255])) return "image/jpeg";
744
+ if (ascii(bytes, 0, 6) === "GIF87a" || ascii(bytes, 0, 6) === "GIF89a") return "image/gif";
745
+ if (ascii(bytes, 0, 4) === "RIFF" && ascii(bytes, 8, 4) === "WEBP") return "image/webp";
746
+ const prefix = new TextDecoder().decode(bytes.subarray(0, Math.min(bytes.length, 1024))).replace(/^\uFEFF/u, "");
747
+ if (/^\s*(?:<\?xml[^>]*>\s*)?<svg(?:\s|>)/iu.test(prefix)) return "image/svg+xml";
748
+ return null;
749
+ }
750
+ function imageDimensions(bytes, mimeType) {
751
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
752
+ switch (mimeType) {
753
+ case "image/png":
754
+ return bytes.length >= 24 ? { width: view.getUint32(16), height: view.getUint32(20) } : null;
755
+ case "image/gif":
756
+ return bytes.length >= 10 ? { width: view.getUint16(6, true), height: view.getUint16(8, true) } : null;
757
+ case "image/jpeg":
758
+ return jpegDimensions(bytes);
759
+ case "image/webp":
760
+ return webpDimensions(bytes);
761
+ case "image/svg+xml":
762
+ return svgDimensions(new TextDecoder().decode(bytes));
763
+ default:
764
+ return null;
765
+ }
766
+ }
767
+ function jpegDimensions(bytes) {
768
+ let offset = 2;
769
+ while (offset + 8 < bytes.length) {
770
+ if (bytes[offset] !== 255) {
771
+ offset += 1;
772
+ continue;
773
+ }
774
+ const marker = bytes[offset + 1] ?? 0;
775
+ offset += 2;
776
+ if (marker === 216 || marker === 217) continue;
777
+ if (offset + 2 > bytes.length) return null;
778
+ const segmentLength = bytes[offset] << 8 | bytes[offset + 1];
779
+ if (segmentLength < 2 || offset + segmentLength > bytes.length) return null;
780
+ if ([192, 193, 194, 195, 197, 198, 199, 201, 202, 203, 205, 206, 207].includes(marker)) {
781
+ return {
782
+ height: bytes[offset + 3] << 8 | bytes[offset + 4],
783
+ width: bytes[offset + 5] << 8 | bytes[offset + 6]
784
+ };
785
+ }
786
+ offset += segmentLength;
787
+ }
788
+ return null;
789
+ }
790
+ function webpDimensions(bytes) {
791
+ const chunk = ascii(bytes, 12, 4);
792
+ if (chunk === "VP8X" && bytes.length >= 30) {
793
+ return {
794
+ width: 1 + uint24(bytes, 24),
795
+ height: 1 + uint24(bytes, 27)
796
+ };
797
+ }
798
+ if (chunk === "VP8 " && bytes.length >= 30 && hasBytes(bytes, [157, 1, 42], 23)) {
799
+ return {
800
+ width: (bytes[26] | bytes[27] << 8) & 16383,
801
+ height: (bytes[28] | bytes[29] << 8) & 16383
802
+ };
803
+ }
804
+ if (chunk === "VP8L" && bytes.length >= 25 && bytes[20] === 47) {
805
+ return {
806
+ width: 1 + (bytes[21] | (bytes[22] & 63) << 8),
807
+ height: 1 + (bytes[22] >> 6 | bytes[23] << 2 | (bytes[24] & 15) << 10)
808
+ };
809
+ }
810
+ return null;
811
+ }
812
+ function svgDimensions(svg) {
813
+ const root = /^\s*(?:<\?xml[^>]*>\s*)?<svg\b([^>]*)>/iu.exec(svg)?.[1];
814
+ if (!root) return null;
815
+ const width = numericSvgAttribute(root, "width");
816
+ const height = numericSvgAttribute(root, "height");
817
+ if (width && height) return { width, height };
818
+ const viewBox = /\bviewBox\s*=\s*["']\s*[-+\d.eE]+\s+[-+\d.eE]+\s+([-+\d.eE]+)\s+([-+\d.eE]+)\s*["']/u.exec(root);
819
+ if (!viewBox) return null;
820
+ return { width: Number(viewBox[1]), height: Number(viewBox[2]) };
821
+ }
822
+ function numericSvgAttribute(attributes, name) {
823
+ const match = new RegExp(`\\b${name}\\s*=\\s*["']\\s*([-+\\d.eE]+)`, "u").exec(attributes);
824
+ if (!match) return null;
825
+ const value = Number(match[1]);
826
+ return Number.isFinite(value) ? value : null;
827
+ }
828
+ function validateImageDimensions(dimensions) {
829
+ if (!Number.isFinite(dimensions.width) || !Number.isFinite(dimensions.height) || dimensions.width <= 0 || dimensions.height <= 0 || dimensions.width > MAX_IMAGE_DIMENSION || dimensions.height > MAX_IMAGE_DIMENSION || dimensions.width * dimensions.height * 4 > MAX_DECODED_IMAGE_BYTES) {
830
+ throw new Error("whiteboard image dimensions exceed the decoded-memory limit");
831
+ }
832
+ }
833
+ function validateSvg(svg) {
834
+ if (!/^\s*(?:<\?xml[^>]*>\s*)?<svg(?:\s|>)/iu.test(svg) || /<!DOCTYPE|<!ENTITY/iu.test(svg) || /<(?:script|foreignObject|iframe|object|embed|audio|video|use|image)\b/iu.test(svg) || /\bon[a-z]+\s*=/iu.test(svg) || /\b(?:href|src)\s*=\s*["']?\s*(?:https?:|\/\/|javascript:)/iu.test(svg) || /\burl\(\s*["']?\s*(?:https?:|\/\/|javascript:)/iu.test(svg)) {
835
+ throw new Error("whiteboard SVG contains unsafe external or executable content");
836
+ }
837
+ }
838
+ function hasBytes(bytes, expected, offset = 0) {
839
+ return expected.every((value, index) => bytes[offset + index] === value);
840
+ }
841
+ function ascii(bytes, offset, length) {
842
+ return String.fromCharCode(...bytes.subarray(offset, offset + length));
843
+ }
844
+ function uint24(bytes, offset) {
845
+ return bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16;
846
+ }
847
+ function blobToDataURL(blob) {
848
+ return new Promise((resolve, reject) => {
849
+ const reader = new FileReader();
850
+ reader.onerror = () => reject(new Error("whiteboard file could not be encoded"));
851
+ reader.onload = () => resolve(String(reader.result));
852
+ reader.readAsDataURL(blob);
853
+ });
854
+ }
855
+ function safeErrorMessage(cause) {
856
+ const raw = cause instanceof Error ? cause.message : "Whiteboard operation failed";
857
+ const redacted = raw.replace(/\b(?:https?|wss?):\/\/\S+/giu, "[redacted-url]").replace(/\b(?:bearer|token|authorization|credential|secret)\b\s*[:=]?\s*\S*/giu, "[redacted-credential]").replace(/\bdata:[^,\s]+,[^\s]+/giu, "[redacted-data]");
858
+ return redacted.length > 256 ? `${redacted.slice(0, 253)}...` : redacted;
859
+ }
860
+ function compareRevision(left, right) {
861
+ const leftRevision = BigInt(left);
862
+ const rightRevision = BigInt(right);
863
+ return leftRevision === rightRevision ? 0 : leftRevision > rightRevision ? 1 : -1;
864
+ }
865
+ function isRevision(value) {
866
+ return /^(?:0|[1-9]\d*)$/u.test(value);
867
+ }
868
+ function createSceneGeneration() {
869
+ const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto);
870
+ if (randomUUID) return randomUUID();
871
+ return `scene-${Date.now()}-${Math.random().toString(36).slice(2)}`;
872
+ }
873
+ function createMessageId() {
874
+ const randomUUID = globalThis.crypto?.randomUUID?.bind(globalThis.crypto);
875
+ if (randomUUID) return randomUUID();
876
+ return `chalk-whiteboard-${Date.now()}-${Math.random().toString(36).slice(2)}`;
877
+ }
878
+ function recordMessageId(messageIds, messageId) {
879
+ if (messageIds.has(messageId)) return false;
880
+ messageIds.add(messageId);
881
+ if (messageIds.size > MAX_RECENT_MESSAGE_IDS) {
882
+ const oldest = messageIds.values().next().value;
883
+ if (oldest) messageIds.delete(oldest);
884
+ }
885
+ return true;
886
+ }
887
+ export {
888
+ CHALK_EMBEDDED_WHITEBOARD_BRIDGE_VERSION,
889
+ CHALK_EMBEDDED_WHITEBOARD_EXCALIDRAW_VERSION,
890
+ CHALK_EMBEDDED_WHITEBOARD_MAX_MESSAGE_BYTES,
891
+ CHALK_EMBEDDED_WHITEBOARD_RENDERER_BUILD_ID,
892
+ ChalkWhiteboardController,
893
+ chalkEmbeddedWhiteboardManifest,
894
+ decodeEmbeddedWhiteboardHostMessage,
895
+ decodeEmbeddedWhiteboardRendererMessage,
896
+ encodeEmbeddedWhiteboardMessage
897
+ };