@jjlmoya/utils-games-development 1.46.0 → 1.49.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 (66) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -1
  3. package/src/entries.ts +8 -1
  4. package/src/tests/locale_completeness.test.ts +1 -20
  5. package/src/tests/tool_validation.test.ts +2 -3
  6. package/src/tool/itchioGameTester/audit.ts +51 -0
  7. package/src/tool/itchioGameTester/bibliography.astro +6 -0
  8. package/src/tool/itchioGameTester/bibliography.ts +14 -0
  9. package/src/tool/itchioGameTester/client.ts +238 -0
  10. package/src/tool/itchioGameTester/component.astro +97 -0
  11. package/src/tool/itchioGameTester/entry.ts +28 -0
  12. package/src/tool/itchioGameTester/i18n/de.ts +107 -0
  13. package/src/tool/itchioGameTester/i18n/en.ts +164 -0
  14. package/src/tool/itchioGameTester/i18n/es.ts +172 -0
  15. package/src/tool/itchioGameTester/i18n/fr.ts +107 -0
  16. package/src/tool/itchioGameTester/i18n/id.ts +107 -0
  17. package/src/tool/itchioGameTester/i18n/it.ts +107 -0
  18. package/src/tool/itchioGameTester/i18n/ja.ts +107 -0
  19. package/src/tool/itchioGameTester/i18n/ko.ts +107 -0
  20. package/src/tool/itchioGameTester/i18n/nl.ts +107 -0
  21. package/src/tool/itchioGameTester/i18n/pl.ts +107 -0
  22. package/src/tool/itchioGameTester/i18n/pt.ts +107 -0
  23. package/src/tool/itchioGameTester/i18n/ru.ts +107 -0
  24. package/src/tool/itchioGameTester/i18n/sv.ts +107 -0
  25. package/src/tool/itchioGameTester/i18n/tr.ts +107 -0
  26. package/src/tool/itchioGameTester/i18n/zh.ts +107 -0
  27. package/src/tool/itchioGameTester/index.ts +11 -0
  28. package/src/tool/itchioGameTester/itchio-game-tester.css +273 -0
  29. package/src/tool/itchioGameTester/logic.test.ts +56 -0
  30. package/src/tool/itchioGameTester/logic.ts +266 -0
  31. package/src/tool/itchioGameTester/seo.astro +15 -0
  32. package/src/tool/itchioGameTester/ui.ts +20 -0
  33. package/src/tool/spriteSheetPacker/app-client.ts +248 -0
  34. package/src/tool/spriteSheetPacker/bibliography.astro +6 -0
  35. package/src/tool/spriteSheetPacker/bibliography.ts +12 -0
  36. package/src/tool/spriteSheetPacker/component.astro +229 -0
  37. package/src/tool/spriteSheetPacker/dropzone-client.ts +55 -0
  38. package/src/tool/spriteSheetPacker/entry.ts +28 -0
  39. package/src/tool/spriteSheetPacker/exporter.ts +116 -0
  40. package/src/tool/spriteSheetPacker/extractor-client.ts +127 -0
  41. package/src/tool/spriteSheetPacker/flipbook-client.ts +60 -0
  42. package/src/tool/spriteSheetPacker/i18n/de.ts +270 -0
  43. package/src/tool/spriteSheetPacker/i18n/en.ts +275 -0
  44. package/src/tool/spriteSheetPacker/i18n/es.ts +275 -0
  45. package/src/tool/spriteSheetPacker/i18n/fr.ts +270 -0
  46. package/src/tool/spriteSheetPacker/i18n/id.ts +270 -0
  47. package/src/tool/spriteSheetPacker/i18n/it.ts +270 -0
  48. package/src/tool/spriteSheetPacker/i18n/ja.ts +270 -0
  49. package/src/tool/spriteSheetPacker/i18n/ko.ts +270 -0
  50. package/src/tool/spriteSheetPacker/i18n/nl.ts +270 -0
  51. package/src/tool/spriteSheetPacker/i18n/pl.ts +270 -0
  52. package/src/tool/spriteSheetPacker/i18n/pt.ts +270 -0
  53. package/src/tool/spriteSheetPacker/i18n/ru.ts +266 -0
  54. package/src/tool/spriteSheetPacker/i18n/sv.ts +270 -0
  55. package/src/tool/spriteSheetPacker/i18n/tr.ts +270 -0
  56. package/src/tool/spriteSheetPacker/i18n/zh.ts +270 -0
  57. package/src/tool/spriteSheetPacker/index.ts +11 -0
  58. package/src/tool/spriteSheetPacker/logic.test.ts +155 -0
  59. package/src/tool/spriteSheetPacker/logic.ts +32 -0
  60. package/src/tool/spriteSheetPacker/packer-core.ts +121 -0
  61. package/src/tool/spriteSheetPacker/packer-ui.ts +86 -0
  62. package/src/tool/spriteSheetPacker/seo.astro +15 -0
  63. package/src/tool/spriteSheetPacker/sprite-sheet-packer.css +542 -0
  64. package/src/tool/spriteSheetPacker/types.ts +89 -0
  65. package/src/tool/spriteSheetPacker/ui.ts +42 -0
  66. package/src/tools.ts +4 -1
