@jjlmoya/utils-alcohol 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/package.json +2 -1
  2. package/src/category/i18n/id.ts +28 -0
  3. package/src/category/i18n/sv.ts +19 -0
  4. package/src/category/index.ts +2 -0
  5. package/src/tests/faq_count.test.ts +12 -10
  6. package/src/tests/i18n_coverage.test.ts +36 -0
  7. package/src/tests/locale_completeness.test.ts +42 -0
  8. package/src/tests/no_h1_in_components.test.ts +48 -0
  9. package/src/tests/seo_length.test.ts +3 -34
  10. package/src/tests/slug_uniqueness.test.ts +81 -0
  11. package/src/tests/tool_validation.test.ts +4 -4
  12. package/src/tool/alcoholClearance/i18n/de.ts +205 -0
  13. package/src/tool/alcoholClearance/i18n/id.ts +205 -0
  14. package/src/tool/alcoholClearance/i18n/it.ts +180 -0
  15. package/src/tool/alcoholClearance/i18n/ja.ts +205 -0
  16. package/src/tool/alcoholClearance/i18n/ko.ts +205 -0
  17. package/src/tool/alcoholClearance/i18n/nl.ts +205 -0
  18. package/src/tool/alcoholClearance/i18n/pl.ts +205 -0
  19. package/src/tool/alcoholClearance/i18n/pt.ts +205 -0
  20. package/src/tool/alcoholClearance/i18n/ru.ts +205 -0
  21. package/src/tool/alcoholClearance/i18n/sv.ts +205 -0
  22. package/src/tool/alcoholClearance/i18n/tr.ts +180 -0
  23. package/src/tool/alcoholClearance/i18n/zh.ts +205 -0
  24. package/src/tool/alcoholClearance/index.ts +13 -1
  25. package/src/tool/beerCooler/i18n/de.ts +197 -0
  26. package/src/tool/beerCooler/i18n/id.ts +197 -0
  27. package/src/tool/beerCooler/i18n/it.ts +197 -0
  28. package/src/tool/beerCooler/i18n/ja.ts +197 -0
  29. package/src/tool/beerCooler/i18n/ko.ts +197 -0
  30. package/src/tool/beerCooler/i18n/nl.ts +197 -0
  31. package/src/tool/beerCooler/i18n/pl.ts +197 -0
  32. package/src/tool/beerCooler/i18n/pt.ts +197 -0
  33. package/src/tool/beerCooler/i18n/ru.ts +197 -0
  34. package/src/tool/beerCooler/i18n/sv.ts +197 -0
  35. package/src/tool/beerCooler/i18n/tr.ts +197 -0
  36. package/src/tool/beerCooler/i18n/zh.ts +197 -0
  37. package/src/tool/beerCooler/index.ts +13 -1
  38. package/src/tool/carbonationCalculator/i18n/de.ts +200 -0
  39. package/src/tool/carbonationCalculator/i18n/id.ts +200 -0
  40. package/src/tool/carbonationCalculator/i18n/it.ts +200 -0
  41. package/src/tool/carbonationCalculator/i18n/ja.ts +200 -0
  42. package/src/tool/carbonationCalculator/i18n/ko.ts +200 -0
  43. package/src/tool/carbonationCalculator/i18n/nl.ts +200 -0
  44. package/src/tool/carbonationCalculator/i18n/pl.ts +200 -0
  45. package/src/tool/carbonationCalculator/i18n/pt.ts +200 -0
  46. package/src/tool/carbonationCalculator/i18n/ru.ts +200 -0
  47. package/src/tool/carbonationCalculator/i18n/sv.ts +200 -0
  48. package/src/tool/carbonationCalculator/i18n/tr.ts +200 -0
  49. package/src/tool/carbonationCalculator/i18n/zh.ts +200 -0
  50. package/src/tool/carbonationCalculator/index.ts +13 -1
  51. package/src/tool/cocktailBalancer/i18n/de.ts +222 -0
  52. package/src/tool/cocktailBalancer/i18n/id.ts +222 -0
  53. package/src/tool/cocktailBalancer/i18n/it.ts +222 -0
  54. package/src/tool/cocktailBalancer/i18n/ja.ts +222 -0
  55. package/src/tool/cocktailBalancer/i18n/ko.ts +222 -0
  56. package/src/tool/cocktailBalancer/i18n/nl.ts +222 -0
  57. package/src/tool/cocktailBalancer/i18n/pl.ts +222 -0
  58. package/src/tool/cocktailBalancer/i18n/pt.ts +222 -0
  59. package/src/tool/cocktailBalancer/i18n/ru.ts +222 -0
  60. package/src/tool/cocktailBalancer/i18n/sv.ts +222 -0
  61. package/src/tool/cocktailBalancer/i18n/tr.ts +222 -0
  62. package/src/tool/cocktailBalancer/i18n/zh.ts +222 -0
  63. package/src/tool/cocktailBalancer/index.ts +13 -1
  64. package/src/tool/partyKeg/i18n/de.ts +187 -0
  65. package/src/tool/partyKeg/i18n/id.ts +187 -0
  66. package/src/tool/partyKeg/i18n/it.ts +187 -0
  67. package/src/tool/partyKeg/i18n/ja.ts +187 -0
  68. package/src/tool/partyKeg/i18n/ko.ts +187 -0
  69. package/src/tool/partyKeg/i18n/nl.ts +187 -0
  70. package/src/tool/partyKeg/i18n/pl.ts +187 -0
  71. package/src/tool/partyKeg/i18n/pt.ts +187 -0
  72. package/src/tool/partyKeg/i18n/ru.ts +187 -0
  73. package/src/tool/partyKeg/i18n/sv.ts +187 -0
  74. package/src/tool/partyKeg/i18n/tr.ts +187 -0
  75. package/src/tool/partyKeg/i18n/zh.ts +187 -0
  76. package/src/tool/partyKeg/index.ts +13 -1
  77. package/src/types.ts +1 -1
  78. package/src/tests/content_mandatory.test.ts +0 -32
