@jjlmoya/utils-creative 1.6.0 → 1.8.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 (117) hide show
  1. package/package.json +63 -62
  2. package/src/category/i18n/de.ts +9 -0
  3. package/src/category/i18n/id.ts +9 -0
  4. package/src/category/i18n/it.ts +9 -0
  5. package/src/category/i18n/ja.ts +9 -0
  6. package/src/category/i18n/ko.ts +9 -0
  7. package/src/category/i18n/nl.ts +9 -0
  8. package/src/category/i18n/pl.ts +9 -0
  9. package/src/category/i18n/pt.ts +9 -0
  10. package/src/category/i18n/ru.ts +9 -0
  11. package/src/category/i18n/sv.ts +9 -0
  12. package/src/category/i18n/tr.ts +9 -0
  13. package/src/category/i18n/zh.ts +9 -0
  14. package/src/category/index.ts +12 -0
  15. package/src/tests/faq_count.test.ts +1 -1
  16. package/src/tests/i18n_coverage.test.ts +36 -0
  17. package/src/tests/locale_completeness.test.ts +2 -2
  18. package/src/tests/schemas_fulfillment.test.ts +23 -0
  19. package/src/tests/title_quality.test.ts +55 -0
  20. package/src/tests/tool_validation.test.ts +2 -2
  21. package/src/tool/bead-pattern-generator/i18n/de.ts +115 -0
  22. package/src/tool/bead-pattern-generator/i18n/en.ts +59 -17
  23. package/src/tool/bead-pattern-generator/i18n/es.ts +59 -17
  24. package/src/tool/bead-pattern-generator/i18n/fr.ts +59 -17
  25. package/src/tool/bead-pattern-generator/i18n/id.ts +115 -0
  26. package/src/tool/bead-pattern-generator/i18n/it.ts +115 -0
  27. package/src/tool/bead-pattern-generator/i18n/ja.ts +115 -0
  28. package/src/tool/bead-pattern-generator/i18n/ko.ts +115 -0
  29. package/src/tool/bead-pattern-generator/i18n/nl.ts +115 -0
  30. package/src/tool/bead-pattern-generator/i18n/pl.ts +115 -0
  31. package/src/tool/bead-pattern-generator/i18n/pt.ts +115 -0
  32. package/src/tool/bead-pattern-generator/i18n/ru.ts +115 -0
  33. package/src/tool/bead-pattern-generator/i18n/sv.ts +115 -0
  34. package/src/tool/bead-pattern-generator/i18n/tr.ts +115 -0
  35. package/src/tool/bead-pattern-generator/i18n/zh.ts +115 -0
  36. package/src/tool/bead-pattern-generator/index.ts +12 -0
  37. package/src/tool/dice-roller/i18n/de.ts +138 -0
  38. package/src/tool/dice-roller/i18n/en.ts +74 -32
  39. package/src/tool/dice-roller/i18n/es.ts +74 -32
  40. package/src/tool/dice-roller/i18n/fr.ts +74 -32
  41. package/src/tool/dice-roller/i18n/id.ts +138 -0
  42. package/src/tool/dice-roller/i18n/it.ts +138 -0
  43. package/src/tool/dice-roller/i18n/ja.ts +138 -0
  44. package/src/tool/dice-roller/i18n/ko.ts +138 -0
  45. package/src/tool/dice-roller/i18n/nl.ts +138 -0
  46. package/src/tool/dice-roller/i18n/pl.ts +138 -0
  47. package/src/tool/dice-roller/i18n/pt.ts +138 -0
  48. package/src/tool/dice-roller/i18n/ru.ts +138 -0
  49. package/src/tool/dice-roller/i18n/sv.ts +138 -0
  50. package/src/tool/dice-roller/i18n/tr.ts +138 -0
  51. package/src/tool/dice-roller/i18n/zh.ts +138 -0
  52. package/src/tool/dice-roller/index.ts +12 -0
  53. package/src/tool/excuse-generator/i18n/de.ts +122 -0
  54. package/src/tool/excuse-generator/i18n/en.ts +60 -18
  55. package/src/tool/excuse-generator/i18n/es.ts +60 -18
  56. package/src/tool/excuse-generator/i18n/fr.ts +60 -18
  57. package/src/tool/excuse-generator/i18n/id.ts +122 -0
  58. package/src/tool/excuse-generator/i18n/it.ts +122 -0
  59. package/src/tool/excuse-generator/i18n/ja.ts +122 -0
  60. package/src/tool/excuse-generator/i18n/ko.ts +122 -0
  61. package/src/tool/excuse-generator/i18n/nl.ts +122 -0
  62. package/src/tool/excuse-generator/i18n/pl.ts +122 -0
  63. package/src/tool/excuse-generator/i18n/pt.ts +122 -0
  64. package/src/tool/excuse-generator/i18n/ru.ts +122 -0
  65. package/src/tool/excuse-generator/i18n/sv.ts +122 -0
  66. package/src/tool/excuse-generator/i18n/tr.ts +122 -0
  67. package/src/tool/excuse-generator/i18n/zh.ts +122 -0
  68. package/src/tool/excuse-generator/index.ts +12 -0
  69. package/src/tool/fortune-cookie/i18n/de.ts +127 -0
  70. package/src/tool/fortune-cookie/i18n/en.ts +60 -18
  71. package/src/tool/fortune-cookie/i18n/es.ts +60 -18
  72. package/src/tool/fortune-cookie/i18n/fr.ts +60 -18
  73. package/src/tool/fortune-cookie/i18n/id.ts +127 -0
  74. package/src/tool/fortune-cookie/i18n/it.ts +127 -0
  75. package/src/tool/fortune-cookie/i18n/ja.ts +127 -0
  76. package/src/tool/fortune-cookie/i18n/ko.ts +127 -0
  77. package/src/tool/fortune-cookie/i18n/nl.ts +127 -0
  78. package/src/tool/fortune-cookie/i18n/pl.ts +127 -0
  79. package/src/tool/fortune-cookie/i18n/pt.ts +127 -0
  80. package/src/tool/fortune-cookie/i18n/ru.ts +127 -0
  81. package/src/tool/fortune-cookie/i18n/sv.ts +127 -0
  82. package/src/tool/fortune-cookie/i18n/tr.ts +127 -0
  83. package/src/tool/fortune-cookie/i18n/zh.ts +127 -0
  84. package/src/tool/fortune-cookie/index.ts +12 -0
  85. package/src/tool/synesthesia-painter/i18n/de.ts +122 -0
  86. package/src/tool/synesthesia-painter/i18n/en.ts +74 -32
  87. package/src/tool/synesthesia-painter/i18n/es.ts +74 -32
  88. package/src/tool/synesthesia-painter/i18n/fr.ts +75 -33
  89. package/src/tool/synesthesia-painter/i18n/id.ts +122 -0
  90. package/src/tool/synesthesia-painter/i18n/it.ts +122 -0
  91. package/src/tool/synesthesia-painter/i18n/ja.ts +122 -0
  92. package/src/tool/synesthesia-painter/i18n/ko.ts +122 -0
  93. package/src/tool/synesthesia-painter/i18n/nl.ts +122 -0
  94. package/src/tool/synesthesia-painter/i18n/pl.ts +122 -0
  95. package/src/tool/synesthesia-painter/i18n/pt.ts +122 -0
  96. package/src/tool/synesthesia-painter/i18n/ru.ts +122 -0
  97. package/src/tool/synesthesia-painter/i18n/sv.ts +122 -0
  98. package/src/tool/synesthesia-painter/i18n/tr.ts +122 -0
  99. package/src/tool/synesthesia-painter/i18n/zh.ts +122 -0
  100. package/src/tool/synesthesia-painter/index.ts +12 -0
  101. package/src/tool/zalgo-generator/i18n/de.ts +113 -0
  102. package/src/tool/zalgo-generator/i18n/en.ts +58 -16
  103. package/src/tool/zalgo-generator/i18n/es.ts +58 -16
  104. package/src/tool/zalgo-generator/i18n/fr.ts +58 -16
  105. package/src/tool/zalgo-generator/i18n/id.ts +113 -0
  106. package/src/tool/zalgo-generator/i18n/it.ts +113 -0
  107. package/src/tool/zalgo-generator/i18n/ja.ts +113 -0
  108. package/src/tool/zalgo-generator/i18n/ko.ts +113 -0
  109. package/src/tool/zalgo-generator/i18n/nl.ts +113 -0
  110. package/src/tool/zalgo-generator/i18n/pl.ts +113 -0
  111. package/src/tool/zalgo-generator/i18n/pt.ts +113 -0
  112. package/src/tool/zalgo-generator/i18n/ru.ts +113 -0
  113. package/src/tool/zalgo-generator/i18n/sv.ts +113 -0
  114. package/src/tool/zalgo-generator/i18n/tr.ts +113 -0
  115. package/src/tool/zalgo-generator/i18n/zh.ts +113 -0
  116. package/src/tool/zalgo-generator/index.ts +12 -0
  117. package/src/tools.ts +14 -1
