react-cheminfo 0.8.0 → 0.9.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/README.md +60 -2
- package/bin/check-tokens.mjs +105 -0
- package/lib/about/core/about.d.ts +95 -0
- package/lib/about/core/about.d.ts.map +1 -0
- package/lib/about/core/about.js +78 -0
- package/lib/about/core/about.js.map +1 -0
- package/lib/about/core/index.d.ts +3 -0
- package/lib/about/core/index.d.ts.map +1 -0
- package/lib/about/core/index.js +2 -0
- package/lib/about/core/index.js.map +1 -0
- package/lib/about/ui/AboutCitations.d.ts +14 -0
- package/lib/about/ui/AboutCitations.d.ts.map +1 -0
- package/lib/about/ui/AboutCitations.js +40 -0
- package/lib/about/ui/AboutCitations.js.map +1 -0
- package/lib/about/ui/AboutPage.d.ts +32 -0
- package/lib/about/ui/AboutPage.d.ts.map +1 -0
- package/lib/about/ui/AboutPage.js +70 -0
- package/lib/about/ui/AboutPage.js.map +1 -0
- package/lib/about/ui/AboutSection.d.ts +23 -0
- package/lib/about/ui/AboutSection.d.ts.map +1 -0
- package/lib/about/ui/AboutSection.js +28 -0
- package/lib/about/ui/AboutSection.js.map +1 -0
- package/lib/about/ui/index.d.ts +7 -0
- package/lib/about/ui/index.d.ts.map +1 -0
- package/lib/about/ui/index.js +4 -0
- package/lib/about/ui/index.js.map +1 -0
- package/lib/chrome/ui/index.d.ts +1 -0
- package/lib/chrome/ui/index.d.ts.map +1 -1
- package/lib/chrome/ui/index.js +3 -0
- package/lib/chrome/ui/index.js.map +1 -1
- package/lib/clipboard/ui/CodeBlock.d.ts.map +1 -1
- package/lib/clipboard/ui/CodeBlock.js +4 -1
- package/lib/clipboard/ui/CodeBlock.js.map +1 -1
- package/lib/color/ui/ColorScaleLegend.js +1 -1
- package/lib/color/ui/ColorScaleLegend.js.map +1 -1
- package/lib/core.d.ts +3 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +5 -0
- package/lib/core.js.map +1 -1
- package/lib/credits/core/credits.d.ts +36 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +42 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/credits/ui/CreditsList.js +1 -1
- package/lib/credits/ui/CreditsList.js.map +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.js +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.js.map +1 -1
- package/lib/ecosystem/core/sites.d.ts +1 -1
- package/lib/ecosystem/core/sites.d.ts.map +1 -1
- package/lib/ecosystem/core/sites.js +10 -0
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/core/tokens.d.ts.map +1 -1
- package/lib/ecosystem/core/tokens.js +1 -0
- package/lib/ecosystem/core/tokens.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.js +2 -2
- package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemMenu.js +1 -1
- package/lib/ecosystem/ui/EcosystemMenu.js.map +1 -1
- package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
- package/lib/ecosystem/ui/SiteTile.js +5 -5
- package/lib/ecosystem/ui/SiteTile.js.map +1 -1
- package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
- package/lib/ecosystem/ui/glyphs.js +3 -0
- package/lib/ecosystem/ui/glyphs.js.map +1 -1
- package/lib/orbital/core/index.d.ts +1 -1
- package/lib/orbital/core/index.d.ts.map +1 -1
- package/lib/orbital/core/index.js +1 -1
- package/lib/orbital/core/index.js.map +1 -1
- package/lib/orbital/core/realHarmonics.d.ts +5 -2
- package/lib/orbital/core/realHarmonics.d.ts.map +1 -1
- package/lib/orbital/core/realHarmonics.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts +18 -0
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.js +84 -7
- package/lib/orbital/ui/AtomicOrbitalCanvas.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts +13 -0
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.js +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.js.map +1 -1
- package/lib/orbital/ui/camera.d.ts +15 -0
- package/lib/orbital/ui/camera.d.ts.map +1 -1
- package/lib/orbital/ui/camera.js +68 -0
- package/lib/orbital/ui/camera.js.map +1 -1
- package/lib/orbital/ui/renderVolume.d.ts.map +1 -1
- package/lib/orbital/ui/renderVolume.js +8 -1
- package/lib/orbital/ui/renderVolume.js.map +1 -1
- package/lib/orbital/ui/serial.d.ts +25 -0
- package/lib/orbital/ui/serial.d.ts.map +1 -0
- package/lib/orbital/ui/serial.js +25 -0
- package/lib/orbital/ui/serial.js.map +1 -0
- package/lib/orbital/ui/viewer.d.ts +23 -0
- package/lib/orbital/ui/viewer.d.ts.map +1 -1
- package/lib/orbital/ui/viewer.js +70 -17
- package/lib/orbital/ui/viewer.js.map +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.js +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryText.js +2 -2
- package/lib/pedagogy/ui/GlossaryText.js.map +1 -1
- package/lib/pedagogy/ui/ReferenceSectionBlock.js +5 -2
- package/lib/pedagogy/ui/ReferenceSectionBlock.js.map +1 -1
- package/lib/pedagogy/ui/SyntaxTooltip.js +2 -2
- package/lib/pedagogy/ui/SyntaxTooltip.js.map +1 -1
- package/lib/pedagogy/ui/TutorialStepStrip.js +4 -1
- package/lib/pedagogy/ui/TutorialStepStrip.js.map +1 -1
- package/lib/periodic/ui/CategoryLegend.js +1 -1
- package/lib/periodic/ui/CategoryLegend.js.map +1 -1
- package/lib/periodic/ui/PeriodicTableChrome.js +2 -2
- package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -1
- package/lib/seo/vite/ogCard.d.ts.map +1 -1
- package/lib/seo/vite/ogCard.js +1 -0
- package/lib/seo/vite/ogCard.js.map +1 -1
- package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
- package/lib/share/ui/ShareDialogContent.js +5 -2
- package/lib/share/ui/ShareDialogContent.js.map +1 -1
- package/lib/share/ui/SharePartOptions.js +1 -1
- package/lib/share/ui/SharePartOptions.js.map +1 -1
- package/lib/slides/core/demoLinks.d.ts +43 -0
- package/lib/slides/core/demoLinks.d.ts.map +1 -0
- package/lib/slides/core/demoLinks.js +104 -0
- package/lib/slides/core/demoLinks.js.map +1 -0
- package/lib/slides/core/index.d.ts +13 -0
- package/lib/slides/core/index.d.ts.map +1 -0
- package/lib/slides/core/index.js +7 -0
- package/lib/slides/core/index.js.map +1 -0
- package/lib/slides/core/sectionHeading.d.ts +19 -0
- package/lib/slides/core/sectionHeading.d.ts.map +1 -0
- package/lib/slides/core/sectionHeading.js +19 -0
- package/lib/slides/core/sectionHeading.js.map +1 -0
- package/lib/slides/core/slideNavigation.d.ts +38 -0
- package/lib/slides/core/slideNavigation.d.ts.map +1 -0
- package/lib/slides/core/slideNavigation.js +65 -0
- package/lib/slides/core/slideNavigation.js.map +1 -0
- package/lib/slides/core/talk.d.ts +82 -0
- package/lib/slides/core/talk.d.ts.map +1 -0
- package/lib/slides/core/talk.js +134 -0
- package/lib/slides/core/talk.js.map +1 -0
- package/lib/slides/core/talkManifest.d.ts +90 -0
- package/lib/slides/core/talkManifest.d.ts.map +1 -0
- package/lib/slides/core/talkManifest.js +109 -0
- package/lib/slides/core/talkManifest.js.map +1 -0
- package/lib/slides/core/talkOrigin.d.ts +50 -0
- package/lib/slides/core/talkOrigin.d.ts.map +1 -0
- package/lib/slides/core/talkOrigin.js +62 -0
- package/lib/slides/core/talkOrigin.js.map +1 -0
- package/lib/slides/ui/BackToSlides.d.ts +26 -0
- package/lib/slides/ui/BackToSlides.d.ts.map +1 -0
- package/lib/slides/ui/BackToSlides.js +24 -0
- package/lib/slides/ui/BackToSlides.js.map +1 -0
- package/lib/slides/ui/DemoLink.d.ts +42 -0
- package/lib/slides/ui/DemoLink.d.ts.map +1 -0
- package/lib/slides/ui/DemoLink.js +17 -0
- package/lib/slides/ui/DemoLink.js.map +1 -0
- package/lib/slides/ui/EmbedSlide.d.ts +19 -0
- package/lib/slides/ui/EmbedSlide.d.ts.map +1 -0
- package/lib/slides/ui/EmbedSlide.js +56 -0
- package/lib/slides/ui/EmbedSlide.js.map +1 -0
- package/lib/slides/ui/SectionSlide.d.ts +18 -0
- package/lib/slides/ui/SectionSlide.d.ts.map +1 -0
- package/lib/slides/ui/SectionSlide.js +18 -0
- package/lib/slides/ui/SectionSlide.js.map +1 -0
- package/lib/slides/ui/Slide.d.ts +52 -0
- package/lib/slides/ui/Slide.d.ts.map +1 -0
- package/lib/slides/ui/Slide.js +58 -0
- package/lib/slides/ui/Slide.js.map +1 -0
- package/lib/slides/ui/SlideBody.d.ts +32 -0
- package/lib/slides/ui/SlideBody.d.ts.map +1 -0
- package/lib/slides/ui/SlideBody.js +27 -0
- package/lib/slides/ui/SlideBody.js.map +1 -0
- package/lib/slides/ui/Slideshow.d.ts +93 -0
- package/lib/slides/ui/Slideshow.d.ts.map +1 -0
- package/lib/slides/ui/Slideshow.js +122 -0
- package/lib/slides/ui/Slideshow.js.map +1 -0
- package/lib/slides/ui/SlideshowBar.d.ts +33 -0
- package/lib/slides/ui/SlideshowBar.d.ts.map +1 -0
- package/lib/slides/ui/SlideshowBar.js +20 -0
- package/lib/slides/ui/SlideshowBar.js.map +1 -0
- package/lib/slides/ui/TalkList.d.ts +37 -0
- package/lib/slides/ui/TalkList.d.ts.map +1 -0
- package/lib/slides/ui/TalkList.js +68 -0
- package/lib/slides/ui/TalkList.js.map +1 -0
- package/lib/slides/ui/index.d.ts +19 -0
- package/lib/slides/ui/index.d.ts.map +1 -0
- package/lib/slides/ui/index.js +10 -0
- package/lib/slides/ui/index.js.map +1 -0
- package/lib/slides/vite/index.d.ts +3 -0
- package/lib/slides/vite/index.d.ts.map +1 -0
- package/lib/slides/vite/index.js +2 -0
- package/lib/slides/vite/index.js.map +1 -0
- package/lib/slides/vite/talks.d.ts +50 -0
- package/lib/slides/vite/talks.d.ts.map +1 -0
- package/lib/slides/vite/talks.js +87 -0
- package/lib/slides/vite/talks.js.map +1 -0
- package/lib/slides.d.ts +3 -0
- package/lib/slides.d.ts.map +1 -0
- package/lib/slides.js +3 -0
- package/lib/slides.js.map +1 -0
- package/lib/structure/ui/StructureEditor.js +2 -2
- package/lib/structure/ui/StructureEditor.js.map +1 -1
- package/lib/structure/ui/StructurePlaceholder.js +1 -1
- package/lib/structure/ui/StructurePlaceholder.js.map +1 -1
- package/lib/tokens/core/checkTokens.d.ts +51 -0
- package/lib/tokens/core/checkTokens.d.ts.map +1 -0
- package/lib/tokens/core/checkTokens.js +188 -0
- package/lib/tokens/core/checkTokens.js.map +1 -0
- package/lib/tokens/core/colors.d.ts +42 -0
- package/lib/tokens/core/colors.d.ts.map +1 -0
- package/lib/tokens/core/colors.js +119 -0
- package/lib/tokens/core/colors.js.map +1 -0
- package/lib/tokens/core/index.d.ts +3 -0
- package/lib/tokens/core/index.d.ts.map +1 -0
- package/lib/tokens/core/index.js +2 -0
- package/lib/tokens/core/index.js.map +1 -0
- package/lib/tokens/core/rules.d.ts +23 -0
- package/lib/tokens/core/rules.d.ts.map +1 -0
- package/lib/tokens/core/rules.js +90 -0
- package/lib/tokens/core/rules.js.map +1 -0
- package/lib/ui.d.ts +1 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +1 -0
- package/lib/ui.js.map +1 -1
- package/lib/vite.d.ts +1 -0
- package/lib/vite.d.ts.map +1 -1
- package/lib/vite.js +1 -0
- package/lib/vite.js.map +1 -1
- package/package.json +11 -3
- package/src/about/core/about.ts +176 -0
- package/src/about/core/index.ts +2 -0
- package/src/about/ui/AboutCitations.tsx +79 -0
- package/src/about/ui/AboutPage.tsx +177 -0
- package/src/about/ui/AboutSection.tsx +56 -0
- package/src/about/ui/index.ts +6 -0
- package/src/chrome/ui/index.ts +3 -0
- package/src/clipboard/ui/CodeBlock.tsx +4 -1
- package/src/color/ui/ColorScaleLegend.tsx +1 -1
- package/src/core.ts +5 -0
- package/src/credits/core/credits.ts +42 -0
- package/src/credits/ui/CreditsList.tsx +1 -1
- package/src/delimited/ui/DelimitedTextPanel.tsx +1 -1
- package/src/ecosystem/core/sites.ts +12 -0
- package/src/ecosystem/core/tokens.ts +1 -0
- package/src/ecosystem/ui/EcosystemLinks.tsx +2 -2
- package/src/ecosystem/ui/EcosystemMenu.tsx +1 -1
- package/src/ecosystem/ui/SiteTile.tsx +7 -5
- package/src/ecosystem/ui/glyphs.tsx +40 -0
- package/src/orbital/core/index.ts +4 -1
- package/src/orbital/core/realHarmonics.ts +5 -2
- package/src/orbital/ui/AtomicOrbitalCanvas.tsx +126 -4
- package/src/orbital/ui/AtomicOrbitalViewer.tsx +14 -1
- package/src/orbital/ui/camera.ts +81 -0
- package/src/orbital/ui/renderVolume.ts +8 -1
- package/src/orbital/ui/serial.ts +35 -0
- package/src/orbital/ui/viewer.ts +72 -13
- package/src/pedagogy/ui/ExerciseProgressHeader.tsx +1 -1
- package/src/pedagogy/ui/GlossaryText.tsx +2 -2
- package/src/pedagogy/ui/ReferenceSectionBlock.tsx +5 -2
- package/src/pedagogy/ui/SyntaxTooltip.tsx +2 -2
- package/src/pedagogy/ui/TutorialStepStrip.tsx +4 -1
- package/src/periodic/ui/CategoryLegend.tsx +1 -1
- package/src/periodic/ui/PeriodicTableChrome.tsx +2 -2
- package/src/seo/vite/ogCard.ts +1 -0
- package/src/share/ui/ShareDialogContent.tsx +5 -2
- package/src/share/ui/SharePartOptions.tsx +1 -1
- package/src/slides/core/demoLinks.ts +113 -0
- package/src/slides/core/index.ts +22 -0
- package/src/slides/core/sectionHeading.ts +29 -0
- package/src/slides/core/slideNavigation.ts +77 -0
- package/src/slides/core/talk.ts +203 -0
- package/src/slides/core/talkManifest.ts +158 -0
- package/src/slides/core/talkOrigin.ts +83 -0
- package/src/slides/ui/BackToSlides.tsx +49 -0
- package/src/slides/ui/DemoLink.tsx +67 -0
- package/src/slides/ui/EmbedSlide.tsx +85 -0
- package/src/slides/ui/SectionSlide.tsx +44 -0
- package/src/slides/ui/Slide.tsx +143 -0
- package/src/slides/ui/SlideBody.tsx +64 -0
- package/src/slides/ui/Slideshow.tsx +282 -0
- package/src/slides/ui/SlideshowBar.tsx +83 -0
- package/src/slides/ui/TalkList.tsx +146 -0
- package/src/slides/ui/index.ts +18 -0
- package/src/slides/vite/index.ts +2 -0
- package/src/slides/vite/talks.ts +126 -0
- package/src/slides.ts +2 -0
- package/src/structure/ui/StructureEditor.tsx +2 -2
- package/src/structure/ui/StructurePlaceholder.tsx +1 -1
- package/src/tokens/core/checkTokens.ts +242 -0
- package/src/tokens/core/colors.ts +122 -0
- package/src/tokens/core/index.ts +6 -0
- package/src/tokens/core/rules.ts +103 -0
- package/src/ui.ts +1 -0
- package/src/vite.ts +1 -0
- package/styles/chrome.css +1 -0
- package/styles/slides.css +667 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The round trip from a slide to a live demo and back.
|
|
3
|
+
*
|
|
4
|
+
* A demo link opens the real tool, so the presenter is then on an ordinary page
|
|
5
|
+
* of an ordinary site with no way back to the talk. One query parameter carries
|
|
6
|
+
* where they came from, which is enough for that page to offer the way back —
|
|
7
|
+
* and, because the site the talk lives on may not be the site the demo runs on,
|
|
8
|
+
* the parameter names both.
|
|
9
|
+
*/
|
|
10
|
+
/** The query parameter a demo link carries its origin in. */
|
|
11
|
+
export declare const TALK_ORIGIN_PARAM = "from";
|
|
12
|
+
/** Where a demo was opened from. */
|
|
13
|
+
export interface TalkOrigin {
|
|
14
|
+
/** Which talk, as the publishing site names it. */
|
|
15
|
+
talkId: string;
|
|
16
|
+
/** Which slide of it, zero-based. */
|
|
17
|
+
slide: number;
|
|
18
|
+
/**
|
|
19
|
+
* The `ECOSYSTEM_SITES` id of the site the talk is published by, for a demo
|
|
20
|
+
* that runs on a different site than the talk.
|
|
21
|
+
* @default undefined — the talk lives on the site the demo runs on
|
|
22
|
+
*/
|
|
23
|
+
site?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Write an origin as the value of the `from` parameter.
|
|
27
|
+
* @param origin - Which talk and slide the demo was opened from.
|
|
28
|
+
* @returns `talk:<site>:<id>:<slide>`, or `talk:<id>:<slide>` when the talk
|
|
29
|
+
* lives on the site the link points at.
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatTalkOrigin(origin: TalkOrigin): string;
|
|
32
|
+
/**
|
|
33
|
+
* Read the origin out of an address's query string.
|
|
34
|
+
*
|
|
35
|
+
* Anything malformed reads as no origin at all: a link retyped from a slide, or
|
|
36
|
+
* one written before the talk was renamed, must still open the tool it points
|
|
37
|
+
* at rather than fail on its way in.
|
|
38
|
+
* @param search - The query string, with or without its leading `?`.
|
|
39
|
+
* @returns The origin, or `null` when the address carries none.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseTalkOrigin(search: string): TalkOrigin | null;
|
|
42
|
+
/**
|
|
43
|
+
* Point a demo link at its target, carrying where it was opened from.
|
|
44
|
+
* @param href - The target, relative or absolute, with or without a query.
|
|
45
|
+
* @param origin - Which talk and slide the link sits on.
|
|
46
|
+
* @returns The same address with the `from` parameter added, its own
|
|
47
|
+
* parameters and its fragment untouched.
|
|
48
|
+
*/
|
|
49
|
+
export declare function withTalkOrigin(href: string, origin: TalkOrigin): string;
|
|
50
|
+
//# sourceMappingURL=talkOrigin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"talkOrigin.d.ts","sourceRoot":"","sources":["../../../src/slides/core/talkOrigin.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,SAAS,CAAC;AAExC,oCAAoC;AACpC,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAI3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CASjE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAWvE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { firstValues, parseQuery } from "../../share/core/query.js";
|
|
2
|
+
/**
|
|
3
|
+
* The round trip from a slide to a live demo and back.
|
|
4
|
+
*
|
|
5
|
+
* A demo link opens the real tool, so the presenter is then on an ordinary page
|
|
6
|
+
* of an ordinary site with no way back to the talk. One query parameter carries
|
|
7
|
+
* where they came from, which is enough for that page to offer the way back —
|
|
8
|
+
* and, because the site the talk lives on may not be the site the demo runs on,
|
|
9
|
+
* the parameter names both.
|
|
10
|
+
*/
|
|
11
|
+
/** The query parameter a demo link carries its origin in. */
|
|
12
|
+
export const TALK_ORIGIN_PARAM = 'from';
|
|
13
|
+
/**
|
|
14
|
+
* Write an origin as the value of the `from` parameter.
|
|
15
|
+
* @param origin - Which talk and slide the demo was opened from.
|
|
16
|
+
* @returns `talk:<site>:<id>:<slide>`, or `talk:<id>:<slide>` when the talk
|
|
17
|
+
* lives on the site the link points at.
|
|
18
|
+
*/
|
|
19
|
+
export function formatTalkOrigin(origin) {
|
|
20
|
+
const slide = Math.max(Math.trunc(origin.slide), 0);
|
|
21
|
+
const site = origin.site === undefined ? '' : `${origin.site}:`;
|
|
22
|
+
return `talk:${site}${origin.talkId}:${slide}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Read the origin out of an address's query string.
|
|
26
|
+
*
|
|
27
|
+
* Anything malformed reads as no origin at all: a link retyped from a slide, or
|
|
28
|
+
* one written before the talk was renamed, must still open the tool it points
|
|
29
|
+
* at rather than fail on its way in.
|
|
30
|
+
* @param search - The query string, with or without its leading `?`.
|
|
31
|
+
* @returns The origin, or `null` when the address carries none.
|
|
32
|
+
*/
|
|
33
|
+
export function parseTalkOrigin(search) {
|
|
34
|
+
const value = firstValues(parseQuery(search)).get(TALK_ORIGIN_PARAM);
|
|
35
|
+
if (value === undefined)
|
|
36
|
+
return null;
|
|
37
|
+
const match = ORIGIN_RE.exec(value);
|
|
38
|
+
const talkId = match?.groups?.talkId;
|
|
39
|
+
const slide = Number.parseInt(match?.groups?.slide ?? '', 10);
|
|
40
|
+
if (talkId === undefined || !Number.isFinite(slide))
|
|
41
|
+
return null;
|
|
42
|
+
const site = match?.groups?.site;
|
|
43
|
+
return site === undefined ? { talkId, slide } : { talkId, slide, site };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Point a demo link at its target, carrying where it was opened from.
|
|
47
|
+
* @param href - The target, relative or absolute, with or without a query.
|
|
48
|
+
* @param origin - Which talk and slide the link sits on.
|
|
49
|
+
* @returns The same address with the `from` parameter added, its own
|
|
50
|
+
* parameters and its fragment untouched.
|
|
51
|
+
*/
|
|
52
|
+
export function withTalkOrigin(href, origin) {
|
|
53
|
+
const cut = href.indexOf('#');
|
|
54
|
+
const address = cut === -1 ? href : href.slice(0, cut);
|
|
55
|
+
const fragment = cut === -1 ? '' : href.slice(cut);
|
|
56
|
+
const separator = address.includes('?') ? '&' : '?';
|
|
57
|
+
// A colon reads as a colon in these links, and parses back identically.
|
|
58
|
+
const value = encodeURIComponent(formatTalkOrigin(origin)).replaceAll('%3A', ':');
|
|
59
|
+
return `${address}${separator}${TALK_ORIGIN_PARAM}=${value}${fragment}`;
|
|
60
|
+
}
|
|
61
|
+
const ORIGIN_RE = /^talk:(?:(?<site>[\da-z-]+):)?(?<talkId>[^:]+):(?<slide>\d+)$/i;
|
|
62
|
+
//# sourceMappingURL=talkOrigin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"talkOrigin.js","sourceRoot":"","sources":["../../../src/slides/core/talkOrigin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;;;;;GAQG;AAEH,6DAA6D;AAC7D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAgBxC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAkB;IACjD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,CAAC;IAChE,OAAO,QAAQ,IAAI,GAAG,MAAM,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACrE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9D,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,MAAM,IAAI,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC;IACjC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AAC1E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,MAAkB;IAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACpD,wEAAwE;IACxE,MAAM,KAAK,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CACnE,KAAK,EACL,GAAG,CACJ,CAAC;IACF,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,iBAAiB,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,SAAS,GACb,gEAAgE,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { TalkOrigin } from '../core/index.ts';
|
|
3
|
+
/** Where the visitor came from, and how to send them back. */
|
|
4
|
+
export interface BackToSlidesProps {
|
|
5
|
+
/** The talk and slide a demo link was opened from, or `null` for none. */
|
|
6
|
+
origin: TalkOrigin | null;
|
|
7
|
+
/** The address of that slide. */
|
|
8
|
+
href: string;
|
|
9
|
+
/**
|
|
10
|
+
* What the site does when the pill is clicked, for a site that routes in the
|
|
11
|
+
* browser. A modified click is left to the browser either way.
|
|
12
|
+
* @default undefined — the browser follows the address
|
|
13
|
+
*/
|
|
14
|
+
onReturn?: () => void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The way back to the slide a demo was opened from.
|
|
18
|
+
*
|
|
19
|
+
* A demo link drops the presenter on an ordinary page of an ordinary site, so
|
|
20
|
+
* during a talk the site stays fully browsable and the talk stays one click
|
|
21
|
+
* away. It renders nothing at all when the page was not reached from a slide.
|
|
22
|
+
* @param props - See {@link BackToSlidesProps}.
|
|
23
|
+
* @returns The pill, or nothing.
|
|
24
|
+
*/
|
|
25
|
+
export declare function BackToSlides(props: BackToSlidesProps): ReactElement | null;
|
|
26
|
+
//# sourceMappingURL=BackToSlides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BackToSlides.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/BackToSlides.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,8DAA8D;AAC9D,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,GAAG,IAAI,CAmB1E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon } from '@blueprintjs/core';
|
|
3
|
+
import { isModifiedClick } from "../../chrome/ui/navItem.js";
|
|
4
|
+
/**
|
|
5
|
+
* The way back to the slide a demo was opened from.
|
|
6
|
+
*
|
|
7
|
+
* A demo link drops the presenter on an ordinary page of an ordinary site, so
|
|
8
|
+
* during a talk the site stays fully browsable and the talk stays one click
|
|
9
|
+
* away. It renders nothing at all when the page was not reached from a slide.
|
|
10
|
+
* @param props - See {@link BackToSlidesProps}.
|
|
11
|
+
* @returns The pill, or nothing.
|
|
12
|
+
*/
|
|
13
|
+
export function BackToSlides(props) {
|
|
14
|
+
const { origin, href, onReturn } = props;
|
|
15
|
+
if (origin === null)
|
|
16
|
+
return null;
|
|
17
|
+
return (_jsxs("a", { className: "back-to-slides no-print", href: href, title: `Back to slide ${origin.slide + 1}`, onClick: (event) => {
|
|
18
|
+
if (onReturn === undefined || isModifiedClick(event))
|
|
19
|
+
return;
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
onReturn();
|
|
22
|
+
}, children: [_jsx(Icon, { icon: "presentation", size: 14 }), "Back to slides"] }));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=BackToSlides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BackToSlides.js","sourceRoot":"","sources":["../../../src/slides/ui/BackToSlides.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGzC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAiB7D;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACzC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,CACL,aACE,SAAS,EAAC,yBAAyB,EACnC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,iBAAiB,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,EAC1C,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACjB,IAAI,QAAQ,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,CAAC;gBAAE,OAAO;YAC7D,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,QAAQ,EAAE,CAAC;QACb,CAAC,aAED,KAAC,IAAI,IAAC,IAAI,EAAC,cAAc,EAAC,IAAI,EAAE,EAAE,GAAI,sBAEpC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { TalkOrigin } from '../core/index.ts';
|
|
3
|
+
/**
|
|
4
|
+
* How a site draws a link that leaves a slide for one of its own pages.
|
|
5
|
+
*
|
|
6
|
+
* The player never navigates: a site that routes in the browser passes its own
|
|
7
|
+
* link here, and the address it is given already carries the slide it was
|
|
8
|
+
* opened from. The children arrive already wrapped in the deck's arrow and
|
|
9
|
+
* label spans, so a site's element only has to carry `slide-demo` for the
|
|
10
|
+
* styling to apply.
|
|
11
|
+
*/
|
|
12
|
+
export type RenderSlideLink = (link: {
|
|
13
|
+
/** The address the link opens, `from` parameter included. */
|
|
14
|
+
href: string;
|
|
15
|
+
/** What the link reads. */
|
|
16
|
+
children: ReactNode;
|
|
17
|
+
}) => ReactElement;
|
|
18
|
+
/** What a demo link points at, and how it is drawn. */
|
|
19
|
+
export interface DemoLinkProps {
|
|
20
|
+
/** The in-app route the demo opens, as the slide wrote it. */
|
|
21
|
+
href: string;
|
|
22
|
+
/**
|
|
23
|
+
* Which slide the link sits on, added to the address so the tool it opens can
|
|
24
|
+
* offer the way back. Nothing is added when it is left out.
|
|
25
|
+
* @default undefined
|
|
26
|
+
*/
|
|
27
|
+
origin?: TalkOrigin;
|
|
28
|
+
/**
|
|
29
|
+
* The site's own link, for a site that routes in the browser.
|
|
30
|
+
* @default undefined — a plain anchor
|
|
31
|
+
*/
|
|
32
|
+
renderLink?: RenderSlideLink;
|
|
33
|
+
/** The link label. */
|
|
34
|
+
children: ReactNode;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A link from a slide into the live tool it demonstrates.
|
|
38
|
+
* @param props - See {@link DemoLinkProps}.
|
|
39
|
+
* @returns The link.
|
|
40
|
+
*/
|
|
41
|
+
export declare function DemoLink(props: DemoLinkProps): ReactElement;
|
|
42
|
+
//# sourceMappingURL=DemoLink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DemoLink.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/DemoLink.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE;IACnC,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,QAAQ,EAAE,SAAS,CAAC;CACrB,KAAK,YAAY,CAAC;AAEnB,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,sBAAsB;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAqB3D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { withTalkOrigin } from "../core/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* A link from a slide into the live tool it demonstrates.
|
|
5
|
+
* @param props - See {@link DemoLinkProps}.
|
|
6
|
+
* @returns The link.
|
|
7
|
+
*/
|
|
8
|
+
export function DemoLink(props) {
|
|
9
|
+
const { href, origin, renderLink, children } = props;
|
|
10
|
+
const address = origin === undefined ? href : withTalkOrigin(href, origin);
|
|
11
|
+
const label = (_jsxs(_Fragment, { children: [_jsx("span", { className: "slide-demo-arrow", "aria-hidden": "true", children: "\u25B8" }), _jsx("span", { className: "slide-demo-label", children: children })] }));
|
|
12
|
+
if (renderLink !== undefined) {
|
|
13
|
+
return renderLink({ href: address, children: label });
|
|
14
|
+
}
|
|
15
|
+
return (_jsx("a", { className: "slide-demo", href: address, children: label }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=DemoLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DemoLink.js","sourceRoot":"","sources":["../../../src/slides/ui/DemoLink.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAqClD;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAoB;IAC3C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACrD,MAAM,OAAO,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,CACZ,8BACE,eAAM,SAAS,EAAC,kBAAkB,iBAAa,MAAM,uBAE9C,EACP,eAAM,SAAS,EAAC,kBAAkB,YAAE,QAAQ,GAAQ,IACnD,CACJ,CAAC;IAEF,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CACL,YAAG,SAAS,EAAC,YAAY,EAAC,IAAI,EAAE,OAAO,YACpC,KAAK,GACJ,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { Slide } from '../core/talk.ts';
|
|
3
|
+
/** What an embedded slide draws. */
|
|
4
|
+
export interface EmbedSlideProps {
|
|
5
|
+
/** The slide, whose body holds the prose and, on its own line, the address. */
|
|
6
|
+
slide: Slide;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A slide that is the tool itself, running.
|
|
10
|
+
*
|
|
11
|
+
* Every tool of the family takes `?embed`, so a lecture can show the real thing
|
|
12
|
+
* instead of a screenshot of it — which is also the only version of the slide
|
|
13
|
+
* that stays true after the tool is improved. The heading and any prose stay
|
|
14
|
+
* above the frame; the last bare URL of the body is what is framed.
|
|
15
|
+
* @param props - See {@link EmbedSlideProps}.
|
|
16
|
+
* @returns The slide.
|
|
17
|
+
*/
|
|
18
|
+
export declare function EmbedSlide(props: EmbedSlideProps): ReactElement;
|
|
19
|
+
//# sourceMappingURL=EmbedSlide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbedSlide.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/EmbedSlide.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAI7C,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B,+EAA+E;IAC/E,KAAK,EAAE,KAAK,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,YAAY,CAuB/D"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SlideBody } from "./SlideBody.js";
|
|
3
|
+
/**
|
|
4
|
+
* A slide that is the tool itself, running.
|
|
5
|
+
*
|
|
6
|
+
* Every tool of the family takes `?embed`, so a lecture can show the real thing
|
|
7
|
+
* instead of a screenshot of it — which is also the only version of the slide
|
|
8
|
+
* that stays true after the tool is improved. The heading and any prose stay
|
|
9
|
+
* above the frame; the last bare URL of the body is what is framed.
|
|
10
|
+
* @param props - See {@link EmbedSlideProps}.
|
|
11
|
+
* @returns The slide.
|
|
12
|
+
*/
|
|
13
|
+
export function EmbedSlide(props) {
|
|
14
|
+
const { slide } = props;
|
|
15
|
+
const { prose, src } = splitEmbedAddress(slide.body);
|
|
16
|
+
return (_jsx("div", { className: "slide slide--embed", children: _jsxs("div", { className: "slide-content", children: [prose === '' ? null : _jsx(SlideBody, { body: prose }), src === null ? (_jsx("p", { className: "slide-embed-missing", children: "This slide frames a tool, but carries no address." })) : (_jsx("iframe", { className: "slide-embed-frame", src: src, title: frameTitle(src), allow: "clipboard-write; fullscreen" }))] }) }));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The prose and the address of an embedded slide.
|
|
20
|
+
*
|
|
21
|
+
* The address is written as a bare URL on its own line, because a teacher
|
|
22
|
+
* pastes what the tool's Share dialog gave them and nothing else.
|
|
23
|
+
* @param body - The slide body.
|
|
24
|
+
* @returns The prose without the address, and the address.
|
|
25
|
+
*/
|
|
26
|
+
function splitEmbedAddress(body) {
|
|
27
|
+
const lines = body.split('\n');
|
|
28
|
+
for (let index = lines.length - 1; index >= 0; index--) {
|
|
29
|
+
const line = (lines[index] ?? '').trim();
|
|
30
|
+
if (line === '')
|
|
31
|
+
continue;
|
|
32
|
+
if (!line.startsWith('http://') && !line.startsWith('https://'))
|
|
33
|
+
break;
|
|
34
|
+
if (line.includes(' '))
|
|
35
|
+
break;
|
|
36
|
+
const prose = [...lines.slice(0, index), ...lines.slice(index + 1)]
|
|
37
|
+
.join('\n')
|
|
38
|
+
.trim();
|
|
39
|
+
return { prose, src: line };
|
|
40
|
+
}
|
|
41
|
+
return { prose: body.trim(), src: null };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A frame without a title is unreadable to a screen reader.
|
|
45
|
+
* @param src - The address being framed.
|
|
46
|
+
* @returns What the frame is called.
|
|
47
|
+
*/
|
|
48
|
+
function frameTitle(src) {
|
|
49
|
+
try {
|
|
50
|
+
return `${new URL(src).hostname}, embedded`;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return 'Embedded tool';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=EmbedSlide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmbedSlide.js","sourceRoot":"","sources":["../../../src/slides/ui/EmbedSlide.tsx"],"names":[],"mappings":";AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAiB,CAAC;AAQ5C;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxB,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAErD,OAAO,CACL,cAAK,SAAS,EAAC,oBAAoB,YACjC,eAAK,SAAS,EAAC,eAAe,aAC3B,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,IAAI,EAAE,KAAK,GAAI,EAChD,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CACd,YAAG,SAAS,EAAC,qBAAqB,kEAE9B,CACL,CAAC,CAAC,CAAC,CACF,iBACE,SAAS,EAAC,mBAAmB,EAC7B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,EACtB,KAAK,EAAC,6BAA6B,GACnC,CACH,IACG,GACF,CACP,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,IAAY;IAIrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,IAAI,KAAK,EAAE;YAAE,SAAS;QAC1B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,MAAM;QACvE,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM;QAC9B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;aAChE,IAAI,CAAC,IAAI,CAAC;aACV,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC3C,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,IAAI,CAAC;QACH,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,YAAY,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
/** The body of a section divider. */
|
|
3
|
+
export interface SectionSlideProps {
|
|
4
|
+
/** The Markdown body, normally starting with `# N · Title`. */
|
|
5
|
+
body: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* The slide that says a new part of the talk starts here: the section number
|
|
9
|
+
* set huge and near-transparent, with the title, an accent rule and whatever
|
|
10
|
+
* else the body holds stacked beside it.
|
|
11
|
+
*
|
|
12
|
+
* The numeral is decoration, not text — the heading beside it already says
|
|
13
|
+
* where the talk is — so it is hidden from a screen reader.
|
|
14
|
+
* @param props - See {@link SectionSlideProps}.
|
|
15
|
+
* @returns The divider slide.
|
|
16
|
+
*/
|
|
17
|
+
export declare function SectionSlide(props: SectionSlideProps): ReactElement;
|
|
18
|
+
//# sourceMappingURL=SectionSlide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionSlide.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/SectionSlide.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAM1C,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAqBnE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { parseSectionHeading } from "../core/index.js";
|
|
3
|
+
import { SlideBody } from "./SlideBody.js";
|
|
4
|
+
/**
|
|
5
|
+
* The slide that says a new part of the talk starts here: the section number
|
|
6
|
+
* set huge and near-transparent, with the title, an accent rule and whatever
|
|
7
|
+
* else the body holds stacked beside it.
|
|
8
|
+
*
|
|
9
|
+
* The numeral is decoration, not text — the heading beside it already says
|
|
10
|
+
* where the talk is — so it is hidden from a screen reader.
|
|
11
|
+
* @param props - See {@link SectionSlideProps}.
|
|
12
|
+
* @returns The divider slide.
|
|
13
|
+
*/
|
|
14
|
+
export function SectionSlide(props) {
|
|
15
|
+
const { number, title, rest } = parseSectionHeading(props.body);
|
|
16
|
+
return (_jsx("div", { className: "slide slide--section", children: _jsxs("div", { className: "section-slide", children: [_jsx("div", { className: "section-number", "aria-hidden": "true", children: number }), _jsxs("div", { className: "section-body", children: [title === '' ? null : _jsx("h1", { className: "section-title", children: title }), _jsx("hr", { className: "section-rule" }), rest === '' ? null : (_jsx("div", { className: "section-sub", children: _jsx(SlideBody, { body: rest }) }))] })] }) }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=SectionSlide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SectionSlide.js","sourceRoot":"","sources":["../../../src/slides/ui/SectionSlide.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAiB,CAAC;AAQ5C;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEhE,OAAO,CACL,cAAK,SAAS,EAAC,sBAAsB,YACnC,eAAK,SAAS,EAAC,eAAe,aAC5B,cAAK,SAAS,EAAC,gBAAgB,iBAAa,MAAM,YAC/C,MAAM,GACH,EACN,eAAK,SAAS,EAAC,cAAc,aAC1B,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAI,SAAS,EAAC,eAAe,YAAE,KAAK,GAAM,EACjE,aAAI,SAAS,EAAC,cAAc,GAAG,EAC9B,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACpB,cAAK,SAAS,EAAC,aAAa,YAC1B,KAAC,SAAS,IAAC,IAAI,EAAE,IAAI,GAAI,GACrB,CACP,IACG,IACF,GACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ComponentType, ReactElement } from 'react';
|
|
2
|
+
import type { Slide as SlideData, TalkMeta } from '../core/index.ts';
|
|
3
|
+
import type { RenderSlideLink } from './DemoLink.tsx';
|
|
4
|
+
/** What every layout — the generic ones and a site's own — is handed. */
|
|
5
|
+
export interface SlideLayoutProps {
|
|
6
|
+
/** The slide to draw. */
|
|
7
|
+
slide: SlideData;
|
|
8
|
+
/** How the publishing site names the talk in its addresses. */
|
|
9
|
+
talkId: string;
|
|
10
|
+
/** Which slide of the talk this is, zero-based. */
|
|
11
|
+
slideIndex: number;
|
|
12
|
+
/**
|
|
13
|
+
* Which site published the deck, written into the way back.
|
|
14
|
+
* @default undefined — the site playing it
|
|
15
|
+
*/
|
|
16
|
+
site?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Where the publishing site lives, which a relative address in the deck is
|
|
19
|
+
* resolved against.
|
|
20
|
+
* @default undefined — the addresses are this site's own
|
|
21
|
+
*/
|
|
22
|
+
talkOrigin?: string;
|
|
23
|
+
/** What the talk's front-matter said, for a layout that draws from it. */
|
|
24
|
+
meta: TalkMeta;
|
|
25
|
+
/**
|
|
26
|
+
* The site's own link, used for the in-app links of the slide.
|
|
27
|
+
* @default undefined — a plain anchor
|
|
28
|
+
*/
|
|
29
|
+
renderLink?: RenderSlideLink;
|
|
30
|
+
}
|
|
31
|
+
/** A slide, and the layouts available to draw it. */
|
|
32
|
+
export interface SlideViewProps extends SlideLayoutProps {
|
|
33
|
+
/**
|
|
34
|
+
* The layouts this site adds, by the name a slide writes in its
|
|
35
|
+
* `<!-- layout: … -->` marker. An entry here also replaces a generic layout
|
|
36
|
+
* of the same name.
|
|
37
|
+
* @default undefined
|
|
38
|
+
*/
|
|
39
|
+
layouts?: Record<string, ComponentType<SlideLayoutProps>>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Draw one slide with the layout it asks for.
|
|
43
|
+
*
|
|
44
|
+
* The layout name is not a closed list — a deck is written before the site
|
|
45
|
+
* knows how to draw it — so a name neither the site nor the player recognises
|
|
46
|
+
* falls back to the plain content layout. A talk must never fail to open
|
|
47
|
+
* because one of its slides asks for something that is not there yet.
|
|
48
|
+
* @param props - See {@link SlideViewProps}.
|
|
49
|
+
* @returns The slide.
|
|
50
|
+
*/
|
|
51
|
+
export declare function SlideView(props: SlideViewProps): ReactElement;
|
|
52
|
+
//# sourceMappingURL=Slide.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slide.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/Slide.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,KAAK,EACV,KAAK,IAAI,SAAS,EAClB,QAAQ,EAET,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMtD,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,IAAI,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAU7D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { demoLabel, splitDemoLinks } from "../core/index.js";
|
|
4
|
+
import { DemoLink } from "./DemoLink.js";
|
|
5
|
+
import { EmbedSlide } from "./EmbedSlide.js";
|
|
6
|
+
import { SectionSlide } from "./SectionSlide.js";
|
|
7
|
+
import { SlideBody } from "./SlideBody.js";
|
|
8
|
+
/**
|
|
9
|
+
* Draw one slide with the layout it asks for.
|
|
10
|
+
*
|
|
11
|
+
* The layout name is not a closed list — a deck is written before the site
|
|
12
|
+
* knows how to draw it — so a name neither the site nor the player recognises
|
|
13
|
+
* falls back to the plain content layout. A talk must never fail to open
|
|
14
|
+
* because one of its slides asks for something that is not there yet.
|
|
15
|
+
* @param props - See {@link SlideViewProps}.
|
|
16
|
+
* @returns The slide.
|
|
17
|
+
*/
|
|
18
|
+
export function SlideView(props) {
|
|
19
|
+
const { layouts, ...layoutProps } = props;
|
|
20
|
+
const { slide } = layoutProps;
|
|
21
|
+
const Custom = layouts?.[slide.layout];
|
|
22
|
+
if (Custom !== undefined)
|
|
23
|
+
return _jsx(Custom, { ...layoutProps });
|
|
24
|
+
if (slide.layout === 'section')
|
|
25
|
+
return _jsx(SectionSlide, { body: slide.body });
|
|
26
|
+
if (slide.layout === 'embed')
|
|
27
|
+
return _jsx(EmbedSlide, { slide: slide });
|
|
28
|
+
return _jsx(GenericSlide, { ...layoutProps });
|
|
29
|
+
}
|
|
30
|
+
/** The layouts the player draws itself, for any deck on any site. */
|
|
31
|
+
const GENERIC_LAYOUTS = new Set(['content', 'title', 'quote', 'thanks']);
|
|
32
|
+
function GenericSlide(props) {
|
|
33
|
+
const { slide, talkId, slideIndex, meta, renderLink, site, talkOrigin } = props;
|
|
34
|
+
const layout = GENERIC_LAYOUTS.has(slide.layout) ? slide.layout : 'content';
|
|
35
|
+
const { body, demos } = splitDemoLinks(slide.body);
|
|
36
|
+
const origin = site === undefined
|
|
37
|
+
? { talkId, slide: slideIndex }
|
|
38
|
+
: { talkId, slide: slideIndex, site };
|
|
39
|
+
const logos = layout === 'title' ? (meta.logos ?? []) : [];
|
|
40
|
+
return (_jsx("div", { className: `slide slide--${layout}`, children: _jsxs("div", { className: "slide-content", children: [_jsx(SlideBody, { body: body, origin: origin, renderLink: renderLink }), logos.length === 0 ? null : (_jsx("div", { className: "slide-logos", children: logos.map((logo) => (_jsx("img", { className: "slide-logo", src: logo, alt: "" }, logo))) })), demos.length === 0 ? null : (_jsxs("div", { className: "slide-demos", children: [_jsx("span", { className: "slide-demos-label", children: "Live demos:" }), demos.map((demo, index) => (_jsxs(Fragment, { children: [index === 0 ? null : (_jsx("span", { className: "slide-demos-separator", "aria-hidden": "true", children: "|" })), _jsx(DemoLink, { href: resolveDemoHref(demo.href, talkOrigin), origin: origin, renderLink: renderLink, children: demoLabel(demo.label) })] }, demo.href)))] }))] }) }));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Where a demo link actually points.
|
|
44
|
+
*
|
|
45
|
+
* A deck writes `/mf-finder?mass=300`, meaning its own site. Played there it is
|
|
46
|
+
* exactly that; played on another site of the family it has to be resolved
|
|
47
|
+
* against the site that wrote it, or the link lands on a page that does not
|
|
48
|
+
* exist.
|
|
49
|
+
* @param href - The address the slide wrote.
|
|
50
|
+
* @param talkOrigin - Where the publishing site lives, when it is not this one.
|
|
51
|
+
* @returns The address to open.
|
|
52
|
+
*/
|
|
53
|
+
function resolveDemoHref(href, talkOrigin) {
|
|
54
|
+
if (talkOrigin === undefined || !href.startsWith('/'))
|
|
55
|
+
return href;
|
|
56
|
+
return `${talkOrigin.replace(/\/$/, '')}${href}`;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=Slide.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Slide.js","sourceRoot":"","sources":["../../../src/slides/ui/Slide.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { TalkOrigin } from '../core/index.ts';
|
|
3
|
+
import type { RenderSlideLink } from './DemoLink.tsx';
|
|
4
|
+
/** The Markdown of a slide, and where its links go. */
|
|
5
|
+
export interface SlideBodyProps {
|
|
6
|
+
/** The Markdown source of the slide, or of one part of it. */
|
|
7
|
+
body: string;
|
|
8
|
+
/**
|
|
9
|
+
* Which slide the body belongs to, carried by every in-app link it holds so
|
|
10
|
+
* the tool a demo opens can offer the way back.
|
|
11
|
+
* @default undefined
|
|
12
|
+
*/
|
|
13
|
+
origin?: TalkOrigin;
|
|
14
|
+
/**
|
|
15
|
+
* The site's own link, used for the in-app links of the body.
|
|
16
|
+
* @default undefined — a plain anchor
|
|
17
|
+
*/
|
|
18
|
+
renderLink?: RenderSlideLink;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Render a slide's Markdown.
|
|
22
|
+
*
|
|
23
|
+
* A talk is written as prose, so raw HTML in the source is kept: a slide
|
|
24
|
+
* routinely holds a `<sub>`, a `<br>` or a figure the Markdown syntax cannot
|
|
25
|
+
* express. A link to an in-app route becomes a demo link; every other link
|
|
26
|
+
* leaves the deck in a tab of its own, so a click during a talk never loses the
|
|
27
|
+
* slide it was made from.
|
|
28
|
+
* @param props - See {@link SlideBodyProps}.
|
|
29
|
+
* @returns The rendered body.
|
|
30
|
+
*/
|
|
31
|
+
export declare function SlideBody(props: SlideBodyProps): ReactElement;
|
|
32
|
+
//# sourceMappingURL=SlideBody.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlideBody.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/SlideBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CA0B7D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import Markdown from 'react-markdown';
|
|
3
|
+
import rehypeRaw from 'rehype-raw';
|
|
4
|
+
import { DemoLink } from "./DemoLink.js";
|
|
5
|
+
/**
|
|
6
|
+
* Render a slide's Markdown.
|
|
7
|
+
*
|
|
8
|
+
* A talk is written as prose, so raw HTML in the source is kept: a slide
|
|
9
|
+
* routinely holds a `<sub>`, a `<br>` or a figure the Markdown syntax cannot
|
|
10
|
+
* express. A link to an in-app route becomes a demo link; every other link
|
|
11
|
+
* leaves the deck in a tab of its own, so a click during a talk never loses the
|
|
12
|
+
* slide it was made from.
|
|
13
|
+
* @param props - See {@link SlideBodyProps}.
|
|
14
|
+
* @returns The rendered body.
|
|
15
|
+
*/
|
|
16
|
+
export function SlideBody(props) {
|
|
17
|
+
const { body, origin, renderLink } = props;
|
|
18
|
+
return (_jsx(Markdown, { rehypePlugins: [rehypeRaw], components: {
|
|
19
|
+
a({ href, children }) {
|
|
20
|
+
if (href?.startsWith('/') === true) {
|
|
21
|
+
return (_jsx(DemoLink, { href: href, origin: origin, renderLink: renderLink, children: children }));
|
|
22
|
+
}
|
|
23
|
+
return (_jsx("a", { href: href, target: "_blank", rel: "noreferrer", children: children }));
|
|
24
|
+
},
|
|
25
|
+
}, children: body }));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=SlideBody.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlideBody.js","sourceRoot":"","sources":["../../../src/slides/ui/SlideBody.tsx"],"names":[],"mappings":";AACA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,SAAS,MAAM,YAAY,CAAC;AAKnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAgB,CAAC;AAmB1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAE3C,OAAO,CACL,KAAC,QAAQ,IACP,aAAa,EAAE,CAAC,SAAS,CAAC,EAC1B,UAAU,EAAE;YACV,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAClB,IAAI,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;oBACnC,OAAO,CACL,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,YACzD,QAAQ,GACA,CACZ,CAAC;gBACJ,CAAC;gBACD,OAAO,CACL,YAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,YAAY,YAC5C,QAAQ,GACP,CACL,CAAC;YACJ,CAAC;SACF,YAEA,IAAI,GACI,CACZ,CAAC;AACJ,CAAC"}
|