@@ -0,0 +1,187 @@
1
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
2
+ import type { PartyKegUI, PartyKegLocaleContent } from '../index';
3
+
4
+ const slug = 'ol-iskalkylator-fest';
5
+ const title = 'Ölkalkylator för Fester: Mängd Per Person för Bröllop och Födelsedagar';
6
+ const description = 'Gratis verktyg för att beräkna hur mycket öl och is du behöver baserat på gäster, varaktighet och temperatur. Perfekt för bröllop, födelsedagar och utomhusevenemang.';
7
+
8
+ const ui: PartyKegUI = {
9
+ calcStockTitle: 'Lagerkalkylator',
10
+ beerIceSub: 'Öl & Is för Event',
11
+ guestsLabel: 'Gäster',
12
+ durationLabel: 'Varaktighet',
13
+ hoursUnit: 'Timmar',
14
+ intensityLabel: 'Intensitet',
15
+ chillLabel: 'Chill',
16
+ standardLabel: 'Standard',
17
+ partyLabel: 'Party',
18
+ tempLabel: 'Temperatur',
19
+ estimatedVolLabel: 'Beräknad Volym',
20
+ kegsLabel: 'Fat',
21
+ iceRequiredLabel: 'Is Behövd',
22
+ bagsLabel: 'Påsar',
23
+ visualizationTitle: 'Lagervisualisering',
24
+ optimalMsg: 'Optimala Förhållanden',
25
+ highMeltMsg: 'Högt Smältningstal Upptäckt',
26
+ highEfficiencyMsg: 'Kall / Hög Effektivitet'
27
+ };
28
+
29
+ const faqTitle = 'Vanliga Frågor';
30
+ const bibliographyTitle = 'Bibliografi och Källor';
31
+
32
+ const faq: PartyKegLocaleContent['faq'] = [
33
+ {
34
+ question: "Hur mycket öl dricker en person på 4 timmar?",
35
+ answer: "I genomsnitt, räkna med 5 öl per person för ett 4-timmar-event. Det förutsätter 2 drycker första timmen och 1 för varje återstående timme.",
36
+ },
37
+ {
38
+ question: "Hur mycket is behöver jag för 100 öl?",
39
+ answer: "Du behöver ungefär 15–20 kilogram is (7–10 påsar). Praktiska regeln är 0,75 kg is per liter dryck under normala förhållanden. På sommaren eller utomhus över 25°C, öka till 1 kg per liter: omgivningsvärmen påskyndar smältningen och du kommer att få slut på is mycket snabbare än förväntat.",
40
+ },
41
+ {
42
+ question: "Vad är skillnaden mellan ett standardfat och ett festfat?",
43
+ answer: "Ett standard-handelsfat innehåller 50 liter, vilket ger cirka 200 portioner (250 ml var). Ett festfat (mini-fat) innehåller vanligtvis 5 liter — cirka 20 portioner. Att känna till dessa storlekar hjälper dig att omvandla kalkylatorns liter-resultat till antalet behållare du behöver köpa.",
44
+ },
45
+ {
46
+ question: "Varför behöver jag så mycket is om ölen redan är kall?",
47
+ answer: "För att kyling och underhåll är två separata processer. Att föra en burk från 25°C till 4°C förbrukar isens latenta smältvärme: cirka 334 kJ/kg. En gång kall fortsätter isen att arbeta för att kompensera för omgivningsvärmen. En sommardag på 35°C kan värmeavgiven till kylfällan smälta 1 kg is per liter dryck var 2–3:e timme. Det är därför förkyling av dryckerna innan festen halverar din totala isförbrukning.",
48
+ },
49
+ ];
50
+
51
+ const howTo: PartyKegLocaleContent['howTo'] = [
52
+ {
53
+ name: "Uppskatta antal gäster",
54
+ text: "Definiera hur många människor som kommer att deltaga. Vår kalkylator justerar mängderna baserat på statistiska konsumtionsgenomsnitt.",
55
+ },
56
+ {
57
+ name: "Definiera varaktighet och intensitet",
58
+ text: "Ange hur många timmar evenemanget kommer att pågå och 'flödet' på festen (chill, standard eller intensiv).",
59
+ },
60
+ {
61
+ name: "Justera för omgivningstemperatur",
62
+ text: "Utomhustemperaturen är nyckeln för isberäkningen. Ju varmare det är, desto högre smältningshastighetsmå vi kompensera för.",
63
+ },
64
+ ];
65
+
66
+ const bibliography: PartyKegLocaleContent['bibliography'] = [
67
+ {
68
+ name: "Event Planning: Alcohol & Bar Calculations - Spruce Eats",
69
+ url: "https://www.thespruceeats.com/stock-your-bar-for-a-party-760394",
70
+ },
71
+ {
72
+ name: "Thermodynamics of Ice Melting - Engineering Toolbox",
73
+ url: "https://www.engineeringtoolbox.com/saturated-ice-steam-d_970.html",
74
+ },
75
+ ];
76
+
77
+ const seo: PartyKegLocaleContent['seo'] = [
78
+ {
79
+ type: 'title',
80
+ text: 'Hur Mycket Öl och Is Behöver Jag Till Min Fest?',
81
+ level: 2
82
+ },
83
+ {
84
+ type: 'paragraph',
85
+ html: 'Miljonfrågan när du organiserar något event: <strong>Hur många liter öl ska jag köpa?</strong> För lite är en katastrof, men för mycket är onödiga utgifter. Det här verktyget hjälper dig att beräkna exakt mängd alkohol och, viktigast av allt, <strong>hur många ispåsar</strong> du behöver för att hålla det kallt. Professionella caterare och eventplanerare använder statistiska konsumtionsmodeller — och nu kan du också, helt gratis.'
86
+ },
87
+ {
88
+ type: 'title',
89
+ text: 'Konsumtionsformeln Per Person',
90
+ level: 2
91
+ },
92
+ {
93
+ type: 'paragraph',
94
+ html: 'För att uppskatta alkoholen som behövs använder professionella caterare en formel baserad på "Konsumtionstakt Per Timme". Det är inte en exakt vetenskap, men statistiken visar att på ett standardfest konsumeras cirka 1,5 enheter per timme per person. Faktorer som omgivningstemperatur, matkvalitet och festavens sociala energi förändrar alla detta basnummer.'
95
+ },
96
+ {
97
+ type: 'stats',
98
+ items: [
99
+ { label: 'Chill-konsumtion', value: '1 dryck/timme', icon: 'mdi:tea-outline' },
100
+ { label: 'Standardfest', value: '1,5 drycker/timme', icon: 'mdi:glass-mug-variant' },
101
+ { label: 'Bröllop / Festival', value: '2,5+ drycker/timme', icon: 'mdi:fire' }
102
+ ],
103
+ columns: 3
104
+ },
105
+ {
106
+ type: 'diagnostic',
107
+ title: 'Isens Fysik',
108
+ icon: 'mdi:snowflake-thermometer',
109
+ variant: 'warning',
110
+ badge: 'Termodynamik',
111
+ html: 'Att beräkna is är där de flesta värdinnor misslyckas. Is har två funktioner: Kylning (föra öl från 25°C till 4°C) och Underhål (bekämpa omgivningsvärmen). Vid temperaturer över 30°C fördubblas smälthastigheten. En full ispåse i direktsol kan försvinna på mindre än 20 minuter, vilket gör att dryckerna blir varma innan festen når sin höjdpunkt.'
112
+ },
113
+ {
114
+ type: 'tip',
115
+ title: 'Proffs Tips för att Spara Is',
116
+ html: 'Håll fat och burkar i skuggan innan du lägger till is. Om dryckerna är varma i solen försvinner de första 50% av din ispåse på 10 minuter genom att bara utbyta latent värme. Börja med förkyld dryck för att drastiskt minska hur mycket is du faktiskt behöver köpa.'
117
+ },
118
+ {
119
+ type: 'title',
120
+ text: 'Referensdata för Logistik',
121
+ level: 2
122
+ },
123
+ {
124
+ type: 'paragraph',
125
+ html: 'Ett standard 50L-fat ger cirka 200 portioner. En typisk ispåse väger 2 kg. Med dessa siffror kan du planera den transport och lagring som krävs för ditt event utan sista-minuten-överraskningar. Räkna med issmältning under transport — en 30-minuterstur sommartid kan kosta dig en hel påse innan festen börjar.'
126
+ },
127
+ {
128
+ type: 'summary',
129
+ title: 'För Vem Är Det Här Verktyget?',
130
+ items: [
131
+ 'Privata Festvärdinnor: Sluta gissa och köp självsäkert exakt vad du behöver till nästa fest.',
132
+ 'Eventplanerare: Använd exakta konsumtionsmodeller för att citera kunder och planera barpersonal professionellt.',
133
+ 'Lokalbehållare: Standardisera lagerberäkningar över återkommande event med olika gästantal.'
134
+ ]
135
+ },
136
+ {
137
+ type: 'paragraph',
138
+ html: 'En ofta förbisedd variabel är <strong>gästernas bortfallstal</strong>. På de flesta fester går 10–15% av gästerna tidigt och 10% kanske inte dricker alls. Kalkylatorn använder ett försiktigt buffert så att du aldrig blir utan, men också inte sittar med ett enormt överskud. Att förstå dessa justeringar hjälper dig att finjustera uppskattningen för din specifika grupp och kontext. Avrunda alltid uppåt vid köp, eftersom öppnade fat normalt inte kan returneras. Ett litet överskud är alltid bättre än att vara utan dryck mitt i festen.'
139
+ }
140
+ ];
141
+
142
+ const schemas: PartyKegLocaleContent['schemas'] = [
143
+ {
144
+ '@context': 'https://schema.org',
145
+ '@type': 'FAQPage',
146
+ mainEntity: faq.map((item) => ({
147
+ '@type': 'Question',
148
+ name: item.question,
149
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
150
+ })),
151
+ } as WithContext<FAQPage>,
152
+ {
153
+ '@context': 'https://schema.org',
154
+ '@type': 'HowTo',
155
+ name: title,
156
+ description: description,
157
+ step: howTo.map((step, i) => ({
158
+ '@type': 'HowToStep',
159
+ position: i + 1,
160
+ name: step.name,
161
+ text: step.text,
162
+ })),
163
+ } as WithContext<HowTo>,
164
+ {
165
+ '@context': 'https://schema.org',
166
+ '@type': 'SoftwareApplication',
167
+ name: title,
168
+ description: description,
169
+ applicationCategory: 'UtilityApplication',
170
+ operatingSystem: 'Web',
171
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
172
+ } as WithContext<SoftwareApplication>,
173
+ ];
174
+
175
+ export const content: PartyKegLocaleContent = {
176
+ slug,
177
+ title,
178
+ description,
179
+ ui,
180
+ seo,
181
+ faqTitle,
182
+ faq,
183
+ bibliographyTitle,
184
+ bibliography,
185
+ howTo,
186
+ schemas,
187
+ };
@@ -0,0 +1,187 @@
1
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
2
+ import type { PartyKegUI, PartyKegLocaleContent } from '../index';
3
+
4
+ const slug = 'parti-birrasi-hesaplayicisi';
5
+ const title = 'Parti Bira Hesaplayıcısı: Düğünler ve Doğum Günleri için Kişi Başına Miktar';
6
+ const description = 'Konuk sayısı, süre ve sıcaklığa dayalı olarak ne kadar bira ve buz gerektiğini hesaplamak için ücretsiz araç. Düğünler, doğum günleri ve açık hava etkinlikleri için mükemmel.';
7
+
8
+ const ui: PartyKegUI = {
9
+ calcStockTitle: 'Stok Hesaplayıcısı',
10
+ beerIceSub: 'Etkinlikler için Bira ve Buz',
11
+ guestsLabel: 'Konuklar',
12
+ durationLabel: 'Süre',
13
+ hoursUnit: 'Saat',
14
+ intensityLabel: 'Yoğunluk',
15
+ chillLabel: 'Sakin',
16
+ standardLabel: 'Standart',
17
+ partyLabel: 'Parti',
18
+ tempLabel: 'Sıcaklık',
19
+ estimatedVolLabel: 'Tahmini Hacim',
20
+ kegsLabel: 'Fıçı',
21
+ iceRequiredLabel: 'Gerekli Buz',
22
+ bagsLabel: 'Torba',
23
+ visualizationTitle: 'Stok Görselleştirmesi',
24
+ optimalMsg: 'Optimal Koşullar',
25
+ highMeltMsg: 'Yüksek Erime Algılandı',
26
+ highEfficiencyMsg: 'Soğuk / Yüksek Verimlilik'
27
+ };
28
+
29
+ const faqTitle = 'Sıkça Sorulan Sorular';
30
+ const bibliographyTitle = 'Bibliyografi ve Kaynaklar';
31
+
32
+ const faq: PartyKegLocaleContent['faq'] = [
33
+ {
34
+ question: '4 saatlik bir etkinlikte bir kişi kaç bira içer?',
35
+ answer: 'Ortalama olarak 4 saatlik bir etkinlik için kişi başına 5 bira hesaplayın. Bu, ilk saat 2 içecek ve kalan her saat 1 içecek varsayılmaktadır.',
36
+ },
37
+ {
38
+ question: '100 bira için ne kadar buz gereklidir?',
39
+ answer: 'Normal koşullar altında yaklaşık 15-20 kilo buz gerekecektir (7-10 torba). Pratik kural, normal koşullar altında içecek litresi başına 0.75 kg buzdur. Yazda veya 25 derecenin üzerinde dışarıda, bunu 1 kg litre başına yükseltin: ortam ısısı erimesini hızlandırır ve beklenenden çok daha hızlı tükenirsiniz.',
40
+ },
41
+ {
42
+ question: 'Standart fıçı ile parti fıçısı arasındaki fark nedir?',
43
+ answer: 'Standart ticari fıçı 50 litre tutar ve yaklaşık 200 porsiyon verir (her biri 250ml). Parti fıçısı (mini fıçı) tipik olarak 5 litre tutar, yaklaşık 20 porsiyon. Bu boyutları bilmek hesaplayıcının litre çıkışını satın alınacak konteyner sayısına çevirmenize yardımcı olur.',
44
+ },
45
+ {
46
+ question: 'Biraları zaten soğuksa neden bu kadar buz gereklidir?',
47
+ answer: 'Çünkü soğutma ve bakım iki ayrı işlemdir. Bir kutuyu 25 dereceden 4 dereceye getirmek buzun füzyon gizli ısısını tüketir: yaklaşık 334 kJ/kg. Soğuk olduktan sonra, buz ortam ısısını dengelemek için çalışmaya devam eder. 35 dereceli yazlık bir günde, ısı transfer bir soğutucu içine saatte başına içecek litresi başına 1kg buz eritebilir. Partiden önce içeceklerinizi önceden soğutmak, toplam buz tüketiminizi yarıya keser.',
48
+ },
49
+ ];
50
+
51
+ const howTo: PartyKegLocaleContent['howTo'] = [
52
+ {
53
+ name: 'Konuk sayısını tahmin edin',
54
+ text: 'Kaç kişinin katılacağını tanımlayın. Hesaplayıcımız miktarları istatistiksel tüketim ortalamalarına dayalı olarak ayarlar.',
55
+ },
56
+ {
57
+ name: 'Süre ve yoğunluğu tanımlayın',
58
+ text: 'Etkinliğin kaç saat süreceğini ve partinin akışını (sakin, standart veya yoğun) gösterin.',
59
+ },
60
+ {
61
+ name: 'Ortam sıcaklığına ayarlayın',
62
+ text: 'Dış sıcaklık buz hesaplaması için anahtardır. Sıcak olduğu kadar, erime hızını telafi etmek için daha yüksek bir değer gerekir.',
63
+ },
64
+ ];
65
+
66
+ const bibliography: PartyKegLocaleContent['bibliography'] = [
67
+ {
68
+ name: 'Etkinlik Planlama: Alkol ve Bar Hesaplamaları - Spruce Eats',
69
+ url: 'https://www.thespruceeats.com/stock-your-bar-for-a-party-760394',
70
+ },
71
+ {
72
+ name: 'Buz Eritme Termodinamiği - Mühendislik Araç Kutusu',
73
+ url: 'https://www.engineeringtoolbox.com/saturated-ice-steam-d_970.html',
74
+ },
75
+ ];
76
+
77
+ const seo: PartyKegLocaleContent['seo'] = [
78
+ {
79
+ type: 'title',
80
+ text: 'Partim için Ne Kadar Bira ve Buz Gerekir?',
81
+ level: 2
82
+ },
83
+ {
84
+ type: 'paragraph',
85
+ html: 'Herhangi bir etkinliği düzenlerken bir milyon dolarlık soru: En çok ne kadar alkol satın almalıyım? Yetersiz kalmak felakettir, ancak fazla satın almak gereksiz bir harcamadır. Bu araç size ihtiyacınız olan tam alkol miktarını ve en önemlisi ne kadar buz torbaları gerektiğini hesaplamanıza yardımcı olur. Profesyonel catering ve etkinlik plancıları istatistiksel tüketim modellerini kullanırlar ve şimdi siz de bundan ücretsiz yararlanabilirsiniz.'
86
+ },
87
+ {
88
+ type: 'title',
89
+ text: 'Kişi Başına Tüketim Formülü',
90
+ level: 2
91
+ },
92
+ {
93
+ type: 'paragraph',
94
+ html: 'İhtiyacınız olan alkolu tahmin etmek için profesyonel catering işletmeleri "Saatlik Tüketim Hızına" dayalı bir formül kullanırlar. Tam bir bilim değildir, ancak istatistikler gösteriyor ki standart bir partide, kişi başına saatte yaklaşık 1.5 birim tüketilir. Ortam sıcaklığı, gıda mevcudiyeti ve etkinliğin sosyal enerjisi gibi faktörler bu taban sayıyı kaydırır.'
95
+ },
96
+ {
97
+ type: 'stats',
98
+ items: [
99
+ { label: 'Sakin Tüketim', value: '1 içecek/saat', icon: 'mdi:tea-outline' },
100
+ { label: 'Standart Parti', value: '1.5 içecek/saat', icon: 'mdi:glass-mug-variant' },
101
+ { label: 'Düğün / Festival', value: '2.5+ içecek/saat', icon: 'mdi:fire' }
102
+ ],
103
+ columns: 3
104
+ },
105
+ {
106
+ type: 'diagnostic',
107
+ title: "Buzun Fiziği",
108
+ icon: 'mdi:snowflake-thermometer',
109
+ variant: 'warning',
110
+ badge: 'Termodinamik',
111
+ html: "Buz hesaplamak çoğu ev sahibinin başarısız olduğu yer. Buz iki işlev görmektedir: Soğutma (birayı 25°C den 4°C ye getirmek) ve Bakım (ortam ısısına karşı koymak). 30°C üzerindeki sıcaklıklarda erime hızı iki katına çıkar. Doğrudan güneş altında dolu buz torbaları 20 dakikadan kısa sürede kaybolabilir, partinin doruğuna ulaşmadan önce içecekleriniz ılınır."
112
+ },
113
+ {
114
+ type: 'tip',
115
+ title: 'Buz Tasarrufu İçin Profesyonel İpucu',
116
+ html: "Buz eklemeden önce fıçıları ve kutuları gölgede tutun. Güneşte içecekler sıcaksa ilk buz torbanızın ilk yüzde 50 si yalnızca gizli ısı alışverişi yaparak 10 dakikada kaybolur. Önceden soğutulmuş içeceklerle başlayarak gerçekten satın almanız gereken buz miktarını çarpıcı bir şekilde azaltın."
117
+ },
118
+ {
119
+ type: 'title',
120
+ text: 'Lojistik için Referans Verileri',
121
+ level: 2
122
+ },
123
+ {
124
+ type: 'paragraph',
125
+ html: 'Standart 50 litre fıçı yaklaşık 200 porsiyon verir. Tipik buz torbaları 2 kg ağırlığındadır. Bu rakamları bilmek, etkinliğiniz için gerekli taşımacılığı ve depolamayı son anında sürprizler olmadan planlamanıza yardımcı olur. Taşımadaki buz erimesini hesaba katın, yazda 30 dakikalık bir sürüş partinin başlamasından önce tüm torbaları tüketebilir.'
126
+ },
127
+ {
128
+ type: 'summary',
129
+ title: 'Bu Araç Kime Yöneliktir?',
130
+ items: [
131
+ 'Özel Parti Ev Sahipleri: Sonraki kutlamada ihtiyacınız olanı tam olarak satın almak için tahminle bitmek.',
132
+ 'Etkinlik Plancıları: Müşterileri teklif etmek ve bar lojistiğini profesyonelce planlamak için doğru tüketim modellerini kullanın.',
133
+ 'Mekan Yöneticileri: Farklı konuk sayılarıyla yinelenen etkinlikler arasında stok hesaplamalarını standartlaştırın.'
134
+ ]
135
+ },
136
+ {
137
+ type: 'paragraph',
138
+ html: "Sıklıkla gözden kaçırılan bir değişken, konuk düşüş hızıdır. Çoğu partide konukların yüzde 10 ila 15 i erken ayrılır ve yüzde 10 u hiç içmeyebilir. Hesaplayıcı muhafazakâr bir tampon uygular, böylece hiçbir zaman kısa kalmazsınız, aynı zamanda da muazzam bir fazlalığı yok. Bu ayarlamaları anlamak tahmini belirli kalabalığınız ve bağlamınız için ince ayarlamanıza yardımcı olur. Satın alırken her zaman yuvarla, açılmış fıçıları geri vermek genellikle mümkün değildir. Küçük bir fazlalık her zaman partinin ortasında kuru kalmaktan daha iyi."
139
+ }
140
+ ];
141
+
142
+ const schemas: PartyKegLocaleContent['schemas'] = [
143
+ {
144
+ '@context': 'https://schema.org',
145
+ '@type': 'FAQPage',
146
+ mainEntity: faq.map((item) => ({
147
+ '@type': 'Question',
148
+ name: item.question,
149
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
150
+ })),
151
+ } as WithContext<FAQPage>,
152
+ {
153
+ '@context': 'https://schema.org',
154
+ '@type': 'HowTo',
155
+ name: title,
156
+ description: description,
157
+ step: howTo.map((step, i) => ({
158
+ '@type': 'HowToStep',
159
+ position: i + 1,
160
+ name: step.name,
161
+ text: step.text,
162
+ })),
163
+ } as WithContext<HowTo>,
164
+ {
165
+ '@context': 'https://schema.org',
166
+ '@type': 'SoftwareApplication',
167
+ name: title,
168
+ description: description,
169
+ applicationCategory: 'UtilityApplication',
170
+ operatingSystem: 'Web',
171
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
172
+ } as WithContext<SoftwareApplication>,
173
+ ];
174
+
175
+ export const content: PartyKegLocaleContent = {
176
+ slug,
177
+ title,
178
+ description,
179
+ ui,
180
+ seo,
181
+ faqTitle,
182
+ faq,
183
+ bibliographyTitle,
184
+ bibliography,
185
+ howTo,
186
+ schemas,
187
+ };
@@ -0,0 +1,187 @@
1
+ import type { WithContext, SoftwareApplication, FAQPage, HowTo } from 'schema-dts';
2
+ import type { PartyKegUI, PartyKegLocaleContent } from '../index';
3
+
4
+ const slug = 'party-stock-calculator';
5
+ const title = '派对啤酒计算器:婚礼和生日派对的人均用量';
6
+ const description = '根据嘉宾数量、活动时长和温度计算所需啤酒和冰块数量的免费工具。非常适合婚礼、生日派对和户外活动。';
7
+
8
+ const ui: PartyKegUI = {
9
+ calcStockTitle: '库存计算器',
10
+ beerIceSub: '派对用啤酒和冰块',
11
+ guestsLabel: '嘉宾人数',
12
+ durationLabel: '活动时长',
13
+ hoursUnit: '小时',
14
+ intensityLabel: '强度',
15
+ chillLabel: '悠闲',
16
+ standardLabel: '标准',
17
+ partyLabel: '热烈',
18
+ tempLabel: '温度',
19
+ estimatedVolLabel: '估算容量',
20
+ kegsLabel: '桶',
21
+ iceRequiredLabel: '所需冰块',
22
+ bagsLabel: '袋',
23
+ visualizationTitle: '库存可视化',
24
+ optimalMsg: '最优条件',
25
+ highMeltMsg: '检测到高融化速度',
26
+ highEfficiencyMsg: '寒冷/高效率'
27
+ };
28
+
29
+ const faqTitle = '常见问题';
30
+ const bibliographyTitle = '参考文献和来源';
31
+
32
+ const faq: PartyKegLocaleContent['faq'] = [
33
+ {
34
+ question: "4小时内1个人要喝多少啤酒?",
35
+ answer: "平均而言,4小时派对中每人需准备5瓶啤酒。这假设第一小时有2杯饮品,之后每小时1杯。",
36
+ },
37
+ {
38
+ question: "100瓶啤酒需要多少冰块?",
39
+ answer: "您大约需要15-20公斤冰块(7-10袋)。经验法则是正常条件下每升饮料配0.75公斤冰块。在夏季或室外温度超过25°C时,增加到每升1公斤:环境热量会加速融化,冰块会比预期更快耗尽。",
40
+ },
41
+ {
42
+ question: "标准啤酒桶和派对桶之间有什么区别?",
43
+ answer: "标准商用啤酒桶容量50升,可产生约200份饮品(每份250毫升)。派对桶(迷你桶)通常容量5升,约20份饮品。了解这些规格有助于将计算器的升数转换为您需要购买的桶数。",
44
+ },
45
+ {
46
+ question: "如果啤酒已经冷了,为什么还需要这么多冰块?",
47
+ answer: "因为冷却和保温是两个不同的过程。将一罐啤酒从25°C冷却到4°C需要消耗冰块的潜热,约334千焦/千克。冰块冷却后,它会继续工作来抵消环境热量。在35°C的夏日,冷却效果对每升饮料可能每2-3小时融化1公斤冰块。这就是为什么派对前预冷饮料可以将总冰块消耗量减少一半。",
48
+ },
49
+ ];
50
+
51
+ const howTo: PartyKegLocaleContent['howTo'] = [
52
+ {
53
+ name: "估算嘉宾人数",
54
+ text: "确定将有多少人参加。我们的计算器会根据统计消费平均值调整用量。",
55
+ },
56
+ {
57
+ name: "确定时长和强度",
58
+ text: "说明活动持续多少小时以及派对的'节奏'(悠闲、标准或热烈)。",
59
+ },
60
+ {
61
+ name: "根据环境温度调整",
62
+ text: "室外温度对冰块计算至关重要。温度越高,需要补偿的融化速度就越大。",
63
+ },
64
+ ];
65
+
66
+ const bibliography: PartyKegLocaleContent['bibliography'] = [
67
+ {
68
+ name: "Event Planning: Alcohol & Bar Calculations - Spruce Eats",
69
+ url: "https://www.thespruceeats.com/stock-your-bar-for-a-party-760394",
70
+ },
71
+ {
72
+ name: "Thermodynamics of Ice Melting - Engineering Toolbox",
73
+ url: "https://www.engineeringtoolbox.com/saturated-ice-steam-d_970.html",
74
+ },
75
+ ];
76
+
77
+ const seo: PartyKegLocaleContent['seo'] = [
78
+ {
79
+ type: 'title',
80
+ text: '派对需要多少啤酒和冰块?',
81
+ level: 2
82
+ },
83
+ {
84
+ type: 'paragraph',
85
+ html: '组织任何活动时的百万美元问题:<strong>我应该买多少升啤酒?</strong>太少是灾难,太多是不必要的开支。该工具帮助您计算准确的酒精量,最重要的是计算出<strong>需要多少袋冰块</strong>来保持冷度。专业餐饮服务和活动规划人员使用统计消费模型——现在您也可以免费使用。'
86
+ },
87
+ {
88
+ type: 'title',
89
+ text: '人均消费公式',
90
+ level: 2
91
+ },
92
+ {
93
+ type: 'paragraph',
94
+ html: '为了估算所需的酒精,专业餐饮服务使用基于"小时消费率"的公式。这不是精确的科学,但统计数据表明,在标准派对上,每人每小时大约消费1.5单位。环境温度、食物供应和活动的社交氛围等因素都会改变这个基准数字。'
95
+ },
96
+ {
97
+ type: 'stats',
98
+ items: [
99
+ { label: '悠闲消费', value: '1杯/小时', icon: 'mdi:tea-outline' },
100
+ { label: '标准派对', value: '1.5杯/小时', icon: 'mdi:glass-mug-variant' },
101
+ { label: '婚礼/音乐节', value: '2.5+杯/小时', icon: 'mdi:fire' }
102
+ ],
103
+ columns: 3
104
+ },
105
+ {
106
+ type: 'diagnostic',
107
+ title: '冰块的物理学',
108
+ icon: 'mdi:snowflake-thermometer',
109
+ variant: 'warning',
110
+ badge: '热力学',
111
+ html: '计算冰块是大多数派对主人失败的地方。冰块有两个功能:冷却(将啤酒从25°C降至4°C)和维持(对抗环境热量)。在超过30°C的温度下,融化速度翻倍。一袋冰块在阳光直射下可能在20分钟内全部融化,导致派对高潮时饮料已经变温。'
112
+ },
113
+ {
114
+ type: 'tip',
115
+ title: '节省冰块的专业建议',
116
+ html: '在添加冰块前,将啤酒桶和罐子存放在阴凉处。如果饮料在阳光下受热,您的第一袋冰块会因潜热交换在10分钟内损失50%。从预冷的饮料开始,可以大幅减少您实际需要购买的冰块量。'
117
+ },
118
+ {
119
+ type: 'title',
120
+ text: '物流参考数据',
121
+ level: 2
122
+ },
123
+ {
124
+ type: 'paragraph',
125
+ html: '标准50升啤酒桶可产生约200份饮品。典型冰块袋重2公斤。了解这些数据可以帮助您规划活动所需的运输和储存,避免临时突发事件。考虑运输过程中的冰块融化——夏季30分钟的运车可能会损耗一整袋冰块,派对还未开始。'
126
+ },
127
+ {
128
+ type: 'summary',
129
+ title: '该工具面向谁?',
130
+ items: [
131
+ '私人派对主办者:停止猜测,自信地购买下一场庆祝所需的确切用量。',
132
+ '活动策划人:使用准确的消费模型为客户报价并专业地规划酒吧物流。',
133
+ '场地管理者:在不同嘉宾数量的重复性活动中标准化库存计算。'
134
+ ]
135
+ },
136
+ {
137
+ type: 'paragraph',
138
+ html: '一个常被忽视的变量是<strong>嘉宾缺席率</strong>。在大多数派对中,10-15%的嘉宾会提早离场,10%可能根本不喝酒。计算器应用保守的缓冲区,确保您永远不会短缺,但也不会有巨额剩余。理解这些调整有助于为您的特定人群和场景微调估算。购买时始终向上取整,因为开封的啤酒桶通常无法退货。小的过量总是优于派对中途饮品用尽。'
139
+ }
140
+ ];
141
+
142
+ const schemas: PartyKegLocaleContent['schemas'] = [
143
+ {
144
+ '@context': 'https://schema.org',
145
+ '@type': 'FAQPage',
146
+ mainEntity: faq.map((item) => ({
147
+ '@type': 'Question',
148
+ name: item.question,
149
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
150
+ })),
151
+ } as WithContext<FAQPage>,
152
+ {
153
+ '@context': 'https://schema.org',
154
+ '@type': 'HowTo',
155
+ name: title,
156
+ description: description,
157
+ step: howTo.map((step, i) => ({
158
+ '@type': 'HowToStep',
159
+ position: i + 1,
160
+ name: step.name,
161
+ text: step.text,
162
+ })),
163
+ } as WithContext<HowTo>,
164
+ {
165
+ '@context': 'https://schema.org',
166
+ '@type': 'SoftwareApplication',
167
+ name: title,
168
+ description: description,
169
+ applicationCategory: 'UtilityApplication',
170
+ operatingSystem: 'Web',
171
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
172
+ } as WithContext<SoftwareApplication>,
173
+ ];
174
+
175
+ export const content: PartyKegLocaleContent = {
176
+ slug,
177
+ title,
178
+ description,
179
+ ui,
180
+ seo,
181
+ faqTitle,
182
+ faq,
183
+ bibliographyTitle,
184
+ bibliography,
185
+ howTo,
186
+ schemas,
187
+ };
@@ -34,9 +34,21 @@ export const partyKeg: AlcoholToolEntry<PartyKegUI> = {
34
34
  fg: 'mdi:keg',
35
35
  },