@@ -0,0 +1,122 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ExcuseGeneratorLocaleContent } from '../index';
3
+
4
+ const slug = 'ursaktsgenerator';
5
+ const title = 'Ursaktsgenerator';
6
+ const description = 'Semantisk slumpmaskin för att slippa åtaganden med stil. Generera surrealistiska och oemotsägliga ursäkter omedelbart.';
7
+
8
+ const faq: ExcuseGeneratorLocaleContent['faq'] = [
9
+ {
10
+ question: 'Kan den här generatorn rädda mitt äktenskap?',
11
+ answer: 'Även om vi inte är terapeuter, kan undvikandet av den där middagen med svärföräldrarna genom en rimlig teknisk nödsituation minska spänningen avsevärt. Använd med ansvar.'
12
+ },
13
+ {
14
+ question: 'Varför sådana surrealistiska fraser?',
15
+ answer: 'Strategin bygger på kognitiv dissonans. Om du säger något tråkigt är det verifierbart. Om du säger något absurt, blockerar överraskningen förmågan till vrede.'
16
+ }
17
+ ];
18
+
19
+ const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
20
+ { name: 'Generera', text: 'Klicka på generera-knappen för att skapa en ny ursäkt.' },
21
+ { name: 'Kopiera', text: 'Klicka på kopiera-knappen för att föra över ursäkten till ditt urklipp.' }
22
+ ];
23
+
24
+ const faqSchema: WithContext<FAQPage> = {
25
+ '@context': 'https://schema.org',
26
+ '@type': 'FAQPage',
27
+ mainEntity: faq.map((item) => ({
28
+ '@type': 'Question',
29
+ name: item.question,
30
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
31
+ })),
32
+ };
33
+
34
+ const howToSchema: WithContext<HowTo> = {
35
+ '@context': 'https://schema.org',
36
+ '@type': 'HowTo',
37
+ name: title,
38
+ description,
39
+ step: howTo.map((step) => ({
40
+ '@type': 'HowToStep',
41
+ name: step.name,
42
+ text: step.text,
43
+ })),
44
+ };
45
+
46
+ const appSchema: WithContext<SoftwareApplication> = {
47
+ '@context': 'https://schema.org',
48
+ '@type': 'SoftwareApplication',
49
+ name: title,
50
+ description,
51
+ applicationCategory: 'UtilitiesApplication',
52
+ operatingSystem: 'Web',
53
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
54
+ inLanguage: 'sv',
55
+ };
56
+
57
+ export const content: ExcuseGeneratorLocaleContent = {
58
+ slug,
59
+ title,
60
+ description,
61
+ faqTitle: 'Vanliga frågor',
62
+ bibliographyTitle: 'Fritidsbibliografi',
63
+ ui: {
64
+ title: 'Surrealistisk Ursaktsgenerator',
65
+ description: 'Nästa generations alibi-kalkylator.',
66
+ subjectLabel: 'Subjekt',
67
+ actionLabel: 'Handling',
68
+ victimLabel: 'Offer',
69
+ generateBtn: 'GENERERA URSAKT',
70
+ copyBtn: 'Kopiera denna galenskap',
71
+ copied: 'Kopierad!',
72
+ starts: JSON.stringify([
73
+ "Min katt", "Min mormor", "Presidenten", "En utomjording", "Min granne från 5:e våningen",
74
+ "Wifi", "Mitt horoskop", "En tidsresenär", "Tvättmaskinen", "Mitt kylskåp",
75
+ "Jultomten", "Min skugga", "En ninja", "Veganpolisen", "Siri",
76
+ "Min köttätande växt", "Amazon-budet", "Min onda klon", "En trollkarl", "Godzilla"
77
+ ]),
78
+ middles: JSON.stringify([
79
+ "har förklarat krig mot", "har ätit upp", "har kidnappat", "har satt eld på",
80
+ "anordnar en fest i", "har kräkts på", "vägrar lämna",
81
+ "har hackat", "har stulit", "har blivit kär i", "mediterar över",
82
+ "har förtrollat", "protesterar mot", "har grundat en kult i",
83
+ "dansar samba i", "har frammanat en demon i", "har blockerat åtkomst till",
84
+ "har förvandlats till guld", "försöker sälja", "har skrivit en bok om"
85
+ ]),
86
+ ends: JSON.stringify([
87
+ "mina hemnycklar.", "min livslust.", "garageporten.",
88
+ "mina favoritbyxor.", "routern i vardagsrummet.", "mina enda skor.",
89
+ "fysikens lagar.", "min värdighet.", "byggnadens hiss.",
90
+ "mitt Netflix-konto.", "min tandborste.", "mina lagfarter.",
91
+ "min samling av pogs.", "bilens handbroms.", "min lust att socialisera.",
92
+ "mitt kaffeförråd.", "toalettlocket.", "TV-fjärrkontrollen.",
93
+ "mina lyckostrumpor.", "den västerländska civilisationen."
94
+ ]),
95
+ faqTitle: 'FAQ',
96
+ bibliographyTitle: 'Referenser'
97
+ },
98
+ seo: [
99
+ { type: 'title', text: 'Den vetenskapliga konsten att skapa den perfekta ursäkten', level: 2 },
100
+ { type: 'paragraph', html: 'Vi lever i en era av hyperuppkoppling. Din telefon vibrerar, din klocka ger dig notiser, och din sociala agenda ser ut som ett spel Tetris som håller på att förloras. Pressen att säga "ja" till allt har skapat en epidemi av social utmattning.' },
101
+ { type: 'title', text: 'Renässansen för JOMO (Joy of Missing Out)', level: 3 },
102
+ { type: 'paragraph', html: 'Medan FOMO (Fear of Missing Out) dominerade det senaste decenniet, förespråkar digitala hälsoexperter nu <strong>JOMO: Glädjen i att missa saker</strong>. Det handlar inte om isolering, utan om avsiktlighet.' },
103
+ { type: 'tip', title: 'Formeln för det oemotsägliga alibit', html: '<strong>Det dissocierade subjektet:</strong> Du är aldrig den skyldige. Det är "wifi", "min katt", "universum". Flytta skulden till en extern enhet.<br><strong>Den hyperboliska handlingen:</strong> Situationen måste vara tillräckligt absurd eller teknisk för att ingen ska fråga efter detaljer.<br><strong>Den fysiska blockaden:</strong> Slutresultatet måste vara binärt: antingen går jag eller så stannar jag hemma.' },
104
+ { type: 'title', text: 'En kort historia om ursäkten', level: 3 },
105
+ { type: 'list', items: [
106
+ '<strong>Medeltiden:</strong> "Min häst har tappat en sko" (En tidlös klassiker).',
107
+ '<strong>Industriella revolutionen:</strong> "Ångmaskinen blev överhettad".',
108
+ '<strong>Digitala eran:</strong> "Mitt internet lade av mitt i en uppdatering".',
109
+ ]},
110
+ { type: 'proscons', items: [
111
+ { pro: 'Lindrar omedelbart social press', con: 'Överanvändning urholkar förtroendet' },
112
+ { pro: 'Skyddar din energi och dina gränser', con: 'Kan skapa skuldkänslor om den används vårdslöst' },
113
+ { pro: 'Kreativ och humoristisk ton dämpar spänningen', con: 'Inte lämplig för formella eller professionella sammanhang' },
114
+ ]},
115
+ ],
116
+ faq,
117
+ bibliography: [
118
+ { name: 'Prokrastinerarens manifest', url: 'https://example.com/manifesto' }
119
+ ],
120
+ howTo,
121
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
122
+ };
@@ -0,0 +1,122 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ExcuseGeneratorLocaleContent } from '../index';
3
+
4
+ const slug = 'bahane-ureteci';
5
+ const title = 'Bahane Üreteci';
6
+ const description = 'Sorumluluklardan şık bir şekilde kurtulmak için anlamsal bir kumar makinesi. Anında gerçeküstü ve reddedilemez bahaneler üretin.';
7
+
8
+ const faq: ExcuseGeneratorLocaleContent['faq'] = [
9
+ {
10
+ question: 'Bu üreteç evliliğimi kurtarabilir mi?',
11
+ answer: 'Terapist olmasak da, kayınvalidenizle o akşam yemeğinden makul bir teknik acil durum bahanesiyle kaçınmak gerginliği önemli ölçüde azaltabilir. Sorumlu bir şekilde kullanın.'
12
+ },
13
+ {
14
+ question: 'Neden bu kadar gerçeküstü cümleler?',
15
+ answer: 'Strateji Bilişsel Çelişki\'ye dayanmaktadır. Sıkıcı bir şey söylerseniz doğrulanabilir. Saçma bir şey söylerseniz, şaşkınlık öfkelenme yetisini engeller.'
16
+ }
17
+ ];
18
+
19
+ const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
20
+ { name: 'Üret', text: 'Yeni bir bahane oluşturmak için üret düğmesine tıklayın.' },
21
+ { name: 'Kopyala', text: 'Bahane panonuza kopyalamak için kopyala düğmesine tıklayın.' }
22
+ ];
23
+
24
+ const faqSchema: WithContext<FAQPage> = {
25
+ '@context': 'https://schema.org',
26
+ '@type': 'FAQPage',
27
+ mainEntity: faq.map((item) => ({
28
+ '@type': 'Question',
29
+ name: item.question,
30
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
31
+ })),
32
+ };
33
+
34
+ const howToSchema: WithContext<HowTo> = {
35
+ '@context': 'https://schema.org',
36
+ '@type': 'HowTo',
37
+ name: title,
38
+ description,
39
+ step: howTo.map((step) => ({
40
+ '@type': 'HowToStep',
41
+ name: step.name,
42
+ text: step.text,
43
+ })),
44
+ };
45
+
46
+ const appSchema: WithContext<SoftwareApplication> = {
47
+ '@context': 'https://schema.org',
48
+ '@type': 'SoftwareApplication',
49
+ name: title,
50
+ description,
51
+ applicationCategory: 'UtilitiesApplication',
52
+ operatingSystem: 'Web',
53
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
54
+ inLanguage: 'tr',
55
+ };
56
+
57
+ export const content: ExcuseGeneratorLocaleContent = {
58
+ slug,
59
+ title,
60
+ description,
61
+ faqTitle: 'Sıkça Sorulan Sorular',
62
+ bibliographyTitle: 'Boş Zaman Kaynakçası',
63
+ ui: {
64
+ title: 'Gerçeküstü Bahane Üreteci',
65
+ description: 'Yeni nesil alibi hesaplayıcı.',
66
+ subjectLabel: 'Özne',
67
+ actionLabel: 'Eylem',
68
+ victimLabel: 'Kurban',
69
+ generateBtn: 'BAHANE ÜRET',
70
+ copyBtn: 'Bu çılgınlığı kopyala',
71
+ copied: 'Kopyalandı!',
72
+ starts: JSON.stringify([
73
+ "Kedim", "Büyükannem", "Başkan", "Bir uzaylı", "5. kattaki komşum",
74
+ "Wifi", "Burcum", "Bir zaman yolcusu", "Çamaşır makinesi", "Buzdolabım",
75
+ "Noel ruhu", "Gölgem", "Bir ninja", "Vegan polisi", "Siri",
76
+ "Etobur bitkim", "Amazon kuryesi", "Kötü klonum", "Bir büyücü", "Godzilla"
77
+ ]),
78
+ middles: JSON.stringify([
79
+ "savaş ilan etti", "yedi", "kaçırdı", "ateşe verdi",
80
+ "şurada bir parti düzenliyor:", "üzerine kustu", "çıkmayı reddediyor:",
81
+ "hackledi", "çaldı", "şuna aşık oldu:", "üzerine meditasyon yapıyor:",
82
+ "üzerine büyü yaptı", "şunu protesto ediyor:", "şurada bir tarikat kurdu:",
83
+ "samba yapıyor:", "bir iblis çağırdı:", "erişimi engelledi:",
84
+ "altına dönüştü", "satmaya çalışıyor", "hakkında bir kitap yazdı:"
85
+ ]),
86
+ ends: JSON.stringify([
87
+ "evimin anahtarlarını.", "yaşama sevincimi.", "garaj kapısını.",
88
+ "en sevdiğim pantolonumu.", "oturma odasındaki yönlendiriciyi.", "tek ayakkabımı.",
89
+ "fizik yasalarını.", "onurumu.", "binanın asansörünü.",
90
+ "Netflix hesabımı.", "diş fırçamı.", "evimin tapularını.",
91
+ "taso koleksiyonumu.", "arabanın el frenini.", "sosyalleşme isteğimi.",
92
+ "kahve stoklarımı.", "klozet kapağını.", "TV kumandasını.",
93
+ "şanslı çoraplarımı.", "Batı medeniyetini."
94
+ ]),
95
+ faqTitle: 'FAQ',
96
+ bibliographyTitle: 'Referanslar'
97
+ },
98
+ seo: [
99
+ { type: 'title', text: 'Mükemmel Bahanenin Bilimsel Sanatı', level: 2 },
100
+ { type: 'paragraph', html: 'Hiper-bağlantılılık çağında yaşıyoruz. Telefonunuz titriyor, saatiniz bildirim gönderiyor ve sosyal ajandanız kaybedilmek üzere olan bir Tetris oyunu gibi görünüyor. Her şeye "evet" deme baskısı bir sosyal tükenmişlik salgını yarattı.' },
101
+ { type: 'title', text: 'JOMO\'nun (Joy of Missing Out) Rönesansı', level: 3 },
102
+ { type: 'paragraph', html: 'Geçtiğimiz on yıla FOMO (Kaçırma Korkusu) hakim olsa da, dijital sağlık uzmanları artık <strong>JOMO: Kaçırmanın Keyfi</strong>\'ni savunuyor. Bu izolasyonla ilgili değil, niyetlilikle ilgili.' },
103
+ { type: 'tip', title: 'Reddedilemez Alibi Formülü', html: '<strong>Ayrışmış Özne:</strong> Suçlu asla siz değilsiniz. Bu "wifi", "kedim", "evren". Suçu dış bir varlığa kaydırın.<br><strong>Hiperbolik Eylem:</strong> Durum, kimsenin ayrıntı sormayacağı kadar saçma veya teknik olmalıdır.<br><strong>Fiziksel Blok:</strong> Nihai sonuç ikili olmalıdır: ya giderim ya da evde kalırım.' },
104
+ { type: 'title', text: 'Bahanenin Kısa Tarihi', level: 3 },
105
+ { type: 'list', items: [
106
+ '<strong>Orta Çağ:</strong> "Atım nalını kaybetti" (Zamansız bir klasik).',
107
+ '<strong>Sanayi Devrimi:</strong> "Buhar makinesi aşırı ısındı".',
108
+ '<strong>Dijital Çağ:</strong> "İnternetim tam bir güncellemenin ortasında koptu".',
109
+ ]},
110
+ { type: 'proscons', items: [
111
+ { pro: 'Sosyal baskıyı anında hafifletir', con: 'Aşırı kullanım güveni sarsar' },
112
+ { pro: 'Enerjinizi ve sınırlarınızı korur', con: 'Dikkatsizce kullanılırsa suçluluk duygusu yaratabilir' },
113
+ { pro: 'Yaratıcı ve esprili ton gerginliği dağıtır', con: 'Resmi veya profesyonel bağlamlar için uygun değildir' },
114
+ ]},
115
+ ],
116
+ faq,
117
+ bibliography: [
118
+ { name: 'Erteleyicinin Manifestosu', url: 'https://example.com/manifesto' }
119
+ ],
120
+ howTo,
121
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
122
+ };
@@ -0,0 +1,122 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ExcuseGeneratorLocaleContent } from '../index';
3
+
4
+ const slug = 'excuse-generator-zh';
5
+ const title = '借口生成器';
6
+ const description = '语义化的随机机器,让您有格调地摆脱承诺。瞬间生成超现实且无可辩驳的借口。';
7
+
8
+ const faq: ExcuseGeneratorLocaleContent['faq'] = [
9
+ {
10
+ question: '这个生成器能挽救我的婚姻吗?',
11
+ answer: '虽然我们不是治疗师,但利用一个合理的“技术故障”来避免与姻亲的聚餐,确实能显著缓解紧张气氛。请负责任地使用。'
12
+ },
13
+ {
14
+ question: '为什么句子这么荒诞?',
15
+ answer: '策略核心是“认知失调”。如果你说一件平庸的事,那是可以验证的;如果你说一件荒谬的事,这种诧异感会瞬间阻断对方生气的能力。'
16
+ }
17
+ ];
18
+
19
+ const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
20
+ { name: '生成', text: '点击生成按钮来创建一个新的借口。' },
21
+ { name: '复制', text: '点击复制按钮将生成的借口保存到剪贴板。' }
22
+ ];
23
+
24
+ const faqSchema: WithContext<FAQPage> = {
25
+ '@context': 'https://schema.org',
26
+ '@type': 'FAQPage',
27
+ mainEntity: faq.map((item) => ({
28
+ '@type': 'Question',
29
+ name: item.question,
30
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
31
+ })),
32
+ };
33
+
34
+ const howToSchema: WithContext<HowTo> = {
35
+ '@context': 'https://schema.org',
36
+ '@type': 'HowTo',
37
+ name: title,
38
+ description,
39
+ step: howTo.map((step) => ({
40
+ '@type': 'HowToStep',
41
+ name: step.name,
42
+ text: step.text,
43
+ })),
44
+ };
45
+
46
+ const appSchema: WithContext<SoftwareApplication> = {
47
+ '@context': 'https://schema.org',
48
+ '@type': 'SoftwareApplication',
49
+ name: title,
50
+ description,
51
+ applicationCategory: 'UtilitiesApplication',
52
+ operatingSystem: 'Web',
53
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
54
+ inLanguage: 'zh',
55
+ };
56
+
57
+ export const content: ExcuseGeneratorLocaleContent = {
58
+ slug,
59
+ title,
60
+ description,
61
+ faqTitle: '常见问题解答',
62
+ bibliographyTitle: '闲暇文献',
63
+ ui: {
64
+ title: '荒诞借口生成器',
65
+ description: '下一代不在场证明计算器。',
66
+ subjectLabel: '主语',
67
+ actionLabel: '动作',
68
+ victimLabel: '对象',
69
+ generateBtn: '生成借口',
70
+ copyBtn: '复制这疯狂的想法',
71
+ copied: '已复制!',
72
+ starts: JSON.stringify([
73
+ "我家猫", "我奶奶", "总统", "外星人", "五楼的邻居",
74
+ "Wifi", "我的星座运势", "一个时空旅行者", "洗衣机", "我家冰箱",
75
+ "圣诞精神", "我的影子", "一个忍者", "素食警察", "Siri",
76
+ "我的食肉植物", "亚马逊快递员", "我的邪恶克隆体", "一个巫师", "哥斯拉"
77
+ ]),
78
+ middles: JSON.stringify([
79
+ "向...宣战了", "吃掉了", "绑架了", "纵火焚烧了",
80
+ "正在...举办派对", "在...上面呕吐了", "拒绝离开",
81
+ "黑进了", "偷走了", "爱上了", "正在对...冥想",
82
+ "对...施了咒语", "正在抗议", "在...创立了教派",
83
+ "在...跳桑巴舞", "在...召唤了恶魔", "封锁了去...的通道",
84
+ "变成了黄金", "正试图变卖", "写了一本关于...的书"
85
+ ]),
86
+ ends: JSON.stringify([
87
+ "我的房门钥匙。", "我的求生欲。", "车库门。",
88
+ "我最喜欢的裤子。", "客厅的路由器。", "我唯一的一双鞋。",
89
+ "物理定律。", "我的尊严。", "大楼的电梯。",
90
+ "我的 Netflix 账号。", "我的牙刷。", "我的房产证。",
91
+ "我的圆牌收藏。", "汽车手刹。", "我的社交欲望。",
92
+ "我的咖啡储备。", "马桶盖。", "电视遥控器。",
93
+ "我的幸运袜。", "西方文明。"
94
+ ]),
95
+ faqTitle: 'FAQ',
96
+ bibliographyTitle: '参考资料'
97
+ },
98
+ seo: [
99
+ { type: 'title', text: '完美借口的科学艺术', level: 2 },
100
+ { type: 'paragraph', html: '我们生活在一个过度连接的时代。你的手机在震动,手表在提醒,社交日程表看起来就像一局即将败北的俄罗斯方块。对所有事情都说“是”的压力造成了社交疲劳的流行。' },
101
+ { type: 'title', text: 'JOMO(错失的快乐)的复兴', level: 3 },
102
+ { type: 'paragraph', html: '虽然 FOMO(错失恐惧症)统治了过去十年,但数字健康专家现在提倡 <strong>JOMO:错失的快乐</strong>。这关乎的不是孤立,而是有目的的选择。' },
103
+ { type: 'tip', title: '无可辩驳的不在场证明公式', html: '<strong>分离主语:</strong>你永远不是罪魁祸首。它是“Wifi”、“我家猫”或“宇宙”。将责任推给外部实体。<br><strong>夸张的动作:</strong>情况必须足够荒诞或专业,以至于没有人会追问细节。<br><strong>物理阻断:</strong>最终结果必须是二元的:要么我去,要么我呆在家里。' },
104
+ { type: 'title', text: '借口简史', level: 3 },
105
+ { type: 'list', items: [
106
+ '<strong>中世纪:</strong> “我的马掉了一个马掌”(永恒的经典)。',
107
+ '<strong>工业革命:</strong> “蒸汽机过热了”。',
108
+ '<strong>数字时代:</strong> “我的网络在更新到一半时断了”。'
109
+ ]},
110
+ { type: 'proscons', items: [
111
+ { pro: '瞬间缓解社交压力', con: '过度使用会破坏信任' },
112
+ { pro: '保护您的精力与边界', con: '如果使用不当可能会产生负罪感' },
113
+ { pro: '创意且幽默的语调能化解紧张气氛', con: '不适合正式或职业场合' }
114
+ ]},
115
+ ],
116
+ faq,
117
+ bibliography: [
118
+ { name: '拖延者宣言', url: 'https://example.com/manifesto' }
119
+ ],
120
+ howTo,
121
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
122
+ };
@@ -29,6 +29,18 @@ export const excuseGenerator: CreativeToolEntry<ExcuseGeneratorUI> = {
29
29
  es: () => import('./i18n/es').then((m) => m.content),
30
30
  en: () => import('./i18n/en').then((m) => m.content),
31
31
  fr: () => import('./i18n/fr').then((m) => m.content),
32
+ de: () => import('./i18n/de').then((m) => m.content),
33
+ id: () => import('./i18n/id').then((m) => m.content),
34
+ it: () => import('./i18n/it').then((m) => m.content),
35
+ ja: () => import('./i18n/ja').then((m) => m.content),
36
+ ko: () => import('./i18n/ko').then((m) => m.content),
37
+ nl: () => import('./i18n/nl').then((m) => m.content),
38
+ pl: () => import('./i18n/pl').then((m) => m.content),
39
+ pt: () => import('./i18n/pt').then((m) => m.content),
40
+ ru: () => import('./i18n/ru').then((m) => m.content),
41
+ sv: () => import('./i18n/sv').then((m) => m.content),
42
+ tr: () => import('./i18n/tr').then((m) => m.content),
43
+ zh: () => import('./i18n/zh').then((m) => m.content),
32
44
  },
