@tomako/tools-runtime 0.1.0 → 0.1.2

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 (35) hide show
  1. package/package.json +13 -6
  2. package/src/components/tomato-logo.tsx +71 -0
  3. package/src/components/tools/workspace/tool-workspace-layout.tsx +1 -1
  4. package/src/constants/related-tools.ts +4 -0
  5. package/src/features/tools/app-icon-resizer/app-icon-resizer.container.tsx +15 -2
  6. package/src/features/tools/app-icon-resizer/app-icon-resizer.spec.ts +1 -1
  7. package/src/features/tools/app-icon-resizer/widget/app-icon-resizer.tsx +54 -11
  8. package/src/features/tools/app-icon-resizer/widget/platform-icons.tsx +2 -5
  9. package/src/features/tools/mrr-calculator/mrr-calculator.container.tsx +23 -0
  10. package/src/features/tools/mrr-calculator/mrr-calculator.spec.ts +15 -0
  11. package/src/features/tools/mrr-calculator/widget/calculations.ts +74 -0
  12. package/src/features/tools/mrr-calculator/widget/index.ts +1 -0
  13. package/src/features/tools/mrr-calculator/widget/mrr-calculator.tsx +581 -0
  14. package/src/features/tools/registry.ts +6 -0
  15. package/src/features/tools/runtime-registry.ts +4 -0
  16. package/src/features/tools/shared/create-standard-landing-container.tsx +35 -5
  17. package/src/features/tools/shared/tool-page-shell.tsx +10 -137
  18. package/src/features/tools/shared/tool-standard-landing-sections.tsx +262 -52
  19. package/src/features/tools/spec-registry.ts +2 -0
  20. package/src/features/tools/tarot-reading/tarot-reading.container.tsx +1 -22
  21. package/src/features/tools/widget-registry.ts +2 -0
  22. package/src/i18n/messages/en/tools/app-icon-resizer.ts +90 -62
  23. package/src/i18n/messages/en/tools/index.ts +2 -0
  24. package/src/i18n/messages/en/tools/mrr-calculator.ts +202 -0
  25. package/src/i18n/messages/en/tools-ui.ts +3 -2
  26. package/src/i18n/messages/zh/page/tools.ts +2 -3
  27. package/src/i18n/messages/zh/tools/app-icon-resizer.ts +90 -62
  28. package/src/i18n/messages/zh/tools/index.ts +2 -0
  29. package/src/i18n/messages/zh/tools/mrr-calculator.ts +112 -0
  30. package/src/i18n/messages/zh/tools-ui.ts +3 -2
  31. package/src/i18n/messages/zh-tw/tools/app-icon-resizer.ts +90 -62
  32. package/src/i18n/messages/zh-tw/tools/index.ts +2 -0
  33. package/src/i18n/messages/zh-tw/tools/mrr-calculator.ts +52 -0
  34. package/src/i18n/messages/zh-tw/tools-ui.ts +3 -2
  35. package/src/lib/tools/resolve-tool-locale-copy.ts +7 -1