36
36
  i18n: {
37
- es: () => import('./i18n/es').then((m) => m.content),
37
+ de: () => import('./i18n/de').then((m) => m.content),
38
38
  en: () => import('./i18n/en').then((m) => m.content),
39
+ es: () => import('./i18n/es').then((m) => m.content),
39
40
  fr: () => import('./i18n/fr').then((m) => m.content),
41
+ id: () => import('./i18n/id').then((m) => m.content),
42
+ it: () => import('./i18n/it').then((m) => m.content),
43
+ ja: () => import('./i18n/ja').then((m) => m.content),
44
+ ko: () => import('./i18n/ko').then((m) => m.content),
45
+ nl: () => import('./i18n/nl').then((m) => m.content),
46
+ pl: () => import('./i18n/pl').then((m) => m.content),
47
+ pt: () => import('./i18n/pt').then((m) => m.content),
48
+ ru: () => import('./i18n/ru').then((m) => m.content),
49
+ sv: () => import('./i18n/sv').then((m) => m.content),
50
+ tr: () => import('./i18n/tr').then((m) => m.content),
51
+ zh: () => import('./i18n/zh').then((m) => m.content),
40
52
  },
41
53
  };
42
54
 
package/src/types.ts CHANGED
@@ -5,7 +5,7 @@ export type { SEOSection };
5
5
 
