You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/vite.config.ts

139 lines
5.8 KiB

import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vitest/config';
import { playwright } from '@vitest/browser-playwright';
import { sveltekit } from '@sveltejs/kit/vite';
import { fileURLToPath } from 'url';
import { resolve, dirname } from 'path';
// __dirname no existe en ESM — se reconstruye así
const __dirname = dirname(fileURLToPath(import.meta.url));
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
resolve: {
alias: {
deprecate src/lib + wire new ecosystem aliases (Phase 0+1) Phase 0 — mark legacy as deprecated: - Add @deprecated JSDoc header to all 27 top-level barrels under src/lib (ext/{app,lang,dates,money,nums,units,presentation}, {actx,ling,logr,glob,sium,util}, root index.ts). - Add src/lib/README.md with the migration map: legacy module → new equivalent under src/arts + src/libs + src/svrs. - Zero behavior change. Only IDE strikethrough at usage sites. Phase 1 — wire new ecosystem aliases in vite.config.ts and svelte.config.js: - 18 new $arts/* aliases: $active-app, $adom, $auth, $bus, $cache, $connection, $format, $frontend, $http, $lang, $logger, $orca, $perm, $prefs, $session, $sium, $storage, $timer. - $libs (src/libs), $locale (src/libs/locale), $svrs (src/svrs). - $reactive rewired from src/lib/util/reactive to src/libs/reactive (export surfaces verified compatible — same symbols, drop-in). - Legacy aliases ($lib, $glob, $langs, @/ling, @/logr, @/glob, @/actx, @/uiux) preserved for backwards compat during migration. - SvelteKit auto-regenerates .svelte-kit/tsconfig.json paths from svelte.config.js, so TS resolution updates without manual edits. The migration plan (Phases 2-6) lives in src/lib/README.md: Phase 2 — sweep src/lib/util/* imports to $libs/* (drop-in). Phase 3 — morfo/schema.ts: 3 imports to $libs/standard-schema. Phase 4 — soma's App.create() composition to createActiveApp with explicit service slots (including semantic for sema). Only step that changes architecture. Phase 5 — sweep ~82 test pages to use new aliases. Phase 6 — remove src/lib/{glob,ling,actx} after verifying no consumers; investigate sium and util/{dates,times,timers}. Verification: smoke 68/68, morfo-check 66/66. svelte-check baseline unchanged for the alias rewire (no Cannot-find-module errors). The 2 dialog-provider possibly-undefined errors at lines 113-114 are pre-existing (this.soma vs this.soma! after Soma.get() returning Soma | undefined) — not introduced by this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// ── New ecosystem (src/arts + src/libs + src/svrs) ─────────────
// Runtime artifacts (Engine* + Active*) — see src/arts/README.md
'$active-app': resolve(__dirname, 'src/arts/active-app'),
'$adom': resolve(__dirname, 'src/arts/adom'),
'$auth': resolve(__dirname, 'src/arts/auth'),
'$bus': resolve(__dirname, 'src/arts/bus'),
'$cache': resolve(__dirname, 'src/arts/cache'),
'$connection': resolve(__dirname, 'src/arts/connection'),
'$format': resolve(__dirname, 'src/arts/format'),
'$frontend': resolve(__dirname, 'src/arts/frontend'),
'$http': resolve(__dirname, 'src/arts/http'),
'$lang': resolve(__dirname, 'src/arts/lang'),
'$logger': resolve(__dirname, 'src/arts/logger'),
'$orca': resolve(__dirname, 'src/arts/orca'),
'$perm': resolve(__dirname, 'src/arts/perm'),
'$prefs': resolve(__dirname, 'src/arts/prefs'),
'$session': resolve(__dirname, 'src/arts/session'),
'$sium': resolve(__dirname, 'src/arts/sium'),
'$storage': resolve(__dirname, 'src/arts/storage'),
'$timer': resolve(__dirname, 'src/arts/timer'),
// Pure helpers + contracts (zero-dep)
'$libs': resolve(__dirname, 'src/libs'),
'$locale': resolve(__dirname, 'src/libs/locale'),
// Server-authoritative engines
'$svrs': resolve(__dirname, 'src/svrs'),
deprecate src/lib + wire new ecosystem aliases (Phase 0+1) Phase 0 — mark legacy as deprecated: - Add @deprecated JSDoc header to all 27 top-level barrels under src/lib (ext/{app,lang,dates,money,nums,units,presentation}, {actx,ling,logr,glob,sium,util}, root index.ts). - Add src/lib/README.md with the migration map: legacy module → new equivalent under src/arts + src/libs + src/svrs. - Zero behavior change. Only IDE strikethrough at usage sites. Phase 1 — wire new ecosystem aliases in vite.config.ts and svelte.config.js: - 18 new $arts/* aliases: $active-app, $adom, $auth, $bus, $cache, $connection, $format, $frontend, $http, $lang, $logger, $orca, $perm, $prefs, $session, $sium, $storage, $timer. - $libs (src/libs), $locale (src/libs/locale), $svrs (src/svrs). - $reactive rewired from src/lib/util/reactive to src/libs/reactive (export surfaces verified compatible — same symbols, drop-in). - Legacy aliases ($lib, $glob, $langs, @/ling, @/logr, @/glob, @/actx, @/uiux) preserved for backwards compat during migration. - SvelteKit auto-regenerates .svelte-kit/tsconfig.json paths from svelte.config.js, so TS resolution updates without manual edits. The migration plan (Phases 2-6) lives in src/lib/README.md: Phase 2 — sweep src/lib/util/* imports to $libs/* (drop-in). Phase 3 — morfo/schema.ts: 3 imports to $libs/standard-schema. Phase 4 — soma's App.create() composition to createActiveApp with explicit service slots (including semantic for sema). Only step that changes architecture. Phase 5 — sweep ~82 test pages to use new aliases. Phase 6 — remove src/lib/{glob,ling,actx} after verifying no consumers; investigate sium and util/{dates,times,timers}. Verification: smoke 68/68, morfo-check 66/66. svelte-check baseline unchanged for the alias rewire (no Cannot-find-module errors). The 2 dialog-provider possibly-undefined errors at lines 113-114 are pre-existing (this.soma vs this.soma! after Soma.get() returning Soma | undefined) — not introduced by this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// ── UIX layers ──────────────────────────────────────────────────
active-uix: introduce UIX layer between active-app and components Decouples the UIX layer (soma / morfo runtime / sema / eidos) from the App composition layer (`active-app`). UIX components no longer import `\$active-app` directly — they read services through `getActiveUix()`. Two boot paths produce the same `ActiveUix`: - **Standalone** — `createActiveUix({ lang, semantic, … })` bootstraps an `ActiveApp` internally with the UIX services plus any `extraServices`. Owns the app — `dispose()` propagates. - **Attach** — `attachActiveUix(externalApp)` wraps an app the application composed itself (typically when it has services beyond UIX: cache, session, http, …). The external app must declare the UIX services; helper `defineUixServices(options)` returns the slice ready to spread into `createActiveApp({ services })`. Does NOT own the app. In both cases components see only `ActiveUix`. They have no way to tell which boot path was used. Module: src/uix/active-uix/ ├── index.ts barrel ($active-uix) ├── types.ts ActiveUix, ActiveUixOptions, AttachActiveUixOptions ├── services.ts defineUixServices() + UIX_REQUIRED_SERVICES ├── active-uix.svelte.ts createActiveUix() + attachActiveUix() + ActiveUixImpl ├── components/uix.svelte <Uix uix={...}> wrapper (sets context + creates Soma) └── svelte/context.svelte.ts setActiveUix() / getActiveUix() / tryGetActiveUix() Surface exposed by `ActiveUix`: - UIX services: lang, frontend, format (optional), dom, semantic - Core: logger, bus, timers, prefs - Config: somaPortalTo - `app` escape hatch for advanced integration code (NOT for UIX components) Wiring done by active-uix at boot: - `App.lang.extend('components', componentLangs)` — soma component translations always available without per-app boilerplate. - Frontend service auto-configured with `applyDom: true` + `target: () => document.documentElement` so theme/dir/density land on `<html>` automatically. Migration: - `Soma.create()` reads `getActiveUix()` instead of `getActiveApp()`. Soma class no longer imports `\$active-app`. - 3 layouts (test/eidos, test/sium, test/soma) replace `createActiveApp + setActiveApp + <Soma>` with `createActiveUix + <Uix>`. Boilerplate drops ~20 lines per layout. - 7 sium pages replace `getActiveApp() + app.lang.setLocale(…)` with `getActiveUix() + uix.lang.setLocale(…)`. Validation: - `attachActiveUix(app)` throws `ActiveUixMissingServiceError` if the external app didn't declare lang/frontend/dom/semantic. - `getActiveUix()` throws `ActiveUixNoContextError` if no `<Uix>` ancestor mounted. `\$active-uix` alias wired in svelte.config.js + vite.config.ts (both client and server projects). Verified: vitest 197/197, smoke 68/68, morfo-check 66/66, playwright probe (4 routes including dialog with sound) zero page/console errors.
5 months ago
'$uix': resolve(__dirname, 'src/uix'),
'$active-uix': resolve(__dirname, 'src/uix/active-uix'),
'$soma': resolve(__dirname, 'src/uix/soma'),
'$terra': resolve(__dirname, 'src/uix/terra'),
deprecate src/lib + wire new ecosystem aliases (Phase 0+1) Phase 0 — mark legacy as deprecated: - Add @deprecated JSDoc header to all 27 top-level barrels under src/lib (ext/{app,lang,dates,money,nums,units,presentation}, {actx,ling,logr,glob,sium,util}, root index.ts). - Add src/lib/README.md with the migration map: legacy module → new equivalent under src/arts + src/libs + src/svrs. - Zero behavior change. Only IDE strikethrough at usage sites. Phase 1 — wire new ecosystem aliases in vite.config.ts and svelte.config.js: - 18 new $arts/* aliases: $active-app, $adom, $auth, $bus, $cache, $connection, $format, $frontend, $http, $lang, $logger, $orca, $perm, $prefs, $session, $sium, $storage, $timer. - $libs (src/libs), $locale (src/libs/locale), $svrs (src/svrs). - $reactive rewired from src/lib/util/reactive to src/libs/reactive (export surfaces verified compatible — same symbols, drop-in). - Legacy aliases ($lib, $glob, $langs, @/ling, @/logr, @/glob, @/actx, @/uiux) preserved for backwards compat during migration. - SvelteKit auto-regenerates .svelte-kit/tsconfig.json paths from svelte.config.js, so TS resolution updates without manual edits. The migration plan (Phases 2-6) lives in src/lib/README.md: Phase 2 — sweep src/lib/util/* imports to $libs/* (drop-in). Phase 3 — morfo/schema.ts: 3 imports to $libs/standard-schema. Phase 4 — soma's App.create() composition to createActiveApp with explicit service slots (including semantic for sema). Only step that changes architecture. Phase 5 — sweep ~82 test pages to use new aliases. Phase 6 — remove src/lib/{glob,ling,actx} after verifying no consumers; investigate sium and util/{dates,times,timers}. Verification: smoke 68/68, morfo-check 66/66. svelte-check baseline unchanged for the alias rewire (no Cannot-find-module errors). The 2 dialog-provider possibly-undefined errors at lines 113-114 are pre-existing (this.soma vs this.soma! after Soma.get() returning Soma | undefined) — not introduced by this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// ── @/ catch-all ────────────────────────────────────────────────
'@': resolve(__dirname, 'src'),
deprecate src/lib + wire new ecosystem aliases (Phase 0+1) Phase 0 — mark legacy as deprecated: - Add @deprecated JSDoc header to all 27 top-level barrels under src/lib (ext/{app,lang,dates,money,nums,units,presentation}, {actx,ling,logr,glob,sium,util}, root index.ts). - Add src/lib/README.md with the migration map: legacy module → new equivalent under src/arts + src/libs + src/svrs. - Zero behavior change. Only IDE strikethrough at usage sites. Phase 1 — wire new ecosystem aliases in vite.config.ts and svelte.config.js: - 18 new $arts/* aliases: $active-app, $adom, $auth, $bus, $cache, $connection, $format, $frontend, $http, $lang, $logger, $orca, $perm, $prefs, $session, $sium, $storage, $timer. - $libs (src/libs), $locale (src/libs/locale), $svrs (src/svrs). - $reactive rewired from src/lib/util/reactive to src/libs/reactive (export surfaces verified compatible — same symbols, drop-in). - Legacy aliases ($lib, $glob, $langs, @/ling, @/logr, @/glob, @/actx, @/uiux) preserved for backwards compat during migration. - SvelteKit auto-regenerates .svelte-kit/tsconfig.json paths from svelte.config.js, so TS resolution updates without manual edits. The migration plan (Phases 2-6) lives in src/lib/README.md: Phase 2 — sweep src/lib/util/* imports to $libs/* (drop-in). Phase 3 — morfo/schema.ts: 3 imports to $libs/standard-schema. Phase 4 — soma's App.create() composition to createActiveApp with explicit service slots (including semantic for sema). Only step that changes architecture. Phase 5 — sweep ~82 test pages to use new aliases. Phase 6 — remove src/lib/{glob,ling,actx} after verifying no consumers; investigate sium and util/{dates,times,timers}. Verification: smoke 68/68, morfo-check 66/66. svelte-check baseline unchanged for the alias rewire (no Cannot-find-module errors). The 2 dialog-provider possibly-undefined errors at lines 113-114 are pre-existing (this.soma vs this.soma! after Soma.get() returning Soma | undefined) — not introduced by this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// ── Legacy ecosystem (src/lib) — DEPRECATED ─────────────────────
// All paths below should migrate to the new ecosystem above.
// See src/lib/README.md for the migration map.
'$lib': resolve(__dirname, 'src/lib'),
'$glob': resolve(__dirname, 'src/lib/glob'),
'$reactive': resolve(__dirname, 'src/libs/reactive'),
'$langs': resolve(__dirname, 'src/lib/ext/lang/lang.svelte'),
'@/ling': resolve(__dirname, 'src/lib/ling'),
'@/logr': resolve(__dirname, 'src/lib/logr'),
'@/glob': resolve(__dirname, 'src/lib/glob'),
'@/actx': resolve(__dirname, 'src/lib/actx'),
'@/uiux': resolve(__dirname, 'src/lib/uiux'),
},
},
test: {
expect: { requireAssertions: true },
projects: [
{
extends: './vite.config.ts',
test: {
name: 'client',
browser: {
enabled: true,
provider: playwright(),
instances: [{ browser: 'chromium', headless: true }]
},
include: ['src/**/*.svelte.{test,spec}.{js,ts}'],
exclude: ['src/lib/server/**']
}
},
{
extends: './vite.config.ts',
resolve: {
alias: {
deprecate src/lib + wire new ecosystem aliases (Phase 0+1) Phase 0 — mark legacy as deprecated: - Add @deprecated JSDoc header to all 27 top-level barrels under src/lib (ext/{app,lang,dates,money,nums,units,presentation}, {actx,ling,logr,glob,sium,util}, root index.ts). - Add src/lib/README.md with the migration map: legacy module → new equivalent under src/arts + src/libs + src/svrs. - Zero behavior change. Only IDE strikethrough at usage sites. Phase 1 — wire new ecosystem aliases in vite.config.ts and svelte.config.js: - 18 new $arts/* aliases: $active-app, $adom, $auth, $bus, $cache, $connection, $format, $frontend, $http, $lang, $logger, $orca, $perm, $prefs, $session, $sium, $storage, $timer. - $libs (src/libs), $locale (src/libs/locale), $svrs (src/svrs). - $reactive rewired from src/lib/util/reactive to src/libs/reactive (export surfaces verified compatible — same symbols, drop-in). - Legacy aliases ($lib, $glob, $langs, @/ling, @/logr, @/glob, @/actx, @/uiux) preserved for backwards compat during migration. - SvelteKit auto-regenerates .svelte-kit/tsconfig.json paths from svelte.config.js, so TS resolution updates without manual edits. The migration plan (Phases 2-6) lives in src/lib/README.md: Phase 2 — sweep src/lib/util/* imports to $libs/* (drop-in). Phase 3 — morfo/schema.ts: 3 imports to $libs/standard-schema. Phase 4 — soma's App.create() composition to createActiveApp with explicit service slots (including semantic for sema). Only step that changes architecture. Phase 5 — sweep ~82 test pages to use new aliases. Phase 6 — remove src/lib/{glob,ling,actx} after verifying no consumers; investigate sium and util/{dates,times,timers}. Verification: smoke 68/68, morfo-check 66/66. svelte-check baseline unchanged for the alias rewire (no Cannot-find-module errors). The 2 dialog-provider possibly-undefined errors at lines 113-114 are pre-existing (this.soma vs this.soma! after Soma.get() returning Soma | undefined) — not introduced by this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// New ecosystem
'$active-app': resolve(__dirname, 'src/arts/active-app'),
'$adom': resolve(__dirname, 'src/arts/adom'),
'$auth': resolve(__dirname, 'src/arts/auth'),
'$bus': resolve(__dirname, 'src/arts/bus'),
'$cache': resolve(__dirname, 'src/arts/cache'),
'$connection': resolve(__dirname, 'src/arts/connection'),
'$format': resolve(__dirname, 'src/arts/format'),
'$frontend': resolve(__dirname, 'src/arts/frontend'),
'$http': resolve(__dirname, 'src/arts/http'),
'$lang': resolve(__dirname, 'src/arts/lang'),
'$logger': resolve(__dirname, 'src/arts/logger'),
'$orca': resolve(__dirname, 'src/arts/orca'),
'$perm': resolve(__dirname, 'src/arts/perm'),
'$prefs': resolve(__dirname, 'src/arts/prefs'),
'$session': resolve(__dirname, 'src/arts/session'),
'$sium': resolve(__dirname, 'src/arts/sium'),
'$storage': resolve(__dirname, 'src/arts/storage'),
'$timer': resolve(__dirname, 'src/arts/timer'),
'$libs': resolve(__dirname, 'src/libs'),
'$locale': resolve(__dirname, 'src/libs/locale'),
'$svrs': resolve(__dirname, 'src/svrs'),
// UIX
active-uix: introduce UIX layer between active-app and components Decouples the UIX layer (soma / morfo runtime / sema / eidos) from the App composition layer (`active-app`). UIX components no longer import `\$active-app` directly — they read services through `getActiveUix()`. Two boot paths produce the same `ActiveUix`: - **Standalone** — `createActiveUix({ lang, semantic, … })` bootstraps an `ActiveApp` internally with the UIX services plus any `extraServices`. Owns the app — `dispose()` propagates. - **Attach** — `attachActiveUix(externalApp)` wraps an app the application composed itself (typically when it has services beyond UIX: cache, session, http, …). The external app must declare the UIX services; helper `defineUixServices(options)` returns the slice ready to spread into `createActiveApp({ services })`. Does NOT own the app. In both cases components see only `ActiveUix`. They have no way to tell which boot path was used. Module: src/uix/active-uix/ ├── index.ts barrel ($active-uix) ├── types.ts ActiveUix, ActiveUixOptions, AttachActiveUixOptions ├── services.ts defineUixServices() + UIX_REQUIRED_SERVICES ├── active-uix.svelte.ts createActiveUix() + attachActiveUix() + ActiveUixImpl ├── components/uix.svelte <Uix uix={...}> wrapper (sets context + creates Soma) └── svelte/context.svelte.ts setActiveUix() / getActiveUix() / tryGetActiveUix() Surface exposed by `ActiveUix`: - UIX services: lang, frontend, format (optional), dom, semantic - Core: logger, bus, timers, prefs - Config: somaPortalTo - `app` escape hatch for advanced integration code (NOT for UIX components) Wiring done by active-uix at boot: - `App.lang.extend('components', componentLangs)` — soma component translations always available without per-app boilerplate. - Frontend service auto-configured with `applyDom: true` + `target: () => document.documentElement` so theme/dir/density land on `<html>` automatically. Migration: - `Soma.create()` reads `getActiveUix()` instead of `getActiveApp()`. Soma class no longer imports `\$active-app`. - 3 layouts (test/eidos, test/sium, test/soma) replace `createActiveApp + setActiveApp + <Soma>` with `createActiveUix + <Uix>`. Boilerplate drops ~20 lines per layout. - 7 sium pages replace `getActiveApp() + app.lang.setLocale(…)` with `getActiveUix() + uix.lang.setLocale(…)`. Validation: - `attachActiveUix(app)` throws `ActiveUixMissingServiceError` if the external app didn't declare lang/frontend/dom/semantic. - `getActiveUix()` throws `ActiveUixNoContextError` if no `<Uix>` ancestor mounted. `\$active-uix` alias wired in svelte.config.js + vite.config.ts (both client and server projects). Verified: vitest 197/197, smoke 68/68, morfo-check 66/66, playwright probe (4 routes including dialog with sound) zero page/console errors.
5 months ago
'$uix': resolve(__dirname, 'src/uix'),
'$active-uix': resolve(__dirname, 'src/uix/active-uix'),
'$soma': resolve(__dirname, 'src/uix/soma'),
'$terra': resolve(__dirname, 'src/uix/terra'),
deprecate src/lib + wire new ecosystem aliases (Phase 0+1) Phase 0 — mark legacy as deprecated: - Add @deprecated JSDoc header to all 27 top-level barrels under src/lib (ext/{app,lang,dates,money,nums,units,presentation}, {actx,ling,logr,glob,sium,util}, root index.ts). - Add src/lib/README.md with the migration map: legacy module → new equivalent under src/arts + src/libs + src/svrs. - Zero behavior change. Only IDE strikethrough at usage sites. Phase 1 — wire new ecosystem aliases in vite.config.ts and svelte.config.js: - 18 new $arts/* aliases: $active-app, $adom, $auth, $bus, $cache, $connection, $format, $frontend, $http, $lang, $logger, $orca, $perm, $prefs, $session, $sium, $storage, $timer. - $libs (src/libs), $locale (src/libs/locale), $svrs (src/svrs). - $reactive rewired from src/lib/util/reactive to src/libs/reactive (export surfaces verified compatible — same symbols, drop-in). - Legacy aliases ($lib, $glob, $langs, @/ling, @/logr, @/glob, @/actx, @/uiux) preserved for backwards compat during migration. - SvelteKit auto-regenerates .svelte-kit/tsconfig.json paths from svelte.config.js, so TS resolution updates without manual edits. The migration plan (Phases 2-6) lives in src/lib/README.md: Phase 2 — sweep src/lib/util/* imports to $libs/* (drop-in). Phase 3 — morfo/schema.ts: 3 imports to $libs/standard-schema. Phase 4 — soma's App.create() composition to createActiveApp with explicit service slots (including semantic for sema). Only step that changes architecture. Phase 5 — sweep ~82 test pages to use new aliases. Phase 6 — remove src/lib/{glob,ling,actx} after verifying no consumers; investigate sium and util/{dates,times,timers}. Verification: smoke 68/68, morfo-check 66/66. svelte-check baseline unchanged for the alias rewire (no Cannot-find-module errors). The 2 dialog-provider possibly-undefined errors at lines 113-114 are pre-existing (this.soma vs this.soma! after Soma.get() returning Soma | undefined) — not introduced by this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
// @/
'@': resolve(__dirname, 'src'),
// Legacy (DEPRECATED)
'$lib': resolve(__dirname, 'src/lib'),
'$glob': resolve(__dirname, 'src/lib/glob'),
'$reactive': resolve(__dirname, 'src/libs/reactive'),
'@/ling': resolve(__dirname, 'src/lib/ling'),
'@/logr': resolve(__dirname, 'src/lib/logr'),
'@/glob': resolve(__dirname, 'src/lib/glob'),
'@/actx': resolve(__dirname, 'src/lib/actx'),
'@/uiux': resolve(__dirname, 'src/lib/uiux'),
},
},
test: {
name: 'server',
environment: 'node',
include: ['src/**/*.{test,spec}.{js,ts}'],
exclude: ['src/**/*.svelte.{test,spec}.{js,ts}']
}
}
]
}
});

Powered by TurnKey Linux.