Skip to content

wuchale

  • c46696a: Fix new mixed visitor visiting ignored elements when nested #408
  • 40b5c42: Fix runtime not initialized inside funcs with only patterns without messages
  • b6372c2: Fix runtime not initialized error on messages inside hoisted function calls at the top #404
  • d4ef202: Fix inconsistent handling of nested messages with non-nestable block types #402
  • fa12c12: Limit nesting to only element-like nodes to fix unexpected errors (e.g. around {#if})
  • 2d436dc: Fix nested messages applying unnecessary edits #398
  • a8db752: Fix undefined shown in nested messages #395 #396
  • Redo nested message visit algorithm (#393)

    This release is all about the core of wuchale, i.e. the nested message visitor. It has now been vastly improved with a more solid approach.

  • Fix repeated messages when grouping locales for AI translate (ff749d6)

  • Fix long build times caused by wuchale #391 (d4682fa)

  • Fix Vite build error when using granular group patterns with multiple adapters (b3d54ef)
  • Include placeholders in nested messages also indicating nesting like 0.0.1 (2005ea1)

  • ⚠️ BREAKING: Replace outDir config on adapters with CLI flag --modify (89b650b)

    If you want to write the transformed files back to disk, you can specify the flag in the CLI, npx wuchale --modify {adapter1},{adapter2},... and the files for those adapters will be modified in-place. This OVERWRITES the files, therefore only use it when you are certain, and have Git already setup and in a clean state, so that you can restore them. Normally you should use it only to when you use an unsupported bundler and in that case you should only run it in CI just before deployment. Or you can use it for debugging (and restore with Git.)

  • Add property in heuristic details and use it to detect URLs from property names if it’s href, url or link (94ce7fc)

  • Extract template literals that start with a placeholder expression followed by natural language content. (#381)

    Messages like {0} was successfully deleted! were previously ignored because the first character { is not a letter. They are now extracted when the leading placeholder is followed by spaces and letters.

  • ⚠️ BREAKING: proxies now export loadCount instead of loadIDs after #355 (f903655)

    The default loaders have been updated to match but if you use loadLocales in SvelteKit hooks or Astro middlewares, you should update them like:

    await loadLocales(main.key, main.loadIDs, main.loadCatalog, locales)
    await loadLocales(main.key, main.loadCount, main.loadCatalog, locales)
  • ⚠️ BREAKING: Composable storage: dir config in pofile and json storage changed to location, separateUrls removed. (#382)

    The dir config which was used to set the directory under which to save catalog storages is now replaced by location which gives more control. In pofile it should be a file path pattern with {locale} as a placeholder. If you use separateUrls (which was true by default), you should now use the new storageByType layer:

    import { pofile } from 'wuchale'
    import { pofile, storageByType } from 'wuchale'
    export default {
    // ...
    adapters: {
    main: svelte({
    // ...
    storage: pofile({dir: 'src/locales'}),
    storage: storageByType({
    message: pofile({location: 'src/locales/{locale}.po'}),
    url: pofile({location: 'src/locales/{locale}.url.po'})
    }),
    }),
    }
    }

    storageByType returns a storage itself, but if you don’t need to separate the items, you can opt not to use it. But it also opens the possibility of storing URL translations in another format for example.

  • Update default Gemini model to 3.5 flash (589fbca)

  • ⚠️ BREAKING: Rename config hmr to dev with the following options to control behavior during dev: (#377)

    • false: Same behavior as the previous hmr: false
    • 'read': Only uses existing translations and doesn’t add newly detected messages during dev
    • 'add': Adds newly detected messages and updates their refs as they get referenced, but doesn’t touch existing messages
    • 'refs': Same behavior as the previous hmr: true, adds new messages, updates refs and marks obsoletes
    • 'clean': Full behavior same as npx wuchale --clean, deletes unused messages
  • ⚠️ BREAKING: Built-in URL matcher (#363)

    A small purpose-built no-RegExp URL matcher is now included and the glob-like syntax it accepts is different from/simpler than that of path-to-regexp.

    • * for required segments like /foo-* matches /foo-bar
    • ? for optional segments like /foo/? matches /foo and /foo/bar
    • ** for nested like /foo/** matches /foo, /foo/bar and /foo/1/bar

    If you use URL patterns, you have to adjust your config accordingly:

    export default {
    // ...
    adapters: {
    main: svelte({
    // ...
    url: {
    // ...
    patterns: [
    'foo/*rest',
    'foo/**',
    ]
    },
    }),
    }
    }
  • ⚠️ BREAKING: reorganize loading config, use glob patterns and number load IDs (#355)

    • granularLoad is now loading.granular
    • bundleLoad is now loading.direct
    • generateLoadID is replaced by a glob config at loading.group

    Therefore if you use any of these, update your config like this:

    import { defineConfig, defaultGenerateLoadID, pofile } from "wuchale"
    import { defineConfig, pofile } from "wuchale"
    import { adapter as svelte } from '@wuchale/svelte'
    export default defineConfig({
    // ...
    adapters: {
    main: svelte({
    // ...
    bundleLoad: true,
    granularLoad: true,
    generateLoadID: filename => {
    if (filename.includes('grouped')) {
    return 'grouped'
    }
    return defaultGenerateLoadID(filename)
    },
    loading: {
    granular: true,
    direct: true,
    group: [
    '**/*grouped*',
    ]
    }
    }),
    }
    })
  • Fix files adapter config not respected when it’s a bare string (3567c7f)

  • Use the same fallback chains for URL translations (2521033)

  • Extract strings in export const in Astro frontmatter only if they are inside functions and init runtime inside to prevent errors #372 (500616b)
  • Fix TS satisfies expressions not visited (cc89f6e)
  • Make adapter conflicts CLI warnings instead of throwing an error (e6e62d4)

  • Fix wrong files config caused by config merge function regression #357 (7927908)

  • Fix wrong import path in generated files (9b19633)
  • Allow async initialization of storage handlers (e5306c2)

  • Add support for configuring what query params are trimmed in the vite plugin (2d8462e)

  • Add migrateStorage function to assist migrating between different storages (ba05cf2)

    This function can itself be used as a storage config. For example, to migrate from the PO file to JSON:

    wuchale.config.js
    import { defineConfig, pofile, migrateStorage } from "wuchale";
    import { json } from "@wuchale/json";
    export default defineConfig({
    // ...
    adapters: {
    main: svelte({
    // ...
    storage: migrateStorage([pofile()], json()),
    }),
    },
    });

    After running npx wuchale with this config, it can be replaced by the target storage config.

  • Fix wrong handler order when running npx wuchale check --full #342 (18368ae)
  • Fix incorrect behavior on npx wuchale check --full #342 (#344)
  • Windows: fix wrong import path separator for url manifests (5abd24a)
  • Fix AI translate not strictly respecting batchSize config (#329)
  • Fix parsing errors when </script> appears in HMR strings in script blocks (ad74ebb)
  • Include no HMR code when on SSR (bbc828d)
  • Fix items not marked obsolete for no longer existent files on cli without --clean (23ebbab)

  • Fix pofile storage not following localesDir by default (#305)

  • Fix AI translate not working after removing item.id property (ad8d5f7)

  • Fix deleted file not resulting in catalog item obsolete/cleaning #313. Now both file deletion and files pattern updates result in obsoletes/catalog cleaning (a7d8d47)
  • Fix HMR being disabled when running cli while dev server is running #306 (25a1425)
  • Vite: Fix unnecessary full reloads instead of HMR (49e03bb)
  • Fix full reload happening when writing to confUpdate.json (ffc5d2a)

  • Fix unclosed tags of nested messages not considered an error on compile (f510e3a)

  • Fix localesDir not being resolved from project root when it’s not cwd (5ad8f3a)

  • Always normalize separators to fix files patterns not matching on windows (9c7b6e9)

  • Fix wrong handling of adjacent expressions in tagged templates at runtime (43fabca)

  • Fix different paths resolving to the same location being considered different pofile storage keys (808edcf)

  • Fix regression: transform errors not formatted for Vite (8f2cfd6)

  • Fix pofile storage round trip issues and make it resistant to missing items in some catalogs (f0feafb)

  • Fix AI translate being rejected for locales with more than 2 plural forms, and bad translations being persisted after retries (92dbf5f)

  • Fix crash when sourceLocale is not the first in locales array (31ed422)

  • Fix error thrown on String.raw with extracted string at runtime (62c3691)

  • Fix $props with default value string being wrapped in $derived (44ceec8)

  • Add npx wuchale check command to check translation structures for missing placeholders etc. #274 (d53178a)

  • Remove .id field of items (relevant only if you use a custom storage) (2f195f3)

  • Add wuchale check --full command to check if there are any unchecked changes, visits all files to see if there are unextracted messages #274 (346f49f)

  • Add support for JSON output on status command (85c7473)

    The command npx wuchale status now accepts the --json flag and can print the info in a structured JSON format. This can be used to use for e.g. to check the number of untranslated items using jq in CI etc.

  • Write catalog manifest files to know which index in compiled catalog comes from which key in catalog (#288)

  • BREAKING: Merge vite plugin logic into core to share with cli (#289)

    The vite plugin will no longer be a separate package. It is now included in the wuchale package. You should update your vite plugin:

    vite.config.js
    import {wuchale} from '@wuchale/vite-plugin'
    import {wuchale} from 'wuchale/vite'
  • Validate plural rules and check for anything suspecious (89fec64)

    Plural rules that come from the catalogs set by translators are now validated to be ternary expressions in the expected format for correctness, as well as security reasons (although the risk is low)

  • Fix error by adding ; when there is iife right after runtime init (#293)

  • Fix error when adding a new locale to an existing project #294 (eb49dc8)

  • Fix wrong topLevelCall in heuristic details on destructuring assignments (b7f362c)

  • Trim ?t=... in addition to ?v=... before matching files in vite plugin (thanks @mustafa0x) (#290)

  • Fix expressions inside TS as and <assert> expressions not checked when setting heuristic topLevelCall which led to Svelte $derived(...) as Type being wrapped in another $derived (333c64a)

  • Fix strings inside arrow function arguments to top level calls (e.g. $effect(() => {...})) not being extracted (d8a45ef)

  • Make AI translate more robust against malformed LLM output (67f0a99)
  • Add support for grouping locales for AI translation (1dcd46c)

    You can now group target locales in the same prompt:

    export default {
    // ...
    ai: {
    // ...
    group: {
    // en is the source
    en: [
    ["fr", "fr-FR", "fr-CH"],
    ["de", "fr-DE"],
    ],
    },
    },
    };
  • Add support for keeping whole markups as single units (9bb41c5)

    You can now use the new comment directive:

    <!-- @wc-unit -->
    <div>
    <p>Parag 1</p>
    <p>Parag 2</p>
    <p>Parag 3</p>
    </div>

    And it the whole will be extracted as a single message

  • Add support for pluggable storage handlers (#271)

    While the PO for format is a solid choice for most cases, there may be some cases where another format is desired. Therefore, support for storing messages in PO files will continue to be provided out of the box but there will be an interface where another format can be plugged instead. The basic usage will be as a config option to the adapter like:

    export default {
    // ...
    adapters: {
    main: svelte({
    // ...
    storage: pofile({ dir: "..." }),
    }),
    },
    };

    And the storage key can accept any implementation that supports the expected shape for a storage collection.

  • Validate AI translation response for correct placeholders and structure (e7d8d85)

  • localesDir is now always shared, and data.js doesn’t export sourceLocale (121e98e)

    You can put the catalogs in different locations by configuring the dir for the pofile storage as mentioned. But everything wuchale works on is inside a single dir, configurable from the top level config localesDir:

    export default {
    // ...
    localesDir: "src/locales",
    };

    All files inside that dir are per adapter, except data.js which exported shared data, locales and sourceLocale. Now sourceLocale is not exported because it may be different among adapters. You may have to adjust something if you use it.

  • Add support for importing a URL localize function from any module at runtime (347ca5e)

    This adds support for cases where complete flexibility is needed for URLs, for example when the site targets different domain names for different locales, and when one locale can be used in different domains. Now a custom localize function that does the localization can be implemented, and wuchale only handles the translation. This can be used by providing the module path:

    export default {
    // ...
    adapters: {
    svelte({
    url: {
    localize: 'src/lib/url-util.js',
    patterns: [
    // ...
    ]
    }
    })
    }
    }

    The module has to export a localize function that is of type:

    type URLLocalizer = (url: string, locale: string) => string;

    To just use the default of prefixing the locale to the path, set localize: true.

  • Add support for locale fallback chains (8ff01c4)

    This is only for when the message is not yet translated. With no configuration, for locales that have regional variants like fr-CH, it falls back to the base one fr. And explicit chains can be configured by providing from-to pairs in the fallback key:

    wuchale.config.js
    export default {
    // ...
    fallback: {
    "fr-CH": "fr-FR",
    "fr-FR": "fr-ES",
    },
    // ...
    };

    And then the chain for would be fr-CH -> fr-FR -> fr-ES -> fr -> en.

  • URL translations in separate catalog .url.po files (843544b)

  • Store references for URL items just like any other message, and use it to avoid startup visit (#250)

  • Fix possible type error on generated compiled catalogs when using plural functions (324fb80)
  • Fix multiple issues revealed in #234 (2966ded)
  • Allow return outside function for astro frontmatter (823f78e)
  • Fix possible infinite retries on ai translate error/mistake (2b9a61a)
  • 3ca7aac: Accept .ts and .mts config files because node 22+ supports them

  • 9de6b79: Make it easier to choose non-reactive runtime function

    by setting runtime.useReactive in the adapter config.

  • fad845d: Add a flag --log-level to the CLI and use it for all outputs when extracting

  • 197bb11: Accept Gemini model code as config

  • 64f7485: BREAKING: Update locales config to support for 3rd party component libraries

    The sourceLocale is now configured on a per-adapter basis, and on the top level, all desired locales have to be specified.

    You have to make some changes to your config:

    {
    sourceLocale: 'en',
    otherLocales: ['es', 'fr'],
    locales: ['en', 'es', 'fr'],
    adapters: {
    main: svelte({
    sourceLocale: 'en',
    // ...
    })
    }
    }

    Additionally, the sourceLocale on the adapter defaults to the first locale in the main locales array.

    This allows the use of multiple languages in the source code, which may be necessary when you are trying to write the source in another language and you want to use a 3rd party lib written in English for example.

    And now to use 3rd party component libraries, you can specify the file locations in the package dir under node_modules:

    wuchale.config.js
    {
    //...
    adapters: {
    lib: svelte({
    files: "node_modules/foo-lib/dist/*.svelte",
    });
    }
    }

    And additionally, to make sure that Vite doesn’t interfere during dev, you can exclude the library from startup optimization:

    vite.config.js
    export default defineConfig({
    optimizeDeps: {
    exclude: ["foo-lib"],
    },
    });
  • 63fb176: Add support for delaying setting the current locale after loading the catalogs (#163)

    You can now use commitLocale after loadLocale(locale, false) to separate loading from rendering. This can solve SvelteKit rendering the other locale on hover over the language link when preloading is on, by using it in $effect.pre. Previously loadLocale accepted key as the second argument to selectively load catalogs by adapter key. It will now load all available catalogs.

  • f92c641: Use _w_runtime_(...) instead of _w_runtime_.t(...) to further reduce bundle size

  • ae355a5: Fix windows file path difference preventing hot reload on edit po files
  • 3b0e87b: Update Gemini default version to 2.5 (for #218)
  • 67655b3: Fix messages belonging to files matched by removed patterns surviving --clean #200
  • 926aa60: Fix type error on proxies when noUncheckedIndexedAccess is true #202
  • 7471ce3: Fix translation not showing when writing po file after adding new message in source #204
  • 82c4cf9: Fix <style lang="scss"> causing problems in Svelte
  • 6af0d52: Fix error on for loops with some conditions missing #197
  • 0a4e3df: Remove surrounding unnecessary quotes when transforming attributes #191
  • 1b511c3: Fix parsing crashing on TS abstract class declarations #189
  • 5ce8212: Fix switch and try statements not being visited #198
  • 885c131: Fix type errors because of generated compiled catalogs not being typed
  • 44a6d24: Fix ... as type and <type>... expressions in TS not visited sometimes
  • f861f78: Use proper hook name to get reactive runtime in React #181
  • ff87ab3: Don’t update PO-Revision-Date header on extract, should be set by translation tool/platform
  • a1a31f9: Fix errors during build due to granular load IDs and TS types
  • 4a8ba3d: Fix runtime initialization sometimes after early exits in functions

    Causing errors in React apps

  • db45dff: Fix default loader templates, remove obsolete comments

  • 5b0a570: Fix custom loader in config causing errors

  • 978aaa4: Fix compiled catalogs not written on build
  • 37deb80: Always use physical files, change catalog config to localesDir

    Previusly virtual modules offered by Vite made it possible to keep the file system clean and a slight performance advantage when building, but they had disadvantages:

    • Inspecting what Wuchale generates was not possible unless the writeFiles config was enabled
    • They don’t work outside of Vite
    • Supporting physical files was therefore unavoidable and that meant supporting two different systems to export the same things

    Now everything is written to disk, including proxies, compiled catalogs, and locales data too. And writeFiles has been removed. In cases where writing the transformed code is desired, the destination can be provided to the outDir adapter config.

    The second thing is that the location of the catalog files was previusly specified using the catalog adapter config, which accepted a substitution parameter, {locale} but it’s an unnecessary complexity that can lead to problems, and it’s not just catalogs that’s stored in that location. Therefore, it has been replaced by the self descriptive config, localesDir.

  • 37deb80: Improve base heuristic to avoid ALLCAPS like POST and EUR, with no lowercase like “M 0,0” in script and attributes

  • 37deb80: Removed the init CLI command. Loaders are now specified in the config. And they have to export getRuntime and getRuntimeRx.

    The interactive init command was mainly created to scaffold loaders. But since most devs don’t touch the loaders and since updates to what the loaders are expected to export and their locations is not that straightforward to keep up with the package updates, the command has been removed, and the loaders can be specified in the adapter configuration using the key loader.

    The loader config can take some default included loaders and additionally custom as a value. For example, the Svelte adapter can accept the values svelte, sveltekit and custom.

    Specifying the included loaders (svelte or sveltekit in the example case) means you don’t want to control their content and want to use the default. And so the loader(s) contents are (over)written at dev server startup or the extract command. That way, they are automatically kept up to date with the package. But if you want to do custom stuff with the loaders, and don’t want them to be overwritten, you can specify custom.

    The location of the loaders is next to the catalogs, and follows this naming convention:

    {adapter key}.loader[.server].{loader extension}

    For example, for a SvelteKit project, it can be: main.loader.svelte.js (client) and main.loader.server.svelte.js (server). Therefore, if you take ownership of these files and do custom stuff, you can specify custom in the adapter config.

    And next, the (custom) loaders have to export functions getRuntime and getRuntimeRx after wrapping the loaded catalogs with toRuntime from wuchale/runtime.

  • 37deb80: Provide locale as an rgument option for patterns for easy l10n

    You can now use pure functions for l10n like currency and date, etc.

    For example, you can define the function:

    function currency(num, loc = "en") {
    return new Intl.NumberFormat(loc, {
    style: "currency",
    currency: "EUR",
    }).format(num);
    }

    And specify the pattern in the config:

    // ...
    adapters: {
    main: svelte({
    loader: 'sveltekit',
    patterns: [
    {name: 'currency', args: ['other', 'locale']},
    ]
    }),
    // ...

    And when you use it like normal:

    <p>{currency(123456.789)}</p>

    It will produce localized variants based on the locale:

    • en: €123,456.79
    • es: 123.456,79 €
    • fr: 123 456,79 €

    You can use it with ANY l10n approach, you just have to specify the pattern.

  • 37deb80: Run a pre scan and compile catalogs before build to prevent race conditions

    This solves the problem where you start the build process with some messages in the code not yet extracted to the PO files, and are discovered during the build process, which causes the PO file and subsequently the compiled catalogs to be modified, during build. That causes a race condition and makes the build process fail because of a syntax error (the compiled catalog is read while only half of it is written.)

    Additionally, with the new URL handling, links are not directly translated, their translation is derived from the URL pattern translations. That removes the need to store them in the PO files, just the patterns. But that also means they are not known at the start of the build process, which causes the above problem.

    Now all extraction and compilation of messages is performed prior to the build, during build, no PO file writes or compiles are performed, only code transformations happen. This makes builds deterministic.

  • 9d1dff8: Add support for translating URL paths!

    This is the biggest addition on this release. Internationalizing URL paths is now possible, with the same conveniences of no/minimal code changes, while respecting the fact that URLs are to be handled carefully.

    There are two parts to this:

    • Translation: e.g. /about to /uber-uns
    • Localization: e.g. /about to /en/about

    Full guide coming soon in the docs!

  • 5c8cea6: Fix chain expressions (JS) and render tags (Svelte) not being visited
  • a955579: Visit @const declarations in svelte, more compatibility
  • 280ad8d: Fix tagged template strings not extracted
  • 51778eb: Fix patterns not working for template literals
  • 6a9b651: Fix config with files: {include: ..., ignore: ...} not working, and improve verbose output
  • 8e2611d: Export and document all default heuristic functions
  • 5a221a2: Expose interface to make AI translator customizable

    You can now use a custom translator model other than Gemini by supplying the info in the config:

    export default {
    //...
    ai: {
    name: "ChatGPT", // e.g.
    batchSize: 50,
    parallel: 10,
    translate: (content, instruction) => {
    // logic
    return translatedContent;
    },
    },
    //...
    };

    Gemini is still the default, but now it’s separated out and was made customizable:

    import { gemini } from "wuchale";
    export default {
    //...
    ai: gemini({
    batchSize: 40,
    parallel: 5,
    think: true, // default: false
    }),
    //...
    };
  • 15cf377: Pass whole message to heuristic function, with context

  • 0b5c207: Svelte: auto wrap variable declarations by $derived as needed instead of requiring it in the code

  • 16b116c: Customizable log levels, add verbose level where all extracted messages are shown

  • 22198c1: Redesign status command output with tables

  • d531bcc: Add support for multiple custom patterns to support full l10n

    For example, if you want to use Intl.MessageFormat for everything it supports including plurals, you add a signature pattern for a utility function in the config:

    // ...
    adapters: js({
    patterns: [
    {
    name: "formatMsg",
    args: ["message", "other"],
    },
    ],
    });
    //...

    Then you create your reusable utility function with that name:

    // where you get the locale
    let locale = "en";
    export function formatMsg(msg, args) {
    return new IntlMessageFormat(msg, locale).format(args);
    }

    And use it anywhere:

    const msg = formatMsg(
    `{numPhotos, plural,
    =0 {You have no photos.}
    =1 {You have one photo.}
    other {You have # photos.}
    }`,
    { numPhotos: 1000 }
    );

    Then wuchale will extract and transform it into:

    const msg = formatMsg(_w_runtime_.t(0), { numPhotos: 1000 });
  • 9f997c2: Add --sync flag for the CLI command to process files sequentially

  • 6d0a4d3: Make wuchale --clean idempotent and write once at the end
  • 1d57789: Fix locales not separate when written to proxy
  • 5aa768a: Ignore form method attribute and fetch calls

  • 0352c60: Fix issues around arrow functions and function expressions

    These are technically functions but their bodies are not block statement bodies, but expressions. For this reason, they were ignored when they are defined at the top level and when they are inside functions, they would use the runtime instance of their parent. Now their own bodies are tuned into block statement bodies:

    const foo = () => "Hello";

    Now becomes:

    const foo = () => {
    const _w_runtime_ = _w_to_rt_(_w_load_("main"));
    return _w_runtime_.t(0);
    };

    This allows them to be defined at the top level and they should still get their contents properly extracted.

  • 04e28a3: Fix initialization outside <script> when the <script> is empty

  • 4210ee1: Fix error on empty body content when trying to get body start (e.g. in empty <script>)
  • f7c0225: Fix class declarations not visited
  • 973848b: Fix HMR having problems with lazy loaded files
  • fef0d11: Add the @wc-ignore-file comment directive

    As an alternative to ignoring a file in the files config value, you can now ignore a whole file by putting this directive at the beginning of the file, before any extractable messages. The advantage is that it doesn’t need a restart of the dev server and if you rename/move the file it will always be ignored.

  • 4fcf264: Add support for .mjs config as default

  • 46aa3f2: Export locales from proxy when writeFiles is enabled for server to not need tweaking the default loader

  • 37367ca: Add placeholder context comments into PO file

  • f07d484: Gemini: translate in batches of 50 max, auto retry with status messages

    This is useful for one off translation, usually just after adding wuchale to a big project. Gemini sometimes doesn’t translate all messages when it’s given too many, so this update batches the messages into groups of ~50, and when not all of them are translated, shows a message and tries again, until all of them are translated.

  • 3d5d73a: Solve issues with paths on windows
  • 957574f: Fix sequence expressions not visited
  • 0223e40: Fix cli with –clean removing all messages not belonging to the last adapter out of those sharing a catalog
  • 485f5fe: Fix .svelte files with