33
45
  };
34
46
 
@@ -0,0 +1,127 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { FortuneCookieLocaleContent } from '../index';
3
+
4
+ const slug = 'glueckskeks-online';
5
+ const title = 'Glückskeks';
6
+ const description = 'Prüfen Sie Ihr tägliches Schicksal und entdecken Sie Ihre Glückszahlen. Ein Keks pro Tag, enthüllt mit einem Klick.';
7
+
8
+ const faq: FortuneCookieLocaleContent['faq'] = [
9
+ {
10
+ question: 'Kann ich mehr als einen Keks pro Tag öffnen?',
11
+ answer: 'Das Schicksal spricht nur einmal am Tag. Wir speichern Ihr Ergebnis auf dem Gerät, damit es Sie durch den Tag begleitet.'
12
+ },
13
+ {
14
+ question: 'Werden die Sprüche zufällig generiert?',
15
+ answer: 'Ja — jeden Tag wird ein zufälliger Spruch ausgewählt und lokal gespeichert. Jeder der 25 Sprüche hat die gleiche Chance, ausgewählt zu werden, was für Abwechslung sorgt.'
16
+ }
17
+ ];
18
+
19
+ const howTo: FortuneCookieLocaleContent['howTo'] = [
20
+ { name: 'Keks zerbrechen', text: 'Klicken Sie wiederholt auf den Keks, um ihn aufzubrechen.' },
21
+ { name: 'Botschaft lesen', text: 'Entdecken Sie die verborgene Botschaft im Inneren und Ihre heutigen Glückszahlen.' }
22
+ ];
23
+
24
+ const faqSchema: WithContext<FAQPage> = {
25
+ '@context': 'https://schema.org',
26
+ '@type': 'FAQPage',
27
+ mainEntity: faq.map((item) => ({
28
+ '@type': 'Question',
29
+ name: item.question,
30
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
31
+ })),
32
+ };
33
+
34
+ const howToSchema: WithContext<HowTo> = {
35
+ '@context': 'https://schema.org',
36
+ '@type': 'HowTo',
37
+ name: title,
38
+ description,
39
+ step: howTo.map((step) => ({
40
+ '@type': 'HowToStep',
41
+ name: step.name,
42
+ text: step.text,
43
+ })),
44
+ };
45
+
46
+ const appSchema: WithContext<SoftwareApplication> = {
47
+ '@context': 'https://schema.org',
48
+ '@type': 'SoftwareApplication',
49
+ name: title,
50
+ description,
51
+ applicationCategory: 'UtilitiesApplication',
52
+ operatingSystem: 'Web',
53
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
54
+ inLanguage: 'de',
55
+ };
56
+
57
+ export const content: FortuneCookieLocaleContent = {
58
+ slug,
59
+ title,
60
+ description,
61
+ faqTitle: 'Häufig gestellte Fragen',
62
+ bibliographyTitle: 'Schicksals-Bibliographie',
63
+ ui: {
64
+ title: 'Online Glückskeks',
65
+ description: 'Dein tägliches digitales Orakel.',
66
+ instruction: 'Klicke auf den Keks, um dein Schicksal zu enthüllen',
67
+ dailyStatus: 'Dein heutiges Schicksal wurde bereits enthüllt.',
68
+ shareBtn: 'Weisheit teilen',
69
+ shareTitle: 'Mein Glückskeks',
70
+ shareText: 'Das Schicksal hat gesprochen: "$TEXT"\nMeine Zahlen: $NUMS\n\nEntdecke dein Schicksal hier:',
71
+ copied: 'Kopiert!',
72
+ fortunes: JSON.stringify([
73
+ "Das Glück, das du suchst, befindet sich in einem anderen Keks.",
74
+ "Zähle nicht die Tage, mache die Tage zählenswert.",
75
+ "Eine Reise von tausend Meilen beginnt mit einem einzigen Schritt.",
76
+ "Ein Fehler ist das Vorwort zur Entdeckung.",
77
+ "Deine Lernfähigkeit ist dein größtes Kapital.",
78
+ "Lächle, das Universum beobachtet dich.",
79
+ "Geduld ist ein Baum mit bitterer Wurzel, aber sehr süßer Frucht.",
80
+ "Fürchte dich nicht vor langsamem Wachstum, fürchte dich nur vor Stillstand.",
81
+ "Heute ist das Morgen, um das du dir gestern Sorgen gemacht hast.",
82
+ "Glück ist nichts Fertiges. Es entsteht durch dein eigenes Handeln.",
83
+ "Wenn du die Windrichtung nicht ändern kannst, richte deine Segel neu aus.",
84
+ "Was du jetzt säst, wirst du später ernten.",
85
+ "Kreativität ist Intelligenz, die Spaß hat.",
86
+ "Suche nicht nach Fehlern, suche nach Lösungen.",
87
+ "Deine Einstellung, nicht deine Begabung, bestimmt deine Höhe.",
88
+ "Erfolg ist die Summe kleiner Anstrengungen, die Tag für Tag wiederholt werden.",
89
+ "Glaube daran, dass du es kannst, dann hast du schon den halben Weg geschafft.",
90
+ "Der einzige Weg, großartige Arbeit zu leisten, ist zu lieben, was man tut.",
91
+ "Das Leben besteht zu 10 % aus dem, was dir passiert, und zu 90 % daraus, wie du darauf reagierst.",
92
+ "Sei die Veränderung, die du dir für die Welt wünschst.",
93
+ "Der beste Weg, die Zukunft vorherzusagen, ist, sie selbst zu gestalten.",
94
+ "Einfachheit ist die höchste Form der Raffinesse.",
95
+ "Du bist der Herr deines Schicksals und der Kapitän deiner Seele.",
96
+ "Bald wirst du Nachrichten erhalten, die deine Perspektive ändern werden.",
97
+ "Eine unerwartete Reise wird dir große Freude bereiten."
98
+ ]),
99
+ faqTitle: 'FAQ',
100
+ bibliographyTitle: 'Referenzen'
101
+ },
102
+ seo: [
103
+ { type: 'title', text: 'Das Geheimnis des Glückskekses', level: 2 },
104
+ { type: 'paragraph', html: 'Haben Sie sich jemals gefragt, woher diese kuriosen Kekse kommen? Obwohl wir sie mit chinesischem Essen assoziieren, ist ihre Herkunft eine faszinierende Reise zwischen Japan und den Vereinigten Staaten. Der Glückskeks, wie wir ihn heute kennen, wurde wahrscheinlich Anfang des 20. Jahrhunderts in Kalifornien erfunden, nicht in China — dort sind sie praktisch unbekannt.' },
105
+ { type: 'tip', title: 'So funktioniert unser Orakel', html: 'Jeden Tag können Sie einen Keks öffnen. Das System speichert Ihr Schicksal, damit Sie sich 24 Stunden lang daran erinnern können. Die Botschaft wird lokal in Ihrem Browser gespeichert — absolut privat, ohne Beteiligung eines Servers. Kommen Sie morgen für eine neue Vorhersage wieder!' },
106
+ { type: 'title', text: 'Die Philosophie der Orakel', level: 3 },
107
+ { type: 'paragraph', html: 'Menschen haben in unsicheren Zeiten schon immer nach Führung gesucht. Vom Orakel von Delphi bis zum I Ging erfüllen Wahrsagesysteme eine beständige psychologische Funktion: Sie geben uns die Erlaubnis, <strong>inne zu halten und zu reflektieren</strong>. Ein Glückskeks sagt nicht die Zukunft voraus — er regt dazu aus, darüber nachzudenken.' },
108
+ { type: 'list', items: [
109
+ '<strong>Altes China:</strong> Das I Ging (Buch der Wandlungen, ca. 1000 v. Chr.) nutzte Hexagramme, um Entscheidungen zu leiten und das Schicksal zu interpretieren.',
110
+ '<strong>Klassisches Griechenland:</strong> Das Orakel von Delphi zog Herrscher und Bürger gleichermaßen mit kryptischen Aussprüchen an, die als göttliche Führung interpretiert wurden.',
111
+ '<strong>Modernes Japan:</strong> Omikuji-Glückszettel an Shinto-Schreinen, die an Baumzweige gebunden werden, verbinden Schicksal mit Ritual.',
112
+ '<strong>20. Jahrhundert USA:</strong> Glückskekse entstanden in japanisch-amerikanischen Gemeinschaften, bevor sie zum Synonym für die chinesisch-amerikanische Küche wurden.',
113
+ ]},
114
+ { type: 'stats', items: [
115
+ { value: '3 Mrd.+', label: 'Glückskekse jährlich hergestellt', icon: 'mdi:cookie' },
116
+ { value: '~1000 v. Chr.', label: 'Ursprung des I Ging', icon: 'mdi:book-open-variant' },
117
+ { value: '25', label: 'Sprüche in diesem Orakel', icon: 'mdi:star-shooting' },
118
+ { value: '1/Tag', label: 'Ein Schicksal pro Tag', icon: 'mdi:calendar-today' },
119
+ ], columns: 4 },
120
+ ],
121
+ faq,
122
+ bibliography: [
123
+ { name: 'Geschichte des Glückskekses', url: 'https://de.wikipedia.org/wiki/Glückskeks' }
124
+ ],
125
+ howTo,
126
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
127
+ };
@@ -1,9 +1,63 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
1
2
  import type { FortuneCookieLocaleContent } from '../index';