@@ -0,0 +1,107 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { ItchioGameTesterUI } from '../ui';
3
+ import { bibliographyEntries } from '../bibliography';
4
+
5
+ export const content: ToolLocaleContent<ItchioGameTesterUI> = {
6
+ slug: 'itchio-spel-testare',
7
+ title: 'Itch.io Webbspelsinspektör och Realtidsupplösningsoptimering',
8
+ description: 'Ladda upp HTML5-exportfiler eller ZIP-arkiv för att testa viewports live, åtgärda rullningslister, inspektera Godot- och Unity WebGL-byggen och generera Itch.io-inbäddningsinställningar.',
9
+ ui: {
10
+ dropzoneTitle: 'Släpp ditt spelbygge eller ZIP-arkiv här',
11
+ dropzoneHint: 'Släpp en .ZIP-fil, exporterad mapp eller HTML5-buildfiler i det här området för omedelbar inspektion.',
12
+ chooseFiles: 'Välj spelfil eller mapp',
13
+ engineDetected: 'Identifierad motor',
14
+ compatibilityScore: 'Itch.io-kompatibilitetspoäng',
15
+ viewportWidth: 'Viewportbredd (px)',
16
+ viewportHeight: 'Viewporthöjd (px)',
17
+ presets: 'Snabba upplösningsförinställningar',
18
+ fitTest: 'Live layout- och rullningsliststest',
19
+ copySettings: 'Kopiera Itch.io-inbäddningsinställningar',
20
+ copied: 'Kopierat till urklipp',
21
+ embedMode: 'Inbäddningsläge',
22
+ scrollbars: 'Aktivera rullningslister',
23
+ noIssuesFound: 'Alla kontroller har passerats. Paketet uppfyller Itch.io-standarderna till 100%.',
24
+ filesInspected: 'Inspekterade filer',
25
+ resetViewport: 'Återställ viewport',
26
+ autoScaleToggle: 'Skala viewport automatiskt till skärmbredd',
27
+ scaledNotice: 'Viewport överstiger skärmbredden. En konstgjord zoom-ut har applicerats för att hela canvasen ska synas. Inaktivera automatisk skalning för att se den verkliga layouten.',
28
+ },
29
+ seo: [
30
+ {
31
+ type: 'title',
32
+ level: 2,
33
+ text: 'Formateringsriktlinjer för Itch.io HTML5-spelexporter'
34
+ },
35
+ {
36
+ type: 'paragraph',
37
+ html: 'Att publicera HTML5- och WebGL-spel på Itch.io kräver exakt konfiguration av viewportdimensioner, arkivfilstrukturer och cross-origin säkerhetshuvuden.'
38
+ },
39
+ {
40
+ type: 'stats',
41
+ columns: 4,
42
+ items: [
43
+ { label: 'Standardwebbbildförhållande', value: '16:9 Liggande' },
44
+ { label: 'Klassisk Itch-upplösning', value: '960 x 540 px' },
45
+ { label: 'Obligatorisk ingångsfil', value: 'index.html i roten' },
46
+ { label: 'Godot 4-krav', value: 'COOP / COEP-huvuden' }
47
+ ]
48
+ },
49
+ {
50
+ type: 'tip',
51
+ html: 'När du bäddar in ett 1280x720 WebGL-spel på Itch.io, ange inbäddningsviewportens dimensioner till exakt 1280x720 med "Embed in page" aktiverat.'
52
+ }
53
+ ],
54
+ faq: [
55
+ {
56
+ question: 'Varför visar mitt Godot 4-spel en svart skärm på Itch.io?',
57
+ answer: 'Godot 4-webbexporter använder WebAssembly-flertrådning som kräver SharedArrayBuffer-stöd. Aktivera "SharedArrayBuffer support" i ramens alternativ för ditt spel på Itch.io.'
58
+ }
59
+ ],
60
+ howTo: [
61
+ { name: 'Ladda upp spelfiler eller ZIP', text: 'Dra och släpp ditt HTML5-export ZIP-arkiv eller välj din byggkatalog med index.html.' },
62
+ { name: 'Granska kompatibilitetsrapport', text: 'Kontrollera den automatiska granskningsrapporten för root-index.html-placering, skiftlägesvarningar och motoridentifiering.' },
63
+ { name: 'Ändra storlek på viewport live', text: 'Använd upplösningskontrollerna och bildförhållandeförinställningarna för att testa iframe-inbäddning live utan rullningslister.' },
64
+ { name: 'Kopiera Itch.io-inställningar', text: 'Klicka på Kopiera inställningar för att hämta exakta bredd- och höjdvärden för din Itch.io-inlämningssida.' }
65
+ ],
66
+ schemas: [
67
+ {
68
+ '@context': 'https://schema.org',
69
+ '@type': 'SoftwareApplication',
70
+ name: 'Itch.io Webbspelsinspektör',
71
+ applicationCategory: 'DeveloperApplication',
72
+ operatingSystem: 'Any'
73
+ },
74
+ {
75
+ '@context': 'https://schema.org',
76
+ '@type': 'FAQPage',
77
+ mainEntity: [
78
+ {
79
+ '@type': 'Question',
80
+ name: 'Varför visar mitt Godot 4-spel en svart skärm på Itch.io?',
81
+ acceptedAnswer: {
82
+ '@type': 'Answer',
83
+ text: 'Godot 4-webbexporter använder WebAssembly-flertrådning som kräver SharedArrayBuffer-stöd. Aktivera "SharedArrayBuffer support" i ramens alternativ för ditt spel på Itch.io.'
84
+ }
85
+ }
86
+ ]
87
+ },
88
+ {
89
+ '@context': 'https://schema.org',
90
+ '@type': 'HowTo',
91
+ name: 'Så granskar och testar du viewporten för ditt Itch.io-spel',
92
+ step: [
93
+ {
94
+ '@type': 'HowToStep',
95
+ name: 'Ladda upp spelfiler eller ZIP',
96
+ text: 'Dra och släpp ditt HTML5-export ZIP-arkiv eller välj din byggkatalog med index.html.'
97
+ },
98
+ {
99
+ '@type': 'HowToStep',
100
+ name: 'Ändra storlek på viewport live',
101
+ text: 'Använd upplösningskontrollerna och bildförhållandeförinställningarna för att testa iframe-inbäddning live utan rullningslister.'
102
+ }
103
+ ]
104
+ }
105
+ ],
106
+ bibliography: bibliographyEntries
107
+ };
@@ -0,0 +1,107 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { ItchioGameTesterUI } from '../ui';
3
+ import { bibliographyEntries } from '../bibliography';
4
+
5
+ export const content: ToolLocaleContent<ItchioGameTesterUI> = {
6
+ slug: 'itchio-oyun-test-araci',
7
+ title: 'Itch.io Web Oyun Denetçisi ve Canlı Çözünürlük Optimize Edici',
8
+ description: 'HTML5 dışa aktarma dosyalarını veya ZIP arşivlerini yükleyerek görünüm alanlarını canlı test edin, kaydırma çubuklarını düzeltin, Godot ve Unity WebGL derlemelerini denetleyin ve Itch.io yerleştirme ayarları oluşturun.',
9
+ ui: {
10
+ dropzoneTitle: 'Oyun Derlemeni veya ZIP Arşivini Buraya Bırak',
11
+ dropzoneHint: 'Herhangi bir .ZIP dosyasını, dışa aktarılmış klasörü veya HTML5 derleme dosyalarını anında incelemek için bu alana bırakın.',
12
+ chooseFiles: 'Oyun Dosyası veya Klasör Seç',
13
+ engineDetected: 'Algılanan Motor',
14
+ compatibilityScore: 'Itch.io Uyumluluk Puanı',
15
+ viewportWidth: 'Görünüm Alanı Genişliği (px)',
16
+ viewportHeight: 'Görünüm Alanı Yüksekliği (px)',
17
+ presets: 'Hızlı Çözünürlük Ön Ayarları',
18
+ fitTest: 'Canlı Düzen ve Kaydırma Çubuğu Testi',
19
+ copySettings: 'Itch.io Yerleştirme Ayarlarını Kopyala',
20
+ copied: 'Panoya Kopyalandı',
21
+ embedMode: 'Yerleştirme Modu',
22
+ scrollbars: 'Kaydırma Çubuklarını Etkinleştir',
23
+ noIssuesFound: 'Tüm kontroller başarıyla geçildi. Paket Itch.io standartlarıyla %100 uyumludur.',
24
+ filesInspected: 'Denetlenen Dosyalar',
25
+ resetViewport: 'Görünüm Alanını Sıfırla',
26
+ autoScaleToggle: 'Görünüm Alanını Ekran Genişliğine Otomatik Ölçekle',
27
+ scaledNotice: 'Görünüm alanı ekran genişliğini aşıyor. Tuvalin tamamı görünür olsun diye yapay zoom-out uygulandı. Gerçek düzeni görmek için otomatik ölçeklemeyi devre dışı bırakın.',
28
+ },
29
+ seo: [
30
+ {
31
+ type: 'title',
32
+ level: 2,
33
+ text: 'Itch.io HTML5 Oyun Dışa Aktarmaları için Biçimlendirme Yönergeleri'
34
+ },
35
+ {
36
+ type: 'paragraph',
37
+ html: 'Itch.io\'da HTML5 ve WebGL oyunları yayınlamak, görünüm alanı boyutlarının, arşiv dosya yapılarının ve çapraz kaynak güvenlik başlıklarının hassas yapılandırmasını gerektirir.'
38
+ },
39
+ {
40
+ type: 'stats',
41
+ columns: 4,
42
+ items: [
43
+ { label: 'Standart Web En-Boy Oranı', value: '16:9 Yatay' },
44
+ { label: 'Klasik Itch Çözünürlüğü', value: '960 x 540 px' },
45
+ { label: 'Gerekli Giriş Dosyası', value: 'Kök dizinde index.html' },
46
+ { label: 'Godot 4 Gereksinimi', value: 'COOP / COEP Başlıkları' }
47
+ ]
48
+ },
49
+ {
50
+ type: 'tip',
51
+ html: 'Itch.io\'ya 1280x720 WebGL oyunu yerleştirirken, "Embed in page" etkin olarak yerleştirme görünüm alanı boyutlarını tam olarak 1280x720 olarak ayarlayın.'
52
+ }
53
+ ],
54
+ faq: [
55
+ {
56
+ question: 'Godot 4 oyunum neden Itch.io\'da siyah ekran gösteriyor?',
57
+ answer: 'Godot 4 web dışa aktarmaları SharedArrayBuffer desteği gerektiren WebAssembly çoklu iş parçacığını kullanır. Itch.io oyun düzenleme sayfanızda çerçeve seçeneklerinde "SharedArrayBuffer support" özelliğini etkinleştirin.'
58
+ }
59
+ ],
60
+ howTo: [
61
+ { name: 'Oyun Dosyalarını veya ZIP\'i Yükle', text: 'HTML5 dışa aktarma ZIP arşivini sürükle ve bırak ya da index.html içeren derleme klasörünü seç.' },
62
+ { name: 'Uyumluluk Raporunu İncele', text: 'Kök index.html yerleşimi, büyük/küçük harf uyarıları ve motor algılama için otomatik denetim raporunu kontrol et.' },
63
+ { name: 'Görünüm Alanını Canlı Yeniden Boyutlandır', text: 'Kaydırma çubukları olmadan iframe yerleştirmeyi canlı test etmek için çözünürlük kontrollerini ve en-boy oranı ön ayarlarını kullan.' },
64
+ { name: 'Itch.io Ayarlarını Kopyala', text: 'Itch.io oyun gönderme sayfan için tam genişlik ve yükseklik değerlerini almak üzere Ayarları Kopyala\'ya tıkla.' }
65
+ ],
66
+ schemas: [
67
+ {
68
+ '@context': 'https://schema.org',
69
+ '@type': 'SoftwareApplication',
70
+ name: 'Itch.io Web Oyun Denetçisi',
71
+ applicationCategory: 'DeveloperApplication',
72
+ operatingSystem: 'Any'
73
+ },
74
+ {
75
+ '@context': 'https://schema.org',
76
+ '@type': 'FAQPage',
77
+ mainEntity: [
78
+ {
79
+ '@type': 'Question',
80
+ name: 'Godot 4 oyunum neden Itch.io\'da siyah ekran gösteriyor?',
81
+ acceptedAnswer: {
82
+ '@type': 'Answer',
83
+ text: 'Godot 4 web dışa aktarmaları SharedArrayBuffer desteği gerektiren WebAssembly çoklu iş parçacığını kullanır. Itch.io oyun düzenleme sayfanızda çerçeve seçeneklerinde "SharedArrayBuffer support" özelliğini etkinleştirin.'
84
+ }
85
+ }
86
+ ]
87
+ },
88
+ {
89
+ '@context': 'https://schema.org',
90
+ '@type': 'HowTo',
91
+ name: 'Itch.io oyununuzun görünüm alanını denetleme ve test etme',
92
+ step: [
93
+ {
94
+ '@type': 'HowToStep',
95
+ name: 'Oyun Dosyalarını veya ZIP\'i Yükle',
96
+ text: 'HTML5 dışa aktarma ZIP arşivini sürükle ve bırak ya da index.html içeren derleme klasörünü seç.'
97
+ },
98
+ {
99
+ '@type': 'HowToStep',
100
+ name: 'Görünüm Alanını Canlı Yeniden Boyutlandır',
101
+ text: 'Kaydırma çubukları olmadan iframe yerleştirmeyi canlı test etmek için çözünürlük kontrollerini ve en-boy oranı ön ayarlarını kullan.'
102
+ }
103
+ ]
104
+ }
105
+ ],
106
+ bibliography: bibliographyEntries
107
+ };
@@ -0,0 +1,107 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { ItchioGameTesterUI } from '../ui';
3
+ import { bibliographyEntries } from '../bibliography';
4
+
5
+ export const content: ToolLocaleContent<ItchioGameTesterUI> = {
6
+ slug: 'itchio-game-tester',
7
+ title: 'Itch.io 网页游戏检查器与实时分辨率优化工具',
8
+ description: '上传HTML5导出文件或ZIP压缩包,实时测试视口、修复滚动条、检查Godot和Unity WebGL构建,并生成Itch.io嵌入设置。',
9
+ ui: {
10
+ dropzoneTitle: '将游戏构建或ZIP文件拖放至此处',
11
+ dropzoneHint: '将任何.ZIP文件、导出文件夹或HTML5构建文件拖放到此区域即可立即检查。',
12
+ chooseFiles: '选择游戏文件或文件夹',
13
+ engineDetected: '检测到的引擎',
14
+ compatibilityScore: 'Itch.io兼容性评分',
15
+ viewportWidth: '视口宽度 (px)',
16
+ viewportHeight: '视口高度 (px)',
17
+ presets: '快速分辨率预设',
18
+ fitTest: '实时布局与滚动条测试',
19
+ copySettings: '复制Itch.io嵌入设置',
20
+ copied: '已复制到剪贴板',
21
+ embedMode: '嵌入模式',
22
+ scrollbars: '启用滚动条',
23
+ noIssuesFound: '所有检查均已通过。该包100%符合Itch.io标准。',
24
+ filesInspected: '已检查文件',
25
+ resetViewport: '重置视口',
26
+ autoScaleToggle: '自动将视口缩放到屏幕宽度',
27
+ scaledNotice: '视口超出屏幕宽度。已应用人工缩小以使整个画布可见。禁用自动缩放可查看真实的布局效果。',
28
+ },
29
+ seo: [
30
+ {
31
+ type: 'title',
32
+ level: 2,
33
+ text: 'Itch.io HTML5游戏导出格式指南'
34
+ },
35
+ {
36
+ type: 'paragraph',
37
+ html: '在Itch.io上发布HTML5和WebGL游戏需要精确配置视口尺寸、归档文件结构和跨源安全标头。'
38
+ },
39
+ {
40
+ type: 'stats',
41
+ columns: 4,
42
+ items: [
43
+ { label: '标准网页宽高比', value: '16:9 横向' },
44
+ { label: '经典Itch分辨率', value: '960 x 540 px' },
45
+ { label: '必需入口文件', value: '根目录的index.html' },
46
+ { label: 'Godot 4要求', value: 'COOP / COEP标头' }
47
+ ]
48
+ },
49
+ {
50
+ type: 'tip',
51
+ html: '在Itch.io上嵌入1280x720的WebGL游戏时,将嵌入视口尺寸精确设置为1280x720,并启用"Embed in page"。'
52
+ }
53
+ ],
54
+ faq: [
55
+ {
56
+ question: '为什么我的Godot 4游戏在Itch.io上显示黑屏?',
57
+ answer: 'Godot 4网页导出使用需要SharedArrayBuffer支持的WebAssembly多线程。在Itch.io游戏编辑页面的帧选项中启用"SharedArrayBuffer support"。'
58
+ }
59
+ ],
60
+ howTo: [
61
+ { name: '上传游戏文件或ZIP', text: '拖放HTML5导出ZIP压缩包,或选择包含index.html的构建目录。' },
62
+ { name: '查看兼容性报告', text: '检查自动审核报告,了解根目录index.html放置、大小写警告和引擎检测情况。' },
63
+ { name: '实时调整视口大小', text: '使用分辨率滑块和宽高比预设,实时测试无滚动条的iframe嵌入效果。' },
64
+ { name: '复制Itch.io设置', text: '点击复制设置,获取用于Itch.io游戏提交页面的精确宽度和高度值。' }
65
+ ],
66
+ schemas: [
67
+ {
68
+ '@context': 'https://schema.org',
69
+ '@type': 'SoftwareApplication',
70
+ name: 'Itch.io 网页游戏检查器',
71
+ applicationCategory: 'DeveloperApplication',
72
+ operatingSystem: 'Any'
73
+ },
74
+ {
75
+ '@context': 'https://schema.org',
76
+ '@type': 'FAQPage',
77
+ mainEntity: [
78
+ {
79
+ '@type': 'Question',
80
+ name: '为什么我的Godot 4游戏在Itch.io上显示黑屏?',
81
+ acceptedAnswer: {
82
+ '@type': 'Answer',
83
+ text: 'Godot 4网页导出使用需要SharedArrayBuffer支持的WebAssembly多线程。在Itch.io游戏编辑页面的帧选项中启用"SharedArrayBuffer support"。'
84
+ }
85
+ }
86
+ ]
87
+ },
88
+ {
89
+ '@context': 'https://schema.org',
90
+ '@type': 'HowTo',
91
+ name: '如何审核并测试您的Itch.io游戏视口',
92
+ step: [
93
+ {
94
+ '@type': 'HowToStep',
95
+ name: '上传游戏文件或ZIP',
96
+ text: '拖放HTML5导出ZIP压缩包,或选择包含index.html的构建目录。'
97
+ },
98
+ {
99
+ '@type': 'HowToStep',
100
+ name: '实时调整视口大小',
101
+ text: '使用分辨率滑块和宽高比预设,实时测试无滚动条的iframe嵌入效果。'
102
+ }
103
+ ]
104
+ }
105
+ ],
106
+ bibliography: bibliographyEntries
107
+ };
@@ -0,0 +1,11 @@
1
+ import type { ToolDefinition } from '../../types';
2
+ import { itchioGameTester } from './entry';
3
+
4
+ export * from './entry';
5
+
6
+ export const ITCHIO_GAME_TESTER_TOOL: ToolDefinition = {
7
+ entry: itchioGameTester,
8
+ Component: () => import('./component.astro'),
9
+ SEOComponent: () => import('./seo.astro'),
10
+ BibliographyComponent: () => import('./bibliography.astro'),
11
+ };
@@ -0,0 +1,273 @@
1
+ .igt-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 1.5rem;
5
+ width: 100%;
6
+ max-width: 1200px;
7
+ margin: 0 auto;
8
+ }
9
+
10
+ .igt-card {
11
+ background: var(--bg-surface, #fff);
12
+ border: 1px solid var(--border-base, #e2e8f0);
13
+ border-radius: 12px;
14
+ padding: 1.5rem;
15
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
16
+ transition: background-color 0.2s, border-color 0.2s;
17
+ }
18
+
19
+ .igt-card-compact {
20
+ padding: 1rem 1.25rem;
21
+ }
22
+
23
+ .theme-dark .igt-card {
24
+ background: var(--bg-surface, #1e293b);
25
+ border-color: var(--border-base, #334155);
26
+ }
27
+
28
+ .igt-dropzone {
29
+ border: 2px dashed var(--border-base, #cbd5e1);
30
+ border-radius: 12px;
31
+ padding: 2.5rem 1.5rem;
32
+ text-align: center;
33
+ background: var(--bg-hover, #f8fafc);
34
+ cursor: pointer;
35
+ transition: all 0.2s ease-in-out;
36
+ }
37
+
38
+ .igt-dropzone-compact {
39
+ padding: 1.25rem 1rem;
40
+ }
41
+
42
+ .theme-dark .igt-dropzone {
43
+ background: var(--bg-hover, #0f172a);
44
+ border-color: var(--border-base, #475569);
45
+ }
46
+
47
+ .igt-dropzone:hover, .igt-dropzone.igt-dragover {
48
+ border-color: var(--color-primary, #6366f1);
49
+ background: rgba(99, 102, 241, 0.05);
50
+ }
51
+
52
+ .igt-controls-grid {
53
+ display: grid;
54
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
55
+ gap: 1.25rem;
56
+ margin-top: 1rem;
57
+ }
58
+
59
+ .igt-input-group {
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: 0.5rem;
63
+ }
64
+
65
+ .igt-label {
66
+ font-size: 0.875rem;
67
+ font-weight: 600;
68
+ color: var(--text-base, #1e293b);
69
+ }
70
+
71
+ .theme-dark .igt-label {
72
+ color: var(--text-base, #f8fafc);
73
+ }
74
+
75
+ .igt-input, .igt-select {
76
+ padding: 0.625rem 0.875rem;
77
+ border-radius: 8px;
78
+ border: 1px solid var(--border-base, #cbd5e1);
79
+ background: var(--bg-surface, #fff);
80
+ color: var(--text-base, #0f172a);
81
+ font-size: 0.95rem;
82
+ }
83
+
84
+ .theme-dark .igt-input, .theme-dark .igt-select {
85
+ background: var(--bg-surface, #0f172a);
86
+ border-color: var(--border-base, #334155);
87
+ color: var(--text-base, #f8fafc);
88
+ }
89
+
90
+ .igt-preset-chips {
91
+ display: flex;
92
+ flex-wrap: wrap;
93
+ gap: 0.5rem;
94
+ margin-top: 0.75rem;
95
+ }
96
+
97
+ .igt-chip {
98
+ padding: 0.4rem 0.75rem;
99
+ border-radius: 20px;
100
+ border: 1px solid var(--border-base, #cbd5e1);
101
+ background: var(--bg-surface, #f1f5f9);
102
+ color: var(--text-base, #334155);
103
+ font-size: 0.825rem;
104
+ font-weight: 500;
105
+ cursor: pointer;
106
+ transition: all 0.15s ease;
107
+ }
108
+
109
+ .theme-dark .igt-chip {
110
+ background: var(--bg-surface, #334155);
111
+ color: var(--text-base, #e2e8f0);
112
+ border-color: var(--border-base, #475569);
113
+ }
114
+
115
+ .igt-chip:hover {
116
+ background: var(--color-primary, #6366f1);
117
+ color: var(--text-inverse, #fff);
118
+ border-color: var(--color-primary, #6366f1);
119
+ }
120
+
121
+ .igt-chip.active {
122
+ background: var(--color-primary, #4f46e5);
123
+ color: var(--text-inverse, #fff);
124
+ border-color: var(--color-primary, #4f46e5);
125
+ }
126
+
127
+ .igt-emulator-wrapper {
128
+ position: relative;
129
+ display: inline-block;
130
+ max-width: 100%;
131
+ }
132
+
133
+ .igt-emulator-frame {
134
+ position: relative;
135
+ margin: 1.5rem auto;
136
+ border: 4px solid var(--border-base, #0f172a);
137
+ border-radius: 8px;
138
+ overflow: hidden;
139
+ background: #000;
140
+ box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
141
+ transition: width 0.1s ease, height 0.1s ease;
142
+ resize: both;
143
+ }
144
+
145
+ .igt-resize-handle {
146
+ position: absolute;
147
+ right: 0;
148
+ bottom: 0;
149
+ width: 16px;
150
+ height: 16px;
151
+ background: var(--color-primary, #6366f1);
152
+ cursor: se-resize;
153
+ border-top-left-radius: 4px;
154
+ z-index: 10;
155
+ }
156
+
157
+ .igt-iframe {
158
+ width: 100%;
159
+ height: 100%;
160
+ border: none;
161
+ background: #000;
162
+ }
163
+
164
+ .igt-iframe-resizing {
165
+ pointer-events: none;
166
+ }
167
+
168
+
169
+ .igt-audit-badge {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ gap: 0.5rem;
173
+ padding: 0.5rem 1rem;
174
+ border-radius: 20px;
175
+ font-weight: 700;
176
+ font-size: 0.9rem;
177
+ }
178
+
179
+ .igt-badge-pass {
180
+ background: #dcfce7;
181
+ color: var(--text-success, #166534);
182
+ }
183
+
184
+ .igt-badge-warn {
185
+ background: #fef9c3;
186
+ color: var(--text-warning, #854d0e);
187
+ }
188
+
189
+ .igt-badge-error {
190
+ background: #fee2e2;
191
+ color: var(--text-danger, #991b1b);
192
+ }
193
+
194
+ .igt-btn-primary {
195
+ padding: 0.75rem 1.25rem;
196
+ border-radius: 8px;
197
+ border: none;
198
+ background: var(--color-primary, #6366f1);
199
+ color: var(--text-inverse, #fff);
200
+ font-weight: 600;
201
+ cursor: pointer;
202
+ transition: transform 0.1s, background-color 0.15s;
203
+ }
204
+
205
+ .igt-btn-sm {
206
+ padding: 0.45rem 0.85rem;
207
+ font-size: 0.85rem;
208
+ }
209
+
210
+ .igt-btn-primary:hover {
211
+ background: var(--color-primary-hover, #4f46e5);
212
+ transform: translateY(-1px);
213
+ }
214
+
215
+ .igt-btn-primary:active {
216
+ transform: translateY(0);
217
+ }
218
+
219
+ .igt-scale-notice {
220
+ display: none;
221
+ margin-top: 1rem;
222
+ padding: 0.625rem 0.875rem;
223
+ border-radius: 6px;
224
+ background: var(--color-warn-bg, #fef9c3);
225
+ color: var(--color-warn-text, #854d0e);
226
+ font-size: 0.85rem;
227
+ border: 1px solid var(--color-warn-border, #fef08a);
228
+ }
229
+
230
+ .igt-all-clear {
231
+ display: flex;
232
+ align-items: flex-start;
233
+ gap: 0.875rem;
234
+ padding: 1rem 1.25rem;
235
+ border-radius: 10px;
236
+ background: var(--color-success-bg, #dcfce7);
237
+ border: 1px solid var(--color-success-border, #86efac);
238
+ color: var(--color-success-text, #166534);
239
+ }
240
+
241
+ .theme-dark .igt-all-clear {
242
+ background: var(--color-success-bg, #052e16);
243
+ border-color: var(--color-success-border, #166534);
244
+ color: var(--color-success-text, #4ade80);
245
+ }
246
+
247
+ .igt-all-clear-icon {
248
+ flex-shrink: 0;
249
+ width: 22px;
250
+ height: 22px;
251
+ border-radius: 50%;
252
+ background: var(--color-success-text, #166534);
253
+ display: flex;
254
+ align-items: center;
255
+ justify-content: center;
256
+ margin-top: 1px;
257
+ }
258
+
259
+ .theme-dark .igt-all-clear-icon {
260
+ background: var(--color-success-text, #4ade80);
261
+ }
262
+
263
+ .igt-all-clear-body strong {
264
+ display: block;
265
+ font-size: 0.95rem;
266
+ font-weight: 700;
267
+ margin-bottom: 0.25rem;
268
+ }
269
+
270
+ .igt-all-clear-body span {
271
+ font-size: 0.825rem;
272
+ opacity: 0.85;
273
+ }
@@ -0,0 +1,56 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { validateGameFiles, detectGameEngine, calculateAspectRatio, generateItchioEmbedConfig, type WebGameFileInfo } from './logic';
3
+
4
+ describe('Itch.io Game Tester Logic Unit Tests', () => {
5
+ it('should detect Godot 4 Web export files', () => {
6
+ const mockFiles: WebGameFileInfo[] = [
7
+ { name: 'index.html', size: 1024, isDirectory: false },
8
+ { name: 'mygame.wasm', size: 500000, isDirectory: false },
9
+ { name: 'mygame.pck', size: 1200000, isDirectory: false },
10
+ { name: 'godot.side.wasm', size: 10000, isDirectory: false }
11
+ ];
12
+
13
+ const engine = detectGameEngine(mockFiles);
14
+ expect(engine).toBe('Godot 4');
15
+
16
+ const result = validateGameFiles(mockFiles);
17
+ expect(result.hasIndexHtml).toBe(true);
18
+ expect(result.issues.some((i) => i.code === 'GODOT4_HEADERS')).toBe(true);
19
+ });
20
+
21
+ it('should detect Unity WebGL export files', () => {
22
+ const mockFiles: WebGameFileInfo[] = [
23
+ { name: 'index.html', size: 1024, isDirectory: false },
24
+ { name: 'Build/game.framework.js', size: 50000, isDirectory: false },
25
+ { name: 'Build/game.data', size: 500000, isDirectory: false }
26
+ ];
27
+
28
+ const engine = detectGameEngine(mockFiles);
29
+ expect(engine).toBe('Unity WebGL');
30
+ });
31
+
32
+ it('should flag nested index.html error', () => {
33
+ const mockFiles: WebGameFileInfo[] = [
34
+ { name: 'export-folder/index.html', size: 1024, isDirectory: false }
35
+ ];
36
+
37
+ const result = validateGameFiles(mockFiles);
38
+ expect(result.hasIndexHtml).toBe(false);
39
+ expect(result.indexHtmlPath).toBe('export-folder/index.html');
40
+ expect(result.issues.some((i) => i.code === 'NESTED_INDEX')).toBe(true);
41
+ });
42
+
43
+ it('should calculate aspect ratios accurately', () => {
44
+ expect(calculateAspectRatio(1280, 720)).toBe('16:9');
45
+ expect(calculateAspectRatio(800, 600)).toBe('4:3');
46
+ expect(calculateAspectRatio(960, 640)).toBe('3:2');
47
+ expect(calculateAspectRatio(800, 800)).toBe('1:1');
48
+ });
49
+
50
+ it('should generate embed config text correctly', () => {
51
+ const config = generateItchioEmbedConfig(960, 600, 'landscape');
52
+ expect(config.viewportWidth).toBe(960);
53
+ expect(config.viewportHeight).toBe(600);
54
+ expect(config.codeSnippet).toContain('960px x 600px');
55
+ });
56
+ });