@bytechain.cn/colamd 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/.github/workflows/release.yml +66 -0
  2. package/.trae/documents/fix-mermaid-colors-and-sankey.md +50 -0
  3. package/CLAUDE.md +87 -0
  4. package/LICENSE +21 -0
  5. package/README.md +540 -0
  6. package/README_CN.md +543 -0
  7. package/demo.md +486 -0
  8. package/dist/main/index.js +735 -0
  9. package/dist/preload/index.js +71 -0
  10. package/dist/renderer/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  11. package/dist/renderer/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  12. package/dist/renderer/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  13. package/dist/renderer/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  14. package/dist/renderer/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  15. package/dist/renderer/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  16. package/dist/renderer/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  17. package/dist/renderer/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  18. package/dist/renderer/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  19. package/dist/renderer/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  20. package/dist/renderer/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  21. package/dist/renderer/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  22. package/dist/renderer/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  23. package/dist/renderer/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  24. package/dist/renderer/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  25. package/dist/renderer/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  26. package/dist/renderer/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  27. package/dist/renderer/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  28. package/dist/renderer/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  29. package/dist/renderer/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  30. package/dist/renderer/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  31. package/dist/renderer/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  32. package/dist/renderer/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  33. package/dist/renderer/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  34. package/dist/renderer/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  35. package/dist/renderer/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  36. package/dist/renderer/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  37. package/dist/renderer/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  38. package/dist/renderer/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  39. package/dist/renderer/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  40. package/dist/renderer/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  41. package/dist/renderer/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  42. package/dist/renderer/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  43. package/dist/renderer/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  44. package/dist/renderer/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  45. package/dist/renderer/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  46. package/dist/renderer/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  47. package/dist/renderer/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  48. package/dist/renderer/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  49. package/dist/renderer/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  50. package/dist/renderer/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  51. package/dist/renderer/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  52. package/dist/renderer/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  53. package/dist/renderer/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  54. package/dist/renderer/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  55. package/dist/renderer/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  56. package/dist/renderer/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  57. package/dist/renderer/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  58. package/dist/renderer/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  59. package/dist/renderer/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  60. package/dist/renderer/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  61. package/dist/renderer/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  62. package/dist/renderer/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  63. package/dist/renderer/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  64. package/dist/renderer/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  65. package/dist/renderer/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  66. package/dist/renderer/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  67. package/dist/renderer/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  68. package/dist/renderer/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  69. package/dist/renderer/assets/arc-tTbbM8LO.js +131 -0
  70. package/dist/renderer/assets/architectureDiagram-3BPJPVTR-CEgYow6c.js +8720 -0
  71. package/dist/renderer/assets/blockDiagram-GPEHLZMM-LHyVtPwW.js +3825 -0
  72. package/dist/renderer/assets/c4Diagram-AAUBKEIU-C1P1eJrf.js +2482 -0
  73. package/dist/renderer/assets/channel-upve91Tq.js +7 -0
  74. package/dist/renderer/assets/chunk-2J33WTMH-lag2vhq9.js +24 -0
  75. package/dist/renderer/assets/chunk-4BX2VUAB-BXJ8Ggh-.js +16 -0
  76. package/dist/renderer/assets/chunk-55IACEB6-CiBpxRa1.js +13 -0
  77. package/dist/renderer/assets/chunk-727SXJPM-ODeKQFXC.js +2016 -0
  78. package/dist/renderer/assets/chunk-AQP2D5EJ-BK7xJolB.js +1953 -0
  79. package/dist/renderer/assets/chunk-FMBD7UC4-BxpCZPtz.js +19 -0
  80. package/dist/renderer/assets/chunk-ND2GUHAM-CqqaU9Ue.js +116 -0
  81. package/dist/renderer/assets/chunk-QZHKN3VN-Biq_K124.js +19 -0
  82. package/dist/renderer/assets/classDiagram-4FO5ZUOK-Cq95X99o.js +23 -0
  83. package/dist/renderer/assets/classDiagram-v2-Q7XG4LA2-Cq95X99o.js +23 -0
  84. package/dist/renderer/assets/cose-bilkent-S5V4N54A-XasiD0bu.js +4942 -0
  85. package/dist/renderer/assets/cytoscape.esm-CpHeHM5e.js +30269 -0
  86. package/dist/renderer/assets/dagre-BM42HDAG-Nq84Gfx4.js +705 -0
  87. package/dist/renderer/assets/defaultLocale-B2RvLBDe.js +206 -0
  88. package/dist/renderer/assets/diagram-2AECGRRQ-DwuB1GWt.js +301 -0
  89. package/dist/renderer/assets/diagram-5GNKFQAL-C2tgeI1h.js +169 -0
  90. package/dist/renderer/assets/diagram-KO2AKTUF-D5KzjNBc.js +632 -0
  91. package/dist/renderer/assets/diagram-LMA3HP47-C12xHS1c.js +212 -0
  92. package/dist/renderer/assets/diagram-OG6HWLK6-CnxI9oEa.js +851 -0
  93. package/dist/renderer/assets/erDiagram-TEJ5UH35-D_uPaKwn.js +1227 -0
  94. package/dist/renderer/assets/flowDiagram-I6XJVG4X-B6q_1-tE.js +2332 -0
  95. package/dist/renderer/assets/ganttDiagram-6RSMTGT7-CFo7ifF9.js +3720 -0
  96. package/dist/renderer/assets/gitGraphDiagram-PVQCEYII-WSexHTnq.js +1373 -0
  97. package/dist/renderer/assets/graph-DyX_9f6d.js +1988 -0
  98. package/dist/renderer/assets/index-DW7LS8C1.js +72292 -0
  99. package/dist/renderer/assets/index-dyHEFYvY.css +2184 -0
  100. package/dist/renderer/assets/infoDiagram-5YYISTIA-DaeJdLRq.js +31 -0
  101. package/dist/renderer/assets/init-ZxktEp_H.js +16 -0
  102. package/dist/renderer/assets/ishikawaDiagram-YF4QCWOH-DDCZc35f.js +967 -0
  103. package/dist/renderer/assets/journeyDiagram-JHISSGLW-BEdmpAgl.js +1255 -0
  104. package/dist/renderer/assets/kanban-definition-UN3LZRKU-BEFtQcFb.js +1052 -0
  105. package/dist/renderer/assets/layout-CAJgQHdw.js +2610 -0
  106. package/dist/renderer/assets/linear-B2ggJ8Am.js +340 -0
  107. package/dist/renderer/assets/mindmap-definition-RKZ34NQL-DSxVgHB5.js +1180 -0
  108. package/dist/renderer/assets/ordinal-DSZU4PqD.js +76 -0
  109. package/dist/renderer/assets/pieDiagram-4H26LBE5-CwYoJBuL.js +246 -0
  110. package/dist/renderer/assets/quadrantDiagram-W4KKPZXB-CST9Fvg9.js +1344 -0
  111. package/dist/renderer/assets/requirementDiagram-4Y6WPE33-DtrH52jS.js +1204 -0
  112. package/dist/renderer/assets/sankeyDiagram-5OEKKPKP-ca1tPzJ_.js +1274 -0
  113. package/dist/renderer/assets/sequenceDiagram-3UESZ5HK-Dfp1EJZ7.js +4514 -0
  114. package/dist/renderer/assets/stateDiagram-AJRCARHV-Bha2QoNB.js +450 -0
  115. package/dist/renderer/assets/stateDiagram-v2-BHNVJYJU-DWgFUYu1.js +21 -0
  116. package/dist/renderer/assets/timeline-definition-PNZ67QCA-C3h_-OTj.js +1596 -0
  117. package/dist/renderer/assets/vennDiagram-CIIHVFJN-DFzjSrZi.js +2486 -0
  118. package/dist/renderer/assets/wardley-L42UT6IY-Cx-VbqoS.js +30699 -0
  119. package/dist/renderer/assets/wardleyDiagram-YWT4CUSO-S2D9XqX6.js +975 -0
  120. package/dist/renderer/assets/xychartDiagram-2RQKCTM6-Cfxigbts.js +1932 -0
  121. package/dist/renderer/index.html +19 -0
  122. package/docs/agent-diff-view.md +48 -0
  123. package/electron-builder.yml +57 -0
  124. package/electron.vite.config.ts +30 -0
  125. package/package.json +40 -0
  126. package/resources/entitlements.mac.plist +12 -0
  127. package/resources/icon.icns +0 -0
  128. package/resources/icon.png +0 -0
  129. package/resources/icon.svg +23 -0
  130. package/resources/templates/slides/icon.png +0 -0
  131. package/resources/templates/slides/slides-template.md +74 -0
  132. package/resources/templates/slides/template.html +535 -0
  133. package/scripts/afterPack.js +13 -0
  134. package/src/main/index.ts +881 -0
  135. package/src/preload/index.ts +110 -0
  136. package/src/renderer/editor/editor.ts +204 -0
  137. package/src/renderer/editor/html-view.ts +15 -0
  138. package/src/renderer/editor/plugins/index.ts +76 -0
  139. package/src/renderer/editor/plugins/math-plugin.ts +297 -0
  140. package/src/renderer/editor/plugins/mermaid-plugin-custom.css +431 -0
  141. package/src/renderer/editor/plugins/mermaid-plugin-dark.css +428 -0
  142. package/src/renderer/editor/plugins/mermaid-plugin-elegant.css +443 -0
  143. package/src/renderer/editor/plugins/mermaid-plugin-newsprint.css +208 -0
  144. package/src/renderer/editor/plugins/mermaid-plugin.css +111 -0
  145. package/src/renderer/editor/plugins/mermaid-plugin.ts +679 -0
  146. package/src/renderer/env.d.ts +7 -0
  147. package/src/renderer/index.html +18 -0
  148. package/src/renderer/main.ts +303 -0
  149. package/src/renderer/themes/base.css +509 -0
  150. package/src/renderer/themes/theme-manager.ts +40 -0
  151. package/themes/README.md +280 -0
  152. package/themes/elegant.css +664 -0
  153. package/themes/guizang.css +732 -0
  154. package/tsconfig.json +14 -0
  155. package/tsconfig.main.json +11 -0
  156. package/tsconfig.preload.json +11 -0
  157. package/tsconfig.renderer.json +12 -0