@@ -1,9 +1,9 @@
1
1
  const appIconResizer = {
2
2
  meta: {
3
- title: "App Icon 切图:iOS 与 Android 尺寸包",
3
+ title: "App Icon 尺寸生成器:iOS 与 Android",
4
4
  description:
5
- "上传一张 App Icon,本地切出 iOS / App Store / Google Play / Android 尺寸包,并打包 ZIP 下载。",
6
- intro: " App 上架和工程交付准备图标资源。上传 1024px+ 方形源图,选择 Apple、Google Play 或双平台尺寸包,源图不上传服务器。",
5
+ "上传方形 App Icon,在浏览器本地生成 Xcode AppIcon、Google Play 512 Android launcher 图标包,预览后下载 ZIP",
6
+ intro: "上传 1024px+ 方形源图,本地生成 Xcode AppIcon、Google Play 图标和 Android legacy launcher 文件。",
7
7
  category: "App 上架工具",
8
8
  keywords: [
9
9
  "app icon 切图",
@@ -19,48 +19,61 @@ const appIconResizer = {
19
19
  guide: {
20
20
  heroVisualAlt:
21
21
  "App Icon 资源包视觉图,展示一个源图标导出为商店提交图标、Xcode 资源和 Android launcher 文件。",
22
- workspaceHeading: "App Icon 切图",
22
+ workspaceHeading: "App Icon 尺寸包生成器",
23
23
  workspaceHint:
24
- "上传源图,本地生成商店与工程图标 ZIP。",
24
+ "一张源图,本地生成商店与工程图标 ZIP。",
25
25
  workspaceBadge: "PNG + ZIP",
26
26
  standard: {
27
27
  benefits: {
28
- title: "这个 App Icon 切图工具能带来什么",
28
+ title: "为什么用这个工具",
29
29
  cards: [
30
30
  {
31
- title: "一张源图覆盖多端",
32
- body: "一次生成 Xcode AppIcon、App Store 1024、Google Play 512 和 Android mipmap,减少重复导出。",
31
+ title: "一次生成交付文件",
32
+ body: "不用逐张建画板和导出。一次生成 Xcode AppIcon、Google Play 512 和 Android legacy launcher 文件。",
33
33
  },
34
34
  {
35
- title: "尺寸与目录自动整理",
36
- body: " Apple、Google Play 或双平台分组、命名和打包,设计与研发更容易拿到正确文件。",
35
+ title: "目录和命名已整理",
36
+ body: "商店上传图、Xcode 资源和 Android 工程文件按用途分组,下载后不用自己建目录或逐张改名。",
37
37
  },
38
38
  {
39
- title: "本地生成,先看再下",
40
- body: "源图不上传服务器;先在透明网格中检查裁切、边缘和体积风险,再下载 PNG 或 ZIP。",
39
+ title: "先预览再下载",
40
+ body: "检查透明背景、裁切方式和文件体积风险后再下载。切图和 ZIP 打包都在当前浏览器完成。",
41
41
  },
42
42
  ],
43
43
  },
44
- imageTextSections: [
45
- {
46
- id: "icon-package",
47
- title: "一张源图\n生成完整尺寸包",
48
- body: [
49
- "App Icon 切图最容易出错的地方不是缩放,而是尺寸、目录和命名混乱。这个工具把 iOS AppIcon.appiconset、App Store 1024、Google Play 512 Android mipmap 分组输出。",
50
- "源图只在浏览器本地读取,生成后你可以直接下载 ZIP,也可以筛选平台逐个复核 PNG。",
51
- ],
52
- image: {
53
- src: "/tools/app-icon-resizer-section-primary-8bit-v3.webp",
54
- alt: "App Icon 源图生成平台图标尺寸包的 8bit 场景图",
44
+ outputPreview: {
45
+ eyebrow: "示例输出",
46
+ title: "下载包里有什么",
47
+ intro: "选择双平台后,文件会按真实交付位置分组。下面展示的是当前工具会生成的目录和文件,不是抽象功能说明。",
48
+ inputLabel: "示例输入",
49
+ input: "一张 1024 × 1024 方形 PNG,选择 Apple + Google Play / Android",
50
+ outputLabel: "ZIP 主要内容",
51
+ fields: [
52
+ {
53
+ label: "Apple/AppIcon.appiconset",
54
+ body: "iPhone、iPad ios-marketing 兼容尺寸,附 Contents.json。",
55
55
  },
56
- imageFirst: true,
57
- },
56
+ {
57
+ label: "Apple/AppStoreIcon-1024.png",
58
+ body: "供团队在上架前检查主体、留白和品牌一致性的 1024px 副本。",
59
+ },
60
+ {
61
+ label: "GooglePlay/app-icon-512.png",
62
+ body: "Play Console store listing 使用的 512 × 512 PNG。",
63
+ },
64
+ {
65
+ label: "Android/res/mipmap-*",
66
+ body: "mdpi 到 xxxhdpi 的 legacy launcher PNG;不含 Adaptive Icon 图层。",
67
+ },
68
+ ],
69
+ },
70
+ imageTextSections: [
58
71
  {
59
72
  id: "platform-scope",
60
- title: "按平台选择\n不混淆上传图和工程图",
73
+ title: "下载后怎么使用",
61
74
  body: [
62
- "Apple、Google Play 和 Android 工程资源不是同一个文件。Apple 侧主要交给 Xcode 资产目录,Google Play 需要 512 x 512 商店图,Android launcher 还会按密度分目录。",
63
- "选择平台范围后,结果区会按平台筛选,方便设计、研发和 ASO 团队确认自己该拿哪一组文件。",
75
+ " Apple/AppIcon.appiconset 导入 Xcode asset catalog,再随 build 提交;GooglePlay/app-icon-512.png 用于 Play Console store listing。",
76
+ "Android/res/mipmap-* legacy launcher 工程资源。如果项目使用 Adaptive Icon,仍需在 Android Studio 中配置前景、背景和可选的 monochrome 图层。",
64
77
  ],
65
78
  image: {
66
79
  src: "/tools/app-icon-resizer-section-variation-8bit-v3.webp",
@@ -69,10 +82,10 @@ const appIconResizer = {
69
82
  },
70
83
  {
71
84
  id: "handoff-review",
72
- title: "先预览再下载\n减少上架前返工",
85
+ title: "使用前需要知道",
73
86
  body: [
74
- "结果区会用透明网格展示每个 PNG,避免把透明像素误看成灰底。非方形图会居中裁切,过小源图会被拦截。",
75
- "下载后的 README 会说明每个目录的使用位置,并提醒圆角、阴影、adaptive icon、版权和平台最新规则仍需要人工复核。",
87
+ "非方形图片会居中裁成方形,不会拉伸。正式交付优先使用方形满版源图,并且不要预先添加圆角或外阴影。",
88
+ "图片读取、缩放和 ZIP 打包都在浏览器本地完成。正式发布前仍需复核平台最新规则、品牌版权以及浅色和深色背景下的识别度。",
76
89
  ],
77
90
  image: {
78
91
  src: "/tools/app-icon-resizer-section-support-8bit-v3.webp",
@@ -82,31 +95,56 @@ const appIconResizer = {
82
95
  },
83
96
  ],
84
97
  generation: {
85
- title: "App Icon\n切图流程",
98
+ title: "三步完成",
86
99
  imageAlt: "上传 App Icon 后选择平台、裁切预览并导出 ZIP 的 8bit 流程图",
87
100
  ctaLabel: "生成图标资源包",
88
101
  steps: [
89
102
  {
90
- title: "上传一张源图",
91
- body: "从设计源文件导出方形满版 PNG,或上传 JPG / WebPApple 或双平台包需要源图短边至少 1024px。",
103
+ title: "上传并选择平台",
104
+ body: "上传 PNGJPG WebP,再选择 Apple、Google Play / Android 或双平台。Apple 包需要源图短边至少 1024px。",
92
105
  },
93
106
  {
94
- title: "选择平台范围",
95
- body: "选择 AppleGoogle Play 或双平台。工具会自动匹配对应尺寸清单和目录结构。",
107
+ title: "本地生成尺寸包",
108
+ body: "浏览器完成裁切、缩放、命名和目录整理,同时生成 PNGContents.json README。",
96
109
  },
97
110
  {
98
- title: "生成 PNG 与 README",
99
- body: "浏览器本地裁切、缩放、保留透明像素,并写入说明文件,不把源图上传到服务器。",
111
+ title: "预览并下载 ZIP",
112
+ body: "在结果区筛选平台、检查透明网格和体积风险,然后下载完整 ZIP 或单个 PNG。",
100
113
  },
114
+ ],
115
+ },
116
+ referenceTable: {
117
+ title: "实际输出与使用位置",
118
+ intro: "现代 Xcode 可以从单张 1024px 图标生成较小变体;Tomako 仍提供完整兼容型 AppIcon.appiconset,方便接入现有工程和团队交付。",
119
+ mobileHint: "表格可左右滑动,查看完整文件去向。",
120
+ columns: ["输出组", "包含内容", "当前用途", "使用位置"],
121
+ rows: [
101
122
  {
102
- title: "复核后下载 ZIP",
103
- body: "在结果区筛选平台、检查透明网格和体积风险,然后下载完整 ZIP 或单个 PNG。",
123
+ label: "Xcode AppIcon",
124
+ cells: ["20–1024px 兼容尺寸,附 Contents.json", "iOS / iPadOS 工程图标", "Xcode asset catalog"],
125
+ },
126
+ {
127
+ label: "Apple 1024 副本",
128
+ cells: ["Apple/AppStoreIcon-1024.png", "团队视觉复核,不是另一套固定上传流程", "上架前检查主体与留白"],
129
+ },
130
+ {
131
+ label: "Google Play",
132
+ cells: ["GooglePlay/app-icon-512.png", "512 × 512 PNG;超过 1024KB 时提示", "Play Console store listing"],
133
+ },
134
+ {
135
+ label: "Android legacy launcher",
136
+ cells: ["48 / 72 / 96 / 144 / 192px", "兼容型 launcher PNG", "Android/res/mipmap-*"],
137
+ },
138
+ {
139
+ label: "交付说明",
140
+ cells: ["README.txt", "目录用途与边界说明", "设计、研发与 ASO 交接"],
104
141
  },
105
142
  ],
143
+ note: "Google Play 图标需同时满足平台的 PNG、文件大小和内容规范。当前不生成 Android Adaptive Icon 的 foreground、background 或 monochrome 图层。",
106
144
  },
107
145
  faqIntro:
108
- "这些问题帮助你判断源图是否合适、生成的文件怎么用,以及哪些平台边界仍要手动复核。",
109
- faqCtaLabel: "查看边界",
146
+ "先确认源图要求和文件去向,再判断这套输出是否适合你的发布流程。",
147
+ faqCtaLabel: "回到工作台",
110
148
  },
111
149
  whatYouGetHeading: "生成后会得到什么",
112
150
  valueVisualAlt: "整理好的 App Icon 文件包,包含 Xcode 资源目录、商店提交图标、Android 工程目录和 ZIP 下载包。",
@@ -192,44 +230,34 @@ const appIconResizer = {
192
230
  faqHeading: "常见问题",
193
231
  faqItems: [
194
232
  {
195
- question: "上传的 App Icon 会保存到服务器吗?",
233
+ question: "源图应该准备成什么格式和尺寸?",
196
234
  answer:
197
- "不会。当前工具在浏览器本地读取图片、绘制 canvas、生成 PNG 和 ZIP;刷新页面后文件状态会消失,源图不会上传到服务器。",
235
+ "建议使用 1024 × 1024 或更大的方形 PNG。JPGWebP 也支持;只生成 Google Play / Android 时,源图短边至少需要 512px。",
198
236
  },
199
237
  {
200
- question: "生成的图标能直接上传到 App Store 和 Google Play 吗?",
238
+ question: "上传的 App Icon 会保存到服务器吗?",
201
239
  answer:
202
- "GooglePlay/app-icon-512.png 面向 Google Play Console 的 App icon 上传要求。Apple 侧更准确的路径是把 AppIcon.appiconset 放入 Xcode,随 build 提交到 App Store Connect。",
240
+ "不会。图片读取、canvas 切图和 ZIP 打包都在浏览器本地完成。刷新页面后文件状态会消失,源图不会上传服务器。",
203
241
  },
204
242
  {
205
- question: "源图应该准备成什么格式和尺寸?",
243
+ question: "生成的图标能直接用于 App Store 和 Google Play 吗?",
206
244
  answer:
207
- "推荐上传 1024 x 1024 或更大的方形 PNG。JPG WebP 也支持,但正式交付前建议从设计源文件导出方形满版图,避免压缩、透明或边缘问题。",
245
+ "可以作为工程接入和商店上传素材,但正式发布前仍需复核。GooglePlay/app-icon-512.png 用于 Play Console;Apple/AppIcon.appiconset 应放入 Xcode,再随 build 提交到 App Store Connect。",
208
246
  },
209
247
  {
210
248
  question: "为什么不自动加圆角或阴影?",
211
249
  answer:
212
- "商店和系统会应用自己的遮罩、圆角或阴影。提前把图标做圆角可能导致二次裁切、边缘不齐或不符合平台要求。",
250
+ "不用提前添加。商店和系统会应用自己的遮罩、圆角或阴影,预先处理可能造成二次裁切或边缘不齐。",
213
251
  },
214
252
  {
215
- question: "源图不是方形怎么办?",
253
+ question: "源图不是方形或带透明背景怎么办?",
216
254
  answer:
217
- "当前会按中心裁成方形,不会拉伸图片。正式交付建议回到设计源文件导出方形满版图,避免主体偏移或边缘被裁掉。",
218
- },
219
- {
220
- question: "透明背景的图标会怎么处理?",
221
- answer:
222
- "工具会保留透明像素,并在结果预览里用透明网格展示。正式上架前建议确认图标在浅色、深色和平台遮罩下都能被清楚识别。",
255
+ "会居中裁成方形,不会拉伸图片。透明像素会保留;正式发布前仍要检查主体位置、裁切边缘和不同背景下的识别度。",
223
256
  },
224
257
  {
225
258
  question: "这个工具会生成 Android adaptive icon 吗?",
226
259
  answer:
227
- "不会。当前输出 Google Play 512 和 legacy launcher mipmap PNG,不生成 adaptive icon 的 foreground/background XML 组合。需要 adaptive icon 时仍要在 Android 工程中按品牌规范配置。",
228
- },
229
- {
230
- question: "图片太小会怎样?",
231
- answer:
232
- "选择 Apple 或双平台时,源图短边低于 1024px 会被拦截;只生成 Google Play / Android 时,短边低于 512px 会被拦截。Google Play 512 图标超过 1024KB 时会显示风险提示。",
260
+ "不会。当前输出 Google Play 512 和 legacy launcher mipmap PNG,不生成 adaptive icon 的 foreground/background XML。你需要在 Android 工程里另外配置。",
233
261
  },
234
262
  ],
235
263
  ctaPrimary: "继续做商店截图",
@@ -14,6 +14,7 @@ import kokoCodexAssistant from "./koko-codex-assistant";
14
14
  import logoGenerator from "./logo-generator";
15
15
  import marketForecastReport from "./market-forecast-report";
16
16
  import millionUserGrowthTest from "./million-user-growth-test";
17
+ import mrrCalculator from "./mrr-calculator";
17
18
  import ogImageGenerator from "./og-image-generator";
18
19
  import productAgreementGenerator from "./product-agreement-generator";
19
20
  import pitchDeckGenerator from "./pitch-deck-generator";
@@ -59,6 +60,7 @@ const toolsPages = {
59
60
  logoGenerator,
60
61
  marketForecastReport,
61
62
  millionUserGrowthTest,
63
+ mrrCalculator,
62
64
  ogImageGenerator,
63
65
  appStoreScreenshotGenerator,
64
66
  twitterGifDownloader,
@@ -0,0 +1,112 @@
1
+ const mrrCalculator = {
2
+ meta: {
3
+ title: "SaaS MRR 计算器|月度经常性收入计算",
4
+ description: "用客户数据计算 MRR 和 ARR,或根据公开网站流量、套餐价格和可调整假设估算 SaaS MRR。",
5
+ intro: "把月付、季付或年付订阅统一换算为月度经常性收入,也可以切换到公开数据估算模式。",
6
+ category: "SaaS 指标工具",
7
+ keywords: ["MRR 计算器", "月度经常性收入计算器", "MRR 公式", "如何计算 MRR", "MRR 转 ARR", "SaaS MRR 计算器"],
8
+ inputSignal: "客户与计费数据,或公开流量与套餐价格",
9
+ outputSignal: "MRR、ARR、月度 ARPA、增长率或公开数据估算",
10
+ boundarySignal: "浏览器本地计算;估算结果仅供方向判断,并非公司披露收入",
11
+ },
12
+ guide: {
13
+ workspaceHeading: "SaaS MRR 计算器",
14
+ workspaceHint: "用已知客户数据计算月度经常性收入,或切换到估算模式,用公开流量和套餐价格粗略判断 SaaS MRR。",
15
+ standard: {
16
+ benefits: {
17
+ title: "这个 MRR 计算器会返回什么",
18
+ cards: [
19
+ { title: "同时得到 MRR 和 ARR", body: "无需制作表格,直接查看月度经常性收入、年度经常性收入和月度 ARPA。" },
20
+ { title: "自动统一计费周期", body: "输入月付、季付或年付价格,计算器会先统一换算到每月口径。" },
21
+ { title: "也能粗略评估竞品", body: "不知道客户数时,用公开流量、套餐价格和可调整假设得到明确标注的估算结果。" },
22
+ ],
23
+ },
24
+ imageTextSections: [
25
+ {
26
+ id: "choose-the-right-mrr-method",
27
+ title: "选择正确的\nMRR 计算方式",
28
+ body: [
29
+ { text: "想计算自己产品的 MRR 或 ARR 时,使用默认的“计算 MRR”。填写活跃付费客户数、每位客户的经常性金额和计费周期,工具会直接计算结果。", highlights: ["计算 MRR"] },
30
+ { text: "想粗略了解竞品或其他 SaaS 的收入量级时,切换到“估算 SaaS MRR”。根据公开网站流量和套餐价格填写估算条件;结果只用于方向判断,不是对方披露的收入。", highlights: ["估算 SaaS MRR"] },
31
+ ],
32
+ image: { src: "/tools/mrr-calculator-section-steps-8bit.webp", alt: "像素风工作台对比用客户数据计算 MRR 与用公开流量和套餐价格估算 SaaS MRR。" },
33
+ imageFirst: true,
34
+ hideImageOnMobile: true,
35
+ },
36
+ {
37
+ id: "monthly-recurring-revenue-formula",
38
+ title: "如何计算\n月度经常性收入",
39
+ body: [
40
+ { text: "月度经常性收入公式是:MRR = 活跃付费客户数 × 月度 ARPA。季付经常性金额先除以 3,年付金额先除以 12,再乘以客户数。", highlights: ["MRR = 活跃付费客户数 × 月度 ARPA"] },
41
+ "例如,12 位客户每年支付 1,200 美元,月度 ARPA 为 100 美元,MRR 为 1,200 美元,ARR 为 14,400 美元。若上月 MRR 为 1,000 美元,环比增长率是(1,200 − 1,000)÷ 1,000 = 20%。",
42
+ ],
43
+ image: { src: "/tools/mrr-calculator-section-primary-8bit.webp", alt: "像素风 SaaS 账本把月付、季付和年付订阅统一换算成 MRR。" },
44
+ },
45
+ {
46
+ id: "estimate-saas-mrr",
47
+ title: "用公开数据\n估算 SaaS MRR",
48
+ body: [
49
+ "估算模式先用“访问量 × 可用于获客的访问占比 × 访问者转付费率”估算每月新增付费客户,再用平均付费周期估算活跃客户数,最后乘以统一到每月的套餐价格。",
50
+ "重复访问、现有客户、渠道结构、转化率、套餐结构和流失仍然未知。比较多个产品时应保持假设一致,业务模式不同时再调整;结果只适合方向判断。",
51
+ ],
52
+ image: { src: "/tools/mrr-calculator-section-variation-8bit.webp", alt: "像素风公开流量图和套餐价格卡片进入明确标注的 SaaS MRR 估算结果。" },
53
+ imageFirst: true,
54
+ },
55
+ ],
56
+ editorialSections: [
57
+ {
58
+ id: "what-counts-as-mrr",
59
+ title: "哪些收入应该计入月度经常性收入",
60
+ body: [
61
+ "MRR 是统一到单月口径的经常性订阅收入。应计入当前合同下持续发生的有效套餐收入,季付或年付金额需要先换算到每月。",
62
+ "不要计入一次性设置费、实施费、专业服务、硬件、税费和其他非经常性收款。如果涉及折扣、退款、用量计费、扩张、收缩或流失,应使用账单系统数据和更完整的收入模型。",
63
+ ],
64
+ },
65
+ {
66
+ id: "common-mrr-calculation-mistakes",
67
+ title: "常见的 MRR 计算错误",
68
+ body: [
69
+ "不要把整笔年付收入全部放进一个月,也不要计入一次性收入,或把新增 MRR 当成公司总 MRR。涉及多个套餐时,应分别计算后相加,或使用加权平均月价,不要假设客户平均分布。",
70
+ "在估算模式中,不要把所有网站访问量或直接访问都当成新客户。流量可能包含回访者、现有客户、员工和重复会话,因此可用于获客的访问占比必须保持为明确假设。",
71
+ "最重要的是,不要把 Estimated MRR 场景写成竞品真实收入。公开流量和价格无法揭示真实客户数、折扣、留存和渠道结构。",
72
+ ],
73
+ },
74
+ {
75
+ id: "use-mrr-and-arr-results",
76
+ title: "如何使用 MRR 和 ARR 结果",
77
+ body: [
78
+ "核对客户数、经常性金额和计费周期后,可以把计算 MRR 用于经营检查、月度汇报或套餐情景测试。填写上月 MRR 可以查看环比增长,把 MRR 转成 ARR 可以得到年度运行率视角。",
79
+ "估算 MRR 只适合竞品方向性比较。比较不同产品时保持同一组假设,记录结果依据,并在流量或价格变化后重新计算。",
80
+ "这些结果可以继续用于流失率、留存和 LTV:CAC 分析,但不属于会计报表、财务建议或估值意见。",
81
+ ],
82
+ },
83
+ ],
84
+ faqIntro: "补充回答多套餐、零分母、直接访问、估算边界和浏览器本地数据处理问题。",
85
+ faqCtaLabel: "使用计算器",
86
+ },
87
+ faqHeading: "MRR 计算器常见问题",
88
+ faqItems: [
89
+ { question: "这个 MRR 计算器如何使用?", answer: "想计算自己产品的 MRR 或 ARR 时,保留默认的“计算 MRR”,填写活跃付费客户数、每位客户的经常性金额和计费周期。想粗略了解竞品或其他 SaaS 的收入量级时,切换到“估算 SaaS MRR”,根据公开网站流量和套餐价格填写估算条件。前者是基于你的输入直接计算;后者只是方向性估算。" },
90
+ { question: "不同套餐可以一起计算吗?", answer: "V1 接收一个混合平均经常性金额。你可以分别计算各套餐后相加,或在知道套餐占比时先算出加权平均月价。" },
91
+ { question: "上月 MRR 为零时怎么办?", answer: "工具仍会返回本月 MRR 和 ARR,但不会显示环比增长率,因为分母为零时百分比增长没有可靠含义。" },
92
+ { question: "可以把直接访问流量当成新客户吗?", answer: "不可以。直接访问可能包含回访者、现有客户、员工、书签访问和无法归因的会话。估算时只应计入一部分可用于获客的访问量。" },
93
+ { question: "SaaS MRR 估算有多准确?", answer: "它只适合方向判断,不是精确结果。是否有参考价值取决于流量、价格、转化率和付费周期假设是否接近被评估产品。" },
94
+ { question: "这个估算属于财务建议或估值意见吗?", answer: "不属于。它只是基于公开输入和你的假设得到的场景,不应作为会计证据、公司收入事实、财务建议或估值结论。" },
95
+ { question: "输入的数据会离开浏览器吗?", answer: "不会。当前版本在浏览器内完成计算,不上传输入值,也不需要注册账号。" },
96
+ ],
97
+ },
98
+ widget: {
99
+ calculateMode: "计算 MRR", estimateMode: "估算 SaaS MRR", modeSwitchLabel: "切换计算与估算 MRR 模式",
100
+ calculateHint: "使用已知付费客户和订阅数据,得到计算结果。", estimateHint: "使用公开流量和价格进行粗略估算,并非公司披露收入。",
101
+ activeCustomers: "活跃付费客户数", recurringAmount: "每位客户的经常性金额", billingPeriod: "计费周期", previousMrr: "上月 MRR", optional: "可选", addPreviousMrr: "添加上月 MRR(可选)", currency: "币种",
102
+ monthlyVisits: "估算的网站月访问量", planPrice: "有代表性的公开套餐价格", showAssumptions: "调整估算假设", hideAssumptions: "收起估算假设",
103
+ assumptionNote: "这些只是起始假设,不是行业基准。请根据被评估产品进行调整。", eligibleVisitShare: "可用于获客的访问占比(%)", visitorToPaidRate: "访问者转付费率(%)", averagePaidLifetime: "平均付费周期(月)",
104
+ periods: { month: "月付", quarter: "季付", year: "年付" }, calculatedLabel: "计算结果", estimatedLabel: "估算结果",
105
+ calculatedResultTitle: "月度经常性收入", estimatedResultTitle: "SaaS 收入方向性估算", calculatedMrr: "计算 MRR", estimatedMrr: "估算 MRR", arr: "ARR", estimatedArr: "估算 ARR", monthlyArpa: "月度 ARPA", monthlyPlanPrice: "月度套餐价格", momGrowth: "MRR 环比增长", newPaidCustomers: "每月新增付费客户", activePaidCustomers: "估算活跃付费客户", formula: "算式检查", perMonth: "每月", assumptionsUsed: "本次使用的假设", notAvailable: "无法计算",
106
+ calculatedGuidance: "只计入经常性订阅收入,排除一次性费用、税费和非经常性服务。", estimateDisclaimer: "仅为公开数据估算。实际流量质量、转化率、套餐结构、流失和收入可能不同。",
107
+ copyResult: "复制结果", copied: "已复制", reset: "重置", fixInputsTitle: "检查标红的输入项", fixInputsBody: "输入有效数值后,结果会自动更新。",
108
+ errors: { nonNegative: "请输入零或正数。", positive: "请输入大于零的数值。", percent: "请输入 0 到 100 之间的百分比。" },
109
+ },
110
+ } as const;
111
+
112
+ export default mrrCalculator;
@@ -634,8 +634,9 @@ const toolsUi = {
634
634
  downloadZip: "下载 ZIP",
635
635
  selectedTitle: "选中图标",
636
636
  downloadPng: "下载 PNG",
637
- outputEmptyTitle: "先上传源图并选择平台",
638
- outputEmptyHint: "上传 1024px+ 方形源图,选择 Apple、Google Play 或双平台资源包,然后生成。完成后这里会展示 ZIP 下载和图标预览。",
637
+ outputEmptyTitle: "上传后在这里检查文件包",
638
+ outputEmptyHint: "当前平台选择会生成下面这些主要目录。上传源图并生成后,这里会切换为真实 PNG 预览和 ZIP 下载。",
639
+ outputExampleLabel: "app-icon-assets.zip 示例结构",
639
640
  platforms: {
640
641
  all: "App Store + Google Play",
641
642
  apple: "Apple App Store / iOS",
@@ -1,9 +1,9 @@
1
1
  const appIconResizer = {
2
2
  meta: {
3
- title: "App Icon 切圖:iOS 與 Android 尺寸包",
3
+ title: "App Icon 尺寸產生器:iOS 與 Android",
4
4
  description:
5
- "上傳一張 App Icon,本地切出 iOS / App Store / Google Play / Android 尺寸包,並打包 ZIP 下載。",
6
- intro: " App 上架和工程交付準備圖標資源。上傳 1024px+ 方形源圖,選擇 Apple、Google Play 或雙平臺尺寸包,源圖不上傳服務器。",
5
+ "上傳方形 App Icon,在瀏覽器本地產生 Xcode AppIcon、Google Play 512 Android launcher 圖示包,預覽後下載 ZIP",
6
+ intro: "上傳 1024px+ 方形原圖,本地產生 Xcode AppIcon、Google Play 圖示和 Android legacy launcher 檔案。",
7
7
  category: "App 上架工具",
8
8
  keywords: [
9
9
  "app icon 切圖",
@@ -19,48 +19,61 @@ const appIconResizer = {
19
19
  guide: {
20
20
  heroVisualAlt:
21
21
  "App Icon 資源包視覺圖,展示一個源圖標導出為商店提交圖標、Xcode 資源和 Android launcher 文件。",
22
- workspaceHeading: "App Icon 切圖",
22
+ workspaceHeading: "App Icon 尺寸包產生器",
23
23
  workspaceHint:
24
- "上傳源圖,本地生成商店與工程圖標 ZIP。",
24
+ "一張原圖,本地產生商店與工程圖示 ZIP。",
25
25
  workspaceBadge: "PNG + ZIP",
26
26
  standard: {
27
27
  benefits: {
28
- title: "這個 App Icon 切圖工具能帶來什麼",
28
+ title: "為什麼用這個工具",
29
29
  cards: [
30
30
  {
31
- title: "一張源圖覆蓋多端",
32
- body: "一次生成 Xcode AppIcon、App Store 1024、Google Play 512 Android mipmap,減少重複導出。",
31
+ title: "一次產生交付檔案",
32
+ body: "不用逐張建立畫板和匯出。一次產生 Xcode AppIcon、Google Play 512 Android legacy launcher 檔案。",
33
33
  },
34
34
  {
35
- title: "尺寸與目錄自動整理",
36
- body: " Apple、Google Play 或雙平臺分組、命名和打包,設計與研發更容易拿到正確文件。",
35
+ title: "目錄和命名已整理",
36
+ body: "商店上傳圖、Xcode 資源與 Android 工程檔案按用途分組,下載後不用自己建目錄或逐張改名。",
37
37
  },
38
38
  {
39
- title: "本地生成,先看再下",
40
- body: "源圖不上傳服務器;先在透明網格中檢查裁切、邊緣和體積風險,再下載 PNG 或 ZIP。",
39
+ title: "先預覽再下載",
40
+ body: "先檢查透明背景、裁切方式和檔案大小風險。切圖和 ZIP 打包都在目前瀏覽器完成。",
41
41
  },
42
42
  ],
43
43
  },
44
- imageTextSections: [
45
- {
46
- id: "icon-package",
47
- title: "一張源圖\n生成完整尺寸包",
48
- body: [
49
- "App Icon 切圖最容易出錯的地方不是縮放,而是尺寸、目錄和命名混亂。這個工具把 iOS AppIcon.appiconset、App Store 1024、Google Play 512 Android mipmap 分組輸出。",
50
- "源圖只在瀏覽器本地讀取,生成後你可以直接下載 ZIP,也可以篩選平臺逐個複核 PNG。",
51
- ],
52
- image: {
53
- src: "/tools/app-icon-resizer-section-primary-8bit-v3.webp",
54
- alt: "App Icon 源圖生成平臺圖標尺寸包的 8bit 場景圖",
44
+ outputPreview: {
45
+ eyebrow: "範例輸出",
46
+ title: "下載包裡有什麼",
47
+ intro: "選擇雙平台後,檔案會按實際交付位置分組。下面是目前工具會產生的目錄和檔案。",
48
+ inputLabel: "範例輸入",
49
+ input: "一張 1024 × 1024 方形 PNG,選擇 Apple + Google Play / Android",
50
+ outputLabel: "ZIP 主要內容",
51
+ fields: [
52
+ {
53
+ label: "Apple/AppIcon.appiconset",
54
+ body: "iPhone、iPad ios-marketing 相容尺寸,附 Contents.json。",
55
55
  },
56
- imageFirst: true,
57
- },
56
+ {
57
+ label: "Apple/AppStoreIcon-1024.png",
58
+ body: "供團隊在上架前檢查主體、留白和品牌一致性的 1024px 副本。",
59
+ },
60
+ {
61
+ label: "GooglePlay/app-icon-512.png",
62
+ body: "Play Console store listing 使用的 512 × 512 PNG。",
63
+ },
64
+ {
65
+ label: "Android/res/mipmap-*",
66
+ body: "mdpi 到 xxxhdpi 的 legacy launcher PNG;不含 Adaptive Icon 圖層。",
67
+ },
68
+ ],
69
+ },
70
+ imageTextSections: [
58
71
  {
59
72
  id: "platform-scope",
60
- title: "按平臺選擇\n不混淆上傳圖和工程圖",
73
+ title: "下載後怎麼使用",
61
74
  body: [
62
- "Apple、Google Play 和 Android 工程資源不是同一個文件。Apple 側主要交給 Xcode 資產目錄,Google Play 需要 512 x 512 商店圖,Android launcher 還會按密度分目錄。",
63
- "選擇平臺範圍後,結果區會按平臺篩選,方便設計、研發和 ASO 團隊確認自己該拿哪一組文件。",
75
+ " Apple/AppIcon.appiconset 匯入 Xcode asset catalog,再隨 build 提交;GooglePlay/app-icon-512.png 用於 Play Console store listing。",
76
+ "Android/res/mipmap-* legacy launcher 工程資源。如果專案使用 Adaptive Icon,仍需在 Android Studio 設定前景、背景和可選的 monochrome 圖層。",
64
77
  ],
65
78
  image: {
66
79
  src: "/tools/app-icon-resizer-section-variation-8bit-v3.webp",
@@ -69,10 +82,10 @@ const appIconResizer = {
69
82
  },
70
83
  {
71
84
  id: "handoff-review",
72
- title: "先預覽再下載\n減少上架前返工",
85
+ title: "使用前需要知道",
73
86
  body: [
74
- "結果區會用透明網格展示每個 PNG,避免把透明像素誤看成灰底。非方形圖會居中裁切,過小源圖會被攔截。",
75
- "下載後的 README 會說明每個目錄的使用位置,並提醒圓角、陰影、adaptive icon、版權和平臺最新規則仍需要人工複核。",
87
+ "非方形圖片會置中裁成方形,不會拉伸。正式交付應優先使用方形滿版源圖,也不要預先加入圓角或外陰影。",
88
+ "圖片讀取、縮放和 ZIP 打包都在瀏覽器本地完成。正式發布前仍需複核平台最新規則、品牌版權,以及淺色和深色背景下的辨識度。",
76
89
  ],
77
90
  image: {
78
91
  src: "/tools/app-icon-resizer-section-support-8bit-v3.webp",
@@ -82,31 +95,56 @@ const appIconResizer = {
82
95
  },
83
96
  ],
84
97
  generation: {
85
- title: "App Icon\n切圖流程",
98
+ title: "三步完成",
86
99
  imageAlt: "上傳 App Icon 後選擇平臺、裁切預覽並導出 ZIP 的 8bit 流程圖",
87
100
  ctaLabel: "生成圖標資源包",
88
101
  steps: [
89
102
  {
90
- title: "上傳一張源圖",
91
- body: "從設計源文件導出方形滿版 PNG,或上傳 JPG / WebPApple 或雙平臺包需要源圖短邊至少 1024px。",
103
+ title: "上傳並選擇平台",
104
+ body: "上傳 PNGJPG WebP,再選擇 Apple、Google Play / Android 或雙平台。Apple 包需要原圖短邊至少 1024px。",
92
105
  },
93
106
  {
94
- title: "選擇平臺範圍",
95
- body: "選擇 AppleGoogle Play 或雙平臺。工具會自動匹配對應尺寸清單和目錄結構。",
107
+ title: "本地生成尺寸包",
108
+ body: "瀏覽器完成裁切、縮放、命名和目錄整理,同時生成 PNGContents.json README。",
96
109
  },
97
110
  {
98
- title: "生成 PNG 與 README",
99
- body: "瀏覽器本地裁切、縮放、保留透明像素,並寫入說明文件,不把源圖上傳到服務器。",
111
+ title: "預覽並下載 ZIP",
112
+ body: "在結果區篩選平台、檢查透明網格和檔案大小風險,然後下載完整 ZIP 或單個 PNG。",
113
+ },
114
+ ],
115
+ },
116
+ referenceTable: {
117
+ title: "實際輸出與使用位置",
118
+ intro: "現代 Xcode 可以從單張 1024px 圖示產生較小變體;Tomako 仍提供完整相容型 AppIcon.appiconset,方便接入現有專案和團隊交付。",
119
+ mobileHint: "表格可左右滑動,查看完整檔案去向。",
120
+ columns: ["輸出組", "包含內容", "目前用途", "使用位置"],
121
+ rows: [
122
+ {
123
+ label: "Xcode AppIcon",
124
+ cells: ["20–1024px 相容尺寸,附 Contents.json", "iOS / iPadOS 工程圖示", "Xcode asset catalog"],
125
+ },
126
+ {
127
+ label: "Apple 1024 副本",
128
+ cells: ["Apple/AppStoreIcon-1024.png", "團隊視覺複核,不是另一套固定上傳流程", "上架前檢查主體與留白"],
129
+ },
130
+ {
131
+ label: "Google Play",
132
+ cells: ["GooglePlay/app-icon-512.png", "512 × 512 PNG;超過 1024KB 時提示", "Play Console store listing"],
100
133
  },
101
134
  {
102
- title: "複核後下載 ZIP",
103
- body: "在結果區篩選平臺、檢查透明網格和體積風險,然後下載完整 ZIP 或單個 PNG",
135
+ label: "Android legacy launcher",
136
+ cells: ["48 / 72 / 96 / 144 / 192px", "相容型 launcher PNG", "Android/res/mipmap-*"],
137
+ },
138
+ {
139
+ label: "交付說明",
140
+ cells: ["README.txt", "目錄用途與邊界說明", "設計、工程與 ASO 交接"],
104
141
  },
105
142
  ],
143
+ note: "Google Play 圖示還需符合平台的 PNG、檔案大小和內容規範。目前不產生 Android Adaptive Icon 的 foreground、background 或 monochrome 圖層。",
106
144
  },
107
145
  faqIntro:
108
- "這些問題幫助你判斷源圖是否合適、生成的文件怎麼用,以及哪些平臺邊界仍要手動複核。",
109
- faqCtaLabel: "查看邊界",
146
+ "先確認原圖要求和檔案去向,再判斷這套輸出是否適合你的發布流程。",
147
+ faqCtaLabel: "回到工作台",
110
148
  },
111
149
  whatYouGetHeading: "生成後會得到什麼",
112
150
  valueVisualAlt: "整理好的 App Icon 文件包,包含 Xcode 資源目錄、商店提交圖標、Android 工程目錄和 ZIP 下載包。",
@@ -192,44 +230,34 @@ const appIconResizer = {
192
230
  faqHeading: "常見問題",
193
231
  faqItems: [
194
232
  {
195
- question: "上傳的 App Icon 會保存到服務器嗎?",
233
+ question: "原圖應該準備成什麼格式和尺寸?",
196
234
  answer:
197
- "不會。當前工具在瀏覽器本地讀取圖片、繪製 canvas、生成 PNG 和 ZIP;刷新頁面後文件狀態會消失,源圖不會上傳到服務器。",
235
+ "建議使用 1024 × 1024 或更大的方形 PNG。JPGWebP 也支援;只生成 Google Play / Android 時,原圖短邊至少需要 512px。",
198
236
  },
199
237
  {
200
- question: "生成的圖標能直接上傳到 App Store 和 Google Play 嗎?",
238
+ question: "上傳的 App Icon 會儲存到伺服器嗎?",
201
239
  answer:
202
- "GooglePlay/app-icon-512.png 面向 Google Play Console 的 App icon 上傳要求。Apple 側更準確的路徑是把 AppIcon.appiconset 放入 Xcode,隨 build 提交到 App Store Connect。",
240
+ "不會。圖片讀取、canvas 切圖和 ZIP 打包都在瀏覽器本地完成。重新整理頁面後檔案狀態會消失,原圖不會上傳伺服器。",
203
241
  },
204
242
  {
205
- question: "源圖應該準備成什麼格式和尺寸?",
243
+ question: "生成的圖示能直接用於 App Store 和 Google Play 嗎?",
206
244
  answer:
207
- "推薦上傳 1024 x 1024 或更大的方形 PNG。JPG WebP 也支持,但正式交付前建議從設計源文件導出方形滿版圖,避免壓縮、透明或邊緣問題。",
245
+ "可以作為工程接入和商店上傳素材,但正式發布前仍需複核。GooglePlay/app-icon-512.png 用於 Play Console;Apple/AppIcon.appiconset 應放入 Xcode,再隨 build 提交到 App Store Connect。",
208
246
  },
209
247
  {
210
248
  question: "為什麼不自動加圓角或陰影?",
211
249
  answer:
212
- "商店和系統會應用自己的遮罩、圓角或陰影。提前把圖標做圓角可能導致二次裁切、邊緣不齊或不符合平臺要求。",
213
- },
214
- {
215
- question: "源圖不是方形怎麼辦?",
216
- answer:
217
- "當前會按中心裁成方形,不會拉伸圖片。正式交付建議回到設計源文件導出方形滿版圖,避免主體偏移或邊緣被裁掉。",
250
+ "不用提前加入。商店和系統會套用自己的遮罩、圓角或陰影,預先處理可能造成二次裁切或邊緣不齊。",
218
251
  },
219
252
  {
220
- question: "透明背景的圖標會怎麼處理?",
253
+ question: "原圖不是方形或帶透明背景怎麼辦?",
221
254
  answer:
222
- "工具會保留透明像素,並在結果預覽裡用透明網格展示。正式上架前建議確認圖標在淺色、深色和平臺遮罩下都能被清楚識別。",
255
+ "會置中裁成方形,不會拉伸圖片。透明像素會保留;正式發布前仍要檢查主體位置、裁切邊緣和不同背景下的辨識度。",
223
256
  },
224
257
  {
225
258
  question: "這個工具會生成 Android adaptive icon 嗎?",
226
259
  answer:
227
- "不會。當前輸出 Google Play 512 和 legacy launcher mipmap PNG,不生成 adaptive icon 的 foreground/background XML 組合。需要 adaptive icon 時仍要在 Android 工程中按品牌規範配置。",
228
- },
229
- {
230
- question: "圖片太小會怎樣?",
231
- answer:
232
- "選擇 Apple 或雙平臺時,源圖短邊低於 1024px 會被攔截;只生成 Google Play / Android 時,短邊低於 512px 會被攔截。Google Play 512 圖標超過 1024KB 時會顯示風險提示。",
260
+ "不會。目前輸出 Google Play 512 和 legacy launcher mipmap PNG,不生成 adaptive icon 的 foreground/background XML。你需要在 Android 工程裡另外設定。",
233
261
  },
234
262
  ],
235
263
  ctaPrimary: "繼續做商店截圖",