@bendyline/squisq 2.1.0 → 2.2.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.
- package/LICENSE +21 -0
- package/NOTICE.md +24 -0
- package/dist/{ContentContainer-BXUlIf18.d.ts → ContentContainer-B2w9sUoL.d.ts} +15 -0
- package/dist/{Doc-DynJleo-.d.ts → Doc-BubIpWsp.d.ts} +1 -1
- package/dist/{ImageEditDoc-Ca4Tr9uN.d.ts → ImageEditDoc-CGxk5CHc.d.ts} +1 -1
- package/dist/{annotationCoercion-Dr_DY9Hx.d.ts → annotationCoercion-PtRQhk5V.d.ts} +1 -1
- package/dist/chunk-2L55443L.js +0 -0
- package/dist/{chunk-VWCJ2WXC.js → chunk-2ZWIXGAC.js} +0 -1
- package/dist/{chunk-VYFRI7R6.js → chunk-32R2RZAO.js} +72 -3
- package/dist/chunk-3IGPAPQ7.js +645 -0
- package/dist/{chunk-QE7TWGVT.js → chunk-4VOD55SX.js} +0 -1
- package/dist/{chunk-3E5F2XMR.js → chunk-67L6WRJN.js} +0 -1
- package/dist/{chunk-5DKBFXPY.js → chunk-6ECMNUIP.js} +26 -18
- package/dist/{chunk-JI77MGAK.js → chunk-7ARJZYQY.js} +159 -120
- package/dist/{chunk-DBS6RIFL.js → chunk-7N4G32LG.js} +0 -1
- package/dist/{chunk-JOQYPRDZ.js → chunk-7YEZFHLS.js} +10 -8
- package/dist/{chunk-2UQOHYE2.js → chunk-7ZAAICW4.js} +0 -1
- package/dist/{chunk-66QO7XFB.js → chunk-ACZOVWX3.js} +117 -7
- package/dist/{chunk-5J4HKRJF.js → chunk-BAOV476U.js} +0 -1
- package/dist/chunk-BCCXTMN5.js +699 -0
- package/dist/{chunk-JHZWYRSW.js → chunk-C33GTPUZ.js} +11 -4
- package/dist/{chunk-QUUPYOSP.js → chunk-CB45YGAM.js} +2 -3
- package/dist/{chunk-XNLB57UD.js → chunk-DYPMOPIW.js} +18 -2
- package/dist/{chunk-VR7UPJ7C.js → chunk-FCG3BIZN.js} +12 -1
- package/dist/{chunk-5UYI3RJB.js → chunk-FDYDYL77.js} +54 -40
- package/dist/{chunk-OTKVFVL6.js → chunk-I2O6W7DX.js} +116 -44
- package/dist/{chunk-Q7LROV2H.js → chunk-NKNMGIIN.js} +0 -1
- package/dist/chunk-OPO5K4DZ.js +241 -0
- package/dist/{chunk-TUWMK62B.js → chunk-PUS54YU6.js} +45 -2
- package/dist/chunk-QKPXHDLR.js +0 -0
- package/dist/{chunk-GZY66SDN.js → chunk-R3KTTOMS.js} +0 -1
- package/dist/{chunk-ILWDXLUK.js → chunk-RS5AP3J4.js} +49 -10
- package/dist/chunk-WV5ARNDA.js +0 -0
- package/dist/{chunk-4X3JQXNM.js → chunk-XOFT65EX.js} +1 -2
- package/dist/{chunk-FVTQSNR7.js → chunk-XRW6P7IF.js} +13 -5
- package/dist/chunk-XWNNA3KE.js +0 -0
- package/dist/chunk-YZNGMV3G.js +0 -0
- package/dist/{chunk-R2YZTCLO.js → chunk-ZQKZSJAX.js} +1 -2
- package/dist/doc/index.d.ts +27 -12
- package/dist/doc/index.js +16 -17
- package/dist/generate/index.d.ts +2 -2
- package/dist/generate/index.js +2 -3
- package/dist/icons/index.js +3 -4
- package/dist/icons/inlineIconMarker.js +1 -2
- package/dist/imageEdit/index.d.ts +48 -17
- package/dist/imageEdit/index.js +3 -4
- package/dist/index.d.ts +11 -11
- package/dist/index.js +60 -33
- package/dist/jsonForm/index.d.ts +10 -3
- package/dist/jsonForm/index.js +8 -7
- package/dist/markdown/index.d.ts +75 -11
- package/dist/markdown/index.js +32 -7
- package/dist/{materializePageSection-DDzubQXo.d.ts → materializePageSection-wSLA2A1g.d.ts} +2 -2
- package/dist/narration/index.d.ts +16 -3
- package/dist/narration/index.js +13 -14
- package/dist/random/index.d.ts +11 -2
- package/dist/random/index.js +2 -3
- package/dist/recommend/index.d.ts +1 -1
- package/dist/recommend/index.js +3 -4
- package/dist/schemas/index.d.ts +5 -5
- package/dist/schemas/index.js +5 -6
- package/dist/spatial/index.d.ts +2 -1
- package/dist/spatial/index.js +1 -2
- package/dist/storage/index.d.ts +4 -2
- package/dist/storage/index.js +1 -2
- package/dist/{themeLibrary-B72m0W1y.d.ts → themeLibrary-DU9mUmVl.d.ts} +1 -1
- package/dist/timing/index.js +3 -4
- package/dist/transform/index.d.ts +3 -3
- package/dist/transform/index.js +6 -7
- package/dist/{types-C4kiRn_k.d.ts → types-8QjefM9J.d.ts} +38 -2
- package/dist/{types-BwMPl2CB.d.ts → types-CUNc9biN.d.ts} +24 -1
- package/dist/versions/index.d.ts +14 -11
- package/dist/versions/index.js +2 -3
- package/package.json +4 -2
- package/dist/chunk-2UQOHYE2.js.map +0 -1
- package/dist/chunk-3E5F2XMR.js.map +0 -1
- package/dist/chunk-4X3JQXNM.js.map +0 -1
- package/dist/chunk-5DKBFXPY.js.map +0 -1
- package/dist/chunk-5J4HKRJF.js.map +0 -1
- package/dist/chunk-5UYI3RJB.js.map +0 -1
- package/dist/chunk-66QO7XFB.js.map +0 -1
- package/dist/chunk-AMIR72JP.js +0 -380
- package/dist/chunk-AMIR72JP.js.map +0 -1
- package/dist/chunk-DBS6RIFL.js.map +0 -1
- package/dist/chunk-DNJKBAI7.js +0 -1
- package/dist/chunk-DNJKBAI7.js.map +0 -1
- package/dist/chunk-ET53IIEP.js +0 -1
- package/dist/chunk-ET53IIEP.js.map +0 -1
- package/dist/chunk-FVTQSNR7.js.map +0 -1
- package/dist/chunk-GZY66SDN.js.map +0 -1
- package/dist/chunk-ILWDXLUK.js.map +0 -1
- package/dist/chunk-JHZWYRSW.js.map +0 -1
- package/dist/chunk-JI77MGAK.js.map +0 -1
- package/dist/chunk-JOQYPRDZ.js.map +0 -1
- package/dist/chunk-OTKVFVL6.js.map +0 -1
- package/dist/chunk-PGGGKYWG.js +0 -1
- package/dist/chunk-PGGGKYWG.js.map +0 -1
- package/dist/chunk-Q7LROV2H.js.map +0 -1
- package/dist/chunk-QE7TWGVT.js.map +0 -1
- package/dist/chunk-QUUPYOSP.js.map +0 -1
- package/dist/chunk-R2GC6RLD.js +0 -344
- package/dist/chunk-R2GC6RLD.js.map +0 -1
- package/dist/chunk-R2YZTCLO.js.map +0 -1
- package/dist/chunk-S7A5D7ZJ.js +0 -174
- package/dist/chunk-S7A5D7ZJ.js.map +0 -1
- package/dist/chunk-TUWMK62B.js.map +0 -1
- package/dist/chunk-V543AI2F.js +0 -1
- package/dist/chunk-V543AI2F.js.map +0 -1
- package/dist/chunk-VR7UPJ7C.js.map +0 -1
- package/dist/chunk-VWCJ2WXC.js.map +0 -1
- package/dist/chunk-VYFRI7R6.js.map +0 -1
- package/dist/chunk-XNLB57UD.js.map +0 -1
- package/dist/chunk-ZLQKNOZQ.js +0 -1
- package/dist/chunk-ZLQKNOZQ.js.map +0 -1
- package/dist/doc/index.js.map +0 -1
- package/dist/generate/index.js.map +0 -1
- package/dist/icons/index.js.map +0 -1
- package/dist/icons/inlineIconMarker.js.map +0 -1
- package/dist/imageEdit/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jsonForm/index.js.map +0 -1
- package/dist/markdown/index.js.map +0 -1
- package/dist/narration/index.js.map +0 -1
- package/dist/random/index.js.map +0 -1
- package/dist/recommend/index.js.map +0 -1
- package/dist/schemas/index.js.map +0 -1
- package/dist/spatial/index.js.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/timing/index.js.map +0 -1
- package/dist/transform/index.js.map +0 -1
- package/dist/versions/index.js.map +0 -1
- package/src/__tests__/animationUtils.test.ts +0 -117
- package/src/__tests__/annotationCoercion.test.ts +0 -243
- package/src/__tests__/applyNarrationTiming.test.ts +0 -190
- package/src/__tests__/applyRenderStyle.test.ts +0 -146
- package/src/__tests__/asciiDiagramBattle.test.ts +0 -246
- package/src/__tests__/asciiDiagramDetect.test.ts +0 -162
- package/src/__tests__/asciiDiagramMapping.test.ts +0 -38
- package/src/__tests__/asciiDiagramParse.test.ts +0 -233
- package/src/__tests__/asciiDiagramPipeline.test.ts +0 -273
- package/src/__tests__/asciiDiagramRender.test.ts +0 -162
- package/src/__tests__/asciiDiagramRepair.test.ts +0 -84
- package/src/__tests__/asciiTimelineDetect.test.ts +0 -157
- package/src/__tests__/asciiTimelineParse.test.ts +0 -205
- package/src/__tests__/asciiTimelinePipeline.test.ts +0 -349
- package/src/__tests__/asciiTimelineRender.test.ts +0 -376
- package/src/__tests__/atmosphereLayers.test.ts +0 -108
- package/src/__tests__/attrTokens.test.ts +0 -167
- package/src/__tests__/colorUtils.test.ts +0 -112
- package/src/__tests__/contentContainer.test.ts +0 -325
- package/src/__tests__/contentExtractor.test.ts +0 -243
- package/src/__tests__/coverBlock.test.ts +0 -310
- package/src/__tests__/customTemplateSample.test.ts +0 -144
- package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -221
- package/src/__tests__/customThemesFrontmatter.test.ts +0 -146
- package/src/__tests__/dataTable.test.ts +0 -145
- package/src/__tests__/diagramBlock.test.ts +0 -122
- package/src/__tests__/diagramLayout.test.ts +0 -134
- package/src/__tests__/diagramText.test.ts +0 -26
- package/src/__tests__/docToMarkdownMedia.test.ts +0 -83
- package/src/__tests__/drawing.test.ts +0 -109
- package/src/__tests__/drawingBlock.test.ts +0 -124
- package/src/__tests__/drawingLayout.test.ts +0 -171
- package/src/__tests__/fixtures/asciiDiagramBattle.ts +0 -512
- package/src/__tests__/fixtures/asciiDiagrams.ts +0 -287
- package/src/__tests__/fixtures/asciiTimelines.ts +0 -35
- package/src/__tests__/fixtures/treeviewFixtures.ts +0 -243
- package/src/__tests__/geohash.test.ts +0 -110
- package/src/__tests__/getLayers.test.ts +0 -243
- package/src/__tests__/getLayersFallback.test.ts +0 -103
- package/src/__tests__/haversine.test.ts +0 -63
- package/src/__tests__/iconResolve.test.ts +0 -122
- package/src/__tests__/imageEditExportSvg.test.ts +0 -70
- package/src/__tests__/imageEditState.test.ts +0 -74
- package/src/__tests__/imageEditVersions.test.ts +0 -243
- package/src/__tests__/inferDocumentTitle.test.ts +0 -50
- package/src/__tests__/inlineIconMarker.test.ts +0 -36
- package/src/__tests__/inputDescriptors.test.ts +0 -162
- package/src/__tests__/jsonForm.chooseControl.test.ts +0 -86
- package/src/__tests__/jsonForm.evaluateWhen.test.ts +0 -59
- package/src/__tests__/jsonForm.inferSchema.test.ts +0 -25
- package/src/__tests__/jsonForm.pointer.test.ts +0 -149
- package/src/__tests__/jsonForm.tokens.test.ts +0 -84
- package/src/__tests__/layoutBlock.test.ts +0 -83
- package/src/__tests__/layoutLayout.test.ts +0 -169
- package/src/__tests__/localForageAdapter.test.ts +0 -155
- package/src/__tests__/majorApiTypes.test.ts +0 -18
- package/src/__tests__/markdown.test.ts +0 -1009
- package/src/__tests__/markdownIcons.test.ts +0 -104
- package/src/__tests__/markdownSanitize.test.ts +0 -81
- package/src/__tests__/markdownToDoc.test.ts +0 -957
- package/src/__tests__/matchFontFamily.test.ts +0 -114
- package/src/__tests__/materializeBlockLayers.test.ts +0 -167
- package/src/__tests__/materializePageSections.test.ts +0 -404
- package/src/__tests__/materializeTestUtils.ts +0 -17
- package/src/__tests__/mediaAnnotations.test.ts +0 -91
- package/src/__tests__/mediaSchedule.test.ts +0 -118
- package/src/__tests__/narrationAlign.test.ts +0 -150
- package/src/__tests__/narrationFeatures.test.ts +0 -71
- package/src/__tests__/narrationNuclei.test.ts +0 -45
- package/src/__tests__/narrationPacing.test.ts +0 -189
- package/src/__tests__/narrationScript.test.ts +0 -149
- package/src/__tests__/narrationSessionRepro.test.ts +0 -62
- package/src/__tests__/narrationSidecar.test.ts +0 -88
- package/src/__tests__/narrationSyllables.test.ts +0 -65
- package/src/__tests__/narrationTestSignals.ts +0 -167
- package/src/__tests__/narrationVad.test.ts +0 -66
- package/src/__tests__/pageStyle.test.ts +0 -258
- package/src/__tests__/pandocAttrParse.test.ts +0 -187
- package/src/__tests__/recommendTemplates.test.ts +0 -183
- package/src/__tests__/resolveDocTheme.test.ts +0 -69
- package/src/__tests__/rootExports.test.ts +0 -61
- package/src/__tests__/scopedContentContainer.test.ts +0 -109
- package/src/__tests__/seededRandom.test.ts +0 -142
- package/src/__tests__/shapeGeometry.test.ts +0 -138
- package/src/__tests__/shapeVocabulary.test.ts +0 -133
- package/src/__tests__/storage.test.ts +0 -60
- package/src/__tests__/structuredData.test.ts +0 -249
- package/src/__tests__/surface.test.ts +0 -68
- package/src/__tests__/templateAnnotationParse.test.ts +0 -173
- package/src/__tests__/templateInputs.test.ts +0 -69
- package/src/__tests__/templateMetadata.test.ts +0 -32
- package/src/__tests__/templates.test.ts +0 -710
- package/src/__tests__/themeCompile.test.ts +0 -225
- package/src/__tests__/themeValidator.test.ts +0 -131
- package/src/__tests__/timing.test.ts +0 -167
- package/src/__tests__/transformProvenance.test.ts +0 -160
- package/src/__tests__/transformV2.test.ts +0 -163
- package/src/__tests__/transitionNormalize.test.ts +0 -61
- package/src/__tests__/treeviewBattle.test.ts +0 -76
- package/src/__tests__/treeviewDetect.test.ts +0 -168
- package/src/__tests__/treeviewParse.test.ts +0 -118
- package/src/__tests__/treeviewPipeline.test.ts +0 -183
- package/src/__tests__/treeviewRender.test.ts +0 -91
- package/src/__tests__/validateDoc.test.ts +0 -260
- package/src/__tests__/versions.test.ts +0 -459
- package/src/doc/annotationBlocks.ts +0 -117
- package/src/doc/applyNarrationTiming.ts +0 -244
- package/src/doc/asciiDiagram/chars.ts +0 -210
- package/src/doc/asciiDiagram/detect.ts +0 -175
- package/src/doc/asciiDiagram/index.ts +0 -38
- package/src/doc/asciiDiagram/mapping.ts +0 -225
- package/src/doc/asciiDiagram/parse.ts +0 -1095
- package/src/doc/asciiDiagram/render.ts +0 -963
- package/src/doc/asciiDiagram/repair.ts +0 -400
- package/src/doc/asciiDiagram/types.ts +0 -65
- package/src/doc/asciiTimeline/detect.ts +0 -138
- package/src/doc/asciiTimeline/index.ts +0 -26
- package/src/doc/asciiTimeline/mapping.ts +0 -43
- package/src/doc/asciiTimeline/parse.ts +0 -870
- package/src/doc/asciiTimeline/render.ts +0 -427
- package/src/doc/asciiTimeline/types.ts +0 -73
- package/src/doc/asciiTimeline/wrappedFlow.ts +0 -427
- package/src/doc/audioMapping.ts +0 -442
- package/src/doc/customTemplatesFrontmatter.ts +0 -273
- package/src/doc/customThemesFrontmatter.ts +0 -95
- package/src/doc/docToMarkdown.ts +0 -284
- package/src/doc/index.ts +0 -161
- package/src/doc/markdownToDoc.ts +0 -1054
- package/src/doc/materializeBlockLayers.ts +0 -465
- package/src/doc/mediaAnnotations.ts +0 -120
- package/src/doc/page/PageSection.ts +0 -174
- package/src/doc/page/materializePageSection.ts +0 -616
- package/src/doc/page/resolvePageBlock.ts +0 -108
- package/src/doc/page/sectionExtractors.ts +0 -466
- package/src/doc/pageCss.ts +0 -628
- package/src/doc/resolveDocTheme.ts +0 -56
- package/src/doc/standaloneAnnotation.ts +0 -58
- package/src/doc/structuredData.ts +0 -301
- package/src/doc/templateInputs.ts +0 -424
- package/src/doc/templates/__tests__/customTemplate.test.ts +0 -170
- package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +0 -124
- package/src/doc/templates/__tests__/listBlock.test.ts +0 -64
- package/src/doc/templates/accentImage.ts +0 -362
- package/src/doc/templates/captionUtils.ts +0 -56
- package/src/doc/templates/comparisonBar.ts +0 -173
- package/src/doc/templates/coverBlock.ts +0 -255
- package/src/doc/templates/customTemplate.ts +0 -51
- package/src/doc/templates/dataTable.ts +0 -102
- package/src/doc/templates/dateEvent.ts +0 -147
- package/src/doc/templates/definitionCard.ts +0 -140
- package/src/doc/templates/diagramBlock.ts +0 -403
- package/src/doc/templates/diagramLayout.ts +0 -159
- package/src/doc/templates/drawingBlock.ts +0 -325
- package/src/doc/templates/drawingLayout.ts +0 -539
- package/src/doc/templates/factCard.ts +0 -146
- package/src/doc/templates/fallbackBlock.ts +0 -123
- package/src/doc/templates/featureBlock.ts +0 -209
- package/src/doc/templates/fullBleedQuote.ts +0 -83
- package/src/doc/templates/imageWithCaption.ts +0 -186
- package/src/doc/templates/index.ts +0 -642
- package/src/doc/templates/inputDescriptors.ts +0 -451
- package/src/doc/templates/layoutBlock.ts +0 -43
- package/src/doc/templates/layoutLayout.ts +0 -243
- package/src/doc/templates/listBlock.ts +0 -207
- package/src/doc/templates/mapBlock.ts +0 -138
- package/src/doc/templates/metadata.ts +0 -130
- package/src/doc/templates/persistentLayers.ts +0 -526
- package/src/doc/templates/photoGrid.ts +0 -190
- package/src/doc/templates/pullQuote.ts +0 -141
- package/src/doc/templates/quoteBlock.ts +0 -141
- package/src/doc/templates/registry.ts +0 -88
- package/src/doc/templates/sectionHeader.ts +0 -120
- package/src/doc/templates/statHighlight.ts +0 -146
- package/src/doc/templates/templateNames.ts +0 -22
- package/src/doc/templates/timelineBlock.ts +0 -613
- package/src/doc/templates/titleBlock.ts +0 -150
- package/src/doc/templates/tokens/__tests__/resolveTokens.test.ts +0 -487
- package/src/doc/templates/tokens/resolveTokens.ts +0 -453
- package/src/doc/templates/treeBlock.ts +0 -131
- package/src/doc/templates/twoColumn.ts +0 -263
- package/src/doc/templates/videoPullQuote.ts +0 -142
- package/src/doc/templates/videoWithCaption.ts +0 -135
- package/src/doc/treeview/chars.ts +0 -72
- package/src/doc/treeview/detect.ts +0 -145
- package/src/doc/treeview/index.ts +0 -30
- package/src/doc/treeview/mapping.ts +0 -95
- package/src/doc/treeview/parse.ts +0 -201
- package/src/doc/treeview/render.ts +0 -41
- package/src/doc/treeview/types.ts +0 -43
- package/src/doc/utils/animationUtils.ts +0 -399
- package/src/doc/utils/applyRenderStyle.ts +0 -106
- package/src/doc/utils/diagramText.ts +0 -78
- package/src/doc/utils/imageTreatment.ts +0 -70
- package/src/doc/utils/nearest.ts +0 -59
- package/src/doc/utils/shapeGeometry.ts +0 -614
- package/src/doc/utils/themeUtils.ts +0 -243
- package/src/doc/validate.ts +0 -575
- package/src/generate/contentExtractor.ts +0 -921
- package/src/generate/index.ts +0 -18
- package/src/generate/templateMapper.ts +0 -177
- package/src/icons/iconData.ts +0 -31
- package/src/icons/index.ts +0 -26
- package/src/icons/inlineIconMarker.ts +0 -73
- package/src/icons/resolve.ts +0 -139
- package/src/imageEdit/ImageEditVersionManager.ts +0 -73
- package/src/imageEdit/export.ts +0 -410
- package/src/imageEdit/index.ts +0 -72
- package/src/imageEdit/persistence.ts +0 -113
- package/src/imageEdit/state.ts +0 -112
- package/src/imageEdit/versionPaths.ts +0 -44
- package/src/imageEdit/versions.ts +0 -152
- package/src/index.ts +0 -15
- package/src/internal/immutable.ts +0 -58
- package/src/jsonForm/chooseControl.ts +0 -88
- package/src/jsonForm/evaluateWhen.ts +0 -59
- package/src/jsonForm/index.ts +0 -32
- package/src/jsonForm/inferSchema.ts +0 -25
- package/src/jsonForm/pointer.ts +0 -154
- package/src/jsonForm/tokens.ts +0 -78
- package/src/jsonForm/types.ts +0 -167
- package/src/markdown/annotationCoercion.ts +0 -295
- package/src/markdown/attrTokens.ts +0 -243
- package/src/markdown/convert.ts +0 -1353
- package/src/markdown/htmlParse.ts +0 -212
- package/src/markdown/index.ts +0 -152
- package/src/markdown/parse.ts +0 -103
- package/src/markdown/sanitize.ts +0 -318
- package/src/markdown/stringify.ts +0 -207
- package/src/markdown/types.ts +0 -710
- package/src/markdown/utils.ts +0 -459
- package/src/narration/align.ts +0 -514
- package/src/narration/features.ts +0 -231
- package/src/narration/index.ts +0 -86
- package/src/narration/nuclei.ts +0 -118
- package/src/narration/pacing.ts +0 -211
- package/src/narration/script.ts +0 -239
- package/src/narration/session.ts +0 -100
- package/src/narration/sidecar.ts +0 -187
- package/src/narration/syllables.ts +0 -85
- package/src/narration/trace.ts +0 -50
- package/src/narration/types.ts +0 -299
- package/src/narration/vad.ts +0 -131
- package/src/ngeohash.d.ts +0 -11
- package/src/random/SeededRandom.ts +0 -127
- package/src/random/index.ts +0 -1
- package/src/recommend/index.ts +0 -16
- package/src/recommend/numberHighlight.ts +0 -25
- package/src/recommend/templates.ts +0 -393
- package/src/schemas/BlockTemplates.ts +0 -1046
- package/src/schemas/CustomTemplates.ts +0 -126
- package/src/schemas/Doc.ts +0 -1073
- package/src/schemas/ImageEditDoc.ts +0 -102
- package/src/schemas/LayoutStrategy.ts +0 -178
- package/src/schemas/Media.ts +0 -179
- package/src/schemas/MediaProvider.ts +0 -70
- package/src/schemas/PageStyle.ts +0 -213
- package/src/schemas/Theme.ts +0 -413
- package/src/schemas/Transitions.ts +0 -224
- package/src/schemas/Types.ts +0 -15
- package/src/schemas/Viewport.ts +0 -91
- package/src/schemas/colorUtils.ts +0 -219
- package/src/schemas/fontStacks.ts +0 -339
- package/src/schemas/index.ts +0 -31
- package/src/schemas/pageStyleDefaults.ts +0 -204
- package/src/schemas/themeCompile.ts +0 -244
- package/src/schemas/themeConstants.ts +0 -2
- package/src/schemas/themeLibrary.ts +0 -60
- package/src/schemas/themeValidator.ts +0 -609
- package/src/schemas/themes/bold.json +0 -77
- package/src/schemas/themes/cinematic.json +0 -143
- package/src/schemas/themes/documentary.json +0 -125
- package/src/schemas/themes/gezellig.json +0 -123
- package/src/schemas/themes/index.ts +0 -53
- package/src/schemas/themes/magazine.json +0 -126
- package/src/schemas/themes/minimalist.json +0 -74
- package/src/schemas/themes/morning-light.json +0 -117
- package/src/schemas/themes/standard-dark.json +0 -109
- package/src/schemas/themes/standard.json +0 -98
- package/src/schemas/themes/tech-dark.json +0 -143
- package/src/schemas/themes/warm-earth.json +0 -74
- package/src/spatial/Geohash.ts +0 -196
- package/src/spatial/Haversine.ts +0 -59
- package/src/spatial/index.ts +0 -2
- package/src/storage/ContentContainer.ts +0 -220
- package/src/storage/LocalForageAdapter.ts +0 -103
- package/src/storage/LocalStorageAdapter.ts +0 -57
- package/src/storage/MediaProviderFromContainer.ts +0 -92
- package/src/storage/MemoryStorageAdapter.ts +0 -37
- package/src/storage/ScopedContentContainer.ts +0 -143
- package/src/storage/Storage.ts +0 -28
- package/src/storage/index.ts +0 -9
- package/src/timing/index.ts +0 -17
- package/src/timing/narrationTiming.ts +0 -220
- package/src/timing/readingTime.ts +0 -94
- package/src/transform/applyTransform.ts +0 -122
- package/src/transform/blockAnalyzer.ts +0 -181
- package/src/transform/index.ts +0 -23
- package/src/transform/registry.ts +0 -217
- package/src/transform/styles/dataDriven.ts +0 -18
- package/src/transform/styles/documentary.ts +0 -18
- package/src/transform/styles/index.ts +0 -5
- package/src/transform/styles/magazine.ts +0 -19
- package/src/transform/styles/minimal.ts +0 -18
- package/src/transform/styles/narrative.ts +0 -19
- package/src/transform/templateSelector.ts +0 -389
- package/src/transform/timingAllocator.ts +0 -257
- package/src/transform/types.ts +0 -158
- package/src/versions/DocumentVersionManager.ts +0 -70
- package/src/versions/gitignore.ts +0 -34
- package/src/versions/index.ts +0 -56
- package/src/versions/operations.ts +0 -144
- package/src/versions/paths.ts +0 -51
- package/src/versions/snapshotStore.ts +0 -202
- package/src/versions/timestamp.ts +0 -48
- package/src/versions/types.ts +0 -93
package/src/doc/utils/nearest.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared "did-you-mean" edit-distance helpers.
|
|
3
|
-
*
|
|
4
|
-
* A leaf module (no imports) so both `doc/validate.ts` and
|
|
5
|
-
* `doc/templates/inputDescriptors.ts` can share one implementation without
|
|
6
|
-
* risking an import cycle through `templates/index.ts`.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/** Levenshtein edit distance between two strings. */
|
|
10
|
-
export function levenshtein(a: string, b: string): number {
|
|
11
|
-
if (a === b) return 0;
|
|
12
|
-
const m = a.length;
|
|
13
|
-
const n = b.length;
|
|
14
|
-
if (m === 0) return n;
|
|
15
|
-
if (n === 0) return m;
|
|
16
|
-
let prev = new Array<number>(n + 1);
|
|
17
|
-
let curr = new Array<number>(n + 1);
|
|
18
|
-
for (let j = 0; j <= n; j++) prev[j] = j;
|
|
19
|
-
for (let i = 1; i <= m; i++) {
|
|
20
|
-
curr[0] = i;
|
|
21
|
-
for (let j = 1; j <= n; j++) {
|
|
22
|
-
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
23
|
-
curr[j] = Math.min(prev[j] + 1, curr[j - 1] + 1, prev[j - 1] + cost);
|
|
24
|
-
}
|
|
25
|
-
[prev, curr] = [curr, prev];
|
|
26
|
-
}
|
|
27
|
-
return prev[n];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Nearest candidate name by edit distance, or `undefined` when nothing is
|
|
32
|
-
* plausibly close. "Close" means distance ≤ `maxDistance` (default 2) OR
|
|
33
|
-
* ≤ 40% of the input length — the shared threshold both call sites use.
|
|
34
|
-
*
|
|
35
|
-
* @param options.map - Optional post-processor applied to the winning
|
|
36
|
-
* candidate (e.g. `resolveTemplateName` to canonicalize an alias hit).
|
|
37
|
-
* @param options.maxDistance - Absolute distance floor for "close" (default 2).
|
|
38
|
-
*/
|
|
39
|
-
export function nearestName(
|
|
40
|
-
input: string,
|
|
41
|
-
candidates: Iterable<string>,
|
|
42
|
-
options?: { map?: (best: string) => string; maxDistance?: number },
|
|
43
|
-
): string | undefined {
|
|
44
|
-
const maxDistance = options?.maxDistance ?? 2;
|
|
45
|
-
let best: string | undefined;
|
|
46
|
-
let bestDist = Infinity;
|
|
47
|
-
const lower = input.toLowerCase();
|
|
48
|
-
for (const candidate of candidates) {
|
|
49
|
-
const dist = levenshtein(lower, candidate.toLowerCase());
|
|
50
|
-
if (dist < bestDist) {
|
|
51
|
-
bestDist = dist;
|
|
52
|
-
best = candidate;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (best && (bestDist <= maxDistance || bestDist <= Math.ceil(input.length * 0.4))) {
|
|
56
|
-
return options?.map ? options.map(best) : best;
|
|
57
|
-
}
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
@@ -1,614 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* shapeGeometry — pure SVG geometry for the drawing/diagram shape vocabulary.
|
|
3
|
-
*
|
|
4
|
-
* Three concerns, all deterministic and dependency-free:
|
|
5
|
-
* - `shapePath(kind, x, y, w, h)` → an SVG path `d` for a named shape inscribed
|
|
6
|
-
* in a bounding box. Returns null for the natively-rendered primitives
|
|
7
|
-
* (rect / circle / line / text / path) so the caller can keep using a
|
|
8
|
-
* `ShapeLayer` for those; everything else becomes a computed `PathLayer`.
|
|
9
|
-
* - `markerPath(style, dir)` → the `<marker>` path for a line end-style, in the
|
|
10
|
-
* standard 0–10 marker viewBox (shared by the SSR `PathLayer` renderer and the
|
|
11
|
-
* editor's edge renderer).
|
|
12
|
-
* - `connectorPath(routing, start, end)` + `snapEndpoints(a, b)` → the line/edge
|
|
13
|
-
* geometry between two shapes (straight / orthogonal / curved), lifted from the
|
|
14
|
-
* diagram template so drawings and diagrams draw identical connectors. The older
|
|
15
|
-
* `clipEndpoints(a, b)` helper remains for free-angle clipping, but rendered
|
|
16
|
-
* connectors use snapped ports so authored lines land on stable attachment points.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import type { MarkerStyle } from '../../schemas/Doc.js';
|
|
20
|
-
|
|
21
|
-
// ============================================
|
|
22
|
-
// Shapes
|
|
23
|
-
// ============================================
|
|
24
|
-
|
|
25
|
-
/** Connector routing styles. */
|
|
26
|
-
export type ConnectorRouting = 'straight' | 'orthogonal' | 'curved';
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Shape kinds rendered as computed paths (everything except the primitives the
|
|
30
|
-
* renderer draws natively). Used by templates to decide ShapeLayer vs PathLayer.
|
|
31
|
-
*/
|
|
32
|
-
export const PATH_SHAPE_KINDS = new Set([
|
|
33
|
-
'triangle',
|
|
34
|
-
'right-triangle',
|
|
35
|
-
'diamond',
|
|
36
|
-
'pentagon',
|
|
37
|
-
'hexagon',
|
|
38
|
-
'octagon',
|
|
39
|
-
'star',
|
|
40
|
-
'star4',
|
|
41
|
-
'star6',
|
|
42
|
-
'parallelogram',
|
|
43
|
-
'trapezoid',
|
|
44
|
-
'plus',
|
|
45
|
-
'chevron',
|
|
46
|
-
'arrow-right',
|
|
47
|
-
'arrow-left',
|
|
48
|
-
'arrow-up',
|
|
49
|
-
'arrow-down',
|
|
50
|
-
'double-arrow',
|
|
51
|
-
'callout',
|
|
52
|
-
'cylinder',
|
|
53
|
-
'cloud',
|
|
54
|
-
'heart',
|
|
55
|
-
'lightning',
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
|
-
/** Round to 1 decimal for compact, stable path output. */
|
|
59
|
-
function r(n: number): number {
|
|
60
|
-
return Math.round(n * 10) / 10;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Close a list of points into an `M … L … Z` polygon path. */
|
|
64
|
-
function poly(points: ReadonlyArray<readonly [number, number]>): string {
|
|
65
|
-
if (points.length === 0) return '';
|
|
66
|
-
const [first, ...rest] = points;
|
|
67
|
-
const head = `M ${r(first[0])} ${r(first[1])}`;
|
|
68
|
-
const tail = rest.map(([x, y]) => `L ${r(x)} ${r(y)}`).join(' ');
|
|
69
|
-
return `${head} ${tail} Z`;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Regular polygon points inscribed in the box ellipse, `rotation` in radians. */
|
|
73
|
-
function regular(
|
|
74
|
-
cx: number,
|
|
75
|
-
cy: number,
|
|
76
|
-
rx: number,
|
|
77
|
-
ry: number,
|
|
78
|
-
sides: number,
|
|
79
|
-
rotation: number,
|
|
80
|
-
): Array<[number, number]> {
|
|
81
|
-
const pts: Array<[number, number]> = [];
|
|
82
|
-
for (let i = 0; i < sides; i++) {
|
|
83
|
-
const a = rotation + (i * 2 * Math.PI) / sides;
|
|
84
|
-
pts.push([cx + rx * Math.cos(a), cy + ry * Math.sin(a)]);
|
|
85
|
-
}
|
|
86
|
-
return pts;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** Star points alternating outer/inner radius. */
|
|
90
|
-
function star(
|
|
91
|
-
cx: number,
|
|
92
|
-
cy: number,
|
|
93
|
-
rx: number,
|
|
94
|
-
ry: number,
|
|
95
|
-
spikes: number,
|
|
96
|
-
innerRatio: number,
|
|
97
|
-
): Array<[number, number]> {
|
|
98
|
-
const pts: Array<[number, number]> = [];
|
|
99
|
-
const rot = -Math.PI / 2; // first point up
|
|
100
|
-
for (let i = 0; i < spikes * 2; i++) {
|
|
101
|
-
const outer = i % 2 === 0;
|
|
102
|
-
const a = rot + (i * Math.PI) / spikes;
|
|
103
|
-
const fx = outer ? rx : rx * innerRatio;
|
|
104
|
-
const fy = outer ? ry : ry * innerRatio;
|
|
105
|
-
pts.push([cx + fx * Math.cos(a), cy + fy * Math.sin(a)]);
|
|
106
|
-
}
|
|
107
|
-
return pts;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* SVG path `d` for a named shape inscribed in `[x, y, w, h]`, or null when the
|
|
112
|
-
* kind is rendered natively (rect / circle / line / text / path / arrow).
|
|
113
|
-
*/
|
|
114
|
-
export function shapePath(kind: string, x: number, y: number, w: number, h: number): string | null {
|
|
115
|
-
const cx = x + w / 2;
|
|
116
|
-
const cy = y + h / 2;
|
|
117
|
-
const rx = w / 2;
|
|
118
|
-
const ry = h / 2;
|
|
119
|
-
const right = x + w;
|
|
120
|
-
const bottom = y + h;
|
|
121
|
-
|
|
122
|
-
switch (kind) {
|
|
123
|
-
case 'triangle':
|
|
124
|
-
return poly([
|
|
125
|
-
[cx, y],
|
|
126
|
-
[right, bottom],
|
|
127
|
-
[x, bottom],
|
|
128
|
-
]);
|
|
129
|
-
case 'right-triangle':
|
|
130
|
-
return poly([
|
|
131
|
-
[x, y],
|
|
132
|
-
[x, bottom],
|
|
133
|
-
[right, bottom],
|
|
134
|
-
]);
|
|
135
|
-
case 'diamond':
|
|
136
|
-
return poly([
|
|
137
|
-
[cx, y],
|
|
138
|
-
[right, cy],
|
|
139
|
-
[cx, bottom],
|
|
140
|
-
[x, cy],
|
|
141
|
-
]);
|
|
142
|
-
case 'pentagon':
|
|
143
|
-
return poly(regular(cx, cy, rx, ry, 5, -Math.PI / 2));
|
|
144
|
-
case 'hexagon': {
|
|
145
|
-
// Flat top/bottom hexagon: inset the left/right vertices.
|
|
146
|
-
const inset = w * 0.25;
|
|
147
|
-
return poly([
|
|
148
|
-
[x + inset, y],
|
|
149
|
-
[right - inset, y],
|
|
150
|
-
[right, cy],
|
|
151
|
-
[right - inset, bottom],
|
|
152
|
-
[x + inset, bottom],
|
|
153
|
-
[x, cy],
|
|
154
|
-
]);
|
|
155
|
-
}
|
|
156
|
-
case 'octagon': {
|
|
157
|
-
const cut = Math.min(w, h) * 0.29;
|
|
158
|
-
return poly([
|
|
159
|
-
[x + cut, y],
|
|
160
|
-
[right - cut, y],
|
|
161
|
-
[right, y + cut],
|
|
162
|
-
[right, bottom - cut],
|
|
163
|
-
[right - cut, bottom],
|
|
164
|
-
[x + cut, bottom],
|
|
165
|
-
[x, bottom - cut],
|
|
166
|
-
[x, y + cut],
|
|
167
|
-
]);
|
|
168
|
-
}
|
|
169
|
-
case 'star':
|
|
170
|
-
return poly(star(cx, cy, rx, ry, 5, 0.4));
|
|
171
|
-
case 'star4':
|
|
172
|
-
return poly(star(cx, cy, rx, ry, 4, 0.4));
|
|
173
|
-
case 'star6':
|
|
174
|
-
return poly(star(cx, cy, rx, ry, 6, 0.5));
|
|
175
|
-
case 'parallelogram': {
|
|
176
|
-
const off = w * 0.25;
|
|
177
|
-
return poly([
|
|
178
|
-
[x + off, y],
|
|
179
|
-
[right, y],
|
|
180
|
-
[right - off, bottom],
|
|
181
|
-
[x, bottom],
|
|
182
|
-
]);
|
|
183
|
-
}
|
|
184
|
-
case 'trapezoid': {
|
|
185
|
-
const off = w * 0.25;
|
|
186
|
-
return poly([
|
|
187
|
-
[x + off, y],
|
|
188
|
-
[right - off, y],
|
|
189
|
-
[right, bottom],
|
|
190
|
-
[x, bottom],
|
|
191
|
-
]);
|
|
192
|
-
}
|
|
193
|
-
case 'plus': {
|
|
194
|
-
const t = Math.min(w, h) / 3; // arm thickness
|
|
195
|
-
const lx = x + (w - t) / 2;
|
|
196
|
-
const rxp = lx + t;
|
|
197
|
-
const ty = y + (h - t) / 2;
|
|
198
|
-
const byp = ty + t;
|
|
199
|
-
return poly([
|
|
200
|
-
[lx, y],
|
|
201
|
-
[rxp, y],
|
|
202
|
-
[rxp, ty],
|
|
203
|
-
[right, ty],
|
|
204
|
-
[right, byp],
|
|
205
|
-
[rxp, byp],
|
|
206
|
-
[rxp, bottom],
|
|
207
|
-
[lx, bottom],
|
|
208
|
-
[lx, byp],
|
|
209
|
-
[x, byp],
|
|
210
|
-
[x, ty],
|
|
211
|
-
[lx, ty],
|
|
212
|
-
]);
|
|
213
|
-
}
|
|
214
|
-
case 'chevron': {
|
|
215
|
-
const notch = w * 0.25;
|
|
216
|
-
return poly([
|
|
217
|
-
[x, y],
|
|
218
|
-
[right - notch, y],
|
|
219
|
-
[right, cy],
|
|
220
|
-
[right - notch, bottom],
|
|
221
|
-
[x, bottom],
|
|
222
|
-
[x + notch, cy],
|
|
223
|
-
]);
|
|
224
|
-
}
|
|
225
|
-
case 'arrow-right':
|
|
226
|
-
return blockArrow(x, y, w, h, 'right');
|
|
227
|
-
case 'arrow-left':
|
|
228
|
-
return blockArrow(x, y, w, h, 'left');
|
|
229
|
-
case 'arrow-up':
|
|
230
|
-
return blockArrow(x, y, w, h, 'up');
|
|
231
|
-
case 'arrow-down':
|
|
232
|
-
return blockArrow(x, y, w, h, 'down');
|
|
233
|
-
case 'double-arrow': {
|
|
234
|
-
const head = w * 0.3;
|
|
235
|
-
const bodyT = h * 0.4;
|
|
236
|
-
const ty = cy - bodyT / 2;
|
|
237
|
-
const by = cy + bodyT / 2;
|
|
238
|
-
return poly([
|
|
239
|
-
[x, cy],
|
|
240
|
-
[x + head, y],
|
|
241
|
-
[x + head, ty],
|
|
242
|
-
[right - head, ty],
|
|
243
|
-
[right - head, y],
|
|
244
|
-
[right, cy],
|
|
245
|
-
[right - head, bottom],
|
|
246
|
-
[right - head, by],
|
|
247
|
-
[x + head, by],
|
|
248
|
-
[x + head, bottom],
|
|
249
|
-
]);
|
|
250
|
-
}
|
|
251
|
-
case 'callout': {
|
|
252
|
-
// Speech bubble: rounded-ish body (square corners for path simplicity)
|
|
253
|
-
// with a tail off the lower-left.
|
|
254
|
-
const bodyH = h * 0.78;
|
|
255
|
-
const bb = y + bodyH;
|
|
256
|
-
const tailX = x + w * 0.25;
|
|
257
|
-
return `M ${r(x)} ${r(y)} L ${r(right)} ${r(y)} L ${r(right)} ${r(bb)} L ${r(tailX + w * 0.12)} ${r(bb)} L ${r(tailX)} ${r(bottom)} L ${r(tailX - w * 0.02)} ${r(bb)} L ${r(x)} ${r(bb)} Z`;
|
|
258
|
-
}
|
|
259
|
-
case 'cylinder': {
|
|
260
|
-
const ell = h * 0.16; // ellipse half-height
|
|
261
|
-
return (
|
|
262
|
-
`M ${r(x)} ${r(y + ell)} ` +
|
|
263
|
-
`A ${r(rx)} ${r(ell)} 0 0 1 ${r(right)} ${r(y + ell)} ` +
|
|
264
|
-
`L ${r(right)} ${r(bottom - ell)} ` +
|
|
265
|
-
`A ${r(rx)} ${r(ell)} 0 0 1 ${r(x)} ${r(bottom - ell)} ` +
|
|
266
|
-
`Z ` +
|
|
267
|
-
// top ellipse outline
|
|
268
|
-
`M ${r(x)} ${r(y + ell)} ` +
|
|
269
|
-
`A ${r(rx)} ${r(ell)} 0 0 0 ${r(right)} ${r(y + ell)}`
|
|
270
|
-
);
|
|
271
|
-
}
|
|
272
|
-
case 'cloud': {
|
|
273
|
-
// Four bumps along the top + a flat-ish bottom, via arcs.
|
|
274
|
-
const b = h * 0.5;
|
|
275
|
-
return (
|
|
276
|
-
`M ${r(x + w * 0.2)} ${r(bottom)} ` +
|
|
277
|
-
`A ${r(w * 0.2)} ${r(b)} 0 0 1 ${r(x + w * 0.15)} ${r(cy)} ` +
|
|
278
|
-
`A ${r(w * 0.2)} ${r(b)} 0 0 1 ${r(x + w * 0.45)} ${r(y + h * 0.2)} ` +
|
|
279
|
-
`A ${r(w * 0.2)} ${r(b)} 0 0 1 ${r(x + w * 0.8)} ${r(y + h * 0.25)} ` +
|
|
280
|
-
`A ${r(w * 0.18)} ${r(b)} 0 0 1 ${r(x + w * 0.85)} ${r(bottom)} ` +
|
|
281
|
-
`Z`
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
case 'heart': {
|
|
285
|
-
const topY = y + h * 0.3;
|
|
286
|
-
return (
|
|
287
|
-
`M ${r(cx)} ${r(bottom)} ` +
|
|
288
|
-
`C ${r(x - w * 0.1)} ${r(cy)} ${r(x)} ${r(y)} ${r(cx)} ${r(topY)} ` +
|
|
289
|
-
`C ${r(right)} ${r(y)} ${r(right + w * 0.1)} ${r(cy)} ${r(cx)} ${r(bottom)} ` +
|
|
290
|
-
`Z`
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
case 'lightning':
|
|
294
|
-
return poly([
|
|
295
|
-
[x + w * 0.55, y],
|
|
296
|
-
[x + w * 0.2, y + h * 0.55],
|
|
297
|
-
[x + w * 0.45, y + h * 0.55],
|
|
298
|
-
[x + w * 0.3, bottom],
|
|
299
|
-
[right, y + h * 0.4],
|
|
300
|
-
[x + w * 0.55, y + h * 0.4],
|
|
301
|
-
]);
|
|
302
|
-
default:
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/** Block arrow (body rectangle + triangular head) pointing in `dir`. */
|
|
308
|
-
function blockArrow(
|
|
309
|
-
x: number,
|
|
310
|
-
y: number,
|
|
311
|
-
w: number,
|
|
312
|
-
h: number,
|
|
313
|
-
dir: 'right' | 'left' | 'up' | 'down',
|
|
314
|
-
): string {
|
|
315
|
-
const right = x + w;
|
|
316
|
-
const bottom = y + h;
|
|
317
|
-
const cx = x + w / 2;
|
|
318
|
-
const cy = y + h / 2;
|
|
319
|
-
if (dir === 'right' || dir === 'left') {
|
|
320
|
-
const head = w * 0.4;
|
|
321
|
-
const bodyT = h * 0.5;
|
|
322
|
-
const ty = cy - bodyT / 2;
|
|
323
|
-
const by = cy + bodyT / 2;
|
|
324
|
-
if (dir === 'right') {
|
|
325
|
-
return poly([
|
|
326
|
-
[x, ty],
|
|
327
|
-
[right - head, ty],
|
|
328
|
-
[right - head, y],
|
|
329
|
-
[right, cy],
|
|
330
|
-
[right - head, bottom],
|
|
331
|
-
[right - head, by],
|
|
332
|
-
[x, by],
|
|
333
|
-
]);
|
|
334
|
-
}
|
|
335
|
-
return poly([
|
|
336
|
-
[right, ty],
|
|
337
|
-
[x + head, ty],
|
|
338
|
-
[x + head, y],
|
|
339
|
-
[x, cy],
|
|
340
|
-
[x + head, bottom],
|
|
341
|
-
[x + head, by],
|
|
342
|
-
[right, by],
|
|
343
|
-
]);
|
|
344
|
-
}
|
|
345
|
-
const head = h * 0.4;
|
|
346
|
-
const bodyT = w * 0.5;
|
|
347
|
-
const lx = cx - bodyT / 2;
|
|
348
|
-
const rxp = cx + bodyT / 2;
|
|
349
|
-
if (dir === 'down') {
|
|
350
|
-
return poly([
|
|
351
|
-
[lx, y],
|
|
352
|
-
[rxp, y],
|
|
353
|
-
[rxp, bottom - head],
|
|
354
|
-
[right, bottom - head],
|
|
355
|
-
[cx, bottom],
|
|
356
|
-
[x, bottom - head],
|
|
357
|
-
[lx, bottom - head],
|
|
358
|
-
]);
|
|
359
|
-
}
|
|
360
|
-
return poly([
|
|
361
|
-
[lx, bottom],
|
|
362
|
-
[rxp, bottom],
|
|
363
|
-
[rxp, y + head],
|
|
364
|
-
[right, y + head],
|
|
365
|
-
[cx, y],
|
|
366
|
-
[x, y + head],
|
|
367
|
-
[lx, y + head],
|
|
368
|
-
]);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// ============================================
|
|
372
|
-
// End markers
|
|
373
|
-
// ============================================
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* The `<marker>` path for a line end-style, in the 0–10 marker viewBox.
|
|
377
|
-
* `dir` selects orientation (`end` points along +x; `start` is mirrored).
|
|
378
|
-
* Returns null for `'none'`. `filled` shapes paint with the stroke color;
|
|
379
|
-
* non-filled (`open`) draw as a stroked outline.
|
|
380
|
-
*/
|
|
381
|
-
export function markerPath(
|
|
382
|
-
style: MarkerStyle,
|
|
383
|
-
dir: 'start' | 'end',
|
|
384
|
-
): { d: string; filled: boolean } | null {
|
|
385
|
-
const mirror = dir === 'start';
|
|
386
|
-
const mx = (n: number) => (mirror ? 10 - n : n);
|
|
387
|
-
const tri = (closed: boolean) => `M ${mx(0)} 0 L ${mx(10)} 5 L ${mx(0)} 10${closed ? ' z' : ''}`;
|
|
388
|
-
switch (style) {
|
|
389
|
-
case 'arrow':
|
|
390
|
-
return { d: tri(true), filled: true };
|
|
391
|
-
case 'open':
|
|
392
|
-
return { d: tri(false), filled: false };
|
|
393
|
-
case 'diamond':
|
|
394
|
-
return { d: 'M 0 5 L 5 0 L 10 5 L 5 10 z', filled: true };
|
|
395
|
-
case 'square':
|
|
396
|
-
return { d: 'M 1 1 L 9 1 L 9 9 L 1 9 z', filled: true };
|
|
397
|
-
case 'circle':
|
|
398
|
-
return { d: 'M 0 5 A 5 5 0 1 0 10 5 A 5 5 0 1 0 0 5 z', filled: true };
|
|
399
|
-
case 'none':
|
|
400
|
-
default:
|
|
401
|
-
return null;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// ============================================
|
|
406
|
-
// Connector routing
|
|
407
|
-
// ============================================
|
|
408
|
-
|
|
409
|
-
export interface ClipBox {
|
|
410
|
-
cx: number;
|
|
411
|
-
cy: number;
|
|
412
|
-
rx: number;
|
|
413
|
-
ry: number;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
export type ConnectorPort =
|
|
417
|
-
| 'top'
|
|
418
|
-
| 'right'
|
|
419
|
-
| 'bottom'
|
|
420
|
-
| 'left'
|
|
421
|
-
| 'top-left'
|
|
422
|
-
| 'top-right'
|
|
423
|
-
| 'bottom-right'
|
|
424
|
-
| 'bottom-left';
|
|
425
|
-
|
|
426
|
-
export interface ConnectorSnapPoint {
|
|
427
|
-
port: ConnectorPort;
|
|
428
|
-
x: number;
|
|
429
|
-
y: number;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
export interface ConnectorAnchor {
|
|
433
|
-
side: 'top' | 'right' | 'bottom' | 'left';
|
|
434
|
-
offset: number;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
/** Intersection of the center-to-center line with `from`'s bounding box. */
|
|
438
|
-
export function clipPoint(from: ClipBox, to: ClipBox): { x: number; y: number } {
|
|
439
|
-
const dx = to.cx - from.cx;
|
|
440
|
-
const dy = to.cy - from.cy;
|
|
441
|
-
if (dx === 0 && dy === 0) return { x: from.cx, y: from.cy };
|
|
442
|
-
const sx = Math.abs(dx) > 0 ? from.rx / Math.abs(dx) : Infinity;
|
|
443
|
-
const sy = Math.abs(dy) > 0 ? from.ry / Math.abs(dy) : Infinity;
|
|
444
|
-
const s = Math.min(sx, sy);
|
|
445
|
-
return { x: from.cx + dx * s, y: from.cy + dy * s };
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/** Clip both endpoints of an edge to the two shapes it joins. */
|
|
449
|
-
export function clipEndpoints(
|
|
450
|
-
a: ClipBox,
|
|
451
|
-
b: ClipBox,
|
|
452
|
-
): { start: { x: number; y: number }; end: { x: number; y: number } } {
|
|
453
|
-
return { start: clipPoint(a, b), end: clipPoint(b, a) };
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
/** The stable connector ports exposed around a shape/card box. */
|
|
457
|
-
export function snapPoints(box: ClipBox): ConnectorSnapPoint[] {
|
|
458
|
-
const left = box.cx - box.rx;
|
|
459
|
-
const right = box.cx + box.rx;
|
|
460
|
-
const top = box.cy - box.ry;
|
|
461
|
-
const bottom = box.cy + box.ry;
|
|
462
|
-
return [
|
|
463
|
-
{ port: 'top', x: box.cx, y: top },
|
|
464
|
-
{ port: 'right', x: right, y: box.cy },
|
|
465
|
-
{ port: 'bottom', x: box.cx, y: bottom },
|
|
466
|
-
{ port: 'left', x: left, y: box.cy },
|
|
467
|
-
{ port: 'top-left', x: left, y: top },
|
|
468
|
-
{ port: 'top-right', x: right, y: top },
|
|
469
|
-
{ port: 'bottom-right', x: right, y: bottom },
|
|
470
|
-
{ port: 'bottom-left', x: left, y: bottom },
|
|
471
|
-
];
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/** Resolve a normalized authored anchor to a concrete point on a box. */
|
|
475
|
-
export function anchorPoint(box: ClipBox, anchor: ConnectorAnchor): ConnectorSnapPoint {
|
|
476
|
-
const offset = Math.max(0, Math.min(1, anchor.offset));
|
|
477
|
-
const left = box.cx - box.rx;
|
|
478
|
-
const right = box.cx + box.rx;
|
|
479
|
-
const top = box.cy - box.ry;
|
|
480
|
-
const bottom = box.cy + box.ry;
|
|
481
|
-
switch (anchor.side) {
|
|
482
|
-
case 'top':
|
|
483
|
-
return { port: 'top', x: left + (right - left) * offset, y: top };
|
|
484
|
-
case 'right':
|
|
485
|
-
return { port: 'right', x: right, y: top + (bottom - top) * offset };
|
|
486
|
-
case 'bottom':
|
|
487
|
-
return { port: 'bottom', x: left + (right - left) * offset, y: bottom };
|
|
488
|
-
case 'left':
|
|
489
|
-
return { port: 'left', x: left, y: top + (bottom - top) * offset };
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/** Nearest stable connector port on `box` to an arbitrary point. */
|
|
494
|
-
export function nearestSnapPoint(
|
|
495
|
-
box: ClipBox,
|
|
496
|
-
point: { x: number; y: number },
|
|
497
|
-
): ConnectorSnapPoint {
|
|
498
|
-
let best = snapPoints(box)[0];
|
|
499
|
-
let bestScore = Number.POSITIVE_INFINITY;
|
|
500
|
-
for (const candidate of snapPoints(box)) {
|
|
501
|
-
const score = distanceSq(candidate, point) + portTieBreak(candidate.port);
|
|
502
|
-
if (score < bestScore) {
|
|
503
|
-
best = candidate;
|
|
504
|
-
bestScore = score;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
return best;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/**
|
|
511
|
-
* Pick the pair of connector ports, one on each box, with the shortest
|
|
512
|
-
* distance between them. This gives stable attachments to side/corner handles
|
|
513
|
-
* instead of arbitrary center-ray intersections.
|
|
514
|
-
*/
|
|
515
|
-
export function snapEndpoints(
|
|
516
|
-
a: ClipBox,
|
|
517
|
-
b: ClipBox,
|
|
518
|
-
): { start: ConnectorSnapPoint; end: ConnectorSnapPoint } {
|
|
519
|
-
let bestStart = snapPoints(a)[0];
|
|
520
|
-
let bestEnd = snapPoints(b)[0];
|
|
521
|
-
let bestScore = Number.POSITIVE_INFINITY;
|
|
522
|
-
for (const start of snapPoints(a)) {
|
|
523
|
-
for (const end of snapPoints(b)) {
|
|
524
|
-
const score = distanceSq(start, end) + portTieBreak(start.port) + portTieBreak(end.port);
|
|
525
|
-
if (score < bestScore) {
|
|
526
|
-
bestStart = start;
|
|
527
|
-
bestEnd = end;
|
|
528
|
-
bestScore = score;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
return { start: bestStart, end: bestEnd };
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
function distanceSq(a: { x: number; y: number }, b: { x: number; y: number }): number {
|
|
536
|
-
const dx = a.x - b.x;
|
|
537
|
-
const dy = a.y - b.y;
|
|
538
|
-
return dx * dx + dy * dy;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
function portTieBreak(port: ConnectorPort): number {
|
|
542
|
-
return port.includes('-') ? 0.02 : 0;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
/** Build the SVG `d` for a connector between two clipped endpoints. */
|
|
546
|
-
export function connectorPath(
|
|
547
|
-
routing: ConnectorRouting,
|
|
548
|
-
start: { x: number; y: number; port?: ConnectorPort },
|
|
549
|
-
end: { x: number; y: number; port?: ConnectorPort },
|
|
550
|
-
): string {
|
|
551
|
-
if (routing === 'straight') {
|
|
552
|
-
return `M ${r(start.x)} ${r(start.y)} L ${r(end.x)} ${r(end.y)}`;
|
|
553
|
-
}
|
|
554
|
-
if (routing === 'orthogonal') {
|
|
555
|
-
const startAxis = portAxis(start.port);
|
|
556
|
-
const endAxis = portAxis(end.port);
|
|
557
|
-
if (startAxis === 'vertical' && endAxis === 'vertical') {
|
|
558
|
-
const midY = (start.y + end.y) / 2;
|
|
559
|
-
return `M ${r(start.x)} ${r(start.y)} L ${r(start.x)} ${r(midY)} L ${r(end.x)} ${r(midY)} L ${r(end.x)} ${r(end.y)}`;
|
|
560
|
-
}
|
|
561
|
-
if (startAxis === 'vertical' && endAxis === 'horizontal') {
|
|
562
|
-
return `M ${r(start.x)} ${r(start.y)} L ${r(start.x)} ${r(end.y)} L ${r(end.x)} ${r(end.y)}`;
|
|
563
|
-
}
|
|
564
|
-
if (startAxis === 'horizontal' && endAxis === 'vertical') {
|
|
565
|
-
return `M ${r(start.x)} ${r(start.y)} L ${r(end.x)} ${r(start.y)} L ${r(end.x)} ${r(end.y)}`;
|
|
566
|
-
}
|
|
567
|
-
const midX = (start.x + end.x) / 2;
|
|
568
|
-
return `M ${r(start.x)} ${r(start.y)} L ${r(midX)} ${r(start.y)} L ${r(midX)} ${r(end.y)} L ${r(end.x)} ${r(end.y)}`;
|
|
569
|
-
}
|
|
570
|
-
// curved
|
|
571
|
-
const distance = Math.hypot(end.x - start.x, end.y - start.y);
|
|
572
|
-
const cp = Math.max(40, distance / 2);
|
|
573
|
-
const startVector = portVector(start.port, { x: 1, y: 0 });
|
|
574
|
-
const endVector = portVector(end.port, { x: -1, y: 0 });
|
|
575
|
-
return `M ${r(start.x)} ${r(start.y)} C ${r(start.x + startVector.x * cp)} ${r(start.y + startVector.y * cp)}, ${r(end.x + endVector.x * cp)} ${r(end.y + endVector.y * cp)}, ${r(end.x)} ${r(end.y)}`;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
function portAxis(port: ConnectorPort | undefined): 'horizontal' | 'vertical' | null {
|
|
579
|
-
if (port === 'top' || port === 'bottom') return 'vertical';
|
|
580
|
-
if (port === 'left' || port === 'right') return 'horizontal';
|
|
581
|
-
return null;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
function portVector(
|
|
585
|
-
port: ConnectorPort | undefined,
|
|
586
|
-
fallback: { x: number; y: number },
|
|
587
|
-
): { x: number; y: number } {
|
|
588
|
-
switch (port) {
|
|
589
|
-
case 'top':
|
|
590
|
-
return { x: 0, y: -1 };
|
|
591
|
-
case 'right':
|
|
592
|
-
return { x: 1, y: 0 };
|
|
593
|
-
case 'bottom':
|
|
594
|
-
return { x: 0, y: 1 };
|
|
595
|
-
case 'left':
|
|
596
|
-
return { x: -1, y: 0 };
|
|
597
|
-
default:
|
|
598
|
-
return fallback;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
/** Map a `lineStyle` (solid|dashed|dotted) to an SVG `stroke-dasharray`. */
|
|
603
|
-
export function lineStyleDasharray(style: string | undefined): string | undefined {
|
|
604
|
-
switch (style?.toLowerCase()) {
|
|
605
|
-
case 'dashed':
|
|
606
|
-
case 'dash':
|
|
607
|
-
return '8 6';
|
|
608
|
-
case 'dotted':
|
|
609
|
-
case 'dot':
|
|
610
|
-
return '2 6';
|
|
611
|
-
default:
|
|
612
|
-
return undefined;
|
|
613
|
-
}
|
|
614
|
-
}
|