@m1kapp/kit 0.0.22 → 0.0.24

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/bin/m1kkit.mjs CHANGED
@@ -5,6 +5,7 @@
5
5
  * Commands:
6
6
  * m1kkit favicon — 파비콘 생성
7
7
  * m1kkit skills — Claude Code 스킬 설치
8
+ * m1kkit stats — 코드 분석 & kit 사용 현황 생성
8
9
  */
9
10
 
10
11
  const [,, command, ...rest] = process.argv;
@@ -16,6 +17,7 @@ m1kkit — @m1kapp/kit CLI
16
17
  Commands:
17
18
  m1kkit favicon [options] 파비콘 자동 생성
18
19
  m1kkit skills [options] Claude Code 스킬 설치
20
+ m1kkit stats [options] 코드 분석 & kit 사용 현황 생성
19
21
 
20
22
  Options:
21
23
  --help 도움말 보기
@@ -25,6 +27,7 @@ Examples:
25
27
  m1kkit skills
26
28
  m1kkit skills --list
27
29
  m1kkit skills m1kapp-init
30
+ m1kkit stats --dir=src --out=public
28
31
  `);
29
32
  process.exit(0);
30
33
  }
@@ -42,6 +45,9 @@ if (command === "favicon") {
42
45
  } else if (command === "skills") {
43
46
  process.argv = [process.argv[0], process.argv[1], ...rest];
44
47
  await import(path.join(__dirname, "skills.mjs"));
48
+ } else if (command === "stats") {
49
+ process.argv = [process.argv[0], process.argv[1], ...rest];
50
+ await import(path.join(__dirname, "stats.mjs"));
45
51
  } else {
46
52
  console.error(`알 수 없는 커맨드: ${command}`);
47
53
  console.error("사용법: m1kkit --help");
package/bin/stats.mjs ADDED
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * m1kkit stats — 프로젝트의 코드량과 kit 사용 현황을 분석해서 .kit-stats.json 생성
4
+ *
5
+ * Usage:
6
+ * m1kkit stats # src/ 기준 분석
7
+ * m1kkit stats --dir=app # 특정 디렉토리 기준
8
+ * m1kkit stats --out=public # 출력 위치 지정
9
+ */
10
+
11
+ import fs from "fs";
12
+ import path from "path";
13
+ import { createRequire } from "module";
14
+
15
+ const args = process.argv.slice(2);
16
+ const getFlag = (name) => {
17
+ const found = args.find((a) => a.startsWith(`--${name}=`));
18
+ return found ? found.split("=")[1] : undefined;
19
+ };
20
+
21
+ const srcDir = path.resolve(process.cwd(), getFlag("dir") || "src");
22
+ const outDir = path.resolve(process.cwd(), getFlag("out") || "public");
23
+
24
+ // kit의 meta.json에서 실제 측정된 LOC 로드
25
+ let KIT_FEATURES = {};
26
+ let kitVersion = "unknown";
27
+ let kitTotalFeatures = { component: 0, hook: 0, util: 0 };
28
+
29
+ // meta.json 탐색: require.resolve → node_modules 직접 탐색 → 상위 디렉토리
30
+ function findMeta() {
31
+ // 1. require.resolve
32
+ try {
33
+ const require = createRequire(path.resolve(process.cwd(), "package.json"));
34
+ return require.resolve("@m1kapp/kit/dist/meta.json");
35
+ } catch {}
36
+
37
+ // 2. node_modules에서 직접 탐색
38
+ let dir = process.cwd();
39
+ while (dir !== path.dirname(dir)) {
40
+ const candidate = path.join(dir, "node_modules", "@m1kapp", "kit", "dist", "meta.json");
41
+ if (fs.existsSync(candidate)) return candidate;
42
+ dir = path.dirname(dir);
43
+ }
44
+
45
+ // 3. 이 스크립트가 kit 안에 있으면 형제 dist/ 탐색
46
+ const scriptDir = path.dirname(new URL(import.meta.url).pathname);
47
+ const siblingMeta = path.join(scriptDir, "..", "dist", "meta.json");
48
+ if (fs.existsSync(siblingMeta)) return siblingMeta;
49
+
50
+ return null;
51
+ }
52
+
53
+ const metaPath = findMeta();
54
+ if (!metaPath) {
55
+ console.error(" @m1kapp/kit/dist/meta.json을 찾을 수 없습니다.");
56
+ console.error(" kit을 먼저 빌드하거나 npm install 후 다시 시도하세요.\n");
57
+ process.exit(1);
58
+ }
59
+
60
+ const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8"));
61
+ KIT_FEATURES = meta.features;
62
+ kitVersion = meta.version;
63
+
64
+ // kit이 제공하는 전체 요소 수 카운트
65
+ for (const f of Object.values(meta.features)) {
66
+ kitTotalFeatures[f.category] = (kitTotalFeatures[f.category] || 0) + 1;
67
+ }
68
+
69
+ console.log(` meta.json 로드 완료 (v${kitVersion}, ${Object.keys(KIT_FEATURES).length}개 요소)\n`);
70
+
71
+ // 소스 파일 수집
72
+ function collectFiles(dir, exts = [".ts", ".tsx", ".js", ".jsx"]) {
73
+ const results = [];
74
+ if (!fs.existsSync(dir)) return results;
75
+
76
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
77
+ for (const entry of entries) {
78
+ const fullPath = path.join(dir, entry.name);
79
+ if (entry.isDirectory()) {
80
+ if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist") continue;
81
+ results.push(...collectFiles(fullPath, exts));
82
+ } else if (exts.some((ext) => entry.name.endsWith(ext))) {
83
+ results.push(fullPath);
84
+ }
85
+ }
86
+ return results;
87
+ }
88
+
89
+ // 줄 수 카운트 (빈 줄, 주석만 있는 줄 제외)
90
+ function countLines(content) {
91
+ const lines = content.split("\n");
92
+ let total = 0;
93
+ let code = 0;
94
+ for (const line of lines) {
95
+ total++;
96
+ const trimmed = line.trim();
97
+ if (trimmed && !trimmed.startsWith("//") && !trimmed.startsWith("*") && !trimmed.startsWith("/*")) {
98
+ code++;
99
+ }
100
+ }
101
+ return { total, code };
102
+ }
103
+
104
+ // kit import 감지
105
+ function detectKitImports(content) {
106
+ const found = new Set();
107
+ // import { X, Y } from "@m1kapp/kit" 또는 "@m1kapp/kit/..." 패턴
108
+ const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']@m1kapp\/kit(?:\/[^"']*)?["']/g;
109
+ let match;
110
+ while ((match = importRegex.exec(content)) !== null) {
111
+ const names = match[1].split(",").map((s) => s.trim().split(" as ")[0].trim());
112
+ for (const name of names) {
113
+ if (name && !name.startsWith("type ")) {
114
+ found.add(name);
115
+ }
116
+ }
117
+ }
118
+ // import type은 제외 — 타입만 쓰는 건 코드 절약 아님
119
+ return found;
120
+ }
121
+
122
+ // 실행
123
+ console.log(`\n 분석 중... ${srcDir}\n`);
124
+
125
+ const files = collectFiles(srcDir);
126
+ if (files.length === 0) {
127
+ console.error(` 파일을 찾을 수 없습니다: ${srcDir}`);
128
+ process.exit(1);
129
+ }
130
+
131
+ let totalLines = 0;
132
+ let codeLines = 0;
133
+ const allImports = new Set();
134
+
135
+ for (const file of files) {
136
+ const content = fs.readFileSync(file, "utf-8");
137
+ const counts = countLines(content);
138
+ totalLines += counts.total;
139
+ codeLines += counts.code;
140
+ const imports = detectKitImports(content);
141
+ for (const imp of imports) allImports.add(imp);
142
+ }
143
+
144
+ // 절약량 계산
145
+ // 같은 소스 파일에서 여러 export를 쓰더라도 파일 LOC는 한 번만 카운트
146
+ const usedFeatures = [];
147
+ let savedLines = 0;
148
+ const usedByCategory = { component: 0, hook: 0, util: 0 };
149
+ const countedSources = new Set();
150
+
151
+ for (const name of allImports) {
152
+ const meta = KIT_FEATURES[name];
153
+ if (!meta) continue;
154
+
155
+ // 카테고리별 사용 수 (loc 0이어도 카운트 — "Tab"도 사용한 거니까)
156
+ usedByCategory[meta.category] = (usedByCategory[meta.category] || 0) + 1;
157
+
158
+ // LOC 절약은 소스 파일 단위로 1번만
159
+ if (meta.source && countedSources.has(meta.source)) continue;
160
+ if (meta.source) countedSources.add(meta.source);
161
+
162
+ if (meta.loc > 0) {
163
+ usedFeatures.push({ name, loc: meta.loc, category: meta.category });
164
+ savedLines += meta.loc;
165
+ }
166
+ }
167
+
168
+ const estimatedKB = Math.round(savedLines * 40 / 1024);
169
+ const estimatedA4 = Math.round(savedLines / 80);
170
+ const savedPercent = codeLines > 0 ? Math.round((savedLines / (codeLines + savedLines)) * 100) : 0;
171
+
172
+ // 사용률: kit이 제공하는 전체 요소 중 몇 개를 쓰고 있는지
173
+ const usage = {
174
+ component: { used: usedByCategory.component, total: kitTotalFeatures.component, percent: kitTotalFeatures.component > 0 ? Math.round((usedByCategory.component / kitTotalFeatures.component) * 100) : 0 },
175
+ hook: { used: usedByCategory.hook, total: kitTotalFeatures.hook, percent: kitTotalFeatures.hook > 0 ? Math.round((usedByCategory.hook / kitTotalFeatures.hook) * 100) : 0 },
176
+ util: { used: usedByCategory.util, total: kitTotalFeatures.util, percent: kitTotalFeatures.util > 0 ? Math.round((usedByCategory.util / kitTotalFeatures.util) * 100) : 0 },
177
+ };
178
+
179
+ const stats = {
180
+ generatedAt: new Date().toISOString(),
181
+ kitVersion,
182
+ source: {
183
+ dir: path.relative(process.cwd(), srcDir),
184
+ files: files.length,
185
+ totalLines,
186
+ codeLines,
187
+ },
188
+ kit: {
189
+ features: usedFeatures.sort((a, b) => b.loc - a.loc),
190
+ savedLines,
191
+ savedKB: estimatedKB,
192
+ savedA4: estimatedA4,
193
+ savedPercent,
194
+ usage,
195
+ },
196
+ };
197
+
198
+ // 출력
199
+ if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });
200
+ const outPath = path.join(outDir, "kit-stats.json");
201
+ fs.writeFileSync(outPath, JSON.stringify(stats, null, 2));
202
+
203
+ console.log(` 파일: ${files.length}개`);
204
+ console.log(` 코드: ${codeLines.toLocaleString()}줄 (전체 ${totalLines.toLocaleString()}줄)`);
205
+ console.log(` kit 사용: ${usedFeatures.length}개 요소`);
206
+ console.log(` 컴포넌트: ${usage.component.used}/${usage.component.total}개 (${usage.component.percent}%)`);
207
+ console.log(` 훅: ${usage.hook.used}/${usage.hook.total}개 (${usage.hook.percent}%)`);
208
+ console.log(` 유틸리티: ${usage.util.used}/${usage.util.total}개 (${usage.util.percent}%)`);
209
+ console.log(` 절약량: 약 ${savedLines.toLocaleString()}줄, ${estimatedKB}KB (A4 ${estimatedA4}장)`);
210
+ console.log(` 비율: 전체의 약 ${savedPercent}%를 kit이 대신 처리`);
211
+ console.log(`\n 저장됨 → ${path.relative(process.cwd(), outPath)}\n`);
package/dist/index.d.mts CHANGED
@@ -197,6 +197,11 @@ interface WatermarkProps {
197
197
  * <Watermark speed={60} /> // very slow
198
198
  */
199
199
  speed?: number;
200
+ /**
201
+ * Hide the "powered by @m1kapp/kit" badge at the bottom.
202
+ * Default: false (badge is shown)
203
+ */
204
+ hidePoweredBy?: boolean;
200
205
  }
201
206
  /**
202
207
  * Full-screen colored background with repeating animated text watermark pattern.
@@ -204,7 +209,7 @@ interface WatermarkProps {
204
209
  * Renders as a single SVG element with a <pattern> — zero extra DOM nodes per tile.
205
210
  * Sponsor tiles inside the pattern are clickable and support hover effects.
206
211
  */
207
- declare function Watermark({ children, color, text, maxWidth, sponsor, speed, }: WatermarkProps): react_jsx_runtime.JSX.Element;
212
+ declare function Watermark({ children, color, text, maxWidth, sponsor, speed, hidePoweredBy, }: WatermarkProps): react_jsx_runtime.JSX.Element;
208
213
 
209
214
  declare const colors: {
210
215
  readonly blue: "#3b82f6";
@@ -421,6 +426,10 @@ interface GrassMapLabels {
421
426
  less?: string;
422
427
  more?: string;
423
428
  first?: string;
429
+ /** binary 모드 범례 라벨. Default: "완료" */
430
+ done?: string;
431
+ /** binary 모드 범례 라벨. Default: "미완료" */
432
+ notDone?: string;
424
433
  }
425
434
  interface GrassMapProps {
426
435
  data: GrassMapData[];
@@ -428,10 +437,12 @@ interface GrassMapProps {
428
437
  isDark?: boolean;
429
438
  /** Unit label appended to count in tooltip. e.g. "명", "commits". Default: "" */
430
439
  unit?: string;
440
+ /** true면 count > 0을 모두 동일한 accent 색으로 표시 (했다/안했다 2색) */
441
+ binary?: boolean;
431
442
  /** Override default Korean labels for i18n */
432
443
  labels?: GrassMapLabels;
433
444
  }
434
- declare function GrassMap({ data, accent, isDark, unit, labels: _labels }: GrassMapProps): react_jsx_runtime.JSX.Element;
445
+ declare function GrassMap({ data, accent, isDark, unit, binary, labels: _labels }: GrassMapProps): react_jsx_runtime.JSX.Element;
435
446
 
436
447
  type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
437
448
  type AvatarShape = "circle" | "rounded";
@@ -652,6 +663,24 @@ interface InAppSheetProps {
652
663
  }
653
664
  declare function InAppSheet({ open, onClose, children, className, title, fullHeight, hideClose, closeLabel, }: InAppSheetProps): react_jsx_runtime.JSX.Element;
654
665
 
666
+ interface PoweredByKitProps {
667
+ /** Path to kit-stats.json. Default: "/kit-stats.json" */
668
+ statsUrl?: string;
669
+ /** Override version string */
670
+ version?: string;
671
+ /** "default" for inside AppShell, "overlay" for on top of Watermark background */
672
+ variant?: "default" | "overlay";
673
+ className?: string;
674
+ }
675
+ /**
676
+ * "Powered by @m1kapp/kit" badge + credits sheet.
677
+ * Place outside AppShell, in the Watermark padding area.
678
+ *
679
+ * Fetches /kit-stats.json (generated by `m1kkit stats`) on first open
680
+ * to show real code analysis results.
681
+ */
682
+ declare function PoweredByKit({ statsUrl, version, variant, className }: PoweredByKitProps): react_jsx_runtime.JSX.Element;
683
+
655
684
  type PWAInstallState = "android-ready" | "ios-safari" | "installed" | "unsupported";
656
685
  interface UsePWAInstallReturn {
657
686
  state: PWAInstallState;
@@ -865,4 +894,4 @@ declare function formatPrice(amount: number, currency?: string, locale?: string)
865
894
 
866
895
  declare function cn(...inputs: ClassValue[]): string;
867
896
 
868
- export { type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, type ColorName, Dialog, type DialogProps, Divider, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, InAppSheet, type InAppSheetProps, KitStyles, PWAInstallButton, type PWAInstallState, Section, SectionHeader, type SectionHeaderProps, type SectionProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fontFamily, fonts, formatNumber, formatPrice, mobileViewport, relativeTime, svgIcon, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
897
+ export { type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, type ColorName, Dialog, type DialogProps, Divider, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, InAppSheet, type InAppSheetProps, KitStyles, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fontFamily, fonts, formatNumber, formatPrice, mobileViewport, relativeTime, svgIcon, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
package/dist/index.d.ts CHANGED
@@ -197,6 +197,11 @@ interface WatermarkProps {
197
197
  * <Watermark speed={60} /> // very slow
198
198
  */
199
199
  speed?: number;
200
+ /**
201
+ * Hide the "powered by @m1kapp/kit" badge at the bottom.
202
+ * Default: false (badge is shown)
203
+ */
204
+ hidePoweredBy?: boolean;
200
205
  }
201
206
  /**
202
207
  * Full-screen colored background with repeating animated text watermark pattern.
@@ -204,7 +209,7 @@ interface WatermarkProps {
204
209
  * Renders as a single SVG element with a <pattern> — zero extra DOM nodes per tile.
205
210
  * Sponsor tiles inside the pattern are clickable and support hover effects.
206
211
  */
207
- declare function Watermark({ children, color, text, maxWidth, sponsor, speed, }: WatermarkProps): react_jsx_runtime.JSX.Element;
212
+ declare function Watermark({ children, color, text, maxWidth, sponsor, speed, hidePoweredBy, }: WatermarkProps): react_jsx_runtime.JSX.Element;
208
213
 
209
214
  declare const colors: {
210
215
  readonly blue: "#3b82f6";
@@ -421,6 +426,10 @@ interface GrassMapLabels {
421
426
  less?: string;
422
427
  more?: string;
423
428
  first?: string;
429
+ /** binary 모드 범례 라벨. Default: "완료" */
430
+ done?: string;
431
+ /** binary 모드 범례 라벨. Default: "미완료" */
432
+ notDone?: string;
424
433
  }
425
434
  interface GrassMapProps {
426
435
  data: GrassMapData[];
@@ -428,10 +437,12 @@ interface GrassMapProps {
428
437
  isDark?: boolean;
429
438
  /** Unit label appended to count in tooltip. e.g. "명", "commits". Default: "" */
430
439
  unit?: string;
440
+ /** true면 count > 0을 모두 동일한 accent 색으로 표시 (했다/안했다 2색) */
441
+ binary?: boolean;
431
442
  /** Override default Korean labels for i18n */
432
443
  labels?: GrassMapLabels;
433
444
  }
434
- declare function GrassMap({ data, accent, isDark, unit, labels: _labels }: GrassMapProps): react_jsx_runtime.JSX.Element;
445
+ declare function GrassMap({ data, accent, isDark, unit, binary, labels: _labels }: GrassMapProps): react_jsx_runtime.JSX.Element;
435
446
 
436
447
  type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
437
448
  type AvatarShape = "circle" | "rounded";
@@ -652,6 +663,24 @@ interface InAppSheetProps {
652
663
  }
653
664
  declare function InAppSheet({ open, onClose, children, className, title, fullHeight, hideClose, closeLabel, }: InAppSheetProps): react_jsx_runtime.JSX.Element;
654
665
 
666
+ interface PoweredByKitProps {
667
+ /** Path to kit-stats.json. Default: "/kit-stats.json" */
668
+ statsUrl?: string;
669
+ /** Override version string */
670
+ version?: string;
671
+ /** "default" for inside AppShell, "overlay" for on top of Watermark background */
672
+ variant?: "default" | "overlay";
673
+ className?: string;
674
+ }
675
+ /**
676
+ * "Powered by @m1kapp/kit" badge + credits sheet.
677
+ * Place outside AppShell, in the Watermark padding area.
678
+ *
679
+ * Fetches /kit-stats.json (generated by `m1kkit stats`) on first open
680
+ * to show real code analysis results.
681
+ */
682
+ declare function PoweredByKit({ statsUrl, version, variant, className }: PoweredByKitProps): react_jsx_runtime.JSX.Element;
683
+
655
684
  type PWAInstallState = "android-ready" | "ios-safari" | "installed" | "unsupported";
656
685
  interface UsePWAInstallReturn {
657
686
  state: PWAInstallState;
@@ -865,4 +894,4 @@ declare function formatPrice(amount: number, currency?: string, locale?: string)
865
894
 
866
895
  declare function cn(...inputs: ClassValue[]): string;
867
896
 
868
- export { type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, type ColorName, Dialog, type DialogProps, Divider, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, InAppSheet, type InAppSheetProps, KitStyles, PWAInstallButton, type PWAInstallState, Section, SectionHeader, type SectionHeaderProps, type SectionProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fontFamily, fonts, formatNumber, formatPrice, mobileViewport, relativeTime, svgIcon, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };
897
+ export { type ApiClient, type ApiClientOptions, ApiError, AppShell, AppShellContent, type AppShellContentProps, AppShellHeader, type AppShellHeaderProps, type AppShellProps, Avatar, type AvatarProps, Badge, type BadgeProps, Button, type ButtonProps, type ColorName, Dialog, type DialogProps, Divider, EmojiButton, type EmojiButtonProps, EmojiPicker, type EmojiPickerLabels, type EmojiPickerProps, EmptyState, type EmptyStateProps, Fab, type FabProps, FontLinks, type FontName, GrassMap, type GrassMapData, type GrassMapLabels, type GrassMapProps, IOSInstallSheet, InAppSheet, type InAppSheetProps, KitStyles, PWAInstallButton, type PWAInstallState, PoweredByKit, type PoweredByKitProps, Section, SectionHeader, type SectionHeaderProps, type SectionProps, ShareButton, type ShareButtonProps, Skeleton, type SkeletonProps, StatChip, type StatChipProps, THEME_SCRIPT, Tab, TabBar, type TabBarProps, type TabProps, ThemeButton, type ThemeButtonProps, ThemeDialog, type ThemeDialogLabels, type ThemeDialogProps, type ToastOptions, ToastProvider, type ToastVariant, Tooltip, type TooltipProps, Typewriter, type TypewriterProps, type UseFetchOptions, type UseFetchResult, type UseFormSubmitOptions, type UseFormSubmitResult, type UseInViewOptions, type UseInViewResult, type UsePWAInstallReturn, type UsePollingOptions, type UsePollingResult, type UseShareOptions, type UseShareReturn, Watermark, type WatermarkProps, type WatermarkSponsor, clearFetchCache, cn, colors, createApiClient, createManifest, fontFamily, fonts, formatNumber, formatPrice, mobileViewport, relativeTime, svgIcon, useDebounce, useEscapeKey, useFetch, useFocusTrap, useFormSubmit, useInView, useLocalStorage, usePWAInstall, usePolling, usePortalTarget, useScrollLock, useShare, useToast };