@quenty/metricutils 2.4.4 → 2.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.
- package/CHANGELOG.md +6 -0
- package/README.md +80 -2
- package/deploy.nevermore.json +10 -0
- package/package.json +22 -4
- package/src/Shared/Definitions/MetricUnitDefinitions.lua +1082 -0
- package/src/Shared/Definitions/MetricUnitDefinitions.spec.lua +55 -0
- package/src/Shared/Definitions/MetricUnitDimensionUtils.lua +164 -0
- package/src/Shared/Definitions/MetricUnitDimensionUtils.spec.lua +49 -0
- package/src/Shared/Definitions/MetricUnitKinds.lua +237 -0
- package/src/Shared/Definitions/MetricUnitKinds.spec.lua +51 -0
- package/src/Shared/Formatting/MetricUnitDisplayUnitUtils.lua +129 -0
- package/src/Shared/Formatting/MetricUnitFormatUtils.lua +924 -0
- package/src/Shared/Formatting/MetricUnitFormatUtils.spec.lua +280 -0
- package/src/Shared/Formatting/RxMetricUnitFormatUtils.lua +62 -0
- package/src/Shared/Localization/MetricUnitFallbackStrings.lua +289 -0
- package/src/Shared/Localization/MetricUnitFallbackStrings.spec.lua +82 -0
- package/src/Shared/Localization/MetricUnitTranslator/ar.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/de.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/en.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/es.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/fr.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/id.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/init.lua +92 -0
- package/src/Shared/Localization/MetricUnitTranslator/it.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/ja.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/ko.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/pl.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/pt.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/ru.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/th.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/tr.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/vi.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/zh-cn.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator/zh-tw.json.txt +182 -0
- package/src/Shared/Localization/MetricUnitTranslator.spec.lua +309 -0
- package/src/Shared/Localization/PluralCategoryUtils.lua +103 -0
- package/src/Shared/Localization/PluralCategoryUtils.spec.lua +77 -0
- package/src/Shared/Logarithmic/DecibelUtils.lua +72 -0
- package/src/Shared/Logarithmic/DecibelUtils.spec.lua +35 -0
- package/src/Shared/MetricUnit.Angles.spec.lua +80 -0
- package/src/Shared/MetricUnit.Customary.spec.lua +104 -0
- package/src/Shared/MetricUnit.Derived.spec.lua +173 -0
- package/src/Shared/MetricUnit.Display.spec.lua +153 -0
- package/src/Shared/MetricUnit.Electrical.spec.lua +114 -0
- package/src/Shared/MetricUnit.Math.spec.lua +112 -0
- package/src/Shared/MetricUnit.Roblox.spec.lua +34 -0
- package/src/Shared/MetricUnit.SI.spec.lua +127 -0
- package/src/Shared/MetricUnit.Spring.spec.lua +94 -0
- package/src/Shared/MetricUnit.Temperature.spec.lua +212 -0
- package/src/Shared/MetricUnit.Time.spec.lua +202 -0
- package/src/Shared/MetricUnit.Units.spec.lua +210 -0
- package/src/Shared/MetricUnit.lua +1730 -0
- package/src/Shared/MetricUnit.spec.lua +362 -0
- package/src/Shared/MetricUtils.lua +46 -15
- package/src/Shared/MetricUtils.spec.lua +76 -0
- package/src/Shared/Parsing/MetricUnitParseUtils.lua +799 -0
- package/src/Shared/Parsing/MetricUnitParseUtils.spec.lua +189 -0
- package/src/Shared/Systems/MetricUnitSystem.lua +322 -0
- package/src/Shared/Systems/MetricUnitSystem.spec.lua +181 -0
- package/src/Shared/Systems/MetricUnitSystems.lua +225 -0
- package/src/jest.config.lua +3 -0
- package/src/node_modules.project.json +7 -0
- package/test/default.project.json +25 -0
- package/test/scripts/Server/ServerMain.server.lua +14 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
{
|
|
2
|
+
"units": {
|
|
3
|
+
"microsecond": {"long":{"zero":"{n} 微秒","one":"{n} 微秒","two":"{n} 微秒","few":"{n} 微秒","many":"{n} 微秒","other":"{n} 微秒"},"short":{"zero":"{n} 微秒","one":"{n} 微秒","two":"{n} 微秒","few":"{n} 微秒","many":"{n} 微秒","other":"{n} 微秒"}},
|
|
4
|
+
"hertz": {"long":{"zero":"{n} 赫茲","one":"{n} 赫茲","two":"{n} 赫茲","few":"{n} 赫茲","many":"{n} 赫茲","other":"{n} 赫茲"},"short":{"zero":"{n} 赫茲","one":"{n} 赫茲","two":"{n} 赫茲","few":"{n} 赫茲","many":"{n} 赫茲","other":"{n} 赫茲"}},
|
|
5
|
+
"percent": {"long":{"zero":"{n}%","one":"{n}%","two":"{n}%","few":"{n}%","many":"{n}%","other":"{n}%"},"short":{"zero":"{n}%","one":"{n}%","two":"{n}%","few":"{n}%","many":"{n}%","other":"{n}%"}},
|
|
6
|
+
"permille": {"long":{"zero":"{n}‰","one":"{n}‰","two":"{n}‰","few":"{n}‰","many":"{n}‰","other":"{n}‰"},"short":{"zero":"{n}‰","one":"{n}‰","two":"{n}‰","few":"{n}‰","many":"{n}‰","other":"{n}‰"}},
|
|
7
|
+
"millimeter": {"long":{"zero":"{n} 公釐","one":"{n} 公釐","two":"{n} 公釐","few":"{n} 公釐","many":"{n} 公釐","other":"{n} 公釐"},"short":{"zero":"{n} 公釐","one":"{n} 公釐","two":"{n} 公釐","few":"{n} 公釐","many":"{n} 公釐","other":"{n} 公釐"}},
|
|
8
|
+
"centimeter": {"long":{"zero":"{n} 公分","one":"{n} 公分","two":"{n} 公分","few":"{n} 公分","many":"{n} 公分","other":"{n} 公分"},"short":{"zero":"{n} 公分","one":"{n} 公分","two":"{n} 公分","few":"{n} 公分","many":"{n} 公分","other":"{n} 公分"}},
|
|
9
|
+
"meter": {"long":{"zero":"{n} 公尺","one":"{n} 公尺","two":"{n} 公尺","few":"{n} 公尺","many":"{n} 公尺","other":"{n} 公尺"},"short":{"zero":"{n} 公尺","one":"{n} 公尺","two":"{n} 公尺","few":"{n} 公尺","many":"{n} 公尺","other":"{n} 公尺"}},
|
|
10
|
+
"kilometer": {"long":{"zero":"{n} 公里","one":"{n} 公里","two":"{n} 公里","few":"{n} 公里","many":"{n} 公里","other":"{n} 公里"},"short":{"zero":"{n} 公里","one":"{n} 公里","two":"{n} 公里","few":"{n} 公里","many":"{n} 公里","other":"{n} 公里"}},
|
|
11
|
+
"inch": {"long":{"zero":"{n} 英寸","one":"{n} 英寸","two":"{n} 英寸","few":"{n} 英寸","many":"{n} 英寸","other":"{n} 英寸"},"short":{"zero":"{n} 吋","one":"{n} 吋","two":"{n} 吋","few":"{n} 吋","many":"{n} 吋","other":"{n} 吋"}},
|
|
12
|
+
"foot": {"long":{"zero":"{n} 英尺","one":"{n} 英尺","two":"{n} 英尺","few":"{n} 英尺","many":"{n} 英尺","other":"{n} 英尺"},"short":{"zero":"{n}英尺","one":"{n}英尺","two":"{n}英尺","few":"{n}英尺","many":"{n}英尺","other":"{n}英尺"}},
|
|
13
|
+
"yard": {"long":{"zero":"{n} 碼","one":"{n} 碼","two":"{n} 碼","few":"{n} 碼","many":"{n} 碼","other":"{n} 碼"},"short":{"zero":"{n} 碼","one":"{n} 碼","two":"{n} 碼","few":"{n} 碼","many":"{n} 碼","other":"{n} 碼"}},
|
|
14
|
+
"mile": {"long":{"zero":"{n} 英里","one":"{n} 英里","two":"{n} 英里","few":"{n} 英里","many":"{n} 英里","other":"{n} 英里"},"short":{"zero":"{n} 英里","one":"{n} 英里","two":"{n} 英里","few":"{n} 英里","many":"{n} 英里","other":"{n} 英里"}},
|
|
15
|
+
"stud": {"long":{"zero":"{n} studs","one":"{n} studs","two":"{n} studs","few":"{n} studs","many":"{n} studs","other":"{n} studs"},"short":{"zero":"{n} studs","one":"{n} studs","two":"{n} studs","few":"{n} studs","many":"{n} studs","other":"{n} studs"}},
|
|
16
|
+
"squareMillimeter": {"long":{"zero":"{n} 平方公釐","one":"{n} 平方公釐","two":"{n} 平方公釐","few":"{n} 平方公釐","many":"{n} 平方公釐","other":"{n} 平方公釐"},"short":{"zero":"{n} 公釐²","one":"{n} 公釐²","two":"{n} 公釐²","few":"{n} 公釐²","many":"{n} 公釐²","other":"{n} 公釐²"}},
|
|
17
|
+
"squareCentimeter": {"long":{"zero":"{n} 平方公分","one":"{n} 平方公分","two":"{n} 平方公分","few":"{n} 平方公分","many":"{n} 平方公分","other":"{n} 平方公分"},"short":{"zero":"{n} 平方公分","one":"{n} 平方公分","two":"{n} 平方公分","few":"{n} 平方公分","many":"{n} 平方公分","other":"{n} 平方公分"}},
|
|
18
|
+
"squareMeter": {"long":{"zero":"{n} 平方公尺","one":"{n} 平方公尺","two":"{n} 平方公尺","few":"{n} 平方公尺","many":"{n} 平方公尺","other":"{n} 平方公尺"},"short":{"zero":"{n} 平方公尺","one":"{n} 平方公尺","two":"{n} 平方公尺","few":"{n} 平方公尺","many":"{n} 平方公尺","other":"{n} 平方公尺"}},
|
|
19
|
+
"hectare": {"long":{"zero":"{n} 公頃","one":"{n} 公頃","two":"{n} 公頃","few":"{n} 公頃","many":"{n} 公頃","other":"{n} 公頃"},"short":{"zero":"{n} 公頃","one":"{n} 公頃","two":"{n} 公頃","few":"{n} 公頃","many":"{n} 公頃","other":"{n} 公頃"}},
|
|
20
|
+
"squareKilometer": {"long":{"zero":"{n} 平方公里","one":"{n} 平方公里","two":"{n} 平方公里","few":"{n} 平方公里","many":"{n} 平方公里","other":"{n} 平方公里"},"short":{"zero":"{n} 平方公里","one":"{n} 平方公里","two":"{n} 平方公里","few":"{n} 平方公里","many":"{n} 平方公里","other":"{n} 平方公里"}},
|
|
21
|
+
"squareFoot": {"long":{"zero":"{n} 平方英尺","one":"{n} 平方英尺","two":"{n} 平方英尺","few":"{n} 平方英尺","many":"{n} 平方英尺","other":"{n} 平方英尺"},"short":{"zero":"{n} 平方英尺","one":"{n} 平方英尺","two":"{n} 平方英尺","few":"{n} 平方英尺","many":"{n} 平方英尺","other":"{n} 平方英尺"}},
|
|
22
|
+
"acre": {"long":{"zero":"{n} 英畝","one":"{n} 英畝","two":"{n} 英畝","few":"{n} 英畝","many":"{n} 英畝","other":"{n} 英畝"},"short":{"zero":"{n} 英畝","one":"{n} 英畝","two":"{n} 英畝","few":"{n} 英畝","many":"{n} 英畝","other":"{n} 英畝"}},
|
|
23
|
+
"milliliter": {"long":{"zero":"{n} 毫升","one":"{n} 毫升","two":"{n} 毫升","few":"{n} 毫升","many":"{n} 毫升","other":"{n} 毫升"},"short":{"zero":"{n} 毫升","one":"{n} 毫升","two":"{n} 毫升","few":"{n} 毫升","many":"{n} 毫升","other":"{n} 毫升"}},
|
|
24
|
+
"liter": {"long":{"zero":"{n} 公升","one":"{n} 公升","two":"{n} 公升","few":"{n} 公升","many":"{n} 公升","other":"{n} 公升"},"short":{"zero":"{n} 升","one":"{n} 升","two":"{n} 升","few":"{n} 升","many":"{n} 升","other":"{n} 升"}},
|
|
25
|
+
"cubicMeter": {"long":{"zero":"{n} 立方公尺","one":"{n} 立方公尺","two":"{n} 立方公尺","few":"{n} 立方公尺","many":"{n} 立方公尺","other":"{n} 立方公尺"},"short":{"zero":"{n} 立方公尺","one":"{n} 立方公尺","two":"{n} 立方公尺","few":"{n} 立方公尺","many":"{n} 立方公尺","other":"{n} 立方公尺"}},
|
|
26
|
+
"usFluidOunce": {"long":{"zero":"{n} 液盎司","one":"{n} 液盎司","two":"{n} 液盎司","few":"{n} 液盎司","many":"{n} 液盎司","other":"{n} 液盎司"},"short":{"zero":"{n} 液盎司","one":"{n} 液盎司","two":"{n} 液盎司","few":"{n} 液盎司","many":"{n} 液盎司","other":"{n} 液盎司"}},
|
|
27
|
+
"usGallon": {"long":{"zero":"{n} 加侖","one":"{n} 加侖","two":"{n} 加侖","few":"{n} 加侖","many":"{n} 加侖","other":"{n} 加侖"},"short":{"zero":"{n} 加侖","one":"{n} 加侖","two":"{n} 加侖","few":"{n} 加侖","many":"{n} 加侖","other":"{n} 加侖"}},
|
|
28
|
+
"imperialGallon": {"long":{"zero":"{n} 英制加侖","one":"{n} 英制加侖","two":"{n} 英制加侖","few":"{n} 英制加侖","many":"{n} 英制加侖","other":"{n} 英制加侖"},"short":{"zero":"{n} 英制加侖","one":"{n} 英制加侖","two":"{n} 英制加侖","few":"{n} 英制加侖","many":"{n} 英制加侖","other":"{n} 英制加侖"}},
|
|
29
|
+
"bit": {"long":{"zero":"{n} bit","one":"{n} bit","two":"{n} bit","few":"{n} bit","many":"{n} bit","other":"{n} bit"},"short":{"zero":"{n} bit","one":"{n} bit","two":"{n} bit","few":"{n} bit","many":"{n} bit","other":"{n} bit"}},
|
|
30
|
+
"kilobit": {"long":{"zero":"{n} kb","one":"{n} kb","two":"{n} kb","few":"{n} kb","many":"{n} kb","other":"{n} kb"},"short":{"zero":"{n} kb","one":"{n} kb","two":"{n} kb","few":"{n} kb","many":"{n} kb","other":"{n} kb"}},
|
|
31
|
+
"megabit": {"long":{"zero":"{n} Mb","one":"{n} Mb","two":"{n} Mb","few":"{n} Mb","many":"{n} Mb","other":"{n} Mb"},"short":{"zero":"{n} Mb","one":"{n} Mb","two":"{n} Mb","few":"{n} Mb","many":"{n} Mb","other":"{n} Mb"}},
|
|
32
|
+
"gigabit": {"long":{"zero":"{n} Gb","one":"{n} Gb","two":"{n} Gb","few":"{n} Gb","many":"{n} Gb","other":"{n} Gb"},"short":{"zero":"{n} Gb","one":"{n} Gb","two":"{n} Gb","few":"{n} Gb","many":"{n} Gb","other":"{n} Gb"}},
|
|
33
|
+
"byte": {"long":{"zero":"{n} byte","one":"{n} byte","two":"{n} byte","few":"{n} byte","many":"{n} byte","other":"{n} byte"},"short":{"zero":"{n} byte","one":"{n} byte","two":"{n} byte","few":"{n} byte","many":"{n} byte","other":"{n} byte"}},
|
|
34
|
+
"kilobyte": {"long":{"zero":"{n} kB","one":"{n} kB","two":"{n} kB","few":"{n} kB","many":"{n} kB","other":"{n} kB"},"short":{"zero":"{n} kB","one":"{n} kB","two":"{n} kB","few":"{n} kB","many":"{n} kB","other":"{n} kB"}},
|
|
35
|
+
"megabyte": {"long":{"zero":"{n} MB","one":"{n} MB","two":"{n} MB","few":"{n} MB","many":"{n} MB","other":"{n} MB"},"short":{"zero":"{n} MB","one":"{n} MB","two":"{n} MB","few":"{n} MB","many":"{n} MB","other":"{n} MB"}},
|
|
36
|
+
"gigabyte": {"long":{"zero":"{n} GB","one":"{n} GB","two":"{n} GB","few":"{n} GB","many":"{n} GB","other":"{n} GB"},"short":{"zero":"{n} GB","one":"{n} GB","two":"{n} GB","few":"{n} GB","many":"{n} GB","other":"{n} GB"}},
|
|
37
|
+
"bitPerSecond": {"long":{"zero":"每秒 {n} bit","one":"每秒 {n} bit","two":"每秒 {n} bit","few":"每秒 {n} bit","many":"每秒 {n} bit","other":"每秒 {n} bit"},"short":{"zero":"{n} bit/秒","one":"{n} bit/秒","two":"{n} bit/秒","few":"{n} bit/秒","many":"{n} bit/秒","other":"{n} bit/秒"}},
|
|
38
|
+
"kilobitPerSecond": {"long":{"zero":"每秒 {n} kb","one":"每秒 {n} kb","two":"每秒 {n} kb","few":"每秒 {n} kb","many":"每秒 {n} kb","other":"每秒 {n} kb"},"short":{"zero":"{n} kb/秒","one":"{n} kb/秒","two":"{n} kb/秒","few":"{n} kb/秒","many":"{n} kb/秒","other":"{n} kb/秒"}},
|
|
39
|
+
"megabitPerSecond": {"long":{"zero":"每秒 {n} Mb","one":"每秒 {n} Mb","two":"每秒 {n} Mb","few":"每秒 {n} Mb","many":"每秒 {n} Mb","other":"每秒 {n} Mb"},"short":{"zero":"{n} Mb/秒","one":"{n} Mb/秒","two":"{n} Mb/秒","few":"{n} Mb/秒","many":"{n} Mb/秒","other":"{n} Mb/秒"}},
|
|
40
|
+
"gigabitPerSecond": {"long":{"zero":"每秒 {n} Gb","one":"每秒 {n} Gb","two":"每秒 {n} Gb","few":"每秒 {n} Gb","many":"每秒 {n} Gb","other":"每秒 {n} Gb"},"short":{"zero":"{n} Gb/秒","one":"{n} Gb/秒","two":"{n} Gb/秒","few":"{n} Gb/秒","many":"{n} Gb/秒","other":"{n} Gb/秒"}},
|
|
41
|
+
"bytePerSecond": {"long":{"zero":"每秒 {n} byte","one":"每秒 {n} byte","two":"每秒 {n} byte","few":"每秒 {n} byte","many":"每秒 {n} byte","other":"每秒 {n} byte"},"short":{"zero":"{n} byte/秒","one":"{n} byte/秒","two":"{n} byte/秒","few":"{n} byte/秒","many":"{n} byte/秒","other":"{n} byte/秒"}},
|
|
42
|
+
"kilobytePerSecond": {"long":{"zero":"每秒 {n} kB","one":"每秒 {n} kB","two":"每秒 {n} kB","few":"每秒 {n} kB","many":"每秒 {n} kB","other":"每秒 {n} kB"},"short":{"zero":"{n} kB/秒","one":"{n} kB/秒","two":"{n} kB/秒","few":"{n} kB/秒","many":"{n} kB/秒","other":"{n} kB/秒"}},
|
|
43
|
+
"milligram": {"long":{"zero":"{n} 毫克","one":"{n} 毫克","two":"{n} 毫克","few":"{n} 毫克","many":"{n} 毫克","other":"{n} 毫克"},"short":{"zero":"{n} 毫克","one":"{n} 毫克","two":"{n} 毫克","few":"{n} 毫克","many":"{n} 毫克","other":"{n} 毫克"}},
|
|
44
|
+
"gram": {"long":{"zero":"{n} 克","one":"{n} 克","two":"{n} 克","few":"{n} 克","many":"{n} 克","other":"{n} 克"},"short":{"zero":"{n} 克","one":"{n} 克","two":"{n} 克","few":"{n} 克","many":"{n} 克","other":"{n} 克"}},
|
|
45
|
+
"kilogram": {"long":{"zero":"{n} 公斤","one":"{n} 公斤","two":"{n} 公斤","few":"{n} 公斤","many":"{n} 公斤","other":"{n} 公斤"},"short":{"zero":"{n} 公斤","one":"{n} 公斤","two":"{n} 公斤","few":"{n} 公斤","many":"{n} 公斤","other":"{n} 公斤"}},
|
|
46
|
+
"tonne": {"long":{"zero":"{n} 公噸","one":"{n} 公噸","two":"{n} 公噸","few":"{n} 公噸","many":"{n} 公噸","other":"{n} 公噸"},"short":{"zero":"{n} 公噸","one":"{n} 公噸","two":"{n} 公噸","few":"{n} 公噸","many":"{n} 公噸","other":"{n} 公噸"}},
|
|
47
|
+
"ounce": {"long":{"zero":"{n} 盎司","one":"{n} 盎司","two":"{n} 盎司","few":"{n} 盎司","many":"{n} 盎司","other":"{n} 盎司"},"short":{"zero":"{n} 盎司","one":"{n} 盎司","two":"{n} 盎司","few":"{n} 盎司","many":"{n} 盎司","other":"{n} 盎司"}},
|
|
48
|
+
"pound": {"long":{"zero":"{n} 磅","one":"{n} 磅","two":"{n} 磅","few":"{n} 磅","many":"{n} 磅","other":"{n} 磅"},"short":{"zero":"{n} 磅","one":"{n} 磅","two":"{n} 磅","few":"{n} 磅","many":"{n} 磅","other":"{n} 磅"}},
|
|
49
|
+
"stone": {"long":{"zero":"{n} 英石","one":"{n} 英石","two":"{n} 英石","few":"{n} 英石","many":"{n} 英石","other":"{n} 英石"},"short":{"zero":"{n} 英石","one":"{n} 英石","two":"{n} 英石","few":"{n} 英石","many":"{n} 英石","other":"{n} 英石"}},
|
|
50
|
+
"robloxMassUnit": {"long":{"zero":"{n} Roblox mass units","one":"{n} Roblox mass units","two":"{n} Roblox mass units","few":"{n} Roblox mass units","many":"{n} Roblox mass units","other":"{n} Roblox mass units"},"short":{"zero":"{n} RMU","one":"{n} RMU","two":"{n} RMU","few":"{n} RMU","many":"{n} RMU","other":"{n} RMU"}},
|
|
51
|
+
"meterPerSecond": {"long":{"zero":"每秒 {n} 公尺","one":"每秒 {n} 公尺","two":"每秒 {n} 公尺","few":"每秒 {n} 公尺","many":"每秒 {n} 公尺","other":"每秒 {n} 公尺"},"short":{"zero":"{n} 公尺/秒","one":"{n} 公尺/秒","two":"{n} 公尺/秒","few":"{n} 公尺/秒","many":"{n} 公尺/秒","other":"{n} 公尺/秒"}},
|
|
52
|
+
"kilometerPerHour": {"long":{"zero":"每小時 {n} 公里","one":"每小時 {n} 公里","two":"每小時 {n} 公里","few":"每小時 {n} 公里","many":"每小時 {n} 公里","other":"每小時 {n} 公里"},"short":{"zero":"{n} 公里/小時","one":"{n} 公里/小時","two":"{n} 公里/小時","few":"{n} 公里/小時","many":"{n} 公里/小時","other":"{n} 公里/小時"}},
|
|
53
|
+
"milePerHour": {"long":{"zero":"每小時 {n} 英里","one":"每小時 {n} 英里","two":"每小時 {n} 英里","few":"每小時 {n} 英里","many":"每小時 {n} 英里","other":"每小時 {n} 英里"},"short":{"zero":"{n} 英里/小時","one":"{n} 英里/小時","two":"{n} 英里/小時","few":"{n} 英里/小時","many":"{n} 英里/小時","other":"{n} 英里/小時"}},
|
|
54
|
+
"knot": {"long":{"zero":"{n} 節","one":"{n} 節","two":"{n} 節","few":"{n} 節","many":"{n} 節","other":"{n} 節"},"short":{"zero":"{n} 節","one":"{n} 節","two":"{n} 節","few":"{n} 節","many":"{n} 節","other":"{n} 節"}},
|
|
55
|
+
"studPerSecond": {"long":{"zero":"每秒 {n} studs","one":"每秒 {n} studs","two":"每秒 {n} studs","few":"每秒 {n} studs","many":"每秒 {n} studs","other":"每秒 {n} studs"},"short":{"zero":"{n} studs/秒","one":"{n} studs/秒","two":"{n} studs/秒","few":"{n} studs/秒","many":"{n} studs/秒","other":"{n} studs/秒"}},
|
|
56
|
+
"meterPerSecondSquared": {"long":{"zero":"每平方秒 {n} 公尺","one":"每平方秒 {n} 公尺","two":"每平方秒 {n} 公尺","few":"每平方秒 {n} 公尺","many":"每平方秒 {n} 公尺","other":"每平方秒 {n} 公尺"},"short":{"zero":"{n} 公尺/平方秒","one":"{n} 公尺/平方秒","two":"{n} 公尺/平方秒","few":"{n} 公尺/平方秒","many":"{n} 公尺/平方秒","other":"{n} 公尺/平方秒"}},
|
|
57
|
+
"studPerSecondSquared": {"long":{"zero":"每秒² {n} studs","one":"每秒² {n} studs","two":"每秒² {n} studs","few":"每秒² {n} studs","many":"每秒² {n} studs","other":"每秒² {n} studs"},"short":{"zero":"{n} studs/秒²","one":"{n} studs/秒²","two":"{n} studs/秒²","few":"{n} studs/秒²","many":"{n} studs/秒²","other":"{n} studs/秒²"}},
|
|
58
|
+
"newton": {"long":{"zero":"{n} 牛頓","one":"{n} 牛頓","two":"{n} 牛頓","few":"{n} 牛頓","many":"{n} 牛頓","other":"{n} 牛頓"},"short":{"zero":"{n} N","one":"{n} N","two":"{n} N","few":"{n} N","many":"{n} N","other":"{n} N"}},
|
|
59
|
+
"poundForce": {"long":{"zero":"{n} 磅力","one":"{n} 磅力","two":"{n} 磅力","few":"{n} 磅力","many":"{n} 磅力","other":"{n} 磅力"},"short":{"zero":"{n} lbf","one":"{n} lbf","two":"{n} lbf","few":"{n} lbf","many":"{n} lbf","other":"{n} lbf"}},
|
|
60
|
+
"joule": {"long":{"zero":"{n} 焦耳","one":"{n} 焦耳","two":"{n} 焦耳","few":"{n} 焦耳","many":"{n} 焦耳","other":"{n} 焦耳"},"short":{"zero":"{n} 焦","one":"{n} 焦","two":"{n} 焦","few":"{n} 焦","many":"{n} 焦","other":"{n} 焦"}},
|
|
61
|
+
"kilojoule": {"long":{"zero":"{n} 千焦耳","one":"{n} 千焦耳","two":"{n} 千焦耳","few":"{n} 千焦耳","many":"{n} 千焦耳","other":"{n} 千焦耳"},"short":{"zero":"{n} 千焦","one":"{n} 千焦","two":"{n} 千焦","few":"{n} 千焦","many":"{n} 千焦","other":"{n} 千焦"}},
|
|
62
|
+
"kilowattHour": {"long":{"zero":"{n} 千瓦小時","one":"{n} 千瓦小時","two":"{n} 千瓦小時","few":"{n} 千瓦小時","many":"{n} 千瓦小時","other":"{n} 千瓦小時"},"short":{"zero":"{n} 千瓦小時","one":"{n} 千瓦小時","two":"{n} 千瓦小時","few":"{n} 千瓦小時","many":"{n} 千瓦小時","other":"{n} 千瓦小時"}},
|
|
63
|
+
"kilocalorie": {"long":{"zero":"{n} 千卡路里","one":"{n} 千卡路里","two":"{n} 千卡路里","few":"{n} 千卡路里","many":"{n} 千卡路里","other":"{n} 千卡路里"},"short":{"zero":"{n} 千卡","one":"{n} 千卡","two":"{n} 千卡","few":"{n} 千卡","many":"{n} 千卡","other":"{n} 千卡"}},
|
|
64
|
+
"watt": {"long":{"zero":"{n} 瓦特","one":"{n} 瓦特","two":"{n} 瓦特","few":"{n} 瓦特","many":"{n} 瓦特","other":"{n} 瓦特"},"short":{"zero":"{n} 瓦","one":"{n} 瓦","two":"{n} 瓦","few":"{n} 瓦","many":"{n} 瓦","other":"{n} 瓦"}},
|
|
65
|
+
"kilowatt": {"long":{"zero":"{n} 千瓦特","one":"{n} 千瓦特","two":"{n} 千瓦特","few":"{n} 千瓦特","many":"{n} 千瓦特","other":"{n} 千瓦特"},"short":{"zero":"{n} 千瓦","one":"{n} 千瓦","two":"{n} 千瓦","few":"{n} 千瓦","many":"{n} 千瓦","other":"{n} 千瓦"}},
|
|
66
|
+
"megawatt": {"long":{"zero":"{n} 百萬瓦特","one":"{n} 百萬瓦特","two":"{n} 百萬瓦特","few":"{n} 百萬瓦特","many":"{n} 百萬瓦特","other":"{n} 百萬瓦特"},"short":{"zero":"{n} 百萬瓦","one":"{n} 百萬瓦","two":"{n} 百萬瓦","few":"{n} 百萬瓦","many":"{n} 百萬瓦","other":"{n} 百萬瓦"}},
|
|
67
|
+
"pascal": {"long":{"zero":"{n} 帕斯卡","one":"{n} 帕斯卡","two":"{n} 帕斯卡","few":"{n} 帕斯卡","many":"{n} 帕斯卡","other":"{n} 帕斯卡"},"short":{"zero":"{n} 帕","one":"{n} 帕","two":"{n} 帕","few":"{n} 帕","many":"{n} 帕","other":"{n} 帕"}},
|
|
68
|
+
"kilopascal": {"long":{"zero":"{n} 千帕","one":"{n} 千帕","two":"{n} 千帕","few":"{n} 千帕","many":"{n} 千帕","other":"{n} 千帕"},"short":{"zero":"{n} 千帕","one":"{n} 千帕","two":"{n} 千帕","few":"{n} 千帕","many":"{n} 千帕","other":"{n} 千帕"}},
|
|
69
|
+
"megapascal": {"long":{"zero":"{n} 兆帕","one":"{n} 兆帕","two":"{n} 兆帕","few":"{n} 兆帕","many":"{n} 兆帕","other":"{n} 兆帕"},"short":{"zero":"{n} 兆帕","one":"{n} 兆帕","two":"{n} 兆帕","few":"{n} 兆帕","many":"{n} 兆帕","other":"{n} 兆帕"}},
|
|
70
|
+
"bar": {"long":{"zero":"{n} 巴","one":"{n} 巴","two":"{n} 巴","few":"{n} 巴","many":"{n} 巴","other":"{n} 巴"},"short":{"zero":"{n} 巴","one":"{n} 巴","two":"{n} 巴","few":"{n} 巴","many":"{n} 巴","other":"{n} 巴"}},
|
|
71
|
+
"poundForcePerSquareInch": {"long":{"zero":"每平方英寸 {n} 磅力","one":"每平方英寸 {n} 磅力","two":"每平方英寸 {n} 磅力","few":"每平方英寸 {n} 磅力","many":"每平方英寸 {n} 磅力","other":"每平方英寸 {n} 磅力"},"short":{"zero":"{n} 磅力/平方英寸","one":"{n} 磅力/平方英寸","two":"{n} 磅力/平方英寸","few":"{n} 磅力/平方英寸","many":"{n} 磅力/平方英寸","other":"{n} 磅力/平方英寸"}},
|
|
72
|
+
"kilogramPerCubicMeter": {"long":{"zero":"每立方公尺 {n} 公斤","one":"每立方公尺 {n} 公斤","two":"每立方公尺 {n} 公斤","few":"每立方公尺 {n} 公斤","many":"每立方公尺 {n} 公斤","other":"每立方公尺 {n} 公斤"},"short":{"zero":"{n} 公斤/立方公尺","one":"{n} 公斤/立方公尺","two":"{n} 公斤/立方公尺","few":"{n} 公斤/立方公尺","many":"{n} 公斤/立方公尺","other":"{n} 公斤/立方公尺"}},
|
|
73
|
+
"gramPerCubicCentimeter": {"long":{"zero":"每立方公分 {n} 克","one":"每立方公分 {n} 克","two":"每立方公分 {n} 克","few":"每立方公分 {n} 克","many":"每立方公分 {n} 克","other":"每立方公分 {n} 克"},"short":{"zero":"{n} 克/立方公分","one":"{n} 克/立方公分","two":"{n} 克/立方公分","few":"{n} 克/立方公分","many":"{n} 克/立方公分","other":"{n} 克/立方公分"}},
|
|
74
|
+
"kelvin": {"long":{"zero":"{n} 克耳文","one":"{n} 克耳文","two":"{n} 克耳文","few":"{n} 克耳文","many":"{n} 克耳文","other":"{n} 克耳文"},"short":{"zero":"{n} 克耳文","one":"{n} 克耳文","two":"{n} 克耳文","few":"{n} 克耳文","many":"{n} 克耳文","other":"{n} 克耳文"}},
|
|
75
|
+
"celsius": {"long":{"zero":"攝氏 {n} 度","one":"攝氏 {n} 度","two":"攝氏 {n} 度","few":"攝氏 {n} 度","many":"攝氏 {n} 度","other":"攝氏 {n} 度"},"short":{"zero":"{n}°C","one":"{n}°C","two":"{n}°C","few":"{n}°C","many":"{n}°C","other":"{n}°C"}},
|
|
76
|
+
"fahrenheit": {"long":{"zero":"華氏 {n} 度","one":"華氏 {n} 度","two":"華氏 {n} 度","few":"華氏 {n} 度","many":"華氏 {n} 度","other":"華氏 {n} 度"},"short":{"zero":"{n}°F","one":"{n}°F","two":"{n}°F","few":"{n}°F","many":"{n}°F","other":"{n}°F"}},
|
|
77
|
+
"radian": {"long":{"zero":"{n} 弧度","one":"{n} 弧度","two":"{n} 弧度","few":"{n} 弧度","many":"{n} 弧度","other":"{n} 弧度"},"short":{"zero":"{n} 弧度","one":"{n} 弧度","two":"{n} 弧度","few":"{n} 弧度","many":"{n} 弧度","other":"{n} 弧度"}},
|
|
78
|
+
"degree": {"long":{"zero":"{n} 度","one":"{n} 度","two":"{n} 度","few":"{n} 度","many":"{n} 度","other":"{n} 度"},"short":{"zero":"{n} 度","one":"{n} 度","two":"{n} 度","few":"{n} 度","many":"{n} 度","other":"{n} 度"}},
|
|
79
|
+
"revolution": {"long":{"zero":"{n} 圈","one":"{n} 圈","two":"{n} 圈","few":"{n} 圈","many":"{n} 圈","other":"{n} 圈"},"short":{"zero":"{n} 圈","one":"{n} 圈","two":"{n} 圈","few":"{n} 圈","many":"{n} 圈","other":"{n} 圈"}},
|
|
80
|
+
"radianPerSecond": {"long":{"zero":"每秒 {n} 弧度","one":"每秒 {n} 弧度","two":"每秒 {n} 弧度","few":"每秒 {n} 弧度","many":"每秒 {n} 弧度","other":"每秒 {n} 弧度"},"short":{"zero":"{n} 弧度/秒","one":"{n} 弧度/秒","two":"{n} 弧度/秒","few":"{n} 弧度/秒","many":"{n} 弧度/秒","other":"{n} 弧度/秒"}},
|
|
81
|
+
"degreePerSecond": {"long":{"zero":"每秒 {n} 度","one":"每秒 {n} 度","two":"每秒 {n} 度","few":"每秒 {n} 度","many":"每秒 {n} 度","other":"每秒 {n} 度"},"short":{"zero":"{n} 度/秒","one":"{n} 度/秒","two":"{n} 度/秒","few":"{n} 度/秒","many":"{n} 度/秒","other":"{n} 度/秒"}},
|
|
82
|
+
"revolutionPerMinute": {"long":{"zero":"每分鐘 {n} 圈","one":"每分鐘 {n} 圈","two":"每分鐘 {n} 圈","few":"每分鐘 {n} 圈","many":"每分鐘 {n} 圈","other":"每分鐘 {n} 圈"},"short":{"zero":"{n} 圈/分鐘","one":"{n} 圈/分鐘","two":"{n} 圈/分鐘","few":"{n} 圈/分鐘","many":"{n} 圈/分鐘","other":"{n} 圈/分鐘"}},
|
|
83
|
+
"radianPerSecondSquared": {"long":{"zero":"每秒² {n} 弧度","one":"每秒² {n} 弧度","two":"每秒² {n} 弧度","few":"每秒² {n} 弧度","many":"每秒² {n} 弧度","other":"每秒² {n} 弧度"},"short":{"zero":"{n} 弧度/秒²","one":"{n} 弧度/秒²","two":"{n} 弧度/秒²","few":"{n} 弧度/秒²","many":"{n} 弧度/秒²","other":"{n} 弧度/秒²"}},
|
|
84
|
+
"milliampere": {"long":{"zero":"{n} 毫安培","one":"{n} 毫安培","two":"{n} 毫安培","few":"{n} 毫安培","many":"{n} 毫安培","other":"{n} 毫安培"},"short":{"zero":"{n} 毫安培","one":"{n} 毫安培","two":"{n} 毫安培","few":"{n} 毫安培","many":"{n} 毫安培","other":"{n} 毫安培"}},
|
|
85
|
+
"ampere": {"long":{"zero":"{n} 安培","one":"{n} 安培","two":"{n} 安培","few":"{n} 安培","many":"{n} 安培","other":"{n} 安培"},"short":{"zero":"{n} 安培","one":"{n} 安培","two":"{n} 安培","few":"{n} 安培","many":"{n} 安培","other":"{n} 安培"}},
|
|
86
|
+
"coulomb": {"long":{"zero":"{n} 庫侖","one":"{n} 庫侖","two":"{n} 庫侖","few":"{n} 庫侖","many":"{n} 庫侖","other":"{n} 庫侖"},"short":{"zero":"{n} 庫侖","one":"{n} 庫侖","two":"{n} 庫侖","few":"{n} 庫侖","many":"{n} 庫侖","other":"{n} 庫侖"}},
|
|
87
|
+
"volt": {"long":{"zero":"{n} 伏特","one":"{n} 伏特","two":"{n} 伏特","few":"{n} 伏特","many":"{n} 伏特","other":"{n} 伏特"},"short":{"zero":"{n} 伏特","one":"{n} 伏特","two":"{n} 伏特","few":"{n} 伏特","many":"{n} 伏特","other":"{n} 伏特"}},
|
|
88
|
+
"ohm": {"long":{"zero":"{n} 歐姆","one":"{n} 歐姆","two":"{n} 歐姆","few":"{n} 歐姆","many":"{n} 歐姆","other":"{n} 歐姆"},"short":{"zero":"{n} 歐姆","one":"{n} 歐姆","two":"{n} 歐姆","few":"{n} 歐姆","many":"{n} 歐姆","other":"{n} 歐姆"}},
|
|
89
|
+
"siemens": {"long":{"zero":"{n} 西門子","one":"{n} 西門子","two":"{n} 西門子","few":"{n} 西門子","many":"{n} 西門子","other":"{n} 西門子"},"short":{"zero":"{n} S","one":"{n} S","two":"{n} S","few":"{n} S","many":"{n} S","other":"{n} S"}},
|
|
90
|
+
"farad": {"long":{"zero":"{n} 法拉","one":"{n} 法拉","two":"{n} 法拉","few":"{n} 法拉","many":"{n} 法拉","other":"{n} 法拉"},"short":{"zero":"{n} 法拉","one":"{n} 法拉","two":"{n} 法拉","few":"{n} 法拉","many":"{n} 法拉","other":"{n} 法拉"}},
|
|
91
|
+
"henry": {"long":{"zero":"{n} 亨利","one":"{n} 亨利","two":"{n} 亨利","few":"{n} 亨利","many":"{n} 亨利","other":"{n} 亨利"},"short":{"zero":"{n} 亨利","one":"{n} 亨利","two":"{n} 亨利","few":"{n} 亨利","many":"{n} 亨利","other":"{n} 亨利"}},
|
|
92
|
+
"weber": {"long":{"zero":"{n} 韋伯","one":"{n} 韋伯","two":"{n} 韋伯","few":"{n} 韋伯","many":"{n} 韋伯","other":"{n} 韋伯"},"short":{"zero":"{n} Wb","one":"{n} Wb","two":"{n} Wb","few":"{n} Wb","many":"{n} Wb","other":"{n} Wb"}},
|
|
93
|
+
"tesla": {"long":{"zero":"{n} 特斯拉","one":"{n} 特斯拉","two":"{n} 特斯拉","few":"{n} 特斯拉","many":"{n} 特斯拉","other":"{n} 特斯拉"},"short":{"zero":"{n} T","one":"{n} T","two":"{n} T","few":"{n} T","many":"{n} T","other":"{n} T"}},
|
|
94
|
+
"becquerel": {"long":{"zero":"{n} 貝克勒","one":"{n} 貝克勒","two":"{n} 貝克勒","few":"{n} 貝克勒","many":"{n} 貝克勒","other":"{n} 貝克勒"},"short":{"zero":"{n} Bq","one":"{n} Bq","two":"{n} Bq","few":"{n} Bq","many":"{n} Bq","other":"{n} Bq"}},
|
|
95
|
+
"mole": {"long":{"zero":"{n} 莫耳","one":"{n} 莫耳","two":"{n} 莫耳","few":"{n} 莫耳","many":"{n} 莫耳","other":"{n} 莫耳"},"short":{"zero":"{n} 莫耳","one":"{n} 莫耳","two":"{n} 莫耳","few":"{n} 莫耳","many":"{n} 莫耳","other":"{n} 莫耳"}},
|
|
96
|
+
"gramPerMole": {"long":{"zero":"每莫耳 {n} 克","one":"每莫耳 {n} 克","two":"每莫耳 {n} 克","few":"每莫耳 {n} 克","many":"每莫耳 {n} 克","other":"每莫耳 {n} 克"},"short":{"zero":"{n} 克/莫耳","one":"{n} 克/莫耳","two":"{n} 克/莫耳","few":"{n} 克/莫耳","many":"{n} 克/莫耳","other":"{n} 克/莫耳"}},
|
|
97
|
+
"molePerLiter": {"long":{"zero":"每公升 {n} 莫耳","one":"每公升 {n} 莫耳","two":"每公升 {n} 莫耳","few":"每公升 {n} 莫耳","many":"每公升 {n} 莫耳","other":"每公升 {n} 莫耳"},"short":{"zero":"{n} 莫耳/升","one":"{n} 莫耳/升","two":"{n} 莫耳/升","few":"{n} 莫耳/升","many":"{n} 莫耳/升","other":"{n} 莫耳/升"}},
|
|
98
|
+
"millimolePerLiter": {"long":{"zero":"每公升 {n} 毫莫耳","one":"每公升 {n} 毫莫耳","two":"每公升 {n} 毫莫耳","few":"每公升 {n} 毫莫耳","many":"每公升 {n} 毫莫耳","other":"每公升 {n} 毫莫耳"},"short":{"zero":"{n} 毫莫耳/公升","one":"{n} 毫莫耳/公升","two":"{n} 毫莫耳/公升","few":"{n} 毫莫耳/公升","many":"{n} 毫莫耳/公升","other":"{n} 毫莫耳/公升"}},
|
|
99
|
+
"katal": {"long":{"zero":"{n} 開特","one":"{n} 開特","two":"{n} 開特","few":"{n} 開特","many":"{n} 開特","other":"{n} 開特"},"short":{"zero":"{n} kat","one":"{n} kat","two":"{n} kat","few":"{n} kat","many":"{n} kat","other":"{n} kat"}},
|
|
100
|
+
"candela": {"long":{"zero":"{n} 燭光","one":"{n} 燭光","two":"{n} 燭光","few":"{n} 燭光","many":"{n} 燭光","other":"{n} 燭光"},"short":{"zero":"{n} 燭光","one":"{n} 燭光","two":"{n} 燭光","few":"{n} 燭光","many":"{n} 燭光","other":"{n} 燭光"}},
|
|
101
|
+
"steradian": {"long":{"zero":"{n} 球面度","one":"{n} 球面度","two":"{n} 球面度","few":"{n} 球面度","many":"{n} 球面度","other":"{n} 球面度"},"short":{"zero":"{n} sr","one":"{n} sr","two":"{n} sr","few":"{n} sr","many":"{n} sr","other":"{n} sr"}},
|
|
102
|
+
"lumen": {"long":{"zero":"{n} lm","one":"{n} lm","two":"{n} lm","few":"{n} lm","many":"{n} lm","other":"{n} lm"},"short":{"zero":"{n} lm","one":"{n} lm","two":"{n} lm","few":"{n} lm","many":"{n} lm","other":"{n} lm"}},
|
|
103
|
+
"lux": {"long":{"zero":"{n} 勒克斯","one":"{n} 勒克斯","two":"{n} 勒克斯","few":"{n} 勒克斯","many":"{n} 勒克斯","other":"{n} 勒克斯"},"short":{"zero":"{n} 勒克斯","one":"{n} 勒克斯","two":"{n} 勒克斯","few":"{n} 勒克斯","many":"{n} 勒克斯","other":"{n} 勒克斯"}},
|
|
104
|
+
"gray": {"long":{"zero":"{n} 戈雷","one":"{n} 戈雷","two":"{n} 戈雷","few":"{n} 戈雷","many":"{n} 戈雷","other":"{n} 戈雷"},"short":{"zero":"{n} Gy","one":"{n} Gy","two":"{n} Gy","few":"{n} Gy","many":"{n} Gy","other":"{n} Gy"}},
|
|
105
|
+
"sievert": {"long":{"zero":"{n} 西弗","one":"{n} 西弗","two":"{n} 西弗","few":"{n} 西弗","many":"{n} 西弗","other":"{n} 西弗"},"short":{"zero":"{n} Sv","one":"{n} Sv","two":"{n} Sv","few":"{n} Sv","many":"{n} Sv","other":"{n} Sv"}},
|
|
106
|
+
"kilohm": {"long":{"zero":"{n} 歐姆 公里","one":"{n} 歐姆 公里","two":"{n} 歐姆 公里","few":"{n} 歐姆 公里","many":"{n} 歐姆 公里","other":"{n} 歐姆 公里"},"short":{"zero":"{n} 歐姆 公里","one":"{n} 歐姆 公里","two":"{n} 歐姆 公里","few":"{n} 歐姆 公里","many":"{n} 歐姆 公里","other":"{n} 歐姆 公里"}},
|
|
107
|
+
"megohm": {"long":{"zero":"{n} 歐姆 兆米","one":"{n} 歐姆 兆米","two":"{n} 歐姆 兆米","few":"{n} 歐姆 兆米","many":"{n} 歐姆 兆米","other":"{n} 歐姆 兆米"},"short":{"zero":"{n} 歐姆 兆米","one":"{n} 歐姆 兆米","two":"{n} 歐姆 兆米","few":"{n} 歐姆 兆米","many":"{n} 歐姆 兆米","other":"{n} 歐姆 兆米"}},
|
|
108
|
+
"nauticalMile": {"long":{"zero":"{n} 海里","one":"{n} 海里","two":"{n} 海里","few":"{n} 海里","many":"{n} 海里","other":"{n} 海里"},"short":{"zero":"{n} 海里","one":"{n} 海里","two":"{n} 海里","few":"{n} 海里","many":"{n} 海里","other":"{n} 海里"}},
|
|
109
|
+
"literPer100Kilometers": {"long":{"zero":"每 100 公里 {n} 公升","one":"每 100 公里 {n} 公升","two":"每 100 公里 {n} 公升","few":"每 100 公里 {n} 公升","many":"每 100 公里 {n} 公升","other":"每 100 公里 {n} 公升"},"short":{"zero":"{n} 升/100 公里","one":"{n} 升/100 公里","two":"{n} 升/100 公里","few":"{n} 升/100 公里","many":"{n} 升/100 公里","other":"{n} 升/100 公里"}},
|
|
110
|
+
"squareInch": {"long":{"zero":"{n} 平方英寸","one":"{n} 平方英寸","two":"{n} 平方英寸","few":"{n} 平方英寸","many":"{n} 平方英寸","other":"{n} 平方英寸"},"short":{"zero":"{n} 平方英寸","one":"{n} 平方英寸","two":"{n} 平方英寸","few":"{n} 平方英寸","many":"{n} 平方英寸","other":"{n} 平方英寸"}},
|
|
111
|
+
"squareYard": {"long":{"zero":"{n} 平方碼","one":"{n} 平方碼","two":"{n} 平方碼","few":"{n} 平方碼","many":"{n} 平方碼","other":"{n} 平方碼"},"short":{"zero":"{n} 平方碼","one":"{n} 平方碼","two":"{n} 平方碼","few":"{n} 平方碼","many":"{n} 平方碼","other":"{n} 平方碼"}},
|
|
112
|
+
"squareMile": {"long":{"zero":"{n} 平方英里","one":"{n} 平方英里","two":"{n} 平方英里","few":"{n} 平方英里","many":"{n} 平方英里","other":"{n} 平方英里"},"short":{"zero":"{n} 平方英里","one":"{n} 平方英里","two":"{n} 平方英里","few":"{n} 平方英里","many":"{n} 平方英里","other":"{n} 平方英里"}},
|
|
113
|
+
"cubicInch": {"long":{"zero":"{n} 立方英寸","one":"{n} 立方英寸","two":"{n} 立方英寸","few":"{n} 立方英寸","many":"{n} 立方英寸","other":"{n} 立方英寸"},"short":{"zero":"{n} 立方英寸","one":"{n} 立方英寸","two":"{n} 立方英寸","few":"{n} 立方英寸","many":"{n} 立方英寸","other":"{n} 立方英寸"}},
|
|
114
|
+
"cubicFoot": {"long":{"zero":"{n} 立方英尺","one":"{n} 立方英尺","two":"{n} 立方英尺","few":"{n} 立方英尺","many":"{n} 立方英尺","other":"{n} 立方英尺"},"short":{"zero":"{n} 立方英尺","one":"{n} 立方英尺","two":"{n} 立方英尺","few":"{n} 立方英尺","many":"{n} 立方英尺","other":"{n} 立方英尺"}},
|
|
115
|
+
"cubicYard": {"long":{"zero":"{n} 立方碼","one":"{n} 立方碼","two":"{n} 立方碼","few":"{n} 立方碼","many":"{n} 立方碼","other":"{n} 立方碼"},"short":{"zero":"{n} 立方碼","one":"{n} 立方碼","two":"{n} 立方碼","few":"{n} 立方碼","many":"{n} 立方碼","other":"{n} 立方碼"}},
|
|
116
|
+
"usTeaspoon": {"long":{"zero":"{n} 茶匙","one":"{n} 茶匙","two":"{n} 茶匙","few":"{n} 茶匙","many":"{n} 茶匙","other":"{n} 茶匙"},"short":{"zero":"{n} 茶匙","one":"{n} 茶匙","two":"{n} 茶匙","few":"{n} 茶匙","many":"{n} 茶匙","other":"{n} 茶匙"}},
|
|
117
|
+
"usTablespoon": {"long":{"zero":"{n} 湯匙","one":"{n} 湯匙","two":"{n} 湯匙","few":"{n} 湯匙","many":"{n} 湯匙","other":"{n} 湯匙"},"short":{"zero":"{n} 湯匙","one":"{n} 湯匙","two":"{n} 湯匙","few":"{n} 湯匙","many":"{n} 湯匙","other":"{n} 湯匙"}},
|
|
118
|
+
"usCup": {"long":{"zero":"{n} 杯","one":"{n} 杯","two":"{n} 杯","few":"{n} 杯","many":"{n} 杯","other":"{n} 杯"},"short":{"zero":"{n} 杯","one":"{n} 杯","two":"{n} 杯","few":"{n} 杯","many":"{n} 杯","other":"{n} 杯"}},
|
|
119
|
+
"usPint": {"long":{"zero":"{n} 品脫","one":"{n} 品脫","two":"{n} 品脫","few":"{n} 品脫","many":"{n} 品脫","other":"{n} 品脫"},"short":{"zero":"{n} 品脫","one":"{n} 品脫","two":"{n} 品脫","few":"{n} 品脫","many":"{n} 品脫","other":"{n} 品脫"}},
|
|
120
|
+
"usQuart": {"long":{"zero":"{n} 夸脫","one":"{n} 夸脫","two":"{n} 夸脫","few":"{n} 夸脫","many":"{n} 夸脫","other":"{n} 夸脫"},"short":{"zero":"{n} 夸脫","one":"{n} 夸脫","two":"{n} 夸脫","few":"{n} 夸脫","many":"{n} 夸脫","other":"{n} 夸脫"}},
|
|
121
|
+
"imperialFluidOunce": {"long":{"zero":"{n} 英液盎司","one":"{n} 英液盎司","two":"{n} 英液盎司","few":"{n} 英液盎司","many":"{n} 英液盎司","other":"{n} 英液盎司"},"short":{"zero":"{n} 英液盎司","one":"{n} 英液盎司","two":"{n} 英液盎司","few":"{n} 英液盎司","many":"{n} 英液盎司","other":"{n} 英液盎司"}},
|
|
122
|
+
"imperialPint": {"long":{"zero":"{n} pt Imp.","one":"{n} pt Imp.","two":"{n} pt Imp.","few":"{n} pt Imp.","many":"{n} pt Imp.","other":"{n} pt Imp."},"short":{"zero":"{n} pt Imp.","one":"{n} pt Imp.","two":"{n} pt Imp.","few":"{n} pt Imp.","many":"{n} pt Imp.","other":"{n} pt Imp."}},
|
|
123
|
+
"imperialQuart": {"long":{"zero":"{n} 英制夸脫","one":"{n} 英制夸脫","two":"{n} 英制夸脫","few":"{n} 英制夸脫","many":"{n} 英制夸脫","other":"{n} 英制夸脫"},"short":{"zero":"{n} 英制夸脫","one":"{n} 英制夸脫","two":"{n} 英制夸脫","few":"{n} 英制夸脫","many":"{n} 英制夸脫","other":"{n} 英制夸脫"}},
|
|
124
|
+
"shortTon": {"long":{"zero":"{n} 美噸","one":"{n} 美噸","two":"{n} 美噸","few":"{n} 美噸","many":"{n} 美噸","other":"{n} 美噸"},"short":{"zero":"{n} 美噸","one":"{n} 美噸","two":"{n} 美噸","few":"{n} 美噸","many":"{n} 美噸","other":"{n} 美噸"}},
|
|
125
|
+
"footPerSecond": {"long":{"zero":"每秒 {n} 英尺","one":"每秒 {n} 英尺","two":"每秒 {n} 英尺","few":"每秒 {n} 英尺","many":"每秒 {n} 英尺","other":"每秒 {n} 英尺"},"short":{"zero":"{n}英尺/秒","one":"{n}英尺/秒","two":"{n}英尺/秒","few":"{n}英尺/秒","many":"{n}英尺/秒","other":"{n}英尺/秒"}},
|
|
126
|
+
"footPerSecondSquared": {"long":{"zero":"每秒² {n} 英尺","one":"每秒² {n} 英尺","two":"每秒² {n} 英尺","few":"每秒² {n} 英尺","many":"每秒² {n} 英尺","other":"每秒² {n} 英尺"},"short":{"zero":"{n}英尺/秒²","one":"{n}英尺/秒²","two":"{n}英尺/秒²","few":"{n}英尺/秒²","many":"{n}英尺/秒²","other":"{n}英尺/秒²"}},
|
|
127
|
+
"newtonMeter": {"long":{"zero":"{n} 牛頓米","one":"{n} 牛頓米","two":"{n} 牛頓米","few":"{n} 牛頓米","many":"{n} 牛頓米","other":"{n} 牛頓米"},"short":{"zero":"{n} 牛頓米","one":"{n} 牛頓米","two":"{n} 牛頓米","few":"{n} 牛頓米","many":"{n} 牛頓米","other":"{n} 牛頓米"}},
|
|
128
|
+
"britishThermalUnit": {"long":{"zero":"{n} 英熱單位","one":"{n} 英熱單位","two":"{n} 英熱單位","few":"{n} 英熱單位","many":"{n} 英熱單位","other":"{n} 英熱單位"},"short":{"zero":"{n} 英熱單位","one":"{n} 英熱單位","two":"{n} 英熱單位","few":"{n} 英熱單位","many":"{n} 英熱單位","other":"{n} 英熱單位"}},
|
|
129
|
+
"poundFoot": {"long":{"zero":"{n} 磅英尺","one":"{n} 磅英尺","two":"{n} 磅英尺","few":"{n} 磅英尺","many":"{n} 磅英尺","other":"{n} 磅英尺"},"short":{"zero":"{n} 磅英尺","one":"{n} 磅英尺","two":"{n} 磅英尺","few":"{n} 磅英尺","many":"{n} 磅英尺","other":"{n} 磅英尺"}},
|
|
130
|
+
"metricHorsepower": {"long":{"zero":"{n} PS","one":"{n} PS","two":"{n} PS","few":"{n} PS","many":"{n} PS","other":"{n} PS"},"short":{"zero":"{n} PS","one":"{n} PS","two":"{n} PS","few":"{n} PS","many":"{n} PS","other":"{n} PS"}},
|
|
131
|
+
"horsepower": {"long":{"zero":"{n} 匹馬力","one":"{n} 匹馬力","two":"{n} 匹馬力","few":"{n} 匹馬力","many":"{n} 匹馬力","other":"{n} 匹馬力"},"short":{"zero":"{n} 匹","one":"{n} 匹","two":"{n} 匹","few":"{n} 匹","many":"{n} 匹","other":"{n} 匹"}},
|
|
132
|
+
"inchOfMercury": {"long":{"zero":"{n} 英寸汞柱","one":"{n} 英寸汞柱","two":"{n} 英寸汞柱","few":"{n} 英寸汞柱","many":"{n} 英寸汞柱","other":"{n} 英寸汞柱"},"short":{"zero":"{n} 英寸汞柱","one":"{n} 英寸汞柱","two":"{n} 英寸汞柱","few":"{n} 英寸汞柱","many":"{n} 英寸汞柱","other":"{n} 英寸汞柱"}},
|
|
133
|
+
"poundPerCubicFoot": {"long":{"zero":"每立方英尺 {n} 磅","one":"每立方英尺 {n} 磅","two":"每立方英尺 {n} 磅","few":"每立方英尺 {n} 磅","many":"每立方英尺 {n} 磅","other":"每立方英尺 {n} 磅"},"short":{"zero":"{n} 磅/立方英尺","one":"{n} 磅/立方英尺","two":"{n} 磅/立方英尺","few":"{n} 磅/立方英尺","many":"{n} 磅/立方英尺","other":"{n} 磅/立方英尺"}},
|
|
134
|
+
"kilometerPerLiter": {"long":{"zero":"每公升 {n} 公里","one":"每公升 {n} 公里","two":"每公升 {n} 公里","few":"每公升 {n} 公里","many":"每公升 {n} 公里","other":"每公升 {n} 公里"},"short":{"zero":"{n} 公里/升","one":"{n} 公里/升","two":"{n} 公里/升","few":"{n} 公里/升","many":"{n} 公里/升","other":"{n} 公里/升"}},
|
|
135
|
+
"milePerUsGallon": {"long":{"zero":"每加侖 {n} 英里","one":"每加侖 {n} 英里","two":"每加侖 {n} 英里","few":"每加侖 {n} 英里","many":"每加侖 {n} 英里","other":"每加侖 {n} 英里"},"short":{"zero":"{n} 英里/加侖","one":"{n} 英里/加侖","two":"{n} 英里/加侖","few":"{n} 英里/加侖","many":"{n} 英里/加侖","other":"{n} 英里/加侖"}},
|
|
136
|
+
"milePerImperialGallon": {"long":{"zero":"每英制加侖 {n} 英里","one":"每英制加侖 {n} 英里","two":"每英制加侖 {n} 英里","few":"每英制加侖 {n} 英里","many":"每英制加侖 {n} 英里","other":"每英制加侖 {n} 英里"},"short":{"zero":"{n} 英里/英制加侖","one":"{n} 英里/英制加侖","two":"{n} 英里/英制加侖","few":"{n} 英里/英制加侖","many":"{n} 英里/英制加侖","other":"{n} 英里/英制加侖"}},
|
|
137
|
+
"rankine": {"long":{"zero":"{n} °R","one":"{n} °R","two":"{n} °R","few":"{n} °R","many":"{n} °R","other":"{n} °R"},"short":{"zero":"{n} °R","one":"{n} °R","two":"{n} °R","few":"{n} °R","many":"{n} °R","other":"{n} °R"}}
|
|
138
|
+
},
|
|
139
|
+
"per": {
|
|
140
|
+
"second": {"long":"每秒 {n}","short":"{n}/秒"},
|
|
141
|
+
"minute": {"long":"每分鐘 {n}","short":"{n}/分鐘"},
|
|
142
|
+
"hour": {"long":"每小時 {n}","short":"{n}/小時"},
|
|
143
|
+
"day": {"long":"每天 {n}","short":"{n}/天"},
|
|
144
|
+
"week": {"long":"每週 {n}","short":"{n}/週"},
|
|
145
|
+
"month": {"long":"每月 {n}","short":"{n}/月"},
|
|
146
|
+
"year": {"long":"每年 {n}","short":"{n}/年"}
|
|
147
|
+
},
|
|
148
|
+
"prefixes": {
|
|
149
|
+
"quecto": {"long":"{unit} 奎米","short":"{unit} 奎米"},
|
|
150
|
+
"ronto": {"long":"{unit} 戎米","short":"{unit} 戎米"},
|
|
151
|
+
"yocto": {"long":"{unit} 麼米","short":"{unit} 麼米"},
|
|
152
|
+
"zepto": {"long":"{unit} 仄米","short":"{unit} 仄米"},
|
|
153
|
+
"atto": {"long":"{unit} 阿米","short":"{unit} 阿米"},
|
|
154
|
+
"femto": {"long":"{unit} 飛米","short":"{unit} 飛米"},
|
|
155
|
+
"pico": {"long":"{unit} 皮米","short":"{unit} 皮米"},
|
|
156
|
+
"nano": {"long":"{unit} 奈米","short":"{unit} 奈米"},
|
|
157
|
+
"micro": {"long":"{unit} 微米","short":"{unit} 微米"},
|
|
158
|
+
"milli": {"long":"{unit} 公釐","short":"{unit} 公釐"},
|
|
159
|
+
"centi": {"long":"{unit} 公分","short":"{unit} 公分"},
|
|
160
|
+
"deci": {"long":"{unit} 公寸","short":"{unit} 公寸"},
|
|
161
|
+
"deca": {"long":"{unit} 公丈","short":"{unit} 公丈"},
|
|
162
|
+
"hecto": {"long":"{unit} 公引","short":"{unit} 公引"},
|
|
163
|
+
"kilo": {"long":"{unit} 公里","short":"{unit} 公里"},
|
|
164
|
+
"mega": {"long":"{unit} 兆米","short":"{unit} 兆米"},
|
|
165
|
+
"giga": {"long":"{unit} 吉米","short":"{unit} 吉米"},
|
|
166
|
+
"tera": {"long":"{unit} 太米","short":"{unit} 太米"},
|
|
167
|
+
"peta": {"long":"{unit} 拍米","short":"{unit} 拍米"},
|
|
168
|
+
"exa": {"long":"{unit} 艾米","short":"{unit} 艾米"},
|
|
169
|
+
"zetta": {"long":"{unit} 皆米","short":"{unit} 皆米"},
|
|
170
|
+
"yotta": {"long":"{unit} 佑米","short":"{unit} 佑米"},
|
|
171
|
+
"ronna": {"long":"{unit} 羅米","short":"{unit} 羅米"},
|
|
172
|
+
"quetta": {"long":"{unit} 巋米","short":"{unit} 巋米"},
|
|
173
|
+
"kibi": {"long":"{unit} 千位元組","short":"Ki{unit}"},
|
|
174
|
+
"mebi": {"long":"{unit} 百萬位元組","short":"Mi{unit}"},
|
|
175
|
+
"gibi": {"long":"{unit} 吉位元組","short":"Gi{unit}"},
|
|
176
|
+
"tebi": {"long":"{unit} 兆位元組","short":"Ti{unit}"},
|
|
177
|
+
"pebi": {"long":"{unit} 拍位元組","short":"Pi{unit}"},
|
|
178
|
+
"exbi": {"long":"{unit} 艾位元組","short":"Ei{unit}"},
|
|
179
|
+
"zebi": {"long":"{unit} 皆位元組","short":"Zi{unit}"},
|
|
180
|
+
"yobi": {"long":"{unit} 佑位元組","short":"Yi{unit}"}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--[[
|
|
3
|
+
@class MetricUnitTranslator.spec.lua
|
|
4
|
+
]]
|
|
5
|
+
|
|
6
|
+
local require = require(script.Parent.loader).load(script)
|
|
7
|
+
|
|
8
|
+
local Jest = require("Jest")
|
|
9
|
+
local MetricUnit = require("MetricUnit")
|
|
10
|
+
local MetricUnitDefinitions = require("MetricUnitDefinitions")
|
|
11
|
+
local MetricUnitFallbackStrings = require("MetricUnitFallbackStrings")
|
|
12
|
+
local MetricUnitFormatUtils = require("MetricUnitFormatUtils")
|
|
13
|
+
local PluralCategoryUtils = require("PluralCategoryUtils")
|
|
14
|
+
|
|
15
|
+
local describe = Jest.Globals.describe
|
|
16
|
+
local expect = Jest.Globals.expect
|
|
17
|
+
local it = Jest.Globals.it
|
|
18
|
+
|
|
19
|
+
local NB = MetricUnitFormatUtils.NO_BREAK_SPACE
|
|
20
|
+
local CATEGORIES = { "zero", "one", "two", "few", "many", "other" }
|
|
21
|
+
local LANGUAGES =
|
|
22
|
+
{ "en", "es", "fr", "de", "pt", "it", "ru", "pl", "tr", "id", "vi", "th", "ar", "zh-cn", "zh-tw", "ja", "ko" }
|
|
23
|
+
|
|
24
|
+
-- A number in each plural category the language uses, as CLDR's samples give them
|
|
25
|
+
local SAMPLES: { [string]: { [string]: number } } = {
|
|
26
|
+
en = { one = 1, other = 2 },
|
|
27
|
+
es = { one = 1, many = 1000000, other = 2 },
|
|
28
|
+
fr = { one = 1, many = 1000000, other = 2 },
|
|
29
|
+
de = { one = 1, other = 2 },
|
|
30
|
+
pt = { one = 1, many = 1000000, other = 2 },
|
|
31
|
+
it = { one = 1, many = 1000000, other = 2 },
|
|
32
|
+
ru = { one = 1, few = 2, many = 5, other = 1.5 },
|
|
33
|
+
pl = { one = 1, few = 2, many = 5, other = 1.5 },
|
|
34
|
+
tr = { one = 1, other = 2 },
|
|
35
|
+
id = { other = 1 },
|
|
36
|
+
vi = { one = 1, other = 2 },
|
|
37
|
+
th = { other = 1 },
|
|
38
|
+
ar = { zero = 0, one = 1, two = 2, few = 3, many = 11, other = 100 },
|
|
39
|
+
["zh-cn"] = { other = 1 },
|
|
40
|
+
["zh-tw"] = { other = 1 },
|
|
41
|
+
ja = { other = 1 },
|
|
42
|
+
ko = { other = 1 },
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
-- The locale files are StringValues under the translator module, so these read them in Roblox only
|
|
46
|
+
local function readLocale(language: string): any?
|
|
47
|
+
if typeof(script) ~= "Instance" then
|
|
48
|
+
return nil
|
|
49
|
+
end
|
|
50
|
+
local folder = (script :: any).Parent:FindFirstChild("MetricUnitTranslator")
|
|
51
|
+
local file = folder and folder:FindFirstChild(language .. ".json")
|
|
52
|
+
if not file then
|
|
53
|
+
return nil
|
|
54
|
+
end
|
|
55
|
+
return game:GetService("HttpService"):JSONDecode(file.Value)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
-- A translator over one decoded locale file, for formatting every locale without streaming it
|
|
59
|
+
local function fileTranslator(language: string, data: any): any
|
|
60
|
+
local function lookup(key: string): string?
|
|
61
|
+
local node = data
|
|
62
|
+
for part in string.gmatch(key, "[^%.]+") do
|
|
63
|
+
node = if type(node) == "table" then node[part] else nil
|
|
64
|
+
end
|
|
65
|
+
return if type(node) == "string" then node else nil
|
|
66
|
+
end
|
|
67
|
+
return {
|
|
68
|
+
GetLocaleId = function()
|
|
69
|
+
return language
|
|
70
|
+
end,
|
|
71
|
+
FormatByKey = function(_self: any, key: string, args: { [string]: any }?): string
|
|
72
|
+
local text = lookup(key)
|
|
73
|
+
if not text then
|
|
74
|
+
error("No key " .. key)
|
|
75
|
+
end
|
|
76
|
+
return (string.gsub(text, "{(%a+)}", function(name)
|
|
77
|
+
return (args :: any)[name]
|
|
78
|
+
end))
|
|
79
|
+
end,
|
|
80
|
+
ObserveFormatByKey = function()
|
|
81
|
+
error("unused")
|
|
82
|
+
end,
|
|
83
|
+
}
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
local function substitute(template: string, numberText: string): string
|
|
87
|
+
return (string.gsub(template, "{n}", function()
|
|
88
|
+
return numberText
|
|
89
|
+
end))
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe("MetricUnitTranslator locale files", function()
|
|
93
|
+
it("ships every locale, each with every key the English source has, long and short", function()
|
|
94
|
+
local english = readLocale("en")
|
|
95
|
+
if english == nil then
|
|
96
|
+
return
|
|
97
|
+
end
|
|
98
|
+
for _, language in LANGUAGES do
|
|
99
|
+
local locale = readLocale(language)
|
|
100
|
+
assert(locale, string.format("No locale file for %s", language))
|
|
101
|
+
for id in english.units do
|
|
102
|
+
local entry = locale.units[id]
|
|
103
|
+
assert(entry, string.format("%s has no units.%s", language, id))
|
|
104
|
+
for _, display in { "long", "short" } do
|
|
105
|
+
for _, category in CATEGORIES do
|
|
106
|
+
local text = entry[display] and entry[display][category]
|
|
107
|
+
if type(text) ~= "string" or text == "" then
|
|
108
|
+
error(string.format("%s has no units.%s.%s.%s", language, id, display, category))
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
for name in english.prefixes do
|
|
114
|
+
for _, display in { "long", "short" } do
|
|
115
|
+
local text = locale.prefixes[name] and locale.prefixes[name][display]
|
|
116
|
+
if type(text) ~= "string" or string.find(text, "{unit}", 1, true) == nil then
|
|
117
|
+
error(string.format("%s has no prefixes.%s.%s", language, name, display))
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
for id in english.per do
|
|
122
|
+
for _, display in { "long", "short" } do
|
|
123
|
+
local text = locale.per[id] and locale.per[id][display]
|
|
124
|
+
if type(text) ~= "string" or string.find(text, "{n}", 1, true) == nil then
|
|
125
|
+
error(string.format("%s has no per.%s.%s", language, id, display))
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end)
|
|
131
|
+
|
|
132
|
+
it("has an English source that matches the definitions' names and symbols, and every prefix", function()
|
|
133
|
+
local english = readLocale("en")
|
|
134
|
+
if english == nil then
|
|
135
|
+
return
|
|
136
|
+
end
|
|
137
|
+
local named: { [string]: boolean } = {}
|
|
138
|
+
for _, unit in MetricUnitDefinitions.getUnits() do
|
|
139
|
+
local names = unit.names
|
|
140
|
+
local entry = english.units[unit.id]
|
|
141
|
+
local composedFromItsPrefix = unit.prefix ~= nil and entry == nil
|
|
142
|
+
if names and not composedFromItsPrefix then
|
|
143
|
+
named[unit.id] = true
|
|
144
|
+
assert(entry, string.format("en.json has no key for %s", unit.id))
|
|
145
|
+
local fallback = MetricUnitFallbackStrings.getUnitStringsForLocale("en-us")[unit.id] :: any
|
|
146
|
+
for _, category in CATEGORIES do
|
|
147
|
+
local isOne = category == "one"
|
|
148
|
+
expect(entry.long[category]).toBe("{n}" .. NB .. (if isOne then names.one else names.other))
|
|
149
|
+
local short = if isOne then fallback.short.one else fallback.short.other
|
|
150
|
+
expect(entry.short[category]).toBe((string.gsub(short, "%%s", "{n}")))
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
for id in english.units do
|
|
155
|
+
expect(named[id]).toBe(true)
|
|
156
|
+
end
|
|
157
|
+
for _, prefix in MetricUnitDefinitions.getPrefixes() do
|
|
158
|
+
expect(english.prefixes[prefix.name]).toEqual({
|
|
159
|
+
long = prefix.name .. "{unit}",
|
|
160
|
+
short = prefix.symbol .. "{unit}",
|
|
161
|
+
})
|
|
162
|
+
end
|
|
163
|
+
for id, phrases in english.per do
|
|
164
|
+
local unit = MetricUnitDefinitions.getUnit(id)
|
|
165
|
+
assert(unit, id)
|
|
166
|
+
expect(phrases.long).toBe("{n} per " .. id)
|
|
167
|
+
expect(phrases.short).toBe("{n}/" .. unit.symbol)
|
|
168
|
+
end
|
|
169
|
+
end)
|
|
170
|
+
|
|
171
|
+
it("formats a sample in every plural category of every locale", function()
|
|
172
|
+
for _, language in LANGUAGES do
|
|
173
|
+
local data = readLocale(language)
|
|
174
|
+
if data == nil then
|
|
175
|
+
return
|
|
176
|
+
end
|
|
177
|
+
local translator = fileTranslator(language, data)
|
|
178
|
+
for category, sample in SAMPLES[language] do
|
|
179
|
+
expect(PluralCategoryUtils.getPluralCategory(language, sample, nil)).toBe(category)
|
|
180
|
+
local numberText = MetricUnitFormatUtils.formatNumber(sample, { locale = language })
|
|
181
|
+
for _, display in { "long", "short" } do
|
|
182
|
+
local options: MetricUnit.FormatOptions =
|
|
183
|
+
{ unit = "kilometer", unitDisplay = display :: any, translator = translator }
|
|
184
|
+
local expected = substitute(data.units.kilometer[display][category], numberText)
|
|
185
|
+
expect(MetricUnit.format(MetricUnit.kilometers(sample), options)).toBe(expected)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end)
|
|
190
|
+
|
|
191
|
+
it("writes a prefixed unit from its prefix and the unit's own name", function()
|
|
192
|
+
local expectations: { [string]: { string } } = {
|
|
193
|
+
de = { "5 Kilovolt", "5 kV", "3 Nanometer" },
|
|
194
|
+
fr = { "5 kilovolts", "5 kV", "3 nanomètres" },
|
|
195
|
+
ru = { "5 киловольт", "5 кВ", "3 нанометра" },
|
|
196
|
+
ja = { "5 キロボルト", "5 kV", "3 ナノメートル" },
|
|
197
|
+
}
|
|
198
|
+
for language, expected in expectations do
|
|
199
|
+
local data = readLocale(language)
|
|
200
|
+
if data == nil then
|
|
201
|
+
return
|
|
202
|
+
end
|
|
203
|
+
local translator = fileTranslator(language, data)
|
|
204
|
+
local function write(value: MetricUnit.MetricUnit, unit: string, display: string): string
|
|
205
|
+
local options: any = { unit = unit, unitDisplay = display, translator = translator, locale = language }
|
|
206
|
+
return (string.gsub(MetricUnit.format(value, options), NB, " "))
|
|
207
|
+
end
|
|
208
|
+
expect(data.units.kilovolt).toBeNil()
|
|
209
|
+
expect(write(MetricUnit.new(5000, "volt"), "kilovolt", "long")).toBe(expected[1])
|
|
210
|
+
expect(write(MetricUnit.new(5000, "volt"), "kilovolt", "short")).toBe(expected[2])
|
|
211
|
+
expect(write(MetricUnit.new(3, "nanometer" :: any), "nanometer", "long")).toBe(expected[3])
|
|
212
|
+
end
|
|
213
|
+
end)
|
|
214
|
+
|
|
215
|
+
it("writes rates per a time unit in the translator's language", function()
|
|
216
|
+
local data = readLocale("ru")
|
|
217
|
+
if data == nil then
|
|
218
|
+
return
|
|
219
|
+
end
|
|
220
|
+
local options: MetricUnit.FormatOptions = {
|
|
221
|
+
unit = "kilometer",
|
|
222
|
+
perUnit = "hour",
|
|
223
|
+
translator = fileTranslator("ru", data),
|
|
224
|
+
}
|
|
225
|
+
local numerator = substitute(data.units.kilometer.short.many, "5")
|
|
226
|
+
expect(MetricUnit.format(MetricUnit.new(5, "kilometerPerHour"), options)).toBe(
|
|
227
|
+
substitute(data.per.hour.short, numerator)
|
|
228
|
+
)
|
|
229
|
+
end)
|
|
230
|
+
end)
|
|
231
|
+
|
|
232
|
+
describe("MetricUnitTranslator", function()
|
|
233
|
+
local function streamed(language: string, check: (translator: any, data: any) -> ())
|
|
234
|
+
if typeof(script) ~= "Instance" then
|
|
235
|
+
return
|
|
236
|
+
end
|
|
237
|
+
local TranslatorTestUtils = require("TranslatorTestUtils")
|
|
238
|
+
local controller = TranslatorTestUtils.setup()
|
|
239
|
+
controller.setForcedLocaleId(language)
|
|
240
|
+
local folder = (script :: any).Parent.MetricUnitTranslator
|
|
241
|
+
local translator = controller.awaitLoaded(controller.newTranslatorFromInstance(folder))
|
|
242
|
+
controller.awaitEntriesWritten()
|
|
243
|
+
check(translator, readLocale(language))
|
|
244
|
+
controller:Destroy()
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it("streams Spanish names to MetricUnit.format through a real translator", function()
|
|
248
|
+
streamed("es", function(translator)
|
|
249
|
+
local options: MetricUnit.FormatOptions = { unitDisplay = "long", translator = translator }
|
|
250
|
+
expect(MetricUnit.format(MetricUnit.new(3, "mile"):ToUSCustomary(), options)).toBe("3" .. NB .. "millas")
|
|
251
|
+
expect(MetricUnit.format(MetricUnit.kilometers(1), options)).toBe("1" .. NB .. "kilómetro")
|
|
252
|
+
end)
|
|
253
|
+
end)
|
|
254
|
+
|
|
255
|
+
for _, language in { "ar", "ru", "ja" } do
|
|
256
|
+
it(
|
|
257
|
+
string.format("streams %s through a real translator, long and short, in every plural category", language),
|
|
258
|
+
function()
|
|
259
|
+
streamed(language, function(translator, data)
|
|
260
|
+
for category, sample in SAMPLES[language] do
|
|
261
|
+
local numberText = MetricUnitFormatUtils.formatNumber(sample, { locale = language })
|
|
262
|
+
for _, display in { "long", "short" } do
|
|
263
|
+
local options: MetricUnit.FormatOptions =
|
|
264
|
+
{ unit = "kilometer", unitDisplay = display :: any, translator = translator }
|
|
265
|
+
local expected = substitute(data.units.kilometer[display][category], numberText)
|
|
266
|
+
expect(MetricUnit.format(MetricUnit.kilometers(sample), options)).toBe(expected)
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end)
|
|
270
|
+
end
|
|
271
|
+
)
|
|
272
|
+
end
|
|
273
|
+
end)
|
|
274
|
+
|
|
275
|
+
describe("No-break spaces", function()
|
|
276
|
+
it("join a number to its unit", function()
|
|
277
|
+
expect(MetricUnit.format(MetricUnit.kilometers(5))).toBe("5" .. NB .. "km")
|
|
278
|
+
expect(MetricUnit.format(MetricUnit.kilometers(5), { unitDisplay = "long" })).toBe("5" .. NB .. "kilometers")
|
|
279
|
+
expect(MetricUnit.format(MetricUnit.minutes(90))).toBe("1" .. NB .. "hour, 30" .. NB .. "minutes")
|
|
280
|
+
expect(MetricUnit.format(MetricUnit.percent(45), { unit = "percent" })).toBe("45%")
|
|
281
|
+
expect((MetricUnit.parse("5" .. NB .. "km") :: any):In("meter")).toBe(5000)
|
|
282
|
+
end)
|
|
283
|
+
|
|
284
|
+
it("measure as wide as a space in Roblox's fonts", function()
|
|
285
|
+
local dataModel: any = game
|
|
286
|
+
if typeof(dataModel) ~= "Instance" then
|
|
287
|
+
return
|
|
288
|
+
end
|
|
289
|
+
local TextService = (dataModel :: any):GetService("TextService")
|
|
290
|
+
local bounds = Vector2.new(1000, 100)
|
|
291
|
+
for _, font in { Enum.Font.SourceSans, Enum.Font.Gotham, Enum.Font.Arial } do
|
|
292
|
+
local plainWidth = TextService:GetTextSize("5 km", 18, font, bounds).X
|
|
293
|
+
local noBreakWidth = TextService:GetTextSize("5" .. NB .. "km", 18, font, bounds).X
|
|
294
|
+
expect(noBreakWidth).toBe(plainWidth)
|
|
295
|
+
end
|
|
296
|
+
end)
|
|
297
|
+
end)
|
|
298
|
+
|
|
299
|
+
describe("MetricUnitFormatUtils.formatUnit with a translator", function()
|
|
300
|
+
it("takes its locale from the translator, for numbers and plural forms", function()
|
|
301
|
+
local data = readLocale("ru")
|
|
302
|
+
if data == nil then
|
|
303
|
+
return
|
|
304
|
+
end
|
|
305
|
+
local translator = fileTranslator("ru", data)
|
|
306
|
+
local text = MetricUnitFormatUtils.formatUnit("meter", 3, { translator = translator, unitDisplay = "long" })
|
|
307
|
+
expect(text).toBe(substitute(data.units.meter.long.few, "3"))
|
|
308
|
+
end)
|
|
309
|
+
end)
|