@@ -0,0 +1,535 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6
+ <title>Slide Deck</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
8
+ <style>
9
+ :root {
10
+ --paper: #FFFCF8;
11
+ --ink: #1A1918;
12
+ --accent: #F1752D;
13
+ --accent-soft: rgba(241,117,45,0.1);
14
+ --gray-200: #E9E4DE;
15
+ --gray-500: #78716C;
16
+ --gray-600: #57534E;
17
+ --gray-900: #1A1918;
18
+ }
19
+
20
+ * { box-sizing: border-box; margin: 0; padding: 0; }
21
+
22
+ html, body {
23
+ width: 100%; height: 100%; overflow: hidden;
24
+ background:
25
+ radial-gradient(circle at 10% 12%, rgba(241,117,45,0.06) 0, rgba(241,117,45,0) 42%),
26
+ radial-gradient(circle at 88% 84%, rgba(223,116,54,0.06) 0, rgba(223,116,54,0) 40%),
27
+ var(--paper);
28
+ color: var(--ink);
29
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
30
+ -webkit-font-smoothing: antialiased;
31
+ touch-action: pan-y;
32
+ }
33
+
34
+ body::before {
35
+ content: ""; position: fixed; inset: 0;
36
+ background-image:
37
+ repeating-linear-gradient(0deg, rgba(26,25,24,0.012) 0, rgba(26,25,24,0.012) 1px, transparent 1px, transparent 4px),
38
+ repeating-linear-gradient(90deg, rgba(26,25,24,0.008) 0, rgba(26,25,24,0.008) 1px, transparent 1px, transparent 6px);
39
+ pointer-events: none; z-index: 1;
40
+ }
41
+
42
+ .viewport { position: relative; width: 100%; height: 100%; display: grid; place-items: center; padding: 18px; z-index: 2; }
43
+
44
+ .deck {
45
+ position: relative;
46
+ width: min(100vw - 36px, calc((100vh - 36px) * (16 / 9)));
47
+ aspect-ratio: 16 / 9;
48
+ border: 1px solid var(--gray-200); border-radius: 16px; overflow: hidden;
49
+ box-shadow: 0 24px 64px rgba(26,25,24,0.22), 0 8px 24px rgba(26,25,24,0.12), 0 2px 6px rgba(26,25,24,0.08);
50
+ background: linear-gradient(180deg, rgba(255,255,255,0.56), rgba(247,243,238,0.18));
51
+ isolation: isolate;
52
+ }
53
+
54
+ .slides { position: relative; width: 100%; height: 100%; }
55
+
56
+ .slide {
57
+ position: absolute; inset: 0;
58
+ display: grid; grid-template-columns: clamp(16px,1.5vw,26px) 1fr;
59
+ opacity: 0; transform: translateX(32px); pointer-events: none;
60
+ transition: opacity 340ms ease, transform 380ms ease;
61
+ }
62
+ .slide.active { opacity: 1; transform: translateX(0); pointer-events: auto; }
63
+
64
+ .axis-bar {
65
+ background: linear-gradient(180deg, var(--accent) 0 34%, rgba(241,117,45,0.12) 34% 100%);
66
+ box-shadow: inset -1px 0 rgba(26,25,24,0.1);
67
+ }
68
+
69
+ .slide-main {
70
+ position: relative;
71
+ padding: clamp(30px,4.2vw,82px);
72
+ display: grid; grid-template-rows: auto 1fr auto;
73
+ min-height: 0; gap: clamp(10px,1.3vw,20px);
74
+ }
75
+
76
+ .slide header {
77
+ display: flex; align-items: center; justify-content: space-between;
78
+ gap: 18px; min-height: 44px; padding-right: clamp(44px,4.2vw,76px);
79
+ }
80
+
81
+ .kicker {
82
+ font-weight: 600; letter-spacing: 0.06em;
83
+ font-size: clamp(13px,1.15vw,22px); text-transform: uppercase;
84
+ color: var(--accent); white-space: nowrap;
85
+ }
86
+ .top-line { flex: 1; height: 2px; background: linear-gradient(90deg, rgba(241,117,45,0.5), rgba(241,117,45,0)); }
87
+ .marker { color: rgba(241,117,45,0.6); font-size: clamp(12px,1vw,18px); }
88
+
89
+ .content {
90
+ min-height: 0; max-width: 94%;
91
+ display: grid; align-content: center;
92
+ gap: clamp(14px,1.7vw,28px); overflow: hidden;
93
+ padding-right: clamp(6px,0.8vw,12px);
94
+ }
95
+
96
+ h1, h2 {
97
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; line-height: 1.14;
98
+ letter-spacing: 0.01em; text-wrap: balance; max-width: 96%; color: var(--ink);
99
+ }
100
+ h1 { font-weight: 900; font-size: clamp(48px,5.6vw,108px); }
101
+ h2 { font-weight: 800; font-size: clamp(40px,4.4vw,82px); }
102
+
103
+ .md-block {
104
+ white-space: pre-wrap; word-break: break-word; text-wrap: pretty;
105
+ font-size: clamp(23px,2.1vw,44px); line-height: 1.45;
106
+ font-weight: 500; color: var(--gray-900);
107
+ }
108
+
109
+ .statement-only h2 { font-size: clamp(46px,5.2vw,96px); max-width: 98%; }
110
+
111
+ .cover-slide {
112
+ grid-template-columns: 1fr !important;
113
+ display: block !important;
114
+ }
115
+ .cover-slide .axis-bar { display: none; }
116
+ .cover-slide .slide-main {
117
+ width: 100%; height: 100%;
118
+ background: var(--paper);
119
+ background-size: cover; background-position: center; background-repeat: no-repeat;
120
+ padding: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
121
+ }
122
+ .cover-slide .slide-main header { display: none; }
123
+ .cover-slide .slide-main .content {
124
+ display: grid; place-items: center; gap: clamp(8px,1.2vw,18px);
125
+ text-align: center; max-width: 100%; padding: 0 20px;
126
+ flex: 1; align-self: stretch; display: flex; flex-direction: column; align-items: center; justify-content: center;
127
+ }
128
+ .cover-slide .slide-main .content h1 {
129
+ font-size: clamp(64px,7vw,130px); color: var(--accent); font-weight: 900;
130
+ text-shadow: 0 4px 24px rgba(241,117,45,0.25); letter-spacing: 0.01em;
131
+ }
132
+ .cover-slide .slide-main .content .md-block {
133
+ font-size: clamp(22px,2.4vw,44px); color: var(--gray-600);
134
+ font-weight: 500; text-shadow: none;
135
+ }
136
+ .cover-slide .slide-main footer {
137
+ border-top: 1px solid var(--gray-200); justify-content: center; padding-bottom: clamp(20px,2.5vw,40px);
138
+ }
139
+ .cover-slide .slide-main footer .chip { display: none; }
140
+ .cover-slide .slide-main footer .page {
141
+ color: var(--gray-500); font-size: clamp(12px,1vw,18px);
142
+ }
143
+
144
+ .video-slide .content { align-content: center; justify-items: center; }
145
+ .video-slide video {
146
+ width: min(92%, 960px); aspect-ratio: 16 / 9;
147
+ border-radius: 12px; background: #000;
148
+ box-shadow: 0 8px 32px rgba(0,0,0,0.18);
149
+ }
150
+
151
+ .thankyou h2 { font-size: clamp(52px,5.8vw,110px); color: var(--accent); }
152
+ .thankyou .md-block { font-size: clamp(26px,2.4vw,48px); color: var(--gray-600); }
153
+
154
+ footer {
155
+ display: flex; align-items: center; justify-content: space-between;
156
+ gap: 14px; border-top: 1px solid var(--gray-200);
157
+ padding-top: clamp(10px,1.2vw,16px); padding-right: clamp(20px,2vw,40px);
158
+ }
159
+
160
+ .chip {
161
+ font-weight: 600; font-size: clamp(11px,0.95vw,17px);
162
+ letter-spacing: 0.06em; text-transform: uppercase;
163
+ color: var(--accent); background: var(--accent-soft);
164
+ border: 1px solid rgba(241,117,45,0.2); border-radius: 999px; padding: 7px 12px;
165
+ }
166
+ .page {
167
+ font-weight: 600; font-size: clamp(13px,1.1vw,20px);
168
+ color: var(--gray-500); letter-spacing: 0.06em;
169
+ }
170
+
171
+ .hint {
172
+ position: fixed; left: 50%; bottom: max(16px, env(safe-area-inset-bottom));
173
+ transform: translateX(-50%); z-index: 3; font-size: 12px;
174
+ color: var(--gray-500); background: rgba(255,252,248,0.84);
175
+ border: 1px solid var(--gray-200); border-radius: 999px;
176
+ padding: 6px 10px; backdrop-filter: blur(4px);
177
+ }
178
+
179
+ .launch-layer {
180
+ position: fixed; inset: 0; z-index: 4; display: grid; place-items: center; padding: 20px;
181
+ background: rgba(26,25,24,0.48); backdrop-filter: blur(3px);
182
+ opacity: 1; transition: opacity 220ms ease;
183
+ }
184
+ .launch-layer.hidden { opacity: 0; pointer-events: none; }
185
+
186
+ .launch-btn {
187
+ border: 1px solid var(--gray-200);
188
+ background: linear-gradient(180deg, rgba(255,252,248,0.97), rgba(247,243,238,0.9));
189
+ color: var(--ink); border-radius: 16px;
190
+ padding: clamp(16px,2.2vw,24px) clamp(20px,2.8vw,32px);
191
+ min-width: min(88vw, 560px); display: grid; gap: 10px; text-align: left;
192
+ box-shadow: 0 20px 52px rgba(0,0,0,0.28); cursor: pointer;
193
+ }
194
+ .launch-title {
195
+ font-size: clamp(28px,3.2vw,48px);
196
+ font-weight: 700; line-height: 1.12; display: inline-flex; align-items: center; gap: 10px;
197
+ }
198
+ .launch-sub { font-size: clamp(14px,1.2vw,20px); color: var(--gray-600); line-height: 1.4; font-weight: 500; }
199
+
200
+ .slide-preview {
201
+ margin-top: 8px; max-width: clamp(180px,22vw,360px);
202
+ border-radius: 8px; overflow: hidden;
203
+ box-shadow: 0 4px 16px rgba(0,0,0,0.12); border: 1px solid var(--gray-200);
204
+ }
205
+ .slide-preview img { width: 100%; height: auto; display: block; }
206
+
207
+ @keyframes fadeUp {
208
+ from { opacity: 0; transform: translateY(12px); }
209
+ to { opacity: 1; transform: translateY(0); }
210
+ }
211
+ .slide.active h1, .slide.active h2, .slide.active .md-block { animation: fadeUp 320ms ease both; }
212
+ .slide.active .md-block:nth-of-type(2) { animation-delay: 60ms; }
213
+ .slide.active .md-block:nth-of-type(3) { animation-delay: 120ms; }
214
+
215
+ @media (max-width: 900px) {
216
+ .viewport { padding: 10px; }
217
+ .deck { width: calc(100vw - 20px); }
218
+ .slide { grid-template-columns: 10px 1fr; }
219
+ .slide-main { padding: clamp(16px,4.4vw,28px); gap: 8px; }
220
+ h1 { font-size: clamp(34px,7.2vw,56px); }
221
+ h2 { font-size: clamp(30px,6vw,52px); }
222
+ .md-block { font-size: clamp(16px,3.2vw,24px); }
223
+ .cover-slide h1 { font-size: clamp(32px,6.5vw,52px); }
224
+ }
225
+ </style>
226
+ </head>
227
+ <body>
228
+ <div class="viewport">
229
+ <main class="deck">
230
+ <section class="slides" id="slides"></section>
231
+ </main>
232
+ </div>
233
+
234
+ <div class="launch-layer" id="launchLayer">
235
+ <button class="launch-btn" id="launchBtn" type="button">
236
+ <span class="launch-title">
237
+ <i class="fa-solid fa-expand" aria-hidden="true"></i>
238
+ <span id="launchTitle">开始演示(全屏)</span>
239
+ </span>
240
+ <span class="launch-sub">按 F 切换全屏 · ← → 翻页 · 点击左右翻页</span>
241
+ </button>
242
+ </div>
243
+
244
+ <div class="hint">← → / Space / 点击左右 / 滑动</div>
245
+
246
+ <script>
247
+ (function () {
248
+ // ─── Markdown parser ───────────────────────────────────────────────────────
249
+
250
+ function parseFrontmatter(text) {
251
+ const meta = {};
252
+ const match = text.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
253
+ if (!match) return { meta, body: text };
254
+ match[1].split('\n').forEach(line => {
255
+ const [k, ...v] = line.split(':');
256
+ if (k && v.length) meta[k.trim()] = v.join(':').trim();
257
+ });
258
+ return { meta, body: match[2] };
259
+ }
260
+
261
+ function parseDirective(line) {
262
+ // <!-- type: cover, bg: cover-v2.png -->
263
+ const match = line.match(/<!--\s*(.*?)\s*-->/);
264
+ if (!match) return {};
265
+ const result = {};
266
+ match[1].split(',').forEach(pair => {
267
+ const [k, ...v] = pair.split(':');
268
+ if (k) result[k.trim()] = v.join(':').trim();
269
+ });
270
+ return result;
271
+ }
272
+
273
+ function parseSlides(body) {
274
+ // Strip multi-line HTML comments before splitting into slides
275
+ const stripped = body.replace(/<!--[\s\S]*?-->/g, '');
276
+ return stripped.split(/\n---\n/).map(raw => {
277
+ const lines = raw.trim().split('\n');
278
+ const slide = { type: 'section', title: '', blocks: [] };
279
+
280
+ // Check first line for directive comment (single-line only, already stripped above)
281
+ if (lines[0] && lines[0].trim().startsWith('<!--')) {
282
+ Object.assign(slide, parseDirective(lines.shift()));
283
+ }
284
+
285
+ lines.forEach(line => {
286
+ if (line.startsWith('# ')) {
287
+ slide.title = line.slice(2).trim();
288
+ if (!slide.type || slide.type === 'section') slide.type = 'cover';
289
+ } else if (line.startsWith('## ')) {
290
+ slide.title = line.slice(3).trim();
291
+ } else if (line.trim()) {
292
+ slide.blocks.push(line.trim());
293
+ }
294
+ });
295
+
296
+ slide.blocks = mergeBlocks(raw, slide);
297
+
298
+ return slide;
299
+ }).filter(s => s.type || s.title || s.blocks.length);
300
+ }
301
+
302
+ // Re-parse blocks respecting blank-line paragraph breaks
303
+ // Blocks can be text strings or {type:'image', src, alt} objects
304
+ function mergeBlocks(raw, slide) {
305
+ const stripped = raw.replace(/<!--[\s\S]*?-->/g, '');
306
+ const lines = stripped.trim().split('\n');
307
+ const blocks = [];
308
+ let current = [];
309
+
310
+ function flushText() {
311
+ if (current.length) { blocks.push(current.join('\n')); current = []; }
312
+ }
313
+
314
+ lines.forEach(line => {
315
+ if (line.startsWith('#')) return;
316
+ const imgMatch = line.trim().match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
317
+ if (imgMatch) {
318
+ flushText();
319
+ blocks.push({ type: 'image', alt: imgMatch[1], src: imgMatch[2] });
320
+ return;
321
+ }
322
+ if (line.trim() === '') {
323
+ flushText();
324
+ } else {
325
+ current.push(line.trim());
326
+ }
327
+ });
328
+ flushText();
329
+ return blocks;
330
+ }
331
+
332
+ // ─── Render ────────────────────────────────────────────────────────────────
333
+
334
+ function buildDeck(slides, meta) {
335
+ const slidesEl = document.getElementById('slides');
336
+ const kicker = meta.kicker || '';
337
+ const chip = meta.chip || '';
338
+ const page = meta.page || '';
339
+
340
+ // Set launch title from first slide
341
+ const firstTitle = slides[0] && slides[0].title;
342
+ if (firstTitle) document.getElementById('launchTitle').textContent = firstTitle + '(全屏)';
343
+ document.title = firstTitle || 'Slide Deck';
344
+
345
+ slides.forEach((item, idx) => {
346
+ const article = document.createElement('article');
347
+ const classes = ['slide'];
348
+ if (idx === 0) classes.push('active');
349
+ if (item.type === 'cover') classes.push('cover-slide');
350
+ if (item.type === 'statement') classes.push('statement-only');
351
+ if (item.type === 'video') classes.push('video-slide');
352
+ if (item.type === 'thankyou') classes.push('thankyou');
353
+ article.className = classes.join(' ');
354
+ article.dataset.index = String(idx);
355
+
356
+ const axis = document.createElement('div');
357
+ axis.className = 'axis-bar';
358
+
359
+ const main = document.createElement('div');
360
+ main.className = 'slide-main';
361
+
362
+ if (item.type === 'cover') {
363
+ if (item.bg) {
364
+ main.style.background = `linear-gradient(rgba(0,0,0,0.38), rgba(0,0,0,0.52)), url('${item.bg}') center/cover no-repeat`;
365
+ }
366
+ }
367
+
368
+ // Header
369
+ const header = document.createElement('header');
370
+ const kickerEl = document.createElement('span');
371
+ kickerEl.className = 'kicker';
372
+ kickerEl.textContent = idx === 0 ? (meta.kicker || '') : kicker;
373
+ const line = document.createElement('span');
374
+ line.className = 'top-line';
375
+ const marker = document.createElement('span');
376
+ marker.className = 'marker';
377
+ marker.innerHTML = '<i class="fa-solid fa-plus"></i>';
378
+ header.append(kickerEl, line, marker);
379
+
380
+ // Content
381
+ const content = document.createElement('div');
382
+ content.className = 'content';
383
+
384
+ if (item.title) {
385
+ const heading = document.createElement(idx === 0 ? 'h1' : 'h2');
386
+ heading.textContent = item.title;
387
+ content.appendChild(heading);
388
+ }
389
+
390
+ item.blocks.forEach(block => {
391
+ if (block && typeof block === 'object' && block.type === 'image') {
392
+ const wrap = document.createElement('div');
393
+ wrap.className = 'slide-preview';
394
+ const img = document.createElement('img');
395
+ img.src = block.src;
396
+ if (block.alt) img.alt = block.alt;
397
+ wrap.appendChild(img);
398
+ content.appendChild(wrap);
399
+ } else {
400
+ const p = document.createElement('p');
401
+ p.className = 'md-block';
402
+ p.textContent = block;
403
+ content.appendChild(p);
404
+ }
405
+ });
406
+
407
+ if (item.src) {
408
+ const video = document.createElement('video');
409
+ video.src = item.src;
410
+ video.controls = true;
411
+ video.playsInline = true;
412
+ video.preload = 'metadata';
413
+ content.appendChild(video);
414
+ }
415
+
416
+ if (item.preview) {
417
+ const wrap = document.createElement('div');
418
+ wrap.className = 'slide-preview';
419
+ const img = document.createElement('img');
420
+ img.src = item.preview;
421
+ wrap.appendChild(img);
422
+ content.appendChild(wrap);
423
+ }
424
+
425
+ // Footer
426
+ const footer = document.createElement('footer');
427
+ const chipEl = document.createElement('span');
428
+ chipEl.className = 'chip';
429
+ chipEl.textContent = chip;
430
+ const pageEl = document.createElement('span');
431
+ pageEl.className = 'page';
432
+ pageEl.textContent = idx === 0 ? (meta.coverPage || page) : page;
433
+ footer.append(chipEl, pageEl);
434
+
435
+ main.append(header, content, footer);
436
+ article.append(axis, main);
437
+ slidesEl.appendChild(article);
438
+ });
439
+ }
440
+
441
+ // ─── Navigation ────────────────────────────────────────────────────────────
442
+
443
+ function initNav() {
444
+ const slides = Array.from(document.querySelectorAll('.slide'));
445
+ const launchLayer = document.getElementById('launchLayer');
446
+ const launchBtn = document.getElementById('launchBtn');
447
+ let index = 0;
448
+ let touchStartX = 0;
449
+
450
+ function render(next) {
451
+ index = Math.max(0, Math.min(slides.length - 1, next));
452
+ slides.forEach((s, i) => {
453
+ s.classList.toggle('active', i === index);
454
+ if (i !== index) {
455
+ const v = s.querySelector('video');
456
+ if (v && !v.paused) v.pause();
457
+ }
458
+ });
459
+ }
460
+
461
+ function getFS() { return document.fullscreenElement || document.webkitFullscreenElement || null; }
462
+ async function reqFS() {
463
+ if (getFS()) return;
464
+ const r = document.documentElement;
465
+ const fn = r.requestFullscreen || r.webkitRequestFullscreen;
466
+ if (fn) try { await fn.call(r); } catch(e) {}
467
+ }
468
+ async function toggleFS() {
469
+ if (getFS()) {
470
+ const fn = document.exitFullscreen || document.webkitExitFullscreen;
471
+ if (fn) try { await fn.call(document); } catch(e) {}
472
+ } else { await reqFS(); }
473
+ }
474
+ function hideLL() {
475
+ if (!launchLayer || launchLayer.classList.contains('hidden')) return;
476
+ launchLayer.classList.add('hidden');
477
+ setTimeout(() => { if (launchLayer.parentNode) launchLayer.parentNode.removeChild(launchLayer); }, 240);
478
+ }
479
+ async function startPres(e) {
480
+ if (e) { e.preventDefault(); e.stopPropagation(); }
481
+ await reqFS(); hideLL();
482
+ }
483
+
484
+ window.addEventListener('keydown', e => {
485
+ if (e.key === 'Enter' && launchLayer && !launchLayer.classList.contains('hidden')) { startPres(e); return; }
486
+ if (e.key === 'f' || e.key === 'F') { e.preventDefault(); toggleFS(); return; }
487
+ if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { e.preventDefault(); render(index + 1); }
488
+ if (e.key === 'ArrowLeft' || e.key === 'PageUp') { e.preventDefault(); render(index - 1); }
489
+ if (e.key === 'Home') { e.preventDefault(); render(0); }
490
+ if (e.key === 'End') { e.preventDefault(); render(slides.length - 1); }
491
+ });
492
+
493
+ document.addEventListener('click', e => {
494
+ if (launchLayer && !launchLayer.classList.contains('hidden')) return;
495
+ if (e.target.closest('video')) return;
496
+ e.clientX > window.innerWidth * 0.5 ? render(index + 1) : render(index - 1);
497
+ });
498
+
499
+ document.addEventListener('touchstart', e => {
500
+ if (e.changedTouches.length) touchStartX = e.changedTouches[0].clientX;
501
+ }, { passive: true });
502
+
503
+ document.addEventListener('touchend', e => {
504
+ if (launchLayer && !launchLayer.classList.contains('hidden')) return;
505
+ if (!e.changedTouches.length) return;
506
+ const d = e.changedTouches[0].clientX - touchStartX;
507
+ if (Math.abs(d) < 30) return;
508
+ d < 0 ? render(index + 1) : render(index - 1);
509
+ }, { passive: true });
510
+
511
+ if (launchBtn) launchBtn.addEventListener('click', e => startPres(e));
512
+ if (launchLayer) launchLayer.addEventListener('click', e => { if (e.target === launchLayer) startPres(e); });
513
+
514
+ render(0);
515
+ }
516
+
517
+ // ─── Boot: fetch slides.md ──────────────────────────────────────────────────
518
+
519
+ fetch('slides.md')
520
+ .then(r => r.text())
521
+ .then(text => {
522
+ const { meta, body } = parseFrontmatter(text);
523
+ const slides = parseSlides(body);
524
+ buildDeck(slides, meta);
525
+ initNav();
526
+ })
527
+ .catch(err => {
528
+ document.body.innerHTML = `<div style="padding:40px;font-family:monospace;color:red">
529
+ Failed to load slides.md<br>${err.message}
530
+ </div>`;
531
+ });
532
+ })();
533
+ </script>
534
+ </body>
535
+ </html>
@@ -0,0 +1,13 @@
1
+ const { execSync } = require('child_process')
2
+ const path = require('path')
3
+
4
+ exports.default = async function (context) {
5
+ if (process.platform !== 'darwin') return
6
+
7
+ const appPath = path.join(context.appOutDir, `${context.packager.appInfo.productFilename}.app`)
8
+ console.log(`Cleaning extended attributes and resource forks from ${appPath}`)
9
+ // Remove extended attributes
10
+ execSync(`xattr -cr "${appPath}"`)
11
+ // Remove HFS+ resource forks that xattr -cr doesn't handle
12
+ execSync(`find "${appPath}" -type f -exec sh -c 'cat /dev/null > "$1/..namedfork/rsrc" 2>/dev/null; true' _ {} \\;`)
13
+ }