6
6
  export type KnownLocale =
7
7
  | 'ar' | 'da' | 'de' | 'en' | 'es' | 'fi'
8
- | 'fr' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
8
+ | 'fr' | 'id' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
9
9
  | 'pl' | 'pt' | 'ru' | 'sv' | 'tr' | 'zh';
10
10
 
11
11
  export interface FAQItem {
@@ -1,32 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { ALL_TOOLS } from '../tools';
3
- import type { ToolLocaleContent } from '../types';
4
-
5
- describe('Mandatory Tool Content Validation', () => {
6
- ALL_TOOLS.forEach((tool) => {
7
- describe(`Tool: ${tool.entry.id}`, () => {
8
- const locales = Object.keys(tool.entry.i18n) as (keyof typeof tool.entry.i18n)[];
9
-
10
- locales.forEach((locale) => {
11
- it(`should have non-empty FAQ and Bibliography in locale: ${locale}`, async () => {
12
- const loader = tool.entry.i18n[locale];
13
- if (!loader) return;
14
-
15
- const content = await loader() as ToolLocaleContent;
16
-
17
- expect(content.faqTitle, `FAQ title is missing for tool ${tool.entry.id} in locale ${locale}`).toBeDefined();
18
- expect(content.faqTitle.length, `FAQ title should not be empty for tool ${tool.entry.id} in locale ${locale}`).toBeGreaterThan(0);
19
-
20
- expect(content.faq, `FAQ is missing or empty for tool ${tool.entry.id} in locale ${locale}`).toBeDefined();
21
- expect(content.faq.length, `FAQ should have at least one entry for tool ${tool.entry.id} in locale ${locale}`).toBeGreaterThan(0);
22
-
23
- expect(content.bibliographyTitle, `Bibliography title is missing for tool ${tool.entry.id} in locale ${locale}`).toBeDefined();
24
- expect(content.bibliographyTitle.length, `Bibliography title should not be empty for tool ${tool.entry.id} in locale ${locale}`).toBeGreaterThan(0);
25
-
26
- expect(content.bibliography, `Bibliography is missing or empty for tool ${tool.entry.id} in locale ${locale}`).toBeDefined();
27
- expect(content.bibliography.length, `Bibliography should have at least one entry for tool ${tool.entry.id} in locale ${locale}`).toBeGreaterThan(0);
28
- });
29
- });
30
- });
31
- });
32
- });