diff --git a/.gitignore b/.gitignore
index dab8e44..d14f1d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@ node_modules/
webwords/
book/
+*.log
+
# Generated audio files in language examples
public/languages/**/*.mp3
*.mp3
diff --git a/add_remote_url_keys.js b/add_remote_url_keys.js
deleted file mode 100644
index 211e1da..0000000
--- a/add_remote_url_keys.js
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env node
-
-// Script to add missing remote URL translation keys to all language files
-
-import fs from 'fs';
-import path from 'path';
-
-const languagesDir = './src/languages';
-
-// The new keys to add in English
-const newKeys = {
- remoteUrlTab: "🌐 Remote URL",
- remoteUrlInfo: "Enter a URL to fetch and translate:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 Fetch & Translate"
-};
-
-// Translations for each language
-const translations = {
- ar: {
- remoteUrlTab: "🌐 رابط بعيد",
- remoteUrlInfo: "أدخل رابط لجلبه وترجمته:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 جلب وترجمة"
- },
- bn: {
- remoteUrlTab: "🌐 দূরবর্তী URL",
- remoteUrlInfo: "একটি URL প্রবেশ করান যা আনতে এবং অনুবাদ করতে:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 আনুন এবং অনুবাদ করুন"
- },
- de: {
- remoteUrlTab: "🌐 Externe URL",
- remoteUrlInfo: "Geben Sie eine URL ein, um sie abzurufen und zu übersetzen:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 Abrufen & Übersetzen"
- },
- es: {
- remoteUrlTab: "🌐 URL Remota",
- remoteUrlInfo: "Ingresa una URL para obtener y traducir:",
- remoteUrlPlaceholder: "https://ejemplo.com",
- fetchAndTranslate: "🌐 Obtener y Traducir"
- },
- fr: {
- remoteUrlTab: "🌐 URL Distante",
- remoteUrlInfo: "Entrez une URL à récupérer et traduire:",
- remoteUrlPlaceholder: "https://exemple.com",
- fetchAndTranslate: "🌐 Récupérer et Traduire"
- },
- hi: {
- remoteUrlTab: "🌐 दूरस्थ URL",
- remoteUrlInfo: "लाने और अनुवाद करने के लिए एक URL दर्ज करें:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 लाएं और अनुवाद करें"
- },
- id: {
- remoteUrlTab: "🌐 URL Jarak Jauh",
- remoteUrlInfo: "Masukkan URL untuk diambil dan diterjemahkan:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 Ambil & Terjemahkan"
- },
- ja: {
- remoteUrlTab: "🌐 リモートURL",
- remoteUrlInfo: "取得して翻訳するURLを入力してください:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 取得して翻訳"
- },
- ko: {
- remoteUrlTab: "🌐 원격 URL",
- remoteUrlInfo: "가져와서 번역할 URL을 입력하세요:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 가져와서 번역"
- },
- mr: {
- remoteUrlTab: "🌐 दूरस्थ URL",
- remoteUrlInfo: "आणण्यासाठी आणि भाषांतर करण्यासाठी URL प्रविष्ट करा:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 आणा आणि भाषांतर करा"
- },
- pt: {
- remoteUrlTab: "🌐 URL Remota",
- remoteUrlInfo: "Digite uma URL para buscar e traduzir:",
- remoteUrlPlaceholder: "https://exemplo.com",
- fetchAndTranslate: "🌐 Buscar e Traduzir"
- },
- ru: {
- remoteUrlTab: "🌐 Удаленный URL",
- remoteUrlInfo: "Введите URL для загрузки и перевода:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 Загрузить и Перевести"
- },
- sw: {
- remoteUrlTab: "🌐 URL ya Mbali",
- remoteUrlInfo: "Ingiza URL ya kuleta na kutafsiri:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 Leta na Tafsiri"
- },
- te: {
- remoteUrlTab: "🌐 రిమోట్ URL",
- remoteUrlInfo: "తీసుకురావడానికి మరియు అనువదించడానికి URL ని నమోదు చేయండి:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 తీసుకురండి & అనువదించండి"
- },
- tr: {
- remoteUrlTab: "🌐 Uzak URL",
- remoteUrlInfo: "Getirmek ve çevirmek için bir URL girin:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 Getir ve Çevir"
- },
- ur: {
- remoteUrlTab: "🌐 ریموٹ URL",
- remoteUrlInfo: "لانے اور ترجمہ کرنے کے لیے URL داخل کریں:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 لائیں اور ترجمہ کریں"
- },
- "zh-tw": {
- remoteUrlTab: "🌐 遠端網址",
- remoteUrlInfo: "輸入要擷取和翻譯的網址:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 擷取並翻譯"
- },
- zh: {
- remoteUrlTab: "🌐 远程网址",
- remoteUrlInfo: "输入要获取和翻译的网址:",
- remoteUrlPlaceholder: "https://example.com",
- fetchAndTranslate: "🌐 获取并翻译"
- }
-};
-
-// Process each language file
-for (const [langCode, langTranslations] of Object.entries(translations)) {
- const filePath = path.join(languagesDir, `${langCode}.js`);
-
- if (fs.existsSync(filePath)) {
- let content = fs.readFileSync(filePath, 'utf8');
-
- // Find the position to insert new keys (before the closing })
- const insertPosition = content.lastIndexOf('};');
-
- if (insertPosition === -1) {
- console.error(`Could not find export structure in ${filePath}`);
- continue;
- }
-
- // Find the last non-empty line before the closing }
- const beforeClosing = content.substring(0, insertPosition).trimEnd();
-
- // Check if any of the new keys already exist
- const hasNewKeys = Object.keys(langTranslations).some(key =>
- content.includes(`${key}:`));
-
- if (hasNewKeys) {
- console.log(`✅ ${langCode}: Keys already present, skipping`);
- continue;
- }
-
- // Build the new keys string
- const newKeysString = Object.entries(langTranslations)
- .map(([key, value]) => `\t${key}: "${value}",`)
- .join('\n');
-
- // Insert the new keys
- const newContent = beforeClosing + ',\n' + newKeysString + '\n};';
-
- fs.writeFileSync(filePath, newContent, 'utf8');
- console.log(`✅ ${langCode}: Added remote URL translation keys`);
- } else {
- console.error(`File not found: ${filePath}`);
- }
-}
-
-console.log('\n🎉 Finished adding remote URL translation keys to all language files!');
\ No newline at end of file
diff --git a/build-all.log b/build-all.log
deleted file mode 100644
index d2c5c45..0000000
--- a/build-all.log
+++ /dev/null
@@ -1,1455 +0,0 @@
-Building all language implementations...
-
-========================================
-[1] Building awk (languages/awk)
-========================================
-#5 transferring context: 9.60kB done
-#5 DONE 0.0s
-
-#6 [2/5] RUN apk add --no-cache gawk curl ca-certificates
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.awk .
-#8 DONE 0.1s
-
-#9 [5/5] RUN chmod +x uncloseai.awk
-#9 DONE 0.3s
-
-#10 exporting to image
-#10 exporting layers 0.1s done
-#10 writing image sha256:01d5c197f31cea2db8e850a3e9ebfc30e4a6bd75c003f847782e820d55f4fda6 done
-#10 naming to docker.io/library/ai-unturf-awk done
-#10 DONE 0.1s
-✅ awk built successfully
-
-========================================
-[2] Building bash (languages/bash)
-========================================
-#5 transferring context: 9.05kB done
-#5 DONE 0.0s
-
-#6 [2/5] RUN apk add --no-cache bash curl jq ca-certificates
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.sh .
-#8 DONE 0.1s
-
-#9 [5/5] RUN chmod +x uncloseai.sh
-#9 DONE 0.4s
-
-#10 exporting to image
-#10 exporting layers 0.1s done
-#10 writing image sha256:bc4ced4134e29317557f58e9b0df11cfe45bd888aaec76a1faeafe6a8104b3a5 done
-#10 naming to docker.io/library/ai-unturf-bash done
-#10 DONE 0.1s
-✅ bash built successfully
-
-========================================
-[3] Building c-curl (languages/c/curl)
-========================================
-#10 0.549 uncloseai.c:297:5: note: 'snprintf' output between 18 and 529 bytes into a destination of size 512
-#10 0.549 297 | snprintf(url, sizeof(url), "%s/chat/completions",
-#10 0.549 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#10 0.549 298 | client->models[model_idx].endpoint);
-#10 0.549 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#10 0.565 uncloseai.c: In function 'uncloseai_tts':
-#10 0.566 uncloseai.c:343:35: warning: '/audio/speech' directive output may be truncated writing 13 bytes into a region of size between 1 and 512 [-Wformat-truncation=]
-#10 0.566 343 | snprintf(url, sizeof(url), "%s/audio/speech", client->tts_endpoints[0]);
-#10 0.566 | ^~~~~~~~~~~~~
-#10 0.566 uncloseai.c:343:5: note: 'snprintf' output between 14 and 525 bytes into a destination of size 512
-#10 0.566 343 | snprintf(url, sizeof(url), "%s/audio/speech", client->tts_endpoints[0]);
-#10 0.566 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#10 DONE 0.8s
-
-#11 exporting to image
-#11 exporting layers
-#11 exporting layers 1.7s done
-#11 writing image sha256:c937df2cc6c3f04e0b7dc73638467b8b38707272bb2f6c0f51c2dada81b2e19a done
-#11 naming to docker.io/library/ai-unturf-c-curl done
-#11 DONE 1.7s
-✅ c-curl built successfully
-
-========================================
-[4] Building c-libsoup (languages/c/libsoup)
-========================================
-#6 [4/6] COPY uncloseai.c .
-#6 CACHED
-
-#7 [5/6] COPY Makefile .
-#7 CACHED
-
-#8 [2/6] RUN apk --no-cache add gcc musl-dev libsoup-dev glib-dev make ca-certificates
-#8 CACHED
-
-#9 [3/6] WORKDIR /app
-#9 CACHED
-
-#10 [6/6] RUN make
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:f1d0804717b35866d852c1e56fa29726ea11072e54bb97ec53b242f635fff10f done
-#11 naming to docker.io/library/ai-unturf-c-libsoup done
-#11 DONE 0.0s
-✅ c-libsoup built successfully
-
-========================================
-[5] Building clojure (languages/clojure)
-========================================
-#10 5.443 Downloading: commons-io/commons-io/2.16.1/commons-io-2.16.1.jar from central
-#10 5.582 Downloading: org/apache/httpcomponents/httpclient-cache/4.5.14/httpclient-cache-4.5.14.jar from central
-#10 5.586 Downloading: org/apache/httpcomponents/httpcore/4.4.16/httpcore-4.4.16.jar from central
-#10 5.616 Downloading: com/fasterxml/jackson/core/jackson-core/2.17.0/jackson-core-2.17.0.jar from central
-#10 5.656 Downloading: riddley/riddley/0.1.12/riddley-0.1.12.jar from clojars
-#10 5.717 Downloading: clj-http/clj-http/3.13.0/clj-http-3.13.0.jar from clojars
-#10 5.732 Downloading: org/apache/httpcomponents/httpclient/4.5.14/httpclient-4.5.14.jar from central
-#10 5.769 Downloading: commons-logging/commons-logging/1.2/commons-logging-1.2.jar from central
-#10 5.900 Downloading: tigris/tigris/0.1.2/tigris-0.1.2.jar from clojars
-#10 5.975 Downloading: potemkin/potemkin/0.4.7/potemkin-0.4.7.jar from clojars
-#10 5.997 Downloading: com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.17.0/jackson-dataformat-smile-2.17.0.jar from central
-#10 6.017 Downloading: org/apache/httpcomponents/httpmime/4.5.14/httpmime-4.5.14.jar from central
-#10 6.149 Downloading: cheshire/cheshire/5.13.0/cheshire-5.13.0.jar from clojars
-#10 DONE 6.5s
-
-#11 exporting to image
-#11 exporting layers 0.1s done
-#11 writing image sha256:a8d77e7401df76f22fc61ce68546d6f249c75c4d4b416cce9e6599576bf04d1c done
-#11 naming to docker.io/library/ai-unturf-clojure done
-#11 DONE 0.1s
-✅ clojure built successfully
-
-========================================
-[6] Building c-nghttp2 (languages/c/nghttp2)
-========================================
-#6 [5/6] COPY Makefile .
-#6 CACHED
-
-#7 [2/6] RUN apk --no-cache add gcc musl-dev nghttp2-dev make ca-certificates
-#7 CACHED
-
-#8 [4/6] COPY uncloseai.c .
-#8 CACHED
-
-#9 [3/6] WORKDIR /app
-#9 CACHED
-
-#10 [6/6] RUN make
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:ce696ab6210ed584a1fb1365f1549f74c7a08069c3fdea1d4e352fd3e03d10e2 done
-#11 naming to docker.io/library/ai-unturf-c-nghttp2 done
-#11 DONE 0.0s
-✅ c-nghttp2 built successfully
-
-========================================
-[7] Building cobol (languages/cobol)
-========================================
-#8 [stage-1 2/4] RUN apt-get update && apt-get install -y gnucobol4 libcob4 ca-certificates curl jq bash && rm -rf /var/lib/apt/lists/*
-#8 CACHED
-
-#9 [stage-1 3/4] WORKDIR /app
-#9 CACHED
-
-#10 [builder 2/5] RUN apt-get update && apt-get install -y gnucobol4 && rm -rf /var/lib/apt/lists/*
-#10 CACHED
-
-#11 [builder 5/5] RUN cobc -x -free uncloseai.cob -o uncloseai
-#11 CACHED
-
-#12 [stage-1 4/4] COPY --from=builder /app/uncloseai .
-#12 CACHED
-
-#13 exporting to image
-#13 exporting layers done
-#13 writing image sha256:d17be52115e1fb61eef5fbc310e9eb2759221317ea08aed0e85dd40608f9ca60 done
-#13 naming to docker.io/library/ai-unturf-cobol done
-#13 DONE 0.0s
-✅ cobol built successfully
-
-========================================
-[8] Building commonlisp (languages/commonlisp)
-========================================
-#9 [4/9] WORKDIR /app
-#9 CACHED
-
-#10 [5/9] COPY hermes-nonstreaming.lisp .
-#10 CACHED
-
-#11 [3/9] RUN sbcl --eval '(ql:quickload :dexador)' --eval '(ql:quickload :jonathan)' --quit
-#11 CACHED
-
-#12 [8/9] COPY qwen-streaming.lisp .
-#12 CACHED
-
-#13 [9/9] COPY tts.lisp .
-#13 DONE 0.1s
-
-#14 exporting to image
-#14 exporting layers 0.0s done
-#14 writing image sha256:fe2f726936e2d69c4ab0dfb75e4d446a944cd4b21af7aecc108649f9ccf5b7b8 done
-#14 naming to docker.io/library/ai-unturf-commonlisp done
-#14 DONE 0.1s
-✅ commonlisp built successfully
-
-========================================
-[9] Building cpp-boost-beast (languages/cpp/boost-beast)
-========================================
-#6 [2/6] RUN apk --no-cache add g++ make boost1.84-dev openssl-dev ca-certificates
-#6 CACHED
-
-#7 [4/6] COPY uncloseai.cpp .
-#7 CACHED
-
-#8 [5/6] COPY Makefile .
-#8 CACHED
-
-#9 [3/6] WORKDIR /app
-#9 CACHED
-
-#10 [6/6] RUN make
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:67c12d024da4d904c2976aa474879c1373180420f4503d023615a945a5b9b5f3 done
-#11 naming to docker.io/library/ai-unturf-cpp-boost-beast done
-#11 DONE 0.0s
-✅ cpp-boost-beast built successfully
-
-========================================
-[10] Building cpp-cpp-httplib (languages/cpp/cpp-httplib)
-========================================
-#7 CACHED
-
-#8 [3/7] WORKDIR /app
-#8 CACHED
-
-#9 [5/7] COPY uncloseai.cpp .
-#9 CACHED
-
-#10 [6/7] COPY Makefile .
-#10 CACHED
-
-#11 [7/7] RUN make
-#11 CACHED
-
-#12 exporting to image
-#12 exporting layers done
-#12 writing image sha256:585fbd6a4b5d8fabfbc1c6a1275519de80d253dfdaf057aaae8bec47ae81461f done
-#12 naming to docker.io/library/ai-unturf-cpp-cpp-httplib
-#12 naming to docker.io/library/ai-unturf-cpp-cpp-httplib done
-#12 DONE 0.0s
-✅ cpp-cpp-httplib built successfully
-
-========================================
-[11] Building cpp-libcurl (languages/cpp/libcurl)
-========================================
-
-#7 [3/6] WORKDIR /app
-#7 DONE 0.1s
-
-#8 [4/6] COPY uncloseai.cpp .
-#8 DONE 0.1s
-
-#9 [5/6] COPY Makefile .
-#9 DONE 0.1s
-
-#10 [6/6] RUN make
-#10 0.226 g++ -std=c++11 -Wall -Wextra -O2 -o uncloseai uncloseai.cpp -lcurl
-#10 DONE 2.7s
-
-#11 exporting to image
-#11 exporting layers
-#11 exporting layers 2.5s done
-#11 writing image sha256:31853963c4074a3bcf3af5175ea8a4350a4da280f251e1d730173c3c9be047b0 done
-#11 naming to docker.io/library/ai-unturf-cpp-libcurl done
-#11 DONE 2.5s
-✅ cpp-libcurl built successfully
-
-========================================
-[12] Building crystal (languages/crystal)
-========================================
-#9 [builder 3/4] COPY uncloseai.cr .
-#9 DONE 0.1s
-
-#10 [builder 4/4] RUN crystal build --release uncloseai.cr
-#10 DONE 43.9s
-
-#11 [stage-1 2/4] RUN apk add --no-cache ca-certificates gc-dev pcre2-dev libevent-dev
-#11 CACHED
-
-#12 [stage-1 3/4] WORKDIR /app
-#12 CACHED
-
-#13 [stage-1 4/4] COPY --from=builder /app/uncloseai .
-#13 DONE 0.1s
-
-#14 exporting to image
-#14 exporting layers 0.1s done
-#14 writing image sha256:f23a4f18bebddf56759ce9abcd6d20cdddc29b89abe59e0830dbf4b7740fdafa done
-#14 naming to docker.io/library/ai-unturf-crystal done
-#14 DONE 0.1s
-✅ crystal built successfully
-
-========================================
-[13] Building csharp-http (languages/csharp/http)
-========================================
-#13 [builder 5/5] RUN dotnet build -c Release -o out
-#13 1.349 Determining projects to restore...
-#13 2.012 Restored /app/csharp.csproj (in 140 ms).
-#13 6.670 csharp -> /app/out/csharp.dll
-#13 6.689
-#13 6.691 Build succeeded.
-#13 6.691 0 Warning(s)
-#13 6.691 0 Error(s)
-#13 6.694
-#13 6.694 Time Elapsed 00:00:05.95
-#13 DONE 6.8s
-
-#14 [stage-1 4/4] COPY --from=builder /app/out .
-#14 DONE 0.2s
-
-#15 exporting to image
-#15 exporting layers 0.1s done
-#15 writing image sha256:ed7ce024bddb717a45b9f4155a84b26ec172c745946927a6164583dab366fffe done
-#15 naming to docker.io/library/ai-unturf-csharp-http done
-#15 DONE 0.1s
-✅ csharp-http built successfully
-
-========================================
-[14] Building csharp-openai (languages/csharp/openai)
-========================================
-5.546
-5.546 /app/uncloseai.cs(10,7): warning CS8981: The type name 'uncloseai' only contains lower-cased ascii characters. Such names may become reserved for the language. [/app/uncloseai.csproj]
-5.546 /app/uncloseai.cs(47,13): error CS1739: The best overload for 'ChatClient' does not have a parameter named 'apiKey' [/app/uncloseai.csproj]
-5.546 /app/uncloseai.cs(94,13): error CS1739: The best overload for 'ChatClient' does not have a parameter named 'apiKey' [/app/uncloseai.csproj]
-5.547 /app/uncloseai.cs(141,13): error CS1739: The best overload for 'AudioClient' does not have a parameter named 'apiKey' [/app/uncloseai.csproj]
-5.547 /app/uncloseai.cs(153,17): error CS0117: 'SpeechGenerationOptions' does not contain a definition for 'Speed' [/app/uncloseai.csproj]
-5.547 1 Warning(s)
-5.547 4 Error(s)
-5.550
-5.550 Time Elapsed 00:00:04.97
-------
-Dockerfile:12
---------------------
- 10 | # Copy source and build
- 11 | COPY uncloseai.cs ./
- 12 | >>> RUN dotnet build -c Release -o /app/build
- 13 |
- 14 | # Run stage
---------------------
-ERROR: failed to solve: process "/bin/sh -c dotnet build -c Release -o /app/build" did not complete successfully: exit code: 1
-✅ csharp-openai built successfully
-
-========================================
-[15] Building dart (languages/dart)
-========================================
-#9 [build 6/7] RUN dart pub get --offline
-#9 CACHED
-
-#10 [build 7/7] RUN dart compile exe bin/uncloseai.dart -o bin/uncloseai
-#10 CACHED
-
-#11 [build 2/7] WORKDIR /app
-#11 CACHED
-
-#12 [build 3/7] COPY pubspec.* .
-#12 CACHED
-
-#13 [stage-1 2/2] COPY --from=build /app/bin/uncloseai /app/bin/
-#13 CACHED
-
-#14 exporting to image
-#14 exporting layers done
-#14 writing image sha256:86328cf548eb37727bd1d1cfbbf86e4581b5750751ee55d5c614dc66968e9f26 done
-#14 naming to docker.io/library/ai-unturf-dart done
-#14 DONE 0.0s
-✅ dart built successfully
-
-========================================
-[16] Building d (languages/d)
-========================================
-#12 DONE 0.1s
-
-#13 [9/9] RUN dmd -of=hermes_nonstreaming hermes_nonstreaming.d && dmd -of=hermes_streaming hermes_streaming.d && dmd -of=qwen_nonstreaming qwen_nonstreaming.d && dmd -of=qwen_streaming qwen_streaming.d && dmd -of=tts tts.d
-#13 0.436 hermes_nonstreaming.d(21): Error: not an associative array initializer
-#13 ERROR: process "/bin/sh -c dmd -of=hermes_nonstreaming hermes_nonstreaming.d && dmd -of=hermes_streaming hermes_streaming.d && dmd -of=qwen_nonstreaming qwen_nonstreaming.d && dmd -of=qwen_streaming qwen_streaming.d && dmd -of=tts tts.d" did not complete successfully: exit code: 1
-------
- > [9/9] RUN dmd -of=hermes_nonstreaming hermes_nonstreaming.d && dmd -of=hermes_streaming hermes_streaming.d && dmd -of=qwen_nonstreaming qwen_nonstreaming.d && dmd -of=qwen_streaming qwen_streaming.d && dmd -of=tts tts.d:
-0.436 hermes_nonstreaming.d(21): Error: not an associative array initializer
-------
-Dockerfile:19
---------------------
- 18 | # Compile all examples
- 19 | >>> RUN dmd -of=hermes_nonstreaming hermes_nonstreaming.d && \
- 20 | >>> dmd -of=hermes_streaming hermes_streaming.d && \
- 21 | >>> dmd -of=qwen_nonstreaming qwen_nonstreaming.d && \
- 22 | >>> dmd -of=qwen_streaming qwen_streaming.d && \
- 23 | >>> dmd -of=tts tts.d
- 24 |
---------------------
-ERROR: failed to solve: process "/bin/sh -c dmd -of=hermes_nonstreaming hermes_nonstreaming.d && dmd -of=hermes_streaming hermes_streaming.d && dmd -of=qwen_nonstreaming qwen_nonstreaming.d && dmd -of=qwen_streaming qwen_streaming.d && dmd -of=tts tts.d" did not complete successfully: exit code: 1
-✅ d built successfully
-
-========================================
-[17] Building deno (languages/deno)
-========================================
-#3 DONE 0.0s
-
-#4 [1/3] FROM docker.io/denoland/deno:2.1.4@sha256:3bf75873714baa410dcf7fabaf76d806d20f0ac8a7579df11577b4ed97416e34
-#4 DONE 0.0s
-
-#5 [internal] load build context
-#5 transferring context: 93B done
-#5 DONE 0.0s
-
-#6 [2/3] WORKDIR /app
-#6 CACHED
-
-#7 [3/3] COPY uncloseai.ts .
-#7 CACHED
-
-#8 exporting to image
-#8 exporting layers done
-#8 writing image sha256:986244b89b1e93310d23f57e54d904a189784b73bfd41186463d75764c611784 done
-#8 naming to docker.io/library/ai-unturf-deno done
-#8 DONE 0.0s
-✅ deno built successfully
-
-========================================
-[18] Building elixir-httpoison (languages/elixir/httpoison)
-========================================
-#13 [stage-1 7/8] COPY --from=build /app/run.exs /app/run.exs
-#13 CACHED
-
-#14 [build 3/8] RUN mix local.hex --force && mix local.rebar --force
-#14 CACHED
-
-#15 [build 4/8] COPY mix.exs mix.lock* ./
-#15 CACHED
-
-#16 [stage-1 4/8] COPY --from=build /app/_build /app/_build
-#16 CACHED
-
-#17 [stage-1 8/8] COPY --from=build /app/mix.exs /app/mix.exs
-#17 CACHED
-
-#18 exporting to image
-#18 exporting layers done
-#18 writing image sha256:85d6d4eb47ea1b4bf86b5df606799e0fd1616b78f43e66211c95469d3ce4f3a3 done
-#18 naming to docker.io/library/ai-unturf-elixir-httpoison done
-#18 DONE 0.0s
-✅ elixir-httpoison built successfully
-
-========================================
-[19] Building elixir-openai (languages/elixir/openai)
-========================================
-#9 29.82 Compiling 40 files (.ex)
-#9 31.17 Generated openai_ex app
-#9 32.07 ===> Analyzing applications...
-#9 32.12 ===> Compiling metrics
-#9 33.55 ===> Analyzing applications...
-#9 33.77 ===> Compiling hackney
-#9 36.55 ==> httpoison
-#9 36.55 Compiling 3 files (.ex)
-#9 37.33 Generated httpoison app
-#9 DONE 37.5s
-
-#10 [6/6] COPY uncloseai.exs ./
-#10 DONE 0.2s
-
-#11 exporting to image
-#11 exporting layers
-#11 exporting layers 0.3s done
-#11 writing image sha256:d7dc3a70eadd3d30ed99bf17923f848b4e5f5d3119a5d3a8f70189273cc68622 done
-#11 naming to docker.io/library/ai-unturf-elixir-openai 0.0s done
-#11 DONE 0.4s
-✅ elixir-openai built successfully
-
-========================================
-[20] Building erlang (languages/erlang)
-========================================
-#11 [builder 7/7] RUN ./rebar3 compile
-#11 CACHED
-
-#12 [stage-1 3/5] RUN apk add --no-cache ca-certificates
-#12 CACHED
-
-#13 [builder 3/7] RUN apk add --no-cache git && wget https://s3.amazonaws.com/rebar3/rebar3 && chmod +x rebar3
-#13 CACHED
-
-#14 [stage-1 5/5] COPY --from=builder /app/src /app/src
-#14 CACHED
-
-#15 exporting to image
-#15 exporting layers done
-#15 writing image sha256:7c0d118d6828e2e29bd7ea888f074160e16b1203d844d9aaa09adfffee8a2e31 done
-#15 naming to docker.io/library/ai-unturf-erlang done
-#15 DONE 0.0s
-
- [33m1 warning found (use docker --debug to expand):
-[0m - FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 1)
-✅ erlang built successfully
-
-========================================
-[21] Building fortran (languages/fortran)
-========================================
-#5 transferring context: 94B done
-#5 DONE 0.1s
-
-#6 [2/5] RUN apt-get update && apt-get install -y gfortran-14 curl ca-certificates && rm -rf /var/lib/apt/lists/*
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.f90 .
-#8 CACHED
-
-#9 [5/5] RUN gfortran-14 -o uncloseai uncloseai.f90
-#9 CACHED
-
-#10 exporting to image
-#10 exporting layers done
-#10 writing image sha256:c2e559eba5e6881b47ba1535a551b65378e808c73fa864dbca82f7662068af50 done
-#10 naming to docker.io/library/ai-unturf-fortran done
-#10 DONE 0.0s
-✅ fortran built successfully
-
-========================================
-[22] Building fsharp (languages/fsharp)
-========================================
-#11 11.50 0 Error(s)
-#11 11.50
-#11 11.50 Time Elapsed 00:00:10.38
-#11 DONE 11.7s
-
-#12 [stage-1 2/4] RUN apk add --no-cache ca-certificates
-#12 CACHED
-
-#13 [stage-1 3/4] WORKDIR /app
-#13 CACHED
-
-#14 [stage-1 4/4] COPY --from=builder /app/out .
-#14 DONE 0.2s
-
-#15 exporting to image
-#15 exporting layers 0.1s done
-#15 writing image sha256:d583439e0b7d49dba078f59f15887c555377896713c36cd53186f9bc48513748
-#15 writing image sha256:d583439e0b7d49dba078f59f15887c555377896713c36cd53186f9bc48513748 done
-#15 naming to docker.io/library/ai-unturf-fsharp 0.0s done
-#15 DONE 0.2s
-✅ fsharp built successfully
-
-========================================
-[23] Building go-http (languages/go/http)
-========================================
-#11 [builder 5/7] COPY uncloseai/ ./uncloseai/
-#11 ERROR: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::tzkop5au2bw8yxjjck4sy95h3: "/uncloseai": not found
-
-#12 [builder 6/7] COPY examples/ ./examples/
-#12 ERROR: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::tzkop5au2bw8yxjjck4sy95h3: "/examples": not found
-------
- > [builder 5/7] COPY uncloseai/ ./uncloseai/:
-------
-------
- > [builder 6/7] COPY examples/ ./examples/:
-------
-Dockerfile:11
---------------------
- 9 | # Copy module files
- 10 | COPY go.mod .
- 11 | >>> COPY uncloseai/ ./uncloseai/
- 12 | COPY examples/ ./examples/
- 13 |
---------------------
-ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::tzkop5au2bw8yxjjck4sy95h3: "/uncloseai": not found
-✅ go-http built successfully
-
-========================================
-[24] Building go-openai (languages/go/openai)
-========================================
-#13 0.519 go mod download github.com/openai/openai-go
-#13 0.519 main.go:12:2: missing go.sum entry for module providing package github.com/openai/openai-go/option; to add:
-#13 0.519 go mod download github.com/openai/openai-go
-#13 ERROR: process "/bin/sh -c CGO_ENABLED=0 GOOS=linux go build -o /uncloseai main.go" did not complete successfully: exit code: 1
-------
- > [builder 6/6] RUN CGO_ENABLED=0 GOOS=linux go build -o /uncloseai main.go:
-0.519 main.go:11:2: missing go.sum entry for module providing package github.com/openai/openai-go; to add:
-0.519 go mod download github.com/openai/openai-go
-0.519 main.go:12:2: missing go.sum entry for module providing package github.com/openai/openai-go/option; to add:
-0.519 go mod download github.com/openai/openai-go
-------
-Dockerfile:14
---------------------
- 12 |
- 13 | # Build the application
- 14 | >>> RUN CGO_ENABLED=0 GOOS=linux go build -o /uncloseai main.go
- 15 |
- 16 | # Final stage
---------------------
-ERROR: failed to solve: process "/bin/sh -c CGO_ENABLED=0 GOOS=linux go build -o /uncloseai main.go" did not complete successfully: exit code: 1
-✅ go-openai built successfully
-
-========================================
-[25] Building groovy-openai-client (languages/groovy/openai-client)
-========================================
-#7 DONE 0.3s
-
-#8 [4/7] COPY HermesStreaming.groovy .
-#8 DONE 0.2s
-
-#9 [5/7] COPY QwenNonStreaming.groovy .
-#9 DONE 0.2s
-
-#10 [6/7] COPY QwenStreaming.groovy .
-#10 DONE 0.3s
-
-#11 [7/7] COPY TTS.groovy .
-#11 DONE 0.2s
-
-#12 exporting to image
-#12 exporting layers
-#12 exporting layers 0.3s done
-#12 writing image sha256:30c6a907695bd15615fd45c937aa92bee2e11deb124cb57e27b74876a9459503 done
-#12 naming to docker.io/library/ai-unturf-groovy-openai-client 0.0s done
-#12 DONE 0.4s
-✅ groovy-openai-client built successfully
-
-========================================
-[26] Building haskell (languages/haskell)
-========================================
-1.869 Module
-1.869 ‘Network.HTTP.Client.Conduit’
-1.869 does not export
-1.869 ‘streamResponseBody’
-1.869 |
-1.869 11 | import Network.HTTP.Client.Conduit (streamResponseBody)
-1.869 | ^^^^^^^^^^^^^^^^^^
-------
-
- [33m1 warning found (use docker --debug to expand):
-[0m - FromAsCasing: 'as' and 'FROM' keywords' casing do not match (line 1)
-Dockerfile:8
---------------------
- 6 |
- 7 | COPY UncloseAI.hs .
- 8 | >>> RUN cabal build
- 9 |
- 10 | FROM debian:bookworm-slim
---------------------
-ERROR: failed to solve: process "/bin/sh -c cabal build" did not complete successfully: exit code: 1
-✅ haskell built successfully
-
-========================================
-[27] Building java-http (languages/java/http)
-========================================
-
-#5 [internal] load build context
-#5 transferring context: 14.37kB done
-#5 DONE 0.0s
-
-#6 [2/4] WORKDIR /app
-#6 CACHED
-
-#7 [3/4] COPY UncloseAI.java .
-#7 DONE 0.2s
-
-#8 [4/4] RUN javac UncloseAI.java
-#8 DONE 2.4s
-
-#9 exporting to image
-#9 exporting layers
-#9 exporting layers 0.2s done
-#9 writing image sha256:2bad21080f1cf9422e953a6f6d5ea0c5e5d508dc0d80e6eb42229b8bdc428b32 done
-#9 naming to docker.io/library/ai-unturf-java-http 0.0s done
-#9 DONE 0.2s
-✅ java-http built successfully
-
-========================================
-[28] Building java-openai (languages/java/openai)
-========================================
-#12 18.63 [INFO] ------------------------------------------------------------------------
-#12 18.63 [INFO] Total time: 14.482 s
-#12 18.63 [INFO] Finished at: 2025-10-15T20:48:55Z
-#12 18.63 [INFO] ------------------------------------------------------------------------
-#12 DONE 18.8s
-
-#13 [stage-1 3/6] COPY --from=builder /app/target/classes ./classes
-#13 ERROR: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::ajkt24m3vxz5a2qda5yce6fgm: "/app/target/classes": not found
-------
- > [stage-1 3/6] COPY --from=builder /app/target/classes ./classes:
-------
-Dockerfile:19
---------------------
- 17 |
- 18 | # Copy compiled classes and dependencies from builder
- 19 | >>> COPY --from=builder /app/target/classes ./classes
- 20 | COPY --from=builder /root/.m2/repository /root/.m2/repository
- 21 | COPY --from=builder /app/pom.xml ./
---------------------
-ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::ajkt24m3vxz5a2qda5yce6fgm: "/app/target/classes": not found
-✅ java-openai built successfully
-
-========================================
-[29] Building javascript-bun (languages/javascript/bun)
-========================================
-#3 DONE 0.0s
-
-#4 [1/3] FROM docker.io/oven/bun:1@sha256:00cccad6e9c66bbacc250851f689168606aaea551ac473e908bbcf00a5645025
-#4 DONE 0.0s
-
-#5 [2/3] WORKDIR /app
-#5 CACHED
-
-#6 [internal] load build context
-#6 transferring context: 7.11kB done
-#6 DONE 0.1s
-
-#7 [3/3] COPY uncloseai.ts .
-#7 DONE 0.2s
-
-#8 exporting to image
-#8 exporting layers 0.1s done
-#8 writing image sha256:7678ae2232d77f86fde3da0ca03a3cd5a19571deead14c56c2353dd58c190910 done
-#8 naming to docker.io/library/ai-unturf-javascript-bun 0.0s done
-#8 DONE 0.2s
-✅ javascript-bun built successfully
-
-========================================
-[30] Building javascript-nodejs (languages/javascript/nodejs)
-========================================
-#4 DONE 0.0s
-
-#5 [internal] load build context
-#5 transferring context: 10.13kB done
-#5 DONE 0.1s
-
-#6 [2/4] WORKDIR /app
-#6 CACHED
-
-#7 [3/4] COPY uncloseai.js .
-#7 CACHED
-
-#8 [4/4] COPY package.json .
-#8 CACHED
-
-#9 exporting to image
-#9 exporting layers done
-#9 writing image sha256:e4e151ae1f9fe2cbc520baf46621979624d59c93a41e7eea71d9145feff6070c done
-#9 naming to docker.io/library/ai-unturf-javascript-nodejs 0.0s done
-#9 DONE 0.1s
-✅ javascript-nodejs built successfully
-
-========================================
-[31] Building javascript-openai-nodejs (languages/javascript/openai/nodejs)
-========================================
-#5 transferring context: 4.22kB done
-#5 DONE 0.1s
-
-#6 [2/5] WORKDIR /app
-#6 CACHED
-
-#7 [3/5] COPY package.json ./
-#7 CACHED
-
-#8 [4/5] RUN npm install
-#8 CACHED
-
-#9 [5/5] COPY uncloseai.js ./
-#9 CACHED
-
-#10 exporting to image
-#10 exporting layers done
-#10 writing image sha256:8f8b90b16e8725ebbe8aac5b7d64d85e504125287e790b10186e1aaf048124c4 done
-#10 naming to docker.io/library/ai-unturf-javascript-openai-nodejs done
-#10 DONE 0.1s
-✅ javascript-openai-nodejs built successfully
-
-========================================
-[32] Building javascript-typescript (languages/javascript/typescript)
-========================================
-#8 4.991 added 3 packages, and audited 4 packages in 4s
-#8 4.993
-#8 4.993 found 0 vulnerabilities
-#8 4.996 npm notice
-#8 4.996 npm notice New major version of npm available! 10.9.2 -> 11.6.2
-#8 4.996 npm notice Changelog: https://github.com/npm/cli/releases/tag/v11.6.2
-#8 4.996 npm notice To update run: npm install -g npm@11.6.2
-#8 4.996 npm notice
-#8 5.481
-#8 5.481 > uncloseai-typescript-examples@1.0.0 build
-#8 5.481 > tsc
-#8 5.481
-#8 DONE 9.0s
-
-#9 exporting to image
-#9 exporting layers
-#9 exporting layers 0.8s done
-#9 writing image sha256:a1564d45580396be1fcc563f8608653388fb760092682fe188e6b1fd2c873677 done
-#9 naming to docker.io/library/ai-unturf-javascript-typescript 0.0s done
-#9 DONE 0.9s
-✅ javascript-typescript built successfully
-
-========================================
-[33] Building javascript-vanilla (languages/javascript/vanilla)
-========================================
-#3 DONE 0.0s
-
-#4 [1/3] FROM docker.io/library/python:3.13-alpine@sha256:b423d3e1a4e39e34193dd728852bf7d74f2f5bef7ab3e87bf7c459e7482fac44
-#4 DONE 0.0s
-
-#5 [2/3] WORKDIR /app
-#5 CACHED
-
-#6 [internal] load build context
-#6 transferring context: 10.41kB done
-#6 DONE 0.1s
-
-#7 [3/3] COPY uncloseai.html index.html
-#7 DONE 0.2s
-
-#8 exporting to image
-#8 exporting layers 0.1s done
-#8 writing image sha256:107c8bf1ce4ca7950fa22bd4cc086977b7fe41d52d33b13a412b8035ef17e3e0 done
-#8 naming to docker.io/library/ai-unturf-javascript-vanilla 0.0s done
-#8 DONE 0.2s
-✅ javascript-vanilla built successfully
-
-========================================
-[34] Building julia (languages/julia)
-========================================
-#5 resolve docker.io/library/julia:1.11@sha256:b1a53d67d0390aa9f94d93171dd86821775dd869db827e7e2c3bef353a2497a9 0.1s done
-#5 DONE 0.1s
-
-#6 [2/5] WORKDIR /app
-#6 CACHED
-
-#7 [3/5] COPY Project.toml .
-#7 CACHED
-
-#8 [4/5] RUN julia -e 'using Pkg; Pkg.activate("."); Pkg.instantiate(); Pkg.precompile()'
-#8 CACHED
-
-#9 [5/5] COPY src ./src
-#9 CACHED
-
-#10 exporting to image
-#10 exporting layers done
-#10 writing image sha256:c00c8eacf6d51d08b8d92e469f3ecd11ccb405cf97503373ebda25fbd9d79aa7 done
-#10 naming to docker.io/library/ai-unturf-julia done
-#10 DONE 0.0s
-✅ julia built successfully
-
-========================================
-[35] Building kotlin (languages/kotlin)
-========================================
-#12 108.6 > Task :jar
-#12 109.7 > Task :startScripts
-#12 109.8 > Task :installDist
-#12 109.8
-#12 109.8 BUILD SUCCESSFUL in 1m 49s
-#12 109.8 5 actionable tasks: 5 executed
-#12 DONE 110.5s
-
-#13 [stage-1 2/3] WORKDIR /app
-#13 CACHED
-
-#14 [stage-1 3/3] COPY --from=builder /app/build/install/app /app
-#14 DONE 0.2s
-
-#15 exporting to image
-#15 exporting layers
-#15 exporting layers 0.2s done
-#15 writing image sha256:6a3144c8e2e3927d0afd29e4650cf3719a9d3f41656eb4fe562b82febd9f445f done
-#15 naming to docker.io/library/ai-unturf-kotlin 0.0s done
-#15 DONE 0.2s
-✅ kotlin built successfully
-
-========================================
-[36] Building lua (languages/lua)
-========================================
-#5 transferring context: 11.33kB done
-#5 DONE 0.0s
-
-#6 [3/5] RUN luarocks-5.4 install luasocket && luarocks-5.4 install luasec && luarocks-5.4 install lua-cjson
-#6 CACHED
-
-#7 [2/5] RUN apk add --no-cache lua5.4 lua5.4-dev luarocks5.4 ca-certificates openssl-dev gcc musl-dev
-#7 CACHED
-
-#8 [4/5] WORKDIR /app
-#8 CACHED
-
-#9 [5/5] COPY uncloseai.lua .
-#9 DONE 0.2s
-
-#10 exporting to image
-#10 exporting layers 0.1s done
-#10 writing image sha256:36949ae65e58ee5a01959efb2268d7731f74963c8db9b6233ed7978edf40f8c3 done
-#10 naming to docker.io/library/ai-unturf-lua 0.0s done
-#10 DONE 0.2s
-✅ lua built successfully
-
-========================================
-[37] Building mojo (languages/mojo)
-========================================
-#0 building with "default" instance using docker driver
-
-#1 [internal] load build definition from Dockerfile
-#1 transferring dockerfile: 505B done
-#1 DONE 0.1s
-
-#2 [internal] load metadata for docker.io/modular/max:latest
-#2 ERROR: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
-------
- > [internal] load metadata for docker.io/modular/max:latest:
-------
-Dockerfile:3
---------------------
- 1 | # Use Modular MAX container (checked 2025-10-15: latest stable Mojo runtime)
- 2 | # Note: This requires Modular license acceptance
- 3 | >>> FROM modular/max:latest
- 4 |
- 5 | WORKDIR /app
---------------------
-ERROR: failed to solve: modular/max:latest: failed to resolve source metadata for docker.io/modular/max:latest: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
-✅ mojo built successfully
-
-========================================
-[38] Building nim (languages/nim)
-========================================
-#9 4.786 CC: ../nim/lib/pure/streams.nim
-#9 4.997 CC: ../nim/lib/pure/asyncfutures.nim
-#9 5.047 CC: ../nim/lib/pure/asyncdispatch.nim
-#9 5.071 CC: ../nim/lib/pure/httpclient.nim
-#9 5.101 CC: ../nim/lib/pure/lexbase.nim
-#9 5.159 CC: ../nim/lib/pure/parsejson.nim
-#9 5.180 CC: ../nim/lib/pure/json.nim
-#9 5.337 CC: ../nim/lib/pure/strformat.nim
-#9 5.480 CC: uncloseai.nim
-#9 5.904 Hint: [Link]
-#9 5.967 Hint: mm: orc; threads: on; opt: none (DEBUG BUILD, `-d:release` generates faster code)
-#9 5.967 79322 lines; 5.395s; 140.758MiB peakmem; proj: /app/uncloseai.nim; out: /app/uncloseai [SuccessX]
-#9 DONE 6.2s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.2s done
-#10 writing image sha256:befc067e888cca33e1aedf363c80b0634726a1995af380f4f3299e01f5861280 done
-#10 naming to docker.io/library/ai-unturf-nim 0.0s done
-#10 DONE 0.2s
-✅ nim built successfully
-
-========================================
-[39] Building ocaml (languages/ocaml)
-========================================
-#7 CACHED
-
-#8 [4/6] RUN opam install -y lwt cohttp-lwt-unix yojson dune
-#8 CACHED
-
-#9 [5/6] COPY --chown=opam:opam . .
-#9 DONE 0.2s
-
-#10 [6/6] RUN eval $(opam env) && dune build
-#10 DONE 1.8s
-
-#11 exporting to image
-#11 exporting layers
-#11 exporting layers 0.2s done
-#11 writing image sha256:56a713a68317b9a489e45ebd2e587caa2c96a99e311c62842bfe659a816c6adf done
-#11 naming to docker.io/library/ai-unturf-ocaml 0.0s done
-#11 DONE 0.3s
-
- [33m1 warning found (use docker --debug to expand):
-[0m - JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 20)
-✅ ocaml built successfully
-
-========================================
-[40] Building odin (languages/odin)
-========================================
-#5 transferring context: 9.75kB done
-#5 DONE 0.0s
-
-#6 [3/5] RUN wget https://github.com/odin-lang/Odin/releases/download/dev-2025-10/odin-linux-amd64-dev-2025-10-05.tar.gz && tar -xzf odin-linux-amd64-dev-2025-10-05.tar.gz && mv odin-linux-amd64-nightly+2025-10-05 /opt/odin && rm odin-linux-amd64-dev-2025-10-05.tar.gz && rm -rf /var/lib/apt/lists/*
-#6 CACHED
-
-#7 [2/5] RUN apt-get update && apt-get install -y wget llvm-18 clang-18 build-essential ca-certificates && rm -rf /var/lib/apt/lists/*
-#7 CACHED
-
-#8 [4/5] WORKDIR /app
-#8 CACHED
-
-#9 [5/5] COPY uncloseai.odin .
-#9 DONE 0.2s
-
-#10 exporting to image
-#10 exporting layers 0.1s done
-#10 writing image sha256:c96da793fb3a4d37c287fbdc06b3db6e7402a8f5d23ecfc747d59455f82c75e4 done
-#10 naming to docker.io/library/ai-unturf-odin 0.0s done
-#10 DONE 0.2s
-✅ odin built successfully
-
-========================================
-[41] Building perl (languages/perl)
-========================================
-#5 DONE 0.0s
-
-#6 [2/5] RUN apt-get update && apt-get install -y ca-certificates make gcc libc-dev libssl-dev && rm -rf /var/lib/apt/lists/* && cpanm --notest LWP::UserAgent LWP::Protocol::https JSON HTTP::Request && apt-get purge -y make gcc libc-dev && apt-get autoremove -y
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.pl .
-#8 DONE 0.2s
-
-#9 [5/5] RUN chmod +x uncloseai.pl
-#9 DONE 0.5s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.2s done
-#10 writing image sha256:6303e622152fb1407d98d01344fc78e05d7e2764653194fa79de4aebc3874c5e done
-#10 naming to docker.io/library/ai-unturf-perl 0.0s done
-#10 DONE 0.2s
-✅ perl built successfully
-
-========================================
-[42] Building php (languages/php)
-========================================
-#5 DONE 0.0s
-
-#6 [2/5] RUN apk add --no-cache ca-certificates
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.php .
-#8 DONE 0.2s
-
-#9 [5/5] RUN chmod +x uncloseai.php
-#9 DONE 0.6s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.2s done
-#10 writing image sha256:b01fc9abdab97f0e2796d89383fee47affe451e61f8f1352728b37582fce9159 done
-#10 naming to docker.io/library/ai-unturf-php 0.0s done
-#10 DONE 0.3s
-✅ php built successfully
-
-========================================
-[43] Building powershell (languages/powershell)
-========================================
-#5 DONE 0.1s
-
-#6 [2/5] RUN apk add --no-cache ca-certificates
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.ps1 .
-#8 DONE 0.2s
-
-#9 [5/5] RUN chmod +x uncloseai.ps1
-#9 DONE 0.6s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.2s done
-#10 writing image sha256:c62d090199e11dbdb458ab68d9d71c69bed8fe4c352ecb2c52319a20737f67af done
-#10 naming to docker.io/library/ai-unturf-powershell 0.0s done
-#10 DONE 0.2s
-✅ powershell built successfully
-
-========================================
-[44] Building prolog (languages/prolog)
-========================================
-#5 DONE 0.1s
-
-#6 [2/5] RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.pl .
-#8 DONE 0.2s
-
-#9 [5/5] RUN chmod +x uncloseai.pl
-#9 DONE 0.5s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.2s done
-#10 writing image sha256:aba9f229f5161ccc6cad6ef167bc49e18130992ffd860b465a1f5f5549a378a3 done
-#10 naming to docker.io/library/ai-unturf-prolog 0.0s done
-#10 DONE 0.2s
-✅ prolog built successfully
-
-========================================
-[45] Building python-aiohttp (languages/python/aiohttp)
-========================================
-#6 [2/6] WORKDIR /app
-#6 CACHED
-
-#7 [3/6] COPY requirements.txt /app/requirements.txt
-#7 CACHED
-
-#8 [4/6] COPY uncloseai.py /app/uncloseai.py
-#8 CACHED
-
-#9 [5/6] RUN chmod +x /app/uncloseai.py
-#9 CACHED
-
-#10 [6/6] RUN pip3 install --no-cache-dir -r /app/requirements.txt
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:40561f33dc84e22806283699c70a14095174813ee17e9ce9d28142ebcfe711b7 done
-#11 naming to docker.io/library/ai-unturf-python-aiohttp done
-#11 DONE 0.0s
-✅ python-aiohttp built successfully
-
-========================================
-[46] Building python-httpx-async (languages/python/httpx-async)
-========================================
-#6 [5/6] RUN chmod +x /app/uncloseai.py
-#6 CACHED
-
-#7 [2/6] WORKDIR /app
-#7 CACHED
-
-#8 [3/6] COPY requirements.txt /app/requirements.txt
-#8 CACHED
-
-#9 [4/6] COPY uncloseai.py /app/uncloseai.py
-#9 CACHED
-
-#10 [6/6] RUN pip3 install --no-cache-dir -r /app/requirements.txt
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:ba2eda73911f88cc39ff2b5c092b2a9d9b0a544354bedfe7e155e8b92f70ed86 done
-#11 naming to docker.io/library/ai-unturf-python-httpx-async 0.0s done
-#11 DONE 0.0s
-✅ python-httpx-async built successfully
-
-========================================
-[47] Building python-openai (languages/python/openai)
-========================================
-#6 [2/6] WORKDIR /app
-#6 CACHED
-
-#7 [3/6] COPY requirements.txt /app/requirements.txt
-#7 CACHED
-
-#8 [4/6] COPY uncloseai.py /app/uncloseai.py
-#8 CACHED
-
-#9 [5/6] RUN chmod +x /app/uncloseai.py
-#9 CACHED
-
-#10 [6/6] RUN pip3 install --no-cache-dir -r /app/requirements.txt
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:dee85dbeb9b2bc897611caabd4851f489410826e392c622b06e279305426dc71 done
-#11 naming to docker.io/library/ai-unturf-python-openai done
-#11 DONE 0.0s
-✅ python-openai built successfully
-
-========================================
-[48] Building python-requests (languages/python/requests)
-========================================
-#6 [2/6] WORKDIR /app
-#6 CACHED
-
-#7 [3/6] COPY requirements.txt /app/requirements.txt
-#7 CACHED
-
-#8 [4/6] COPY uncloseai.py /app/uncloseai.py
-#8 CACHED
-
-#9 [5/6] RUN chmod +x /app/uncloseai.py
-#9 CACHED
-
-#10 [6/6] RUN pip3 install --no-cache-dir -r /app/requirements.txt
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:57f05217ad6ba799d3e6c99227ff57dcd2c86c06cf5d2bf306329c9e04267b0a done
-#11 naming to docker.io/library/ai-unturf-python-requests done
-#11 DONE 0.0s
-✅ python-requests built successfully
-
-========================================
-[49] Building r (languages/r)
-========================================
-#5 DONE 0.0s
-
-#6 [2/5] RUN apt-get update && apt-get install -y libcurl4-openssl-dev libssl-dev ca-certificates && R -e "install.packages(c('httr', 'jsonlite', 'R6'), repos='https://cloud.r-project.org/')" && rm -rf /var/lib/apt/lists/*
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.R .
-#8 DONE 0.4s
-
-#9 [5/5] RUN chmod +x uncloseai.R
-#9 DONE 0.6s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.3s done
-#10 writing image sha256:64646b72fb21939b4aa41267a27a1eee93f7aca6ae1562bb987a9e25664c3d1e 0.0s done
-#10 naming to docker.io/library/ai-unturf-r 0.0s done
-#10 DONE 0.3s
-✅ r built successfully
-
-========================================
-[50] Building ruby-http (languages/ruby/http)
-========================================
-#4 transferring context: 6.34kB done
-#4 DONE 0.1s
-
-#6 [4/5] COPY uncloseai.rb .
-#6 CACHED
-
-#7 [2/5] RUN apk add --no-cache ca-certificates
-#7 CACHED
-
-#8 [3/5] WORKDIR /app
-#8 CACHED
-
-#9 [5/5] RUN chmod +x uncloseai.rb
-#9 CACHED
-
-#10 exporting to image
-#10 exporting layers done
-#10 writing image sha256:8f82bcf24665cf7963e9b0fba9d96cc25f53e9881745de2c1660cb14a886d7d4 done
-#10 naming to docker.io/library/ai-unturf-ruby-http done
-#10 DONE 0.0s
-✅ ruby-http built successfully
-
-========================================
-[51] Building ruby-openai (languages/ruby/openai)
-========================================
-#6 [2/6] WORKDIR /app
-#6 CACHED
-
-#7 [3/6] COPY Gemfile ./
-#7 CACHED
-
-#8 [4/6] RUN bundle install
-#8 CACHED
-
-#9 [5/6] COPY uncloseai.rb ./
-#9 CACHED
-
-#10 [6/6] RUN chmod +x uncloseai.rb
-#10 CACHED
-
-#11 exporting to image
-#11 exporting layers done
-#11 writing image sha256:ddaa873fb65bd7de3153e115ca64ce7db3140274c1eca5d581ac984b8fb3f04a done
-#11 naming to docker.io/library/ai-unturf-ruby-openai done
-#11 DONE 0.0s
-✅ ruby-openai built successfully
-
-========================================
-[52] Building rust (languages/rust)
-========================================
-#13 [stage-1 2/5] RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
-#13 CACHED
-
-#14 [stage-1 3/5] WORKDIR /app
-#14 CACHED
-
-#15 [stage-1 4/5] COPY --from=builder /app/target/release/uncloseai .
-#15 ERROR: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::ran0wfk0i5h7bk1hadbc29ccb: "/app/target/release/uncloseai": not found
-------
- > [stage-1 4/5] COPY --from=builder /app/target/release/uncloseai .:
-------
-Dockerfile:16
---------------------
- 14 |
- 15 | WORKDIR /app
- 16 | >>> COPY --from=builder /app/target/release/uncloseai .
- 17 | COPY --from=builder /app/target/release/examples/basic ./basic
- 18 |
---------------------
-ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 466bb300-1953-4d46-a0ff-c9ba0efad3a2::ran0wfk0i5h7bk1hadbc29ccb: "/app/target/release/uncloseai": not found
-✅ rust built successfully
-
-========================================
-[53] Building scala (languages/scala)
-========================================
-#12 31.46 [info] done compiling
-#12 32.39 [success] Total time: 21 s, completed Oct 15, 2025, 8:52:16 PM
-#12 32.83 [info] Main Scala API documentation to /app/target/scala-2.13/api...
-#12 33.01 [info] Wrote /app/target/scala-2.13/uncloseai_2.13-0.1.0.pom
-#12 39.78 [info] Main Scala API documentation successful.
-#12 40.26 [success] Total time: 8 s, completed Oct 15, 2025, 8:52:24 PM
-#12 DONE 41.0s
-
-#13 [stage-1 2/3] WORKDIR /app
-#13 CACHED
-
-#14 [stage-1 3/3] COPY --from=builder /app/target/universal/stage .
-#14 DONE 0.2s
-
-#15 exporting to image
-#15 exporting layers
-#15 exporting layers 0.3s done
-#15 writing image sha256:5ecde580fac40a1404f16ff1f800f248b678accab625e3721e5f2ce32b6d71f1 done
-#15 naming to docker.io/library/ai-unturf-scala 0.0s done
-#15 DONE 0.4s
-✅ scala built successfully
-
-========================================
-[54] Building scheme (languages/scheme)
-========================================
-#9 DONE 0.2s
-
-#10 [6/9] COPY qwen-nonstreaming.scm .
-#10 DONE 0.2s
-
-#11 [7/9] COPY qwen-streaming.scm .
-#11 DONE 0.2s
-
-#12 [8/9] COPY tts.scm .
-#12 DONE 0.2s
-
-#13 [9/9] RUN chmod +x *.scm
-#13 DONE 0.5s
-
-#14 exporting to image
-#14 exporting layers
-#14 exporting layers 4.1s done
-#14 writing image sha256:1d0cba4b49c586660f31f75a492607d2b5031f847fd5c8bb6a03b4373bcf77a7 done
-#14 naming to docker.io/library/ai-unturf-scheme 0.0s done
-#14 DONE 4.2s
-✅ scheme built successfully
-
-========================================
-[55] Building tcl (languages/tcl)
-========================================
-#5 DONE 0.1s
-
-#6 [2/5] RUN apk add --no-cache tcl ca-certificates curl jq
-#6 CACHED
-
-#7 [3/5] WORKDIR /app
-#7 CACHED
-
-#8 [4/5] COPY uncloseai.tcl .
-#8 DONE 0.2s
-
-#9 [5/5] RUN chmod +x uncloseai.tcl
-#9 DONE 0.6s
-
-#10 exporting to image
-#10 exporting layers
-#10 exporting layers 0.2s done
-#10 writing image sha256:bc9234d423a400ce7b4aad26e25de10f439b3e737e17ac3f9c2d5486547e1acb done
-#10 naming to docker.io/library/ai-unturf-tcl 0.0s done
-#10 DONE 0.2s
-✅ tcl built successfully
-
-========================================
-[56] Building vbnet (languages/vbnet)
-========================================
-#15 5.438
-#15 5.438 Time Elapsed 00:00:04.53
-#15 DONE 5.6s
-
-#16 [publish 1/1] RUN dotnet publish "UncloseAI.vbproj" -c Release -o /app/publish
-#16 1.504 Determining projects to restore...
-#16 2.127 All projects are up-to-date for restore.
-#16 2.663 UncloseAI -> /src/bin/Release/net8.0/UncloseAI.dll
-#16 2.741 UncloseAI -> /app/publish/
-#16 DONE 2.9s
-
-#17 [final 2/2] COPY --from=publish /app/publish .
-#17 DONE 0.2s
-
-#18 exporting to image
-#18 exporting layers
-#18 exporting layers 0.2s done
-#18 writing image sha256:6c6077652772a5f08c362863a2c2db6ce3e24b618175d57a6b08cc97b468b94a done
-#18 naming to docker.io/library/ai-unturf-vbnet 0.0s done
-#18 DONE 0.4s
-✅ vbnet built successfully
-
-========================================
-[57] Building v (languages/v)
-========================================
-#8 [stage-1 2/3] RUN apk add --no-cache ca-certificates
-#8 CACHED
-
-#9 [builder 2/4] WORKDIR /app
-#9 CACHED
-
-#10 [builder 3/4] COPY v.mod uncloseai.v ./
-#10 CACHED
-
-#11 [builder 4/4] RUN v -prod uncloseai.v
-#11 CACHED
-
-#12 [stage-1 3/3] COPY --from=builder /app/uncloseai /usr/local/bin/uncloseai
-#12 CACHED
-
-#13 exporting to image
-#13 exporting layers done
-#13 writing image sha256:b10b618e2d958833856c33260bf3a4c782008b8f17aa6bece0082db6b03a5c92 done
-#13 naming to docker.io/library/ai-unturf-v done
-#13 DONE 0.0s
-✅ v built successfully
-
-========================================
-[58] Building zig (languages/zig)
-========================================
-#7 [builder 3/5] WORKDIR /app
-#7 CACHED
-
-#8 [builder 4/5] COPY . .
-#8 DONE 0.2s
-
-#9 [builder 5/5] RUN /opt/zig/zig build -Doptimize=ReleaseSafe
-#9 DONE 101.8s
-
-#10 [stage-1 2/3] RUN apk add --no-cache ca-certificates
-#10 CACHED
-
-#11 [stage-1 3/3] COPY --from=builder /app/zig-out/bin/uncloseai /usr/local/bin/uncloseai
-#11 CACHED
-
-#12 exporting to image
-#12 exporting layers done
-#12 writing image sha256:c829bcad3e50c562b087532c60170b498c07704ce811db45ac9589ae31c1afc8 done
-#12 naming to docker.io/library/ai-unturf-zig done
-#12 DONE 0.0s
-✅ zig built successfully
-
-========================================
-Build Summary: 58/58 successful
-✅ All builds successful!
diff --git a/modal_tests.js b/modal_tests.js
deleted file mode 100644
index b33ded9..0000000
--- a/modal_tests.js
+++ /dev/null
@@ -1,376 +0,0 @@
-// Custom Modal Test Suite
-// Tests modal functionality using JSDOM without Jest complexity
-// Run with: node modal_tests.js
-
-import { JSDOM } from 'jsdom';
-import { fileURLToPath } from 'url';
-import { dirname, join } from 'path';
-import fs from 'fs';
-
-const __filename = fileURLToPath(import.meta.url);
-const __dirname = dirname(__filename);
-
-// Test suite state
-let testCount = 0;
-let passedCount = 0;
-let failedCount = 0;
-
-// Simple test framework
-function test(description, testFn) {
- testCount++;
- console.log(`\n🧪 Test: ${description}`);
- try {
- testFn();
- console.log(`✅ PASS`);
- passedCount++;
- } catch (error) {
- console.log(`❌ FAIL: ${error.message}`);
- failedCount++;
- }
-}
-
-function assert(condition, message) {
- if (!condition) {
- throw new Error(message);
- }
-}
-
-function assertEqual(actual, expected, message) {
- if (actual !== expected) {
- throw new Error(`${message} - Expected: ${expected}, Got: ${actual}`);
- }
-}
-
-// Setup mock browser environment
-function setupBrowserMocks() {
- const dom = new JSDOM(`
-
-
- Modal Test Page
-
-
-
-
-
- `, {
- url: "https://ai.unturf.com",
- pretendToBeVisual: true,
- resources: "usable"
- });
-
- // Set up globals safely for Node.js v22
- Object.defineProperty(global, 'window', { value: dom.window, configurable: true });
- Object.defineProperty(global, 'document', { value: dom.window.document, configurable: true });
- Object.defineProperty(global, 'navigator', { value: dom.window.navigator, configurable: true });
- Object.defineProperty(global, 'HTMLElement', { value: dom.window.HTMLElement, configurable: true });
- Object.defineProperty(global, 'Element', { value: dom.window.Element, configurable: true });
- // Polyfill HTMLDialogElement if not available
- if (!dom.window.HTMLDialogElement) {
- dom.window.HTMLDialogElement = class HTMLDialogElement extends dom.window.HTMLElement {
- constructor() {
- super();
- this.open = false;
- }
-
- showModal() {
- this.open = true;
- }
-
- show() {
- this.open = true;
- }
-
- close() {
- this.open = false;
- }
- };
- }
- Object.defineProperty(global, 'HTMLDialogElement', { value: dom.window.HTMLDialogElement, configurable: true });
-
- // Add Event constructor polyfill
- if (!global.Event) {
- global.Event = dom.window.Event;
- }
- if (!global.MouseEvent) {
- global.MouseEvent = dom.window.MouseEvent;
- }
-
- // Mock fetch
- global.fetch = async (url, options) => {
- // Mock model API responses
- if (url.includes('/v1/models')) {
- return {
- ok: true,
- json: async () => ({
- data: [
- { id: 'gpt-4o', object: 'model' },
- { id: 'claude-3-sonnet', object: 'model' }
- ]
- })
- };
- }
-
- // Mock chat completion responses
- if (url.includes('/v1/chat/completions')) {
- return {
- ok: true,
- json: async () => ({
- choices: [{ message: { content: 'Test response' } }]
- })
- };
- }
-
- return { ok: false, status: 404 };
- };
-
- // Mock localStorage
- const localStorageMock = {
- getItem: (key) => localStorageMock.data[key] || null,
- setItem: (key, value) => { localStorageMock.data[key] = value; },
- removeItem: (key) => { delete localStorageMock.data[key]; },
- clear: () => { localStorageMock.data = {}; },
- data: {}
- };
- global.localStorage = localStorageMock;
-
- // Mock other browser APIs
- global.Audio = class MockAudio {
- constructor(src) { this.src = src; }
- play() { return Promise.resolve(); }
- pause() {}
- };
-
- global.speechSynthesis = {
- speak: () => {},
- cancel: () => {},
- getVoices: () => []
- };
-
- return dom;
-}
-
-// Mock external CDN dependencies
-function mockCDNDependencies() {
- // Mock marked
- global.marked = {
- parse: (text) => `${text}
`,
- setOptions: () => {}
- };
-
- // Mock highlight.js
- global.hljs = {
- highlightAuto: (code) => ({ value: code }),
- configure: () => {}
- };
-}
-
-// Load source files for testing
-async function loadSourceFile(filename) {
- const filePath = join(__dirname, 'src', filename);
- const content = fs.readFileSync(filePath, 'utf-8');
-
- // Replace CDN imports with our mocks
- const modifiedContent = content
- .replace(/import\s+\{[^}]+\}\s+from\s+["']https:\/\/cdn\.jsdelivr\.net\/npm\/marked\/lib\/marked\.esm\.js["']/g,
- '// Mock marked import')
- .replace(/import\s+\{[^}]+\}\s+from\s+["']https:\/\/cdnjs\.cloudflare\.com\/ajax\/libs\/highlight\.js\/[^"']+["']/g,
- '// Mock hljs import');
-
- return modifiedContent;
-}
-
-// Test modal creation and basic functionality
-async function testModalCreation() {
- test('Modal dialog element can be created', () => {
- // Create a regular div and enhance it with dialog-like properties
- const modal = document.createElement('div');
- modal.id = 'test-modal';
- modal.className = 'modal-dialog';
-
- // Add dialog-like methods
- modal.open = false;
- modal.showModal = function() { this.open = true; this.style.display = 'block'; };
- modal.show = function() { this.open = true; this.style.display = 'block'; };
- modal.close = function() { this.open = false; this.style.display = 'none'; };
-
- document.body.appendChild(modal);
-
- assert(typeof modal.showModal === 'function', 'Modal should have showModal method');
- assert(modal.id === 'test-modal', 'Modal should have correct ID');
- assert(document.getElementById('test-modal'), 'Modal should be in DOM');
- });
-
- test('Modal can be opened and closed', () => {
- const modal = document.getElementById('test-modal');
-
- modal.showModal();
- assert(modal.open === true, 'Modal should be open after showModal()');
-
- modal.close();
- assert(modal.open === false, 'Modal should be closed after close()');
- });
-}
-
-// Test modal content injection
-async function testModalContent() {
- test('Modal content can be injected', () => {
- const modal = document.getElementById('test-modal');
-
- modal.innerHTML = `
-
-
- `;
-
- assert(modal.querySelector('.modal-header'), 'Modal should have header');
- assert(modal.querySelector('.modal-content'), 'Modal should have content');
- assert(modal.querySelector('.close-btn'), 'Modal should have close button');
- });
-
- test('Modal close button functionality', () => {
- const modal = document.getElementById('test-modal');
- const closeBtn = modal.querySelector('.close-btn');
-
- modal.showModal();
- assert(modal.open === true, 'Modal should be open');
-
- // Simulate click on close button
- closeBtn.click();
- // Note: In real implementation, this would trigger close event
- modal.close(); // Manually close for test
-
- assert(modal.open === false, 'Modal should close when close button clicked');
- });
-}
-
-// Test modal form handling
-async function testModalForms() {
- test('Modal can contain form elements', () => {
- const modal = document.getElementById('test-modal');
-
- modal.innerHTML = `
-
- `;
-
- const form = modal.querySelector('.modal-form');
- const input = modal.querySelector('#test-input');
- const select = modal.querySelector('#test-select');
-
- assert(form, 'Modal should contain form');
- assert(input, 'Modal should contain input field');
- assert(select, 'Modal should contain select field');
- });
-
- test('Modal form inputs can be manipulated', () => {
- const modal = document.getElementById('test-modal');
- const input = modal.querySelector('#test-input');
- const select = modal.querySelector('#test-select');
-
- input.value = 'Test value';
- select.value = 'option2';
-
- assertEqual(input.value, 'Test value', 'Input value should be set');
- assertEqual(select.value, 'option2', 'Select value should be set');
- });
-}
-
-// Test modal event handling
-async function testModalEvents() {
- test('Modal can handle custom events', () => {
- const modal = document.getElementById('test-modal');
- let eventFired = false;
-
- modal.addEventListener('custom-event', () => {
- eventFired = true;
- });
-
- const customEvent = new window.Event('custom-event');
- modal.dispatchEvent(customEvent);
-
- assert(eventFired, 'Custom event should fire');
- });
-
- test('Modal click outside should work', () => {
- const modal = document.getElementById('test-modal');
- modal.showModal();
-
- // Simulate click on backdrop (this would need proper implementation)
- const clickEvent = new MouseEvent('click', {
- clientX: 0,
- clientY: 0
- });
-
- modal.dispatchEvent(clickEvent);
- // In real implementation, this would check if click was outside content
- assert(true, 'Click outside event handling works');
- });
-}
-
-// Test localStorage integration
-async function testLocalStorageIntegration() {
- test('Modal can save state to localStorage', () => {
- const testData = { modalState: 'open', userPrefs: { theme: 'dark' } };
-
- localStorage.setItem('modal-test', JSON.stringify(testData));
- const retrieved = JSON.parse(localStorage.getItem('modal-test'));
-
- assertEqual(retrieved.modalState, 'open', 'localStorage should save modal state');
- assertEqual(retrieved.userPrefs.theme, 'dark', 'localStorage should save user preferences');
- });
-
- test('Modal can load state from localStorage', () => {
- const savedData = localStorage.getItem('modal-test');
- assert(savedData, 'Data should be available in localStorage');
-
- const parsed = JSON.parse(savedData);
- assert(parsed.modalState === 'open', 'Modal state should be restored');
- });
-}
-
-// Main test runner
-async function runModalTests() {
- console.log('🚀 Starting Custom Modal Test Suite\n');
- console.log('=' .repeat(50));
-
- // Setup environment
- setupBrowserMocks();
- mockCDNDependencies();
-
- // Run test suites
- await testModalCreation();
- await testModalContent();
- await testModalForms();
- await testModalEvents();
- await testLocalStorageIntegration();
-
- // Print results
- console.log('\n' + '=' .repeat(50));
- console.log('📊 Modal Test Results:');
- console.log(`Total tests: ${testCount}`);
- console.log(`Passed: ${passedCount} ✅`);
- console.log(`Failed: ${failedCount} ❌`);
-
- if (failedCount === 0) {
- console.log('\n🎉 All modal tests passed!');
- } else {
- console.log('\n💥 Some modal tests failed.');
- process.exit(1);
- }
-}
-
-// Run the tests
-runModalTests().catch(error => {
- console.error('Test runner error:', error);
- process.exit(1);
-});
\ No newline at end of file
diff --git a/simple_tests.js b/simple_tests.js
deleted file mode 100644
index 8690596..0000000
--- a/simple_tests.js
+++ /dev/null
@@ -1,266 +0,0 @@
-// Simple tests that don't require DOM or external dependencies
-import { promises as fs } from 'fs';
-import path from 'path';
-
-const srcDir = './src';
-
-async function runSimpleTests() {
- console.log('🧪 Running Simple Tests\n');
-
- let tests = 0;
- let passed = 0;
- let failed = 0;
-
- function test(description, testFn) {
- tests++;
- try {
- testFn();
- console.log(`✅ ${description}`);
- passed++;
- } catch (error) {
- console.error(`❌ ${description}`);
- console.error(` Error: ${error.message}`);
- failed++;
- }
- }
-
- function assert(condition, message) {
- if (!condition) {
- throw new Error(message);
- }
- }
-
- // Test 1: Core files exist
- test('Core JavaScript files exist', async () => {
- const coreFiles = [
- 'ui.js', 'translation.js', 'tts.js', 'chat.js', 'config.js',
- 'widget-library.js', 'tts-modal.js', 'translate-modal.js',
- 'uncloseai-embed-modal.js'
- ];
-
- for (const file of coreFiles) {
- const filePath = path.join(srcDir, file);
- try {
- await fs.access(filePath);
- } catch (error) {
- throw new Error(`File ${file} does not exist`);
- }
- }
- });
-
- // Test 2: Language files exist
- test('Language files structure is correct', async () => {
- const langDir = path.join(srcDir, 'languages');
- const files = await fs.readdir(langDir);
- const jsFiles = files.filter(f => f.endsWith('.js'));
-
- assert(jsFiles.length >= 18, `Expected at least 18 language files, found ${jsFiles.length}`);
- assert(jsFiles.includes('index.js'), 'Missing languages/index.js');
- assert(jsFiles.includes('en.js'), 'Missing languages/en.js');
- });
-
- // Test 3: File sizes are reasonable
- test('UI.js size is reasonable after refactoring', async () => {
- const content = await fs.readFile(path.join(srcDir, 'ui.js'), 'utf-8');
- const lines = content.split('\n').length;
-
- assert(lines < 600, `UI.js is too large: ${lines} lines (expected < 600)`);
- assert(lines > 100, `UI.js is too small: ${lines} lines (expected > 100)`);
- });
-
- // Test 4: No obvious syntax errors in main files
- test('Main files have balanced braces', async () => {
- const mainFiles = ['ui.js', 'translation.js', 'tts.js', 'chat.js'];
-
- for (const file of mainFiles) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
- const openBraces = (content.match(/{/g) || []).length;
- const closeBraces = (content.match(/}/g) || []).length;
-
- assert(openBraces === closeBraces,
- `${file} has mismatched braces: ${openBraces} open, ${closeBraces} close`);
- }
- });
-
- // Test 5: Export statements exist
- test('Key files have export statements', async () => {
- const filesWithExports = ['ui.js', 'translation.js', 'tts.js', 'widget-library.js'];
-
- for (const file of filesWithExports) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
- assert(content.includes('export'), `${file} has no export statements`);
- }
- });
-
- // Test 6: Import statements are valid
- test('Import statements use correct syntax', async () => {
- const allFiles = await fs.readdir(srcDir);
- const jsFiles = allFiles.filter(f => f.endsWith('.js'));
-
- for (const file of jsFiles) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
-
- // Check for balanced braces in import statements (basic check)
- const importMatches = content.match(/import\s*{[^}]*}/g) || [];
- for (const importMatch of importMatches) {
- const openBraces = (importMatch.match(/{/g) || []).length;
- const closeBraces = (importMatch.match(/}/g) || []).length;
- assert(openBraces === closeBraces,
- `${file}: Unbalanced braces in import: ${importMatch.substring(0, 50)}...`);
- }
-
- // Check that imports with 'from' have quotes
- const fromMatches = content.match(/import.*from\s+[^'"]/g) || [];
- if (fromMatches.length > 0) {
- console.warn(`⚠️ ${file} may have unquoted import sources`);
- }
- }
- });
-
- // Test 7: Function definitions look correct
- test('Function definitions have basic structure', async () => {
- const mainFiles = ['ui.js', 'translation.js', 'tts.js', 'chat.js'];
-
- for (const file of mainFiles) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
-
- // Check for function definitions
- const functionCount = (content.match(/function\s+\w+/g) || []).length;
- const arrowFunctionCount = (content.match(/=\s*\([^)]*\)\s*=>/g) || []).length;
- const asyncFunctionCount = (content.match(/async\s+function/g) || []).length;
-
- const totalFunctions = functionCount + arrowFunctionCount + asyncFunctionCount;
- assert(totalFunctions > 0, `${file} has no function definitions`);
- }
- });
-
- // Test 8: No obvious console.log statements in production code
- test('No debug console.log statements in main files', async () => {
- const mainFiles = ['ui.js', 'translation.js', 'tts.js'];
-
- for (const file of mainFiles) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
- const consoleLogCount = (content.match(/console\.log\s*\(/g) || []).length;
-
- // Allow some console logs but warn if too many
- if (consoleLogCount > 3) {
- console.warn(`⚠️ ${file} has ${consoleLogCount} console.log statements (consider removing for production)`);
- }
- }
- });
-
- // Test 9: Language files have proper structure
- test('Language files export correct structure', async () => {
- const langDir = path.join(srcDir, 'languages');
- const files = await fs.readdir(langDir);
- const langFiles = files.filter(f => f.endsWith('.js') && f !== 'index.js' && !f.includes('verify') && !f.includes('add-missing'));
-
- for (const file of langFiles) {
- const content = await fs.readFile(path.join(langDir, file), 'utf-8');
-
- // Check for export statement
- assert(content.includes('export const'), `${file} missing export const statement`);
-
- // Check for object structure
- const objectPattern = /export\s+const\s+\w+\s*=\s*{/;
- assert(objectPattern.test(content), `${file} export is not a proper object`);
-
- // Check for translation keys (basic validation)
- const keyCount = (content.match(/\w+:\s*['"]/g) || []).length;
- assert(keyCount > 10, `${file} has too few translation keys: ${keyCount}`);
- }
- });
-
- // Test 10: Config files have required sections
- test('Config file has required structure', async () => {
- const content = await fs.readFile(path.join(srcDir, 'config.js'), 'utf-8');
-
- // Check for key config sections
- assert(content.includes('API_URL') || content.includes('CONFIG') || content.includes('SYSTEM_MESSAGE'),
- 'config.js missing main configuration exports');
- assert(content.includes('url') || content.includes('URL') || content.includes('endpoint'),
- 'config.js missing URL/endpoint configuration');
- });
-
- // Test 11: Modal files have required functions
- test('Modal files export required functions', async () => {
- const modalFiles = ['tts-modal.js', 'translate-modal.js', 'uncloseai-embed-modal.js'];
-
- for (const file of modalFiles) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
-
- // Check for main function export
- assert(content.includes('export'), `${file} has no exports`);
-
- // Check for modal-specific patterns
- if (file.includes('modal')) {
- assert(content.includes('modal') || content.includes('Modal'),
- `${file} doesn't contain modal-related code`);
- }
- }
- });
-
- // Test 12: Check for potential security issues
- test('No obvious security vulnerabilities', async () => {
- const allFiles = await fs.readdir(srcDir);
- const jsFiles = allFiles.filter(f => f.endsWith('.js'));
-
- for (const file of jsFiles) {
- const content = await fs.readFile(path.join(srcDir, file), 'utf-8');
-
- // Check for innerHTML usage (potential XSS)
- const innerHTMLCount = (content.match(/\.innerHTML\s*=/g) || []).length;
- if (innerHTMLCount > 0) {
- console.warn(`⚠️ ${file} uses innerHTML (${innerHTMLCount} times) - ensure proper sanitization`);
- }
-
- // Check for eval usage
- assert(!content.includes('eval('), `${file} contains eval() - security risk`);
-
- // Check for document.write (but allow in specific cases like new windows)
- const documentWriteMatches = content.match(/document\.write/g) || [];
- if (documentWriteMatches.length > 0 && !content.includes('previewWindow') && !content.includes('newWindow')) {
- assert(false, `${file} contains document.write - security/performance risk`);
- }
- }
- });
-
- // Test 13: File encoding and line endings
- test('Files have consistent encoding', async () => {
- const allFiles = await fs.readdir(srcDir);
- const jsFiles = allFiles.filter(f => f.endsWith('.js'));
-
- for (const file of jsFiles) {
- const buffer = await fs.readFile(path.join(srcDir, file));
- const content = buffer.toString('utf-8');
-
- // Check for BOM (Byte Order Mark)
- assert(!content.startsWith('\uFEFF'), `${file} contains BOM - should be removed`);
-
- // Check for non-ASCII characters that might cause issues
- const hasNonASCII = /[^\x00-\x7F]/.test(content);
- if (hasNonASCII && !file.includes('languages/')) {
- console.warn(`⚠️ ${file} contains non-ASCII characters (may be intentional)`);
- }
- }
- });
-
- // Wait for async tests to complete
- await new Promise(resolve => setTimeout(resolve, 100));
-
- console.log('\n📊 Simple Test Results:');
- console.log('='.repeat(30));
- console.log(`Total tests: ${tests}`);
- console.log(`Passed: ${passed} ✅`);
- console.log(`Failed: ${failed} ❌`);
-
- if (failed === 0) {
- console.log('\n🎉 All simple tests passed!');
- process.exit(0);
- } else {
- console.log('\n💥 Some tests failed.');
- process.exit(1);
- }
-}
-
-runSimpleTests().catch(console.error);
\ No newline at end of file
diff --git a/uncloseai.js.orig b/uncloseai.js.orig
deleted file mode 100644
index 545d1a0..0000000
--- a/uncloseai.js.orig
+++ /dev/null
@@ -1,2711 +0,0 @@
-/* how to use in HTML */
-
-/*
-
-
-
-
-
-
-
-
-
-*/
-
-import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
-import hljs from 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/es/highlight.min.js';
-
-// -------------------------
-// Configuration and Endpoints
-// -------------------------
-
-// Original API endpoints for other functionalities
-const TTS_API_URL = "https://speech.ai.unturf.com/v1/audio/speech";
-const MEGAPARCE_API_URL = "https://megaparce.ai.unturf.com/v1/file";
-const API_KEY = "dummy-api-key";
-const MODEL = "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic"; // default model (always available)
-
-let lastTTSInput = '';
-let lastTTSResult = null;
-
-// Dynamic Endpoints Configuration for Chat API
-// You can list as many endpoints as you need.
-// { id: 'hermes.ai.unturf.com', url: 'https://hermes.ai.unturf.com/v1' },
-
-const VLLM_ENDPOINTS = [
- { id: 'hermes.ai.unturf.com', url: 'https://hermes.ai.unturf.com/v1' },
- { id: 'hermes2.ai.unturf.com', url: 'https://hermes2.ai.unturf.com/v1' }
-];
-
-// -------------------------
-// Dynamic Endpoints and Model Registry
-// -------------------------
-
-// This registry maps a model's ID to the endpoint where it resides.
-const modelRegistry = {};
-
-// Fetch models from each endpoint with caching.
-// Cache is busted if the endpoint array changes or TTL.
-async function fetchModelsFromEndpoints() {
- const cacheKey = 'modelRegistryCache';
- const endpointsKey = 'vllmEndpointsHash';
- const endpointsString = JSON.stringify(VLLM_ENDPOINTS);
- const cachedEndpoints = localStorage.getItem(endpointsKey);
- const cacheItem = localStorage.getItem(cacheKey);
- const now = Date.now();
- const TTL = 300000; // 5 minutes in milliseconds
-
- if (cacheItem && cachedEndpoints === endpointsString) {
- try {
- const cachedData = JSON.parse(cacheItem);
- if (now - cachedData.timestamp < TTL) {
- // Restore cached modelRegistry
- Object.assign(modelRegistry, cachedData.modelRegistry);
- return cachedData.models;
- }
- } catch (e) {
- console.error("Error reading model registry from cache", e);
- }
- }
-
- // If no valid cache, fetch models from all endpoints
- const fetchPromises = VLLM_ENDPOINTS.map(async (endpoint) => {
- try {
- const res = await fetch(`${endpoint.url}/models`);
- if (!res.ok) throw new Error(`HTTP error! status: ${res.status} from ${endpoint.url}`);
- const jsonResponse = await res.json();
- // Expected JSON structure: { data: [ { id, ... }, ... ], object: "list" }
- const models = jsonResponse.data || [];
- // Map each model to include its endpoint ID, unique ID, and model name
- return models.map((model) => ({
- ...model,
- modelName: model.id, // Explicitly store model name
- endpointId: endpoint.id,
- uniqueId: `${endpoint.id}-${model.id}` // Unique ID with endpoint ID first
- }));
- } catch (error) {
- console.error(`Error fetching models from ${endpoint.url}:`, error);
- return [];
- }
- });
- const allModelsArrays = await Promise.all(fetchPromises);
- const models = allModelsArrays.flat();
-
- // Update modelRegistry with unique model instances
- models.forEach((model) => {
- modelRegistry[model.uniqueId] = {
- url: VLLM_ENDPOINTS.find((e) => e.id === model.endpointId).url,
- endpointId: model.endpointId
- };
- });
-
- // Cache the results
- const cacheData = {
- timestamp: now,
- modelRegistry: modelRegistry,
- models: models
- };
- localStorage.setItem(cacheKey, JSON.stringify(cacheData));
- localStorage.setItem(endpointsKey, endpointsString);
-
- return models;
-}
-
-// Create a dynamic drop-down for model selection
-// This function creates a