2
3
 
4
+ const slug = 'fortune-cookie';
5
+ const title = 'Fortune Cookie';
6
+ const description = 'Check your daily destiny and discover your lucky numbers. One fortune per day, revealed with a click.';
7
+
8
+ const faq: FortuneCookieLocaleContent['faq'] = [
9
+ {
10
+ question: 'Can I open more than one cookie per day?',
11
+ answer: 'Destiny only speaks once a day. We save your fortune on the device so it guides you throughout the day.'
12
+ },
13
+ {
14
+ question: 'Are the fortunes randomly generated?',
15
+ answer: 'Yes — a random fortune is selected each day and saved locally. Each of the 25 fortunes has an equal chance of being chosen, ensuring variety over time.'
16
+ }
17
+ ];
18
+
19
+ const howTo: FortuneCookieLocaleContent['howTo'] = [
20
+ { name: 'Break the cookie', text: 'Click repeatedly on the cookie to crack it open.' },
21
+ { name: 'Read your fortune', text: 'Discover the hidden message inside and your lucky numbers for the day.' }
22
+ ];
23
+
24
+ const faqSchema: WithContext<FAQPage> = {
25
+ '@context': 'https://schema.org',
26
+ '@type': 'FAQPage',
27
+ mainEntity: faq.map((item) => ({
28
+ '@type': 'Question',
29
+ name: item.question,
30
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
31
+ })),
32
+ };
33
+
34
+ const howToSchema: WithContext<HowTo> = {
35
+ '@context': 'https://schema.org',
36
+ '@type': 'HowTo',
37
+ name: title,
38
+ description,
39
+ step: howTo.map((step) => ({
40
+ '@type': 'HowToStep',
41
+ name: step.name,
42
+ text: step.text,
43
+ })),
44
+ };
45
+
46
+ const appSchema: WithContext<SoftwareApplication> = {
47
+ '@context': 'https://schema.org',
48
+ '@type': 'SoftwareApplication',
49
+ name: title,
50
+ description,
51
+ applicationCategory: 'UtilitiesApplication',
52
+ operatingSystem: 'Web',
53
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
54
+ inLanguage: 'en',
55
+ };
56
+
3
57
  export const content: FortuneCookieLocaleContent = {
4
- slug: 'fortune-cookie',
5
- title: 'Fortune Cookie',
6
- description: 'Check your daily destiny and discover your lucky numbers. One fortune per day, revealed with a click.',
58
+ slug,
59
+ title,
60
+ description,
7
61
  faqTitle: 'Frequently Asked Questions',
8
62
  bibliographyTitle: 'Destiny Bibliography',
9
63
  ui: {
@@ -64,22 +118,10 @@ export const content: FortuneCookieLocaleContent = {
64
118
  { value: '1/day', label: 'One destiny per day', icon: 'mdi:calendar-today' },
65
119
  ], columns: 4 },
66
120
  ],
67
- faq: [
68
- {
69
- question: 'Can I open more than one cookie per day?',
70
- answer: 'Destiny only speaks once a day. We save your fortune on the device so it guides you throughout the day.'
71
- },
72
- {
73
- question: 'Are the fortunes randomly generated?',
74
- answer: 'Yes — a random fortune is selected each day and saved locally. Each of the 25 fortunes has an equal chance of being chosen, ensuring variety over time.'
75
- }
76
- ],
121
+ faq,
77
122
  bibliography: [
78
123
  { name: 'History of the Fortune Cookie', url: 'https://en.wikipedia.org/wiki/Fortune_cookie' }
79
124
  ],
80
- howTo: [
81
- { name: 'Break the cookie', text: 'Click repeatedly on the cookie to crack it open.' },
82
- { name: 'Read your fortune', text: 'Discover the hidden message inside and your lucky numbers for the day.' }
83
- ],
84
- schemas: []
125
+ howTo,
126
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
85
127
  };