@jjlmoya/utils-chrono 1.17.0 → 1.19.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/package.json +1 -1
- package/src/category/i18n/fr.ts +1 -1
- package/src/category/index.ts +4 -0
- package/src/entries.ts +7 -1
- package/src/index.ts +2 -0
- package/src/tests/locale_completeness.test.ts +1 -1
- package/src/tests/no_en_dash.test.ts +40 -6
- package/src/tests/title_quality.test.ts +2 -2
- package/src/tests/tool_validation.test.ts +1 -1
- package/src/tool/beat-rate-converter/i18n/de.ts +30 -30
- package/src/tool/beat-rate-converter/i18n/es.ts +33 -33
- package/src/tool/beat-rate-converter/i18n/fr.ts +45 -45
- package/src/tool/beat-rate-converter/i18n/id.ts +6 -6
- package/src/tool/beat-rate-converter/i18n/it.ts +28 -28
- package/src/tool/beat-rate-converter/i18n/ja.ts +56 -56
- package/src/tool/beat-rate-converter/i18n/ko.ts +56 -56
- package/src/tool/beat-rate-converter/i18n/nl.ts +14 -14
- package/src/tool/beat-rate-converter/i18n/pl.ts +48 -48
- package/src/tool/beat-rate-converter/i18n/pt.ts +30 -30
- package/src/tool/beat-rate-converter/i18n/ru.ts +56 -56
- package/src/tool/beat-rate-converter/i18n/sv.ts +44 -44
- package/src/tool/beat-rate-converter/i18n/tr.ts +51 -51
- package/src/tool/beat-rate-converter/i18n/zh.ts +56 -56
- package/src/tool/crown-reference-guide/i18n/de.ts +9 -9
- package/src/tool/crown-reference-guide/i18n/en.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/es.ts +10 -10
- package/src/tool/crown-reference-guide/i18n/fr.ts +18 -18
- package/src/tool/crown-reference-guide/i18n/id.ts +9 -9
- package/src/tool/crown-reference-guide/i18n/it.ts +9 -9
- package/src/tool/crown-reference-guide/i18n/nl.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/pl.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/pt.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/ru.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/sv.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/tr.ts +8 -8
- package/src/tool/crown-reference-guide/i18n/zh.ts +9 -9
- package/src/tool/demagnetizing-timer/i18n/fr.ts +1 -1
- package/src/tool/gear-train-explorer/i18n/de.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/en.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/es.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/fr.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/id.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/it.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/ja.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/ko.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/nl.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/pl.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/pt.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/ru.ts +6 -6
- package/src/tool/gear-train-explorer/i18n/sv.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/tr.ts +2 -2
- package/src/tool/gear-train-explorer/i18n/zh.ts +2 -2
- package/src/tool/gmt-world-timer/i18n/en.ts +7 -7
- package/src/tool/gmt-world-timer/i18n/es.ts +8 -8
- package/src/tool/gmt-world-timer/i18n/fr.ts +12 -12
- package/src/tool/gmt-world-timer/i18n/id.ts +7 -7
- package/src/tool/gmt-world-timer/i18n/it.ts +8 -8
- package/src/tool/gmt-world-timer/i18n/ja.ts +5 -5
- package/src/tool/gmt-world-timer/i18n/ko.ts +5 -5
- package/src/tool/gmt-world-timer/i18n/nl.ts +7 -7
- package/src/tool/gmt-world-timer/i18n/pl.ts +7 -7
- package/src/tool/gmt-world-timer/i18n/pt.ts +7 -7
- package/src/tool/gmt-world-timer/i18n/ru.ts +11 -11
- package/src/tool/gmt-world-timer/i18n/sv.ts +7 -7
- package/src/tool/gmt-world-timer/i18n/tr.ts +6 -6
- package/src/tool/gmt-world-timer/i18n/zh.ts +6 -6
- package/src/tool/lume-color-simulator/i18n/fr.ts +4 -4
- package/src/tool/lume-color-simulator/i18n/id.ts +5 -5
- package/src/tool/lume-color-simulator/i18n/it.ts +4 -4
- package/src/tool/lume-color-simulator/i18n/ja.ts +5 -5
- package/src/tool/lume-color-simulator/i18n/nl.ts +2 -2
- package/src/tool/lume-color-simulator/i18n/pt.ts +5 -5
- package/src/tool/lume-color-simulator/i18n/ru.ts +14 -14
- package/src/tool/lume-color-simulator/i18n/zh.ts +4 -4
- package/src/tool/mainspring-finder/bibliography.astro +16 -0
- package/src/tool/mainspring-finder/bibliography.ts +16 -0
- package/src/tool/mainspring-finder/client.ts +89 -0
- package/src/tool/mainspring-finder/component.astro +72 -0
- package/src/tool/mainspring-finder/entry.ts +50 -0
- package/src/tool/mainspring-finder/helpers.ts +52 -0
- package/src/tool/mainspring-finder/i18n/de.ts +212 -0
- package/src/tool/mainspring-finder/i18n/en.ts +212 -0
- package/src/tool/mainspring-finder/i18n/es.ts +212 -0
- package/src/tool/mainspring-finder/i18n/fr.ts +212 -0
- package/src/tool/mainspring-finder/i18n/id.ts +212 -0
- package/src/tool/mainspring-finder/i18n/it.ts +212 -0
- package/src/tool/mainspring-finder/i18n/ja.ts +212 -0
- package/src/tool/mainspring-finder/i18n/ko.ts +212 -0
- package/src/tool/mainspring-finder/i18n/nl.ts +212 -0
- package/src/tool/mainspring-finder/i18n/pl.ts +212 -0
- package/src/tool/mainspring-finder/i18n/pt.ts +212 -0
- package/src/tool/mainspring-finder/i18n/ru.ts +212 -0
- package/src/tool/mainspring-finder/i18n/sv.ts +212 -0
- package/src/tool/mainspring-finder/i18n/tr.ts +212 -0
- package/src/tool/mainspring-finder/i18n/zh.ts +212 -0
- package/src/tool/mainspring-finder/index.ts +11 -0
- package/src/tool/mainspring-finder/mainspring-finder.css +242 -0
- package/src/tool/mainspring-finder/seo.astro +16 -0
- package/src/tool/moon-phase-visualizer/i18n/fr.ts +4 -4
- package/src/tool/moon-phase-visualizer/i18n/id.ts +4 -4
- package/src/tool/moon-phase-visualizer/i18n/it.ts +4 -4
- package/src/tool/moon-phase-visualizer/i18n/ja.ts +2 -2
- package/src/tool/moon-phase-visualizer/i18n/nl.ts +2 -2
- package/src/tool/moon-phase-visualizer/i18n/pt.ts +4 -4
- package/src/tool/moon-phase-visualizer/i18n/ru.ts +7 -7
- package/src/tool/moon-phase-visualizer/i18n/zh.ts +4 -4
- package/src/tool/perpetual-calendar/i18n/de.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/en.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/es.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/fr.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/id.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/it.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/ja.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/ko.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/nl.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/pl.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/pt.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/ru.ts +2 -2
- package/src/tool/perpetual-calendar/i18n/sv.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/tr.ts +1 -1
- package/src/tool/perpetual-calendar/i18n/zh.ts +1 -1
- package/src/tool/power-reserve-estimator/i18n/de.ts +26 -26
- package/src/tool/power-reserve-estimator/i18n/es.ts +22 -22
- package/src/tool/power-reserve-estimator/i18n/fr.ts +36 -36
- package/src/tool/power-reserve-estimator/i18n/id.ts +5 -5
- package/src/tool/power-reserve-estimator/i18n/it.ts +18 -18
- package/src/tool/power-reserve-estimator/i18n/ja.ts +3 -3
- package/src/tool/power-reserve-estimator/i18n/ko.ts +3 -3
- package/src/tool/power-reserve-estimator/i18n/nl.ts +7 -7
- package/src/tool/power-reserve-estimator/i18n/pl.ts +9 -9
- package/src/tool/power-reserve-estimator/i18n/pt.ts +25 -25
- package/src/tool/power-reserve-estimator/i18n/ru.ts +15 -15
- package/src/tool/power-reserve-estimator/i18n/sv.ts +7 -7
- package/src/tool/power-reserve-estimator/i18n/tr.ts +7 -7
- package/src/tool/power-reserve-estimator/i18n/zh.ts +7 -7
- package/src/tool/quartz-battery-health/bibliography.astro +16 -0
- package/src/tool/quartz-battery-health/bibliography.ts +16 -0
- package/src/tool/quartz-battery-health/client.ts +198 -0
- package/src/tool/quartz-battery-health/component.astro +15 -0
- package/src/tool/quartz-battery-health/components/BatteryHealthPanel.astro +163 -0
- package/src/tool/quartz-battery-health/entry.ts +57 -0
- package/src/tool/quartz-battery-health/i18n/de.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/en.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/es.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/fr.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/id.ts +326 -0
- package/src/tool/quartz-battery-health/i18n/it.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/ja.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/ko.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/nl.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/pl.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/pt.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/ru.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/sv.ts +326 -0
- package/src/tool/quartz-battery-health/i18n/tr.ts +327 -0
- package/src/tool/quartz-battery-health/i18n/zh.ts +327 -0
- package/src/tool/quartz-battery-health/index.ts +11 -0
- package/src/tool/quartz-battery-health/quartz-battery-health.css +447 -0
- package/src/tool/quartz-battery-health/seo.astro +16 -0
- package/src/tool/service-interval-tracker/i18n/fr.ts +1 -1
- package/src/tool/sidereal-time-tracker/i18n/ru.ts +2 -2
- package/src/tool/strap-length-calculator/i18n/fr.ts +1 -1
- package/src/tool/strap-length-calculator/i18n/ru.ts +4 -4
- package/src/tool/strap-taper-calculator/i18n/de.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/en.ts +1 -1
- package/src/tool/strap-taper-calculator/i18n/es.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/fr.ts +4 -4
- package/src/tool/strap-taper-calculator/i18n/id.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/it.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/ja.ts +2 -2
- package/src/tool/strap-taper-calculator/i18n/ko.ts +2 -2
- package/src/tool/strap-taper-calculator/i18n/nl.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/pl.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/pt.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/ru.ts +2 -2
- package/src/tool/strap-taper-calculator/i18n/sv.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/tr.ts +3 -3
- package/src/tool/strap-taper-calculator/i18n/zh.ts +3 -3
- package/src/tool/tachymeter-calculator/i18n/ru.ts +6 -6
- package/src/tool/telemeter-calculator/i18n/ru.ts +3 -3
- package/src/tool/telemeter-calculator/i18n/zh.ts +2 -2
- package/src/tool/tourbillon-visualizer/i18n/de.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/en.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/es.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/fr.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/id.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/it.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/ja.ts +2 -2
- package/src/tool/tourbillon-visualizer/i18n/ko.ts +2 -2
- package/src/tool/tourbillon-visualizer/i18n/nl.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/pl.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/pt.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/ru.ts +5 -5
- package/src/tool/tourbillon-visualizer/i18n/sv.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/tr.ts +3 -3
- package/src/tool/tourbillon-visualizer/i18n/zh.ts +3 -3
- package/src/tool/watch-accuracy-tracker/i18n/fr.ts +1 -1
- package/src/tool/watch-accuracy-tracker/i18n/zh.ts +1 -1
- package/src/tool/watch-savings-planner/i18n/de.ts +25 -25
- package/src/tool/watch-savings-planner/i18n/es.ts +39 -39
- package/src/tool/watch-savings-planner/i18n/fr.ts +51 -51
- package/src/tool/watch-savings-planner/i18n/id.ts +5 -5
- package/src/tool/watch-savings-planner/i18n/it.ts +29 -29
- package/src/tool/watch-savings-planner/i18n/ja.ts +73 -73
- package/src/tool/watch-savings-planner/i18n/ko.ts +73 -73
- package/src/tool/watch-savings-planner/i18n/nl.ts +10 -10
- package/src/tool/watch-savings-planner/i18n/pl.ts +5 -5
- package/src/tool/watch-savings-planner/i18n/pt.ts +43 -43
- package/src/tool/watch-savings-planner/i18n/ru.ts +7 -7
- package/src/tool/watch-savings-planner/i18n/sv.ts +54 -54
- package/src/tool/watch-savings-planner/i18n/tr.ts +50 -50
- package/src/tool/watch-savings-planner/i18n/zh.ts +73 -73
- package/src/tool/watch-size-comparator/i18n/de.ts +2 -2
- package/src/tool/watch-size-comparator/i18n/en.ts +3 -3
- package/src/tool/watch-size-comparator/i18n/es.ts +1 -1
- package/src/tool/watch-size-comparator/i18n/fr.ts +10 -10
- package/src/tool/watch-size-comparator/i18n/id.ts +9 -9
- package/src/tool/watch-size-comparator/i18n/it.ts +8 -8
- package/src/tool/watch-size-comparator/i18n/ja.ts +6 -6
- package/src/tool/watch-size-comparator/i18n/nl.ts +7 -7
- package/src/tool/watch-size-comparator/i18n/pl.ts +2 -2
- package/src/tool/watch-size-comparator/i18n/pt.ts +9 -9
- package/src/tool/watch-size-comparator/i18n/ru.ts +16 -16
- package/src/tool/watch-size-comparator/i18n/tr.ts +1 -1
- package/src/tool/watch-size-comparator/i18n/zh.ts +5 -5
- package/src/tool/water-resistance-converter/i18n/de.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/en.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/es.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/fr.ts +2 -2
- package/src/tool/water-resistance-converter/i18n/id.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/it.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/ja.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/ko.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/nl.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/pl.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/pt.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/ru.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/sv.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/tr.ts +1 -1
- package/src/tool/water-resistance-converter/i18n/zh.ts +4 -4
- package/src/tool/wrist-presence-calculator/i18n/en.ts +1 -1
- package/src/tool/wrist-presence-calculator/i18n/fr.ts +5 -5
- package/src/tool/wrist-presence-calculator/i18n/id.ts +1 -1
- package/src/tool/wrist-presence-calculator/i18n/zh.ts +1 -1
- package/src/tools.ts +4 -0
|
@@ -4,7 +4,7 @@ import { bibliography } from '../bibliography';
|
|
|
4
4
|
|
|
5
5
|
export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
6
6
|
slug: 'simulyator-tsveta-lyuminofora',
|
|
7
|
-
title: 'Симулятор цвета
|
|
7
|
+
title: 'Симулятор цвета люминофора: визуализатор свечения часов',
|
|
8
8
|
description: 'Визуализируйте разные цвета люминофора в реальном времени. Сравнивайте C1, C3, BGW9, LumiNova и другие типы при разной яркости освещения.',
|
|
9
9
|
ui: {
|
|
10
10
|
title: 'Симулятор цвета люминофора',
|
|
@@ -37,8 +37,8 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
37
37
|
tipContent: 'Яркость люминофора зависит от качества пигмента и того, сколько света он поглотил. BGW9 светится голубовато-белым и является самым ярким, тогда как винтажный люминофор даёт тёплое, приглушённое свечение.',
|
|
38
38
|
},
|
|
39
39
|
seo: [
|
|
40
|
-
{ type: 'title', text: 'Симулятор свечения циферблата
|
|
41
|
-
{ type: 'paragraph', html: 'Люминофор
|
|
40
|
+
{ type: 'title', text: 'Симулятор свечения циферблата - визуализатор люминофора в реальном времени', level: 2 },
|
|
41
|
+
{ type: 'paragraph', html: 'Люминофор - один из самых личных аспектов в коллекционировании часов. Вам ближе классическое зелёное свечение <strong>C1 Super-LumiNova</strong> или ледяной голубой <strong>BGW9</strong>? Этот симулятор покажет, как каждый тип люминофора выглядит при разной яркости - от полного дневного света до кромешной тьмы - с точными значениями <strong>HEX и RGB</strong> для каждого оттенка.' },
|
|
42
42
|
{ type: 'title', text: 'Сравнение типов Super-LumiNova', level: 3 },
|
|
43
43
|
{
|
|
44
44
|
type: 'table', headers: ['Тип', 'Цвет днём', 'Цвет свечения', 'Яркость', 'Для каких часов'], rows: [
|
|
@@ -52,7 +52,7 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
52
52
|
['Зелёный', 'Ярко-зелёный', 'Зелёный', 'Высокая', 'Часы в военном стиле'],
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
|
-
{ type: 'title', text: 'C1 vs C3 vs BGW9
|
|
55
|
+
{ type: 'title', text: 'C1 vs C3 vs BGW9 - что выбрать?', level: 3 },
|
|
56
56
|
{
|
|
57
57
|
type: 'comparative', columns: 2, items: [
|
|
58
58
|
{ title: 'C1 Классический зелёный', icon: 'mdi:lightbulb-on', description: 'Оригинальная формула Super-LumiNova. Светится зелёным со средней яркостью. Надёжный, классический выбор, подходящий к любому стилю часов.', points: ['Средняя яркость, видимость 4-6 ч', 'Зелёное свечение, тёплый оттенок', 'Самая доступная формула', 'Часто встречается в начальном сегменте'], highlight: false },
|
|
@@ -65,34 +65,34 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
65
65
|
{ title: 'Винтаж в стиле радия', icon: 'mdi:fire', description: 'Тёплый бежево-кремовый оттенок, имитирующий люминофор 1960-х годов. Намеренно более тусклый ради аутентичности. Свечение тёплое, тонкое и красиво стареет.', points: ['Низкая яркость, видимость 2-4 ч', 'Тёплый кремовый до тусклого янтарного', 'Состаренный вид без радиоактивности', 'Популярен в репликах ретро-моделей'], highlight: false },
|
|
66
66
|
]
|
|
67
67
|
},
|
|
68
|
-
{ type: 'diagnostic', variant: 'info', title: '
|
|
68
|
+
{ type: 'diagnostic', variant: 'info', title: 'Яркость: не главное', icon: 'mdi:palette', html: 'Самый яркий люминофор (C3) не всегда лучший выбор. <strong>BGW9</strong> жертвует небольшую разницу в яркости ради более нейтрального, современного вида, который многим коллекционерам нравится больше. <strong>Винтажный люминофор</strong> ставит историческую достоверность выше производительности. Выбирайте исходя из того, что для вас важнее: <strong>максимальное свечение, современная эстетика или историческая аутентичность.</strong>' },
|
|
69
69
|
{ type: 'title', text: 'Как работает люминофор: наука свечения', level: 3 },
|
|
70
70
|
{
|
|
71
71
|
type: 'glossary', items: [
|
|
72
72
|
{ term: 'Super-LumiNova', definition: 'Фотолюминесцентный пигмент на основе алюмината стронция. Поглощает ультрафиолетовый и видимый свет и переизлучает его в виде свечения. Не радиоактивен и безопасен. Первоначально разработан компанией Nemoto & Co. в 1993 году.' },
|
|
73
73
|
{ term: 'Время зарядки', definition: 'Длительность светового воздействия, необходимая для насыщения люминофора. Полная зарядка занимает 10-30 минут под прямыми солнечными лучами или УФ-лампой. Чем дольше зарядка, тем ярче и дольше свечение.' },
|
|
74
|
-
{ term: 'Длительность свечения', definition: 'Как долго люминофор остаётся видимым после зарядки. Качественный Super-LumiNova светится 6-12 часов. Самый яркий период
|
|
74
|
+
{ term: 'Длительность свечения', definition: 'Как долго люминофор остаётся видимым после зарядки. Качественный Super-LumiNova светится 6-12 часов. Самый яркий период - первые 30 минут после зарядки.' },
|
|
75
75
|
{ term: 'Класс пигмента', definition: 'Качество кристаллов алюмината стронция. Пигменты высшего класса (C3, BGW9) используют более крупные однородные кристаллы для более яркого и долгого свечения. Пигменты низшего класса (LumiNova) используют более мелкие кристаллы и светят тусклее.' },
|
|
76
76
|
]
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
type: 'summary', title: 'Краткий гайд по выбору люминофора', items: [
|
|
80
80
|
'Для максимальной читаемости в темноте: выбирайте C3 (самый яркий зелёный) или BGW9 (самый яркий голубовато-белый).',
|
|
81
|
-
'Для современного люксового вида: BGW9
|
|
81
|
+
'Для современного люксового вида: BGW9 - текущий фаворит среди премиальных брендов.',
|
|
82
82
|
'Для винтажных и ретро-моделей: используйте Vintage или Orange для исторической достоверности.',
|
|
83
|
-
'C1
|
|
84
|
-
'Цвет люминофора днём и цвет свечения сильно отличаются
|
|
83
|
+
'C1 - универсал: хорошая яркость, классический зелёный, доступная цена.',
|
|
84
|
+
'Цвет люминофора днём и цвет свечения сильно отличаются - используйте симулятор, чтобы сравнить оба режима.',
|
|
85
85
|
]
|
|
86
86
|
},
|
|
87
87
|
],
|
|
88
88
|
faq: [
|
|
89
89
|
{
|
|
90
90
|
question: 'Какой люминофор самый яркий?',
|
|
91
|
-
answer: 'C3 Super-LumiNova
|
|
91
|
+
answer: 'C3 Super-LumiNova - самая яркая зелёная формула. BGW9 - самая яркая голубовато-белая. Обе значительно ярче C1 или стандартного LumiNova.',
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
question: 'Что такое люминофор BGW9?',
|
|
95
|
-
answer: 'BGW9
|
|
95
|
+
answer: 'BGW9 - это разновидность Super-LumiNova, которая светится голубовато-белым вместо зелёного. Немного уступает C3 по яркости, но многие ценят его за чистый, современный вид.',
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
question: 'Светится ли винтажный люминофор?',
|
|
@@ -100,7 +100,7 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
question: 'Как долго держится люминофор?',
|
|
103
|
-
answer: 'После полной зарядки под ярким светом качественный Super-LumiNova остаётся видимым 6-12 часов. Самый яркий период
|
|
103
|
+
answer: 'После полной зарядки под ярким светом качественный Super-LumiNova остаётся видимым 6-12 часов. Самый яркий период - первые 30 минут.',
|
|
104
104
|
},
|
|
105
105
|
],
|
|
106
106
|
bibliography,
|
|
@@ -126,12 +126,12 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
126
126
|
{
|
|
127
127
|
'@type': 'Question',
|
|
128
128
|
'name': 'Какой люминофор самый яркий?',
|
|
129
|
-
'acceptedAnswer': { '@type': 'Answer', 'text': 'C3 Super-LumiNova
|
|
129
|
+
'acceptedAnswer': { '@type': 'Answer', 'text': 'C3 Super-LumiNova - самый яркий зелёный. BGW9 - самый яркий голубовато-белый.' },
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
'@type': 'Question',
|
|
133
133
|
'name': 'Что такое люминофор BGW9?',
|
|
134
|
-
'acceptedAnswer': { '@type': 'Answer', 'text': 'BGW9
|
|
134
|
+
'acceptedAnswer': { '@type': 'Answer', 'text': 'BGW9 - это разновидность Super-LumiNova, которая светится голубовато-белым вместо зелёного.' },
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
'@type': 'Question',
|
|
@@ -4,7 +4,7 @@ import { bibliography } from '../bibliography';
|
|
|
4
4
|
|
|
5
5
|
export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
6
6
|
slug: 'lume-color-simulator',
|
|
7
|
-
title: '
|
|
7
|
+
title: '夜光颜色模拟器: 手表夜光效果在线预览',
|
|
8
8
|
description: '实时预览不同夜光颜色的效果。对比 C1、C3、BGW9、LumiNova 等多种夜光在不同环境亮度下的表现。',
|
|
9
9
|
ui: {
|
|
10
10
|
title: '夜光颜色模拟器',
|
|
@@ -37,7 +37,7 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
37
37
|
tipContent: '夜光亮度取决于颜料品质和吸收光量的多少。BGW9 发出蓝白色光,亮度最高;而复古夜光呈暖色,亮度较暗。',
|
|
38
38
|
},
|
|
39
39
|
seo: [
|
|
40
|
-
{ type: 'title', text: '手表夜光颜色模拟器
|
|
40
|
+
{ type: 'title', text: '手表夜光颜色模拟器 - 实时发光效果预览', level: 2 },
|
|
41
41
|
{ type: 'paragraph', html: '夜光是手表收藏中最个性化的选择之一。你偏爱 <strong>C1 Super-LumiNova</strong> 的经典绿色光芒,还是 <strong>BGW9</strong> 的冰蓝色调?本模拟器展示每种夜光类型在从日光到全黑不同亮度等级下的表现,并提供每种颜色的精确 <strong>HEX 和 RGB 值</strong>。' },
|
|
42
42
|
{ type: 'title', text: 'Super-LumiNova 类型对比', level: 3 },
|
|
43
43
|
{
|
|
@@ -52,7 +52,7 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
52
52
|
['Green', '亮绿色', '绿色', '高', '军表风格手表'],
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
|
-
{ type: 'title', text: 'C1 vs C3 vs BGW9
|
|
55
|
+
{ type: 'title', text: 'C1 vs C3 vs BGW9 - 该如何选择?', level: 3 },
|
|
56
56
|
{
|
|
57
57
|
type: 'comparative', columns: 2, items: [
|
|
58
58
|
{ title: 'C1 经典绿色', icon: 'mdi:lightbulb-on', description: 'Super-LumiNova 最早期的配方。发出中等亮度的绿色荧光。安全经典,适合任何手表风格。', points: ['中等亮度,可见 4-6 小时', '绿色发光,暖色调', '最经济的配方', '常见于入门级手表'], highlight: false },
|
|
@@ -81,7 +81,7 @@ export const content: ToolLocaleContent<LumeColorSimulatorUI> = {
|
|
|
81
81
|
'追求现代豪华质感:BGW9 是目前高端手表品牌中的热门之选。',
|
|
82
82
|
'追求复古/复刻风格:使用 Vintage 或 Orange 以获得时代准确的温暖色调。',
|
|
83
83
|
'C1 是万金油:亮度不错、经典绿色、价格实惠。',
|
|
84
|
-
'
|
|
84
|
+
'夜光在日光下的颜色与发光颜色差异很大-使用模拟器同时对比两者。',
|
|
85
85
|
]
|
|
86
86
|
},
|
|
87
87
|
],
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { mainspringFinder } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'en' } = Astro.props as Props;
|
|
11
|
+
const loader = mainspringFinder.i18n[locale] || mainspringFinder.i18n.en;
|
|
12
|
+
const content = await loader?.();
|
|
13
|
+
if (!content) return null;
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
{content && <SharedBibliography links={content.bibliography} />}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BibliographyEntry } from '../../types';
|
|
2
|
+
|
|
3
|
+
export const bibliography: BibliographyEntry[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'Mainspring Dimensions & Specifications - Ranfft',
|
|
6
|
+
url: 'https://ranfft.org/caliber/5755-FHF-76-2',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
name: 'Watch Mainspring Guide',
|
|
10
|
+
url: 'https://www.vintagewatchstraps.com/mainsprings.php',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: 'Mainspring Sizing Chart - Cousins UK',
|
|
14
|
+
url: 'https://www.cousinsuk.com/category/filter/mainsprings-by-size-search-watch-pocket',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { calculateMainspring, fmt } from './helpers';
|
|
2
|
+
|
|
3
|
+
const el = document.querySelector('.msf') as HTMLElement;
|
|
4
|
+
const UI = JSON.parse(el.dataset.ui || '{}');
|
|
5
|
+
|
|
6
|
+
const barrelIn = document.getElementById('msf-barrel') as HTMLInputElement;
|
|
7
|
+
const arborIn = document.getElementById('msf-arbor') as HTMLInputElement;
|
|
8
|
+
const heightIn = document.getElementById('msf-height') as HTMLInputElement;
|
|
9
|
+
const turnsIn = document.getElementById('msf-turns') as HTMLInputElement;
|
|
10
|
+
const unitBtns = document.querySelectorAll('.msf-u-btn') as NodeListOf<HTMLElement>;
|
|
11
|
+
const result = document.getElementById('msf-result') as HTMLElement;
|
|
12
|
+
const thickV = document.getElementById('msf-thick') as HTMLElement;
|
|
13
|
+
const heightV = document.getElementById('msf-h') as HTMLElement;
|
|
14
|
+
const lenV = document.getElementById('msf-len') as HTMLElement;
|
|
15
|
+
const strengthB = document.getElementById('msf-strength') as HTMLElement;
|
|
16
|
+
const commV = document.getElementById('msf-comm') as HTMLElement;
|
|
17
|
+
|
|
18
|
+
const sLabels = [UI.strengthWeak || 'Light', UI.strengthMedium || 'Medium', UI.strengthStrong || 'Strong'];
|
|
19
|
+
const sColors = ['#10b981', '#f59e0b', '#ef4444'];
|
|
20
|
+
const KEY = 'jjlmoya_chrono_msf';
|
|
21
|
+
let cur: 'mm' | 'in' = 'mm';
|
|
22
|
+
|
|
23
|
+
interface S { b: string; a: string; h: string; t: string; u: string }
|
|
24
|
+
|
|
25
|
+
function parseNum(v: string): number {
|
|
26
|
+
return parseFloat(v.replace(',', '.')) || 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function save() {
|
|
30
|
+
try { localStorage.setItem(KEY, JSON.stringify({ b: barrelIn.value, a: arborIn.value, h: heightIn.value, t: turnsIn.value, u: cur } as S)); } catch {}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function load() {
|
|
34
|
+
try {
|
|
35
|
+
const r = localStorage.getItem(KEY);
|
|
36
|
+
if (!r) return;
|
|
37
|
+
const s: S = JSON.parse(r);
|
|
38
|
+
const pairs: [string | undefined, HTMLInputElement][] = [[s.b, barrelIn], [s.a, arborIn], [s.h, heightIn], [s.t, turnsIn]];
|
|
39
|
+
for (const [v, el] of pairs) { if (v) el.value = v; }
|
|
40
|
+
if (s.u === 'in' || s.u === 'mm') cur = s.u;
|
|
41
|
+
} catch {}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function convertVal(v: number, from: 'mm' | 'in', to: 'mm' | 'in'): number {
|
|
45
|
+
if (from === to) return v;
|
|
46
|
+
return to === 'in' ? v / 25.4 : v * 25.4;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function setUnit(u: 'mm' | 'in') {
|
|
50
|
+
if (u === cur) return;
|
|
51
|
+
const b = parseNum(barrelIn.value);
|
|
52
|
+
const a = parseNum(arborIn.value);
|
|
53
|
+
const h = parseNum(heightIn.value);
|
|
54
|
+
barrelIn.value = convertVal(b, cur, u).toFixed(u === 'in' ? 2 : 1);
|
|
55
|
+
arborIn.value = convertVal(a, cur, u).toFixed(u === 'in' ? 3 : 1);
|
|
56
|
+
heightIn.value = convertVal(h, cur, u).toFixed(u === 'in' ? 3 : 2);
|
|
57
|
+
barrelIn.step = ''; arborIn.step = ''; heightIn.step = '';
|
|
58
|
+
cur = u;
|
|
59
|
+
unitBtns.forEach(b => b.classList.toggle('msf-u-on', b.dataset.unit === u));
|
|
60
|
+
calc();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function calc() {
|
|
64
|
+
const barrelId = parseNum(barrelIn.value);
|
|
65
|
+
const arborD = parseNum(arborIn.value);
|
|
66
|
+
const height = parseNum(heightIn.value);
|
|
67
|
+
const turns = parseInt(turnsIn.value, 10) || 6;
|
|
68
|
+
const r = calculateMainspring({ barrelId, barrelH: height, arborD, turns, unit: cur });
|
|
69
|
+
if (!r) { result.style.display = 'none'; return; }
|
|
70
|
+
|
|
71
|
+
const ul = cur;
|
|
72
|
+
thickV.textContent = `${fmt(r.thickness, cur, cur === 'in' ? 4 : 3)} ${ul}`;
|
|
73
|
+
heightV.textContent = `${fmt(r.height, cur, 2)} ${ul}`;
|
|
74
|
+
lenV.textContent = `${fmt(r.length, cur, 1)} ${ul}`;
|
|
75
|
+
strengthB.textContent = sLabels[r.strengthIndex];
|
|
76
|
+
strengthB.style.background = sColors[r.strengthIndex];
|
|
77
|
+
commV.textContent = `${fmt(r.height, cur, 2)} x ${fmt(r.thickness, cur, cur === 'in' ? 4 : 3)} x ${fmt(r.length, cur, 1)} ${ul}`;
|
|
78
|
+
result.style.display = 'flex';
|
|
79
|
+
save();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
unitBtns.forEach(b => b.addEventListener('click', () => setUnit(b.dataset.unit as 'mm' | 'in')));
|
|
83
|
+
barrelIn.addEventListener('input', calc);
|
|
84
|
+
arborIn.addEventListener('input', calc);
|
|
85
|
+
heightIn.addEventListener('input', calc);
|
|
86
|
+
turnsIn.addEventListener('input', calc);
|
|
87
|
+
load();
|
|
88
|
+
setUnit(cur);
|
|
89
|
+
calc();
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface Props { ui: Record<string, string> }
|
|
3
|
+
const { ui } = Astro.props;
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<div class="msf" data-ui={JSON.stringify(ui)}>
|
|
7
|
+
<div class="msf-top">
|
|
8
|
+
<div class="msf-u">
|
|
9
|
+
<button class="msf-u-btn msf-u-on" data-unit="mm" type="button">{ui.mm || "mm"}</button>
|
|
10
|
+
<button class="msf-u-btn" data-unit="in" type="button">{ui.inch || "in"}</button>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="msf-grid">
|
|
15
|
+
<label class="msf-f">
|
|
16
|
+
<span class="msf-f-l">{ui.barrelLabel || "Barrel ID"}</span>
|
|
17
|
+
<input class="msf-f-i" id="msf-barrel" type="text" inputmode="decimal" value="14.0" />
|
|
18
|
+
</label>
|
|
19
|
+
<label class="msf-f">
|
|
20
|
+
<span class="msf-f-l">{ui.arborLabel || "Arbor OD"}</span>
|
|
21
|
+
<input class="msf-f-i" id="msf-arbor" type="text" inputmode="decimal" value="3.5" />
|
|
22
|
+
</label>
|
|
23
|
+
<label class="msf-f">
|
|
24
|
+
<span class="msf-f-l">{ui.heightLabel || "Height"}</span>
|
|
25
|
+
<input class="msf-f-i" id="msf-height" type="text" inputmode="decimal" value="1.50" />
|
|
26
|
+
</label>
|
|
27
|
+
<label class="msf-f">
|
|
28
|
+
<span class="msf-f-l">{ui.turnsLabel || "Turns"}</span>
|
|
29
|
+
<input class="msf-f-i" id="msf-turns" type="text" inputmode="numeric" value="6" />
|
|
30
|
+
</label>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="msf-r" id="msf-result">
|
|
34
|
+
<div class="msf-r-grid">
|
|
35
|
+
<div class="msf-r-c">
|
|
36
|
+
<span class="msf-r-c-l">{ui.resultThickness || "Thickness"}</span>
|
|
37
|
+
<span class="msf-r-c-v" id="msf-thick">--</span>
|
|
38
|
+
</div>
|
|
39
|
+
<div class="msf-r-c">
|
|
40
|
+
<span class="msf-r-c-l">{ui.resultHeight || "Height"}</span>
|
|
41
|
+
<span class="msf-r-c-v" id="msf-h">--</span>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="msf-r-c">
|
|
44
|
+
<span class="msf-r-c-l">{ui.resultLength || "Length"}</span>
|
|
45
|
+
<span class="msf-r-c-v" id="msf-len">--</span>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="msf-r-bot">
|
|
49
|
+
<div class="msf-r-bot-i">
|
|
50
|
+
<span class="msf-r-bot-l">{ui.resultStrength || "Strength"}</span>
|
|
51
|
+
<span class="msf-badge" id="msf-strength">--</span>
|
|
52
|
+
</div>
|
|
53
|
+
<div class="msf-r-bot-i">
|
|
54
|
+
<span class="msf-r-bot-l">{ui.commercial || "Size"}</span>
|
|
55
|
+
<span class="msf-r-bot-v" id="msf-comm">--</span>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="msf-steps">
|
|
61
|
+
<div class="msf-step"><span class="msf-step-n">1</span><span>{ui.step1 || "Measure barrel ID, arbor OD, and height."}</span></div>
|
|
62
|
+
<div class="msf-step"><span class="msf-step-n">2</span><span>{ui.step2 || "Set winding turns (5-8 manual, 6-10 auto)."}</span></div>
|
|
63
|
+
<div class="msf-step"><span class="msf-step-n">3</span><span>{ui.step3 || "Toggle mm/in for your unit."}</span></div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div class="msf-tip">
|
|
67
|
+
<svg viewBox="0 0 24 24" width="14" height="14" style="flex-shrink:0;margin-top:0.05rem"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill="currentColor"/></svg>
|
|
68
|
+
<span>{ui.tipContent || "Always verify against manufacturer specs before ordering."}</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<script src="./client.ts"></script>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { ChronoToolEntry, ToolLocaleContent } from '../../types';
|
|
2
|
+
|
|
3
|
+
export type MainspringFinderUI = {
|
|
4
|
+
title: string;
|
|
5
|
+
barrelLabel: string;
|
|
6
|
+
arborLabel: string;
|
|
7
|
+
heightLabel: string;
|
|
8
|
+
turnsLabel: string;
|
|
9
|
+
calculate: string;
|
|
10
|
+
resultThickness: string;
|
|
11
|
+
resultHeight: string;
|
|
12
|
+
resultLength: string;
|
|
13
|
+
resultStrength: string;
|
|
14
|
+
strengthWeak: string;
|
|
15
|
+
strengthMedium: string;
|
|
16
|
+
strengthStrong: string;
|
|
17
|
+
commercial: string;
|
|
18
|
+
unitLabel: string;
|
|
19
|
+
mm: string;
|
|
20
|
+
inch: string;
|
|
21
|
+
step1: string;
|
|
22
|
+
step2: string;
|
|
23
|
+
step3: string;
|
|
24
|
+
tipTitle: string;
|
|
25
|
+
tipContent: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type MainspringFinderLocaleContent = ToolLocaleContent<MainspringFinderUI>;
|
|
29
|
+
|
|
30
|
+
export const mainspringFinder: ChronoToolEntry<MainspringFinderUI> = {
|
|
31
|
+
id: 'mainspring-finder',
|
|
32
|
+
icons: { bg: 'mdi:ruler', fg: 'mdi:cog-clockwise' },
|
|
33
|
+
i18n: {
|
|
34
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
35
|
+
de: () => import('./i18n/de').then((m) => m.content),
|
|
36
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
37
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
38
|
+
id: () => import('./i18n/id').then((m) => m.content),
|
|
39
|
+
it: () => import('./i18n/it').then((m) => m.content),
|
|
40
|
+
ja: () => import('./i18n/ja').then((m) => m.content),
|
|
41
|
+
ko: () => import('./i18n/ko').then((m) => m.content),
|
|
42
|
+
nl: () => import('./i18n/nl').then((m) => m.content),
|
|
43
|
+
pl: () => import('./i18n/pl').then((m) => m.content),
|
|
44
|
+
pt: () => import('./i18n/pt').then((m) => m.content),
|
|
45
|
+
ru: () => import('./i18n/ru').then((m) => m.content),
|
|
46
|
+
sv: () => import('./i18n/sv').then((m) => m.content),
|
|
47
|
+
tr: () => import('./i18n/tr').then((m) => m.content),
|
|
48
|
+
zh: () => import('./i18n/zh').then((m) => m.content),
|
|
49
|
+
},
|
|
50
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface MainspringInput {
|
|
2
|
+
barrelId: number;
|
|
3
|
+
barrelH: number;
|
|
4
|
+
arborD: number;
|
|
5
|
+
turns: number;
|
|
6
|
+
unit: 'mm' | 'in';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface MainspringResult {
|
|
10
|
+
thickness: number;
|
|
11
|
+
height: number;
|
|
12
|
+
length: number;
|
|
13
|
+
strengthIndex: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function toMm(val: number, unit: 'mm' | 'in'): number {
|
|
17
|
+
return unit === 'in' ? val * 25.4 : val;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function fmt(val: number, unit: 'mm' | 'in', dec: number): string {
|
|
21
|
+
const v = unit === 'in' ? val / 25.4 : val;
|
|
22
|
+
return v.toFixed(dec);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getStrengthIndex(thickness: number): number {
|
|
26
|
+
if (thickness <= 0.10) return 0;
|
|
27
|
+
if (thickness <= 0.18) return 1;
|
|
28
|
+
return 2;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function calculateMainspring(input: MainspringInput): MainspringResult | null {
|
|
32
|
+
let { barrelId, barrelH, arborD } = input;
|
|
33
|
+
const { turns, unit } = input;
|
|
34
|
+
barrelId = toMm(barrelId, unit);
|
|
35
|
+
barrelH = toMm(barrelH, unit);
|
|
36
|
+
arborD = toMm(arborD, unit);
|
|
37
|
+
|
|
38
|
+
if (barrelId <= 0 || arborD <= 0 || barrelH <= 0 || arborD >= barrelId) return null;
|
|
39
|
+
|
|
40
|
+
const clearance = 0.1;
|
|
41
|
+
const height = barrelH - clearance;
|
|
42
|
+
|
|
43
|
+
const thickness = (barrelId - arborD) / (4 * Math.PI * turns);
|
|
44
|
+
const length = (Math.PI * turns * (barrelId + arborD)) / 2;
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
thickness: Math.round(thickness * 1000) / 1000,
|
|
48
|
+
height: Math.round(height * 100) / 100,
|
|
49
|
+
length: Math.round(length * 10) / 10,
|
|
50
|
+
strengthIndex: getStrengthIndex(thickness),
|
|
51
|
+
};
|
|
52
|
+
}
|