@analogjs/platform 2.5.0-beta.5 → 2.5.0-beta.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/platform",
3
- "version": "2.5.0-beta.5",
3
+ "version": "2.5.0-beta.51",
4
4
  "description": "The fullstack meta-framework for Angular",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "nitropack": "^2.13.1",
32
- "@analogjs/vite-plugin-angular": "^2.5.0-beta.5",
33
- "@analogjs/vite-plugin-nitro": "^2.5.0-beta.5",
32
+ "@analogjs/vite-plugin-angular": "^2.5.0-beta.51",
33
+ "@analogjs/vite-plugin-nitro": "^2.5.0-beta.51",
34
34
  "vitefu": "^1.1.2"
35
35
  },
36
36
  "peerDependencies": {
@@ -85,8 +85,7 @@
85
85
  "@analogjs/storybook-angular",
86
86
  "@analogjs/vite-plugin-angular",
87
87
  "@analogjs/vite-plugin-nitro",
88
- "@analogjs/vitest-angular",
89
- "@analogjs/angular-compiler"
88
+ "@analogjs/vitest-angular"
90
89
  ],
91
90
  "migrations": "./migrations/migration.json"
92
91
  },
@@ -5,6 +5,10 @@ export function getShikiHighlighter({ highlighter = {}, highlight = {}, containe
5
5
  if (highlighterInstance) {
6
6
  return highlighterInstance;
7
7
  }
8
+ const additionalLangs = highlighter.additionalLangs ?? [];
9
+ const skipLangs = highlighter.skipLangs ?? [];
10
+ const hasMermaidSupport = highlighter.langs?.includes('mermaid') ||
11
+ additionalLangs.includes('mermaid');
8
12
  if (!highlighter.themes) {
9
13
  if (highlight.theme) {
10
14
  highlighter.themes = [highlight.theme];
@@ -17,13 +21,18 @@ export function getShikiHighlighter({ highlighter = {}, highlight = {}, containe
17
21
  }
18
22
  }
19
23
  if (!highlighter.langs) {
20
- highlighter.langs = defaultHighlighterOptions.langs;
24
+ highlighter.langs = [...defaultHighlighterOptions.langs];
21
25
  }
22
- if (highlighter.additionalLangs) {
23
- highlighter.langs.push(...highlighter.additionalLangs);
24
- delete highlighter.additionalLangs;
26
+ if (additionalLangs.length > 0) {
27
+ highlighter.langs.push(...additionalLangs);
25
28
  }
26
- highlighterInstance = new ShikiHighlighter(highlighter, highlight, container, !!highlighter.langs.includes('mermaid'));
29
+ if (skipLangs.length > 0) {
30
+ const skipSet = new Set(skipLangs);
31
+ highlighter.langs = highlighter.langs.filter((lang) => typeof lang !== 'string' || !skipSet.has(lang));
32
+ }
33
+ delete highlighter.additionalLangs;
34
+ delete highlighter.skipLangs;
35
+ highlighterInstance = new ShikiHighlighter(highlighter, highlight, container, hasMermaidSupport, skipLangs);
27
36
  return highlighterInstance;
28
37
  }
29
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS9zcmMvbGliL2NvbnRlbnQvc2hpa2kvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixnQkFBZ0IsR0FFakIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztBQUU1QixJQUFJLG1CQUFxQyxDQUFDO0FBRTFDLE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxFQUNsQyxXQUFXLEdBQUcsRUFBRSxFQUNoQixTQUFTLEdBQUcsRUFBRSxFQUNkLFNBQVMsR0FBRyxJQUFJLE1BQ2UsRUFBRTtJQUNqQyxJQUFJLG1CQUFtQixFQUFFLENBQUM7UUFDeEIsT0FBTyxtQkFBbUIsQ0FBQztJQUM3QixDQUFDO0lBRUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN4QixJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwQixXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUM7YUFBTSxJQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksT0FBTyxTQUFTLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3BFLFdBQVcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFhLENBQUM7UUFDbkUsQ0FBQzthQUFNLENBQUM7WUFDTixXQUFXLENBQUMsTUFBTSxHQUFHLHlCQUF5QixDQUFDLE1BQU0sQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkIsV0FBVyxDQUFDLEtBQUssR0FBRyx5QkFBeUIsQ0FBQyxLQUFLLENBQUM7SUFDdEQsQ0FBQztJQUVELElBQUksV0FBVyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ2hDLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3ZELE9BQU8sV0FBVyxDQUFDLGVBQWUsQ0FBQztJQUNyQyxDQUFDO0lBRUQsbUJBQW1CLEdBQUcsSUFBSSxnQkFBZ0IsQ0FDeEMsV0FBc0MsRUFDdEMsU0FBUyxFQUNULFNBQVMsRUFDVCxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQ3hDLENBQUM7SUFFRixPQUFPLG1CQUFtQixDQUFDO0FBQzdCLENBQUMifQ==
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS9zcmMvbGliL2NvbnRlbnQvc2hpa2kvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixnQkFBZ0IsR0FFakIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQztBQUU1QixJQUFJLG1CQUFxQyxDQUFDO0FBRTFDLE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxFQUNsQyxXQUFXLEdBQUcsRUFBRSxFQUNoQixTQUFTLEdBQUcsRUFBRSxFQUNkLFNBQVMsR0FBRyxJQUFJLE1BQ2UsRUFBRTtJQUNqQyxJQUFJLG1CQUFtQixFQUFFLENBQUM7UUFDeEIsT0FBTyxtQkFBbUIsQ0FBQztJQUM3QixDQUFDO0lBRUQsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUM7SUFDMUQsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUM7SUFDOUMsTUFBTSxpQkFBaUIsR0FDckIsV0FBVyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDO1FBQ3RDLGVBQWUsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFdEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN4QixJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwQixXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUM7YUFBTSxJQUFJLFNBQVMsQ0FBQyxNQUFNLElBQUksT0FBTyxTQUFTLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3BFLFdBQVcsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFhLENBQUM7UUFDbkUsQ0FBQzthQUFNLENBQUM7WUFDTixXQUFXLENBQUMsTUFBTSxHQUFHLHlCQUF5QixDQUFDLE1BQU0sQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkIsV0FBVyxDQUFDLEtBQUssR0FBRyxDQUFDLEdBQUcseUJBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELElBQUksZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMvQixXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLGVBQWUsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDekIsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQVMsU0FBUyxDQUFDLENBQUM7UUFDM0MsV0FBVyxDQUFDLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDMUMsQ0FBQyxJQUFhLEVBQUUsRUFBRSxDQUFDLE9BQU8sSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQ2xFLENBQUM7SUFDSixDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUMsZUFBZSxDQUFDO0lBQ25DLE9BQU8sV0FBVyxDQUFDLFNBQVMsQ0FBQztJQUU3QixtQkFBbUIsR0FBRyxJQUFJLGdCQUFnQixDQUN4QyxXQUFzQyxFQUN0QyxTQUFTLEVBQ1QsU0FBUyxFQUNULGlCQUFpQixFQUNqQixTQUFTLENBQ1YsQ0FBQztJQUVGLE9BQU8sbUJBQW1CLENBQUM7QUFDN0IsQ0FBQyJ9
@@ -3,6 +3,7 @@ import { BundledLanguage } from 'shiki/langs';
3
3
  export interface WithShikiHighlighterOptions {
4
4
  highlighter?: Partial<ShikiHighlighterOptions> & {
5
5
  additionalLangs?: BundledLanguage[];
6
+ skipLangs?: BundledLanguage[];
6
7
  };
7
8
  highlight?: ShikiHighlightOptions;
8
9
  container?: string;
@@ -1,6 +1,6 @@
1
- import { type BundledLanguage, type BundledTheme, type CodeOptionsMeta, type CodeOptionsMultipleThemes, type CodeOptionsSingleTheme, type CodeToHastOptionsCommon, getHighlighter } from 'shiki';
1
+ import { type BundledLanguage, type BundledTheme, type CodeOptionsMeta, type CodeOptionsMultipleThemes, type CodeOptionsSingleTheme, type CodeToHastOptionsCommon, createHighlighter } from 'shiki';
2
2
  import { MarkedContentHighlighter } from '../marked/marked-content-highlighter.js';
3
- export type ShikiHighlighterOptions = Parameters<typeof getHighlighter>[0];
3
+ export type ShikiHighlighterOptions = Parameters<typeof createHighlighter>[0];
4
4
  export type ShikiHighlightOptions = Partial<Omit<CodeToHastOptionsCommon<BundledLanguage>, 'lang'>> & CodeOptionsMeta & Partial<CodeOptionsSingleTheme<BundledTheme>> & Partial<CodeOptionsMultipleThemes<BundledTheme>>;
5
5
  export declare const defaultHighlighterOptions: {
6
6
  langs: string[];
@@ -11,7 +11,8 @@ export declare class ShikiHighlighter extends MarkedContentHighlighter {
11
11
  private highlightOptions;
12
12
  private container;
13
13
  private hasLoadMermaid;
14
+ private skipLangs;
14
15
  private readonly highlighter;
15
- constructor(highlighterOptions: ShikiHighlighterOptions, highlightOptions: ShikiHighlightOptions, container: string, hasLoadMermaid?: boolean);
16
+ constructor(highlighterOptions: ShikiHighlighterOptions, highlightOptions: ShikiHighlightOptions, container: string, hasLoadMermaid?: boolean, skipLangs?: string[]);
16
17
  getHighlightExtension(): import("marked").MarkedExtension;
17
18
  }
@@ -1,5 +1,5 @@
1
1
  import markedShiki from 'marked-shiki';
2
- import { getHighlighter, } from 'shiki';
2
+ import { createHighlighter, } from 'shiki';
3
3
  import { MarkedContentHighlighter } from '../marked/marked-content-highlighter.js';
4
4
  export const defaultHighlighterOptions = {
5
5
  langs: [
@@ -15,14 +15,23 @@ export const defaultHighlighterOptions = {
15
15
  ],
16
16
  themes: ['github-dark', 'github-light'],
17
17
  };
18
+ function escapeHtml(code) {
19
+ return code
20
+ .replaceAll('&', '&amp;')
21
+ .replaceAll('<', '&lt;')
22
+ .replaceAll('>', '&gt;')
23
+ .replaceAll('"', '&quot;')
24
+ .replaceAll("'", '&#39;');
25
+ }
18
26
  export class ShikiHighlighter extends MarkedContentHighlighter {
19
- constructor(highlighterOptions, highlightOptions, container, hasLoadMermaid = false) {
27
+ constructor(highlighterOptions, highlightOptions, container, hasLoadMermaid = false, skipLangs = []) {
20
28
  super();
21
29
  this.highlighterOptions = highlighterOptions;
22
30
  this.highlightOptions = highlightOptions;
23
31
  this.container = container;
24
32
  this.hasLoadMermaid = hasLoadMermaid;
25
- this.highlighter = getHighlighter(this.highlighterOptions);
33
+ this.skipLangs = skipLangs;
34
+ this.highlighter = createHighlighter(this.highlighterOptions);
26
35
  }
27
36
  getHighlightExtension() {
28
37
  return markedShiki({
@@ -31,6 +40,10 @@ export class ShikiHighlighter extends MarkedContentHighlighter {
31
40
  if (this.hasLoadMermaid && lang === 'mermaid') {
32
41
  return `<pre class="mermaid">${code}</pre>`;
33
42
  }
43
+ if (this.skipLangs.includes(lang)) {
44
+ const escapedCode = escapeHtml(code);
45
+ return `<pre class="language-${lang}"><code class="language-${lang}">${escapedCode}</code></pre>`;
46
+ }
34
47
  const { codeToHtml } = await this.highlighter;
35
48
  return codeToHtml(code, Object.assign({
36
49
  lang,
@@ -42,4 +55,4 @@ export class ShikiHighlighter extends MarkedContentHighlighter {
42
55
  });
43
56
  }
44
57
  }
45
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hpa2ktaGlnaGxpZ2h0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS9zcmMvbGliL2NvbnRlbnQvc2hpa2kvc2hpa2ktaGlnaGxpZ2h0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFPTCxjQUFjLEdBQ2YsTUFBTSxPQUFPLENBQUM7QUFFZixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQVVuRixNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRztJQUN2QyxLQUFLLEVBQUU7UUFDTCxNQUFNO1FBQ04sSUFBSTtRQUNKLEtBQUs7UUFDTCxJQUFJO1FBQ0osS0FBSztRQUNMLE1BQU07UUFDTixLQUFLO1FBQ0wsY0FBYztRQUNkLFlBQVk7S0FDYjtJQUNELE1BQU0sRUFBRSxDQUFDLGFBQWEsRUFBRSxjQUFjLENBQUM7Q0FDeEMsQ0FBQztBQUVGLE1BQU0sT0FBTyxnQkFBaUIsU0FBUSx3QkFBd0I7SUFHNUQsWUFDVSxrQkFBMkMsRUFDM0MsZ0JBQXVDLEVBQ3ZDLFNBQWlCLEVBQ2pCLGlCQUFpQixLQUFLO1FBRTlCLEtBQUssRUFBRSxDQUFDO1FBTEEsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUF5QjtRQUMzQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXVCO1FBQ3ZDLGNBQVMsR0FBVCxTQUFTLENBQVE7UUFDakIsbUJBQWMsR0FBZCxjQUFjLENBQVE7UUFOZixnQkFBVyxHQUFHLGNBQWMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQVN2RSxDQUFDO0lBQ0QscUJBQXFCO1FBQ25CLE9BQU8sV0FBVyxDQUFDO1lBQ2pCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ3JDLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzlDLE9BQU8sd0JBQXdCLElBQUksUUFBUSxDQUFDO2dCQUM5QyxDQUFDO2dCQUVELE1BQU0sRUFBRSxVQUFVLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUM7Z0JBQzlDLE9BQU8sVUFBVSxDQUNmLElBQUksRUFDSixNQUFNLENBQUMsTUFBTSxDQUNYO29CQUNFLElBQUk7b0JBQ0osaUNBQWlDO29CQUNqQyxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDaEMsS0FBSyxFQUFFLGFBQWE7aUJBQ3JCLEVBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUN0QixDQUNGLENBQUM7WUFDSixDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIn0=
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hpa2ktaGlnaGxpZ2h0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS9zcmMvbGliL2NvbnRlbnQvc2hpa2kvc2hpa2ktaGlnaGxpZ2h0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxXQUFXLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFPTCxpQkFBaUIsR0FDbEIsTUFBTSxPQUFPLENBQUM7QUFFZixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQVVuRixNQUFNLENBQUMsTUFBTSx5QkFBeUIsR0FBRztJQUN2QyxLQUFLLEVBQUU7UUFDTCxNQUFNO1FBQ04sSUFBSTtRQUNKLEtBQUs7UUFDTCxJQUFJO1FBQ0osS0FBSztRQUNMLE1BQU07UUFDTixLQUFLO1FBQ0wsY0FBYztRQUNkLFlBQVk7S0FDYjtJQUNELE1BQU0sRUFBRSxDQUFDLGFBQWEsRUFBRSxjQUFjLENBQUM7Q0FDeEMsQ0FBQztBQUVGLFNBQVMsVUFBVSxDQUFDLElBQVk7SUFDOUIsT0FBTyxJQUFJO1NBQ1IsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUM7U0FDeEIsVUFBVSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUM7U0FDdkIsVUFBVSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUM7U0FDdkIsVUFBVSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUM7U0FDekIsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLHdCQUF3QjtJQUc1RCxZQUNVLGtCQUEyQyxFQUMzQyxnQkFBdUMsRUFDdkMsU0FBaUIsRUFDakIsaUJBQWlCLEtBQUssRUFDdEIsWUFBc0IsRUFBRTtRQUVoQyxLQUFLLEVBQUUsQ0FBQztRQU5BLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBeUI7UUFDM0MscUJBQWdCLEdBQWhCLGdCQUFnQixDQUF1QjtRQUN2QyxjQUFTLEdBQVQsU0FBUyxDQUFRO1FBQ2pCLG1CQUFjLEdBQWQsY0FBYyxDQUFRO1FBQ3RCLGNBQVMsR0FBVCxTQUFTLENBQWU7UUFQakIsZ0JBQVcsR0FBRyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQVUxRSxDQUFDO0lBQ0QscUJBQXFCO1FBQ25CLE9BQU8sV0FBVyxDQUFDO1lBQ2pCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixTQUFTLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQ3JDLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzlDLE9BQU8sd0JBQXdCLElBQUksUUFBUSxDQUFDO2dCQUM5QyxDQUFDO2dCQUVELElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsSUFBYyxDQUFDLEVBQUUsQ0FBQztvQkFDNUMsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUVyQyxPQUFPLHdCQUF3QixJQUFJLDJCQUEyQixJQUFJLEtBQUssV0FBVyxlQUFlLENBQUM7Z0JBQ3BHLENBQUM7Z0JBRUQsTUFBTSxFQUFFLFVBQVUsRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztnQkFDOUMsT0FBTyxVQUFVLENBQ2YsSUFBSSxFQUNKLE1BQU0sQ0FBQyxNQUFNLENBQ1g7b0JBQ0UsSUFBSTtvQkFDSixpQ0FBaUM7b0JBQ2pDLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO29CQUNoQyxLQUFLLEVBQUUsYUFBYTtpQkFDckIsRUFDRCxJQUFJLENBQUMsZ0JBQWdCLENBQ3RCLENBQ0YsQ0FBQztZQUNKLENBQUM7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YifQ==
@@ -9,12 +9,12 @@ export function depsPlugin(options) {
9
9
  config() {
10
10
  const useCompilationAPI = options?.vite === false ||
11
11
  options?.vite?.experimental?.useAngularCompilationAPI;
12
- const useAnalogCompiler = options?.vite !== false &&
13
- options?.vite?.experimental?.useAnalogCompiler;
14
- const esbuild = useCompilationAPI || useAnalogCompiler
12
+ const fastCompile = options?.fastCompile ||
13
+ (options?.vite !== false && options?.vite?.fastCompile);
14
+ const esbuild = useCompilationAPI || fastCompile
15
15
  ? {}
16
16
  : { exclude: ['**/*.ts', '**/*.js'] };
17
- const oxc = useCompilationAPI || useAnalogCompiler
17
+ const oxc = useCompilationAPI || fastCompile
18
18
  ? {}
19
19
  : { exclude: ['**/*.ts', '**/*.js'] };
20
20
  return {
@@ -82,4 +82,4 @@ export function depsPlugin(options) {
82
82
  },
83
83
  ];
84
84
  }
85
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwcy1wbHVnaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS9zcmMvbGliL2RlcHMtcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVoRCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFJNUMsTUFBTSxVQUFVLFVBQVUsQ0FBQyxPQUFpQjtJQUMxQyxNQUFNLGFBQWEsR0FBRyxPQUFPLEVBQUUsYUFBYSxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUU5RCxPQUFPO1FBQ0w7WUFDRSxJQUFJLEVBQUUsc0JBQXNCO1lBQzVCLE1BQU07Z0JBQ0osTUFBTSxpQkFBaUIsR0FDckIsT0FBTyxFQUFFLElBQUksS0FBSyxLQUFLO29CQUN2QixPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSx3QkFBd0IsQ0FBQztnQkFDeEQsTUFBTSxpQkFBaUIsR0FDckIsT0FBTyxFQUFFLElBQUksS0FBSyxLQUFLO29CQUN2QixPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxpQkFBaUIsQ0FBQztnQkFFakQsTUFBTSxPQUFPLEdBQ1gsaUJBQWlCLElBQUksaUJBQWlCO29CQUNwQyxDQUFDLENBQUMsRUFBRTtvQkFDSixDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFFMUMsTUFBTSxHQUFHLEdBQ1AsaUJBQWlCLElBQUksaUJBQWlCO29CQUNwQyxDQUFDLENBQUMsRUFBRTtvQkFDSixDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFFMUMsT0FBTztvQkFDTCxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQztvQkFDakQsR0FBRyxFQUFFO3dCQUNILFVBQVUsRUFBRTs0QkFDVixjQUFjOzRCQUNkLGFBQWE7NEJBQ2IsbUJBQW1COzRCQUNuQixRQUFROzRCQUNSLGlCQUFpQjs0QkFDakIsY0FBYzs0QkFDZCxzQ0FBc0M7eUJBQ3ZDO3FCQUNGO29CQUNELFlBQVksRUFBRTt3QkFDWixPQUFPLEVBQUU7NEJBQ1AsaUJBQWlCOzRCQUNqQixzQkFBc0I7NEJBQ3RCLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0NBQzVCLENBQUMsQ0FBQyxDQUFDLDRCQUE0QixDQUFDO2dDQUNoQyxDQUFDLENBQUMsRUFBRSxDQUFDOzRCQUNQLGNBQWM7eUJBQ2Y7d0JBQ0QsT0FBTyxFQUFFOzRCQUNQLDBCQUEwQjs0QkFDMUIsbUJBQW1COzRCQUNuQixrQkFBa0I7NEJBQ2xCLGFBQWE7NEJBQ2IsVUFBVTs0QkFDVixZQUFZOzRCQUNaLFFBQVE7NEJBQ1IsWUFBWTs0QkFDWixhQUFhOzRCQUNiLFVBQVU7NEJBQ1YsUUFBUTs0QkFDUixZQUFZOzRCQUNaLGFBQWE7NEJBQ2IsU0FBUzs0QkFDVCxlQUFlOzRCQUNmLFlBQVk7NEJBQ1osdUJBQXVCOzRCQUN2QixZQUFZOzRCQUNaLFNBQVM7NEJBQ1QsVUFBVTs0QkFDVixJQUFJO3lCQUNMO3FCQUNGO2lCQUNGLENBQUM7WUFDSixDQUFDO1NBQ0Y7UUFDRDtZQUNFLElBQUksRUFBRSw2QkFBNkI7WUFDbkMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFPLEVBQUU7Z0JBQzlCLE1BQU0sU0FBUyxHQUFHLE1BQU0sa0JBQWtCLENBQUM7b0JBQ3pDLElBQUksRUFBRSxhQUFhO29CQUNuQixPQUFPLEVBQUUsT0FBTyxLQUFLLE9BQU87b0JBQzVCLGNBQWMsRUFBRSxNQUFNO29CQUN0Qix3QkFBd0IsQ0FBQyxPQUFPO3dCQUM5QixPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNqRSxDQUFDO2lCQUNGLENBQUMsQ0FBQztnQkFDSCxPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1NBQ0Y7S0FDRixDQUFDO0FBQ0osQ0FBQyJ9
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwcy1wbHVnaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9wbGF0Zm9ybS9zcmMvbGliL2RlcHMtcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUVoRCxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFJNUMsTUFBTSxVQUFVLFVBQVUsQ0FBQyxPQUFpQjtJQUMxQyxNQUFNLGFBQWEsR0FBRyxPQUFPLEVBQUUsYUFBYSxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUU5RCxPQUFPO1FBQ0w7WUFDRSxJQUFJLEVBQUUsc0JBQXNCO1lBQzVCLE1BQU07Z0JBQ0osTUFBTSxpQkFBaUIsR0FDckIsT0FBTyxFQUFFLElBQUksS0FBSyxLQUFLO29CQUN2QixPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSx3QkFBd0IsQ0FBQztnQkFDeEQsTUFBTSxXQUFXLEdBQ2YsT0FBTyxFQUFFLFdBQVc7b0JBQ3BCLENBQUMsT0FBTyxFQUFFLElBQUksS0FBSyxLQUFLLElBQUksT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFFMUQsTUFBTSxPQUFPLEdBQ1gsaUJBQWlCLElBQUksV0FBVztvQkFDOUIsQ0FBQyxDQUFDLEVBQUU7b0JBQ0osQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBRTFDLE1BQU0sR0FBRyxHQUNQLGlCQUFpQixJQUFJLFdBQVc7b0JBQzlCLENBQUMsQ0FBQyxFQUFFO29CQUNKLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUUxQyxPQUFPO29CQUNMLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDO29CQUNqRCxHQUFHLEVBQUU7d0JBQ0gsVUFBVSxFQUFFOzRCQUNWLGNBQWM7NEJBQ2QsYUFBYTs0QkFDYixtQkFBbUI7NEJBQ25CLFFBQVE7NEJBQ1IsaUJBQWlCOzRCQUNqQixjQUFjOzRCQUNkLHNDQUFzQzt5QkFDdkM7cUJBQ0Y7b0JBQ0QsWUFBWSxFQUFFO3dCQUNaLE9BQU8sRUFBRTs0QkFDUCxpQkFBaUI7NEJBQ2pCLHNCQUFzQjs0QkFDdEIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRTtnQ0FDNUIsQ0FBQyxDQUFDLENBQUMsNEJBQTRCLENBQUM7Z0NBQ2hDLENBQUMsQ0FBQyxFQUFFLENBQUM7NEJBQ1AsY0FBYzt5QkFDZjt3QkFDRCxPQUFPLEVBQUU7NEJBQ1AsMEJBQTBCOzRCQUMxQixtQkFBbUI7NEJBQ25CLGtCQUFrQjs0QkFDbEIsYUFBYTs0QkFDYixVQUFVOzRCQUNWLFlBQVk7NEJBQ1osUUFBUTs0QkFDUixZQUFZOzRCQUNaLGFBQWE7NEJBQ2IsVUFBVTs0QkFDVixRQUFROzRCQUNSLFlBQVk7NEJBQ1osYUFBYTs0QkFDYixTQUFTOzRCQUNULGVBQWU7NEJBQ2YsWUFBWTs0QkFDWix1QkFBdUI7NEJBQ3ZCLFlBQVk7NEJBQ1osU0FBUzs0QkFDVCxVQUFVOzRCQUNWLElBQUk7eUJBQ0w7cUJBQ0Y7aUJBQ0YsQ0FBQztZQUNKLENBQUM7U0FDRjtRQUNEO1lBQ0UsSUFBSSxFQUFFLDZCQUE2QjtZQUNuQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRTtnQkFDOUIsTUFBTSxTQUFTLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQztvQkFDekMsSUFBSSxFQUFFLGFBQWE7b0JBQ25CLE9BQU8sRUFBRSxPQUFPLEtBQUssT0FBTztvQkFDNUIsY0FBYyxFQUFFLE1BQU07b0JBQ3RCLHdCQUF3QixDQUFDLE9BQU87d0JBQzlCLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ2pFLENBQUM7aUJBQ0YsQ0FBQyxDQUFDO2dCQUNILE9BQU8sU0FBUyxDQUFDO1lBQ25CLENBQUM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDIn0=
@@ -0,0 +1,33 @@
1
+ import { Plugin } from 'vite';
2
+ import { I18nOptions } from './options.js';
3
+ /**
4
+ * Vite plugin that extracts i18n messages from compiled JavaScript output.
5
+ *
6
+ * After the client build completes, this plugin scans all `.js` files in the
7
+ * output directory for `$localize` tagged template literals and extracts the
8
+ * message IDs and source text. It then writes the extracted messages to a
9
+ * translation source file.
10
+ *
11
+ * Uses `@angular/localize/tools` MessageExtractor when available,
12
+ * falling back to a regex-based extractor.
13
+ */
14
+ export declare function i18nExtractPlugin(i18nOptions: I18nOptions): Plugin;
15
+ export interface ExtractedMessage {
16
+ id: string;
17
+ text: string;
18
+ description?: string;
19
+ }
20
+ /**
21
+ * Regex-based fallback extractor for when @angular/localize/tools is not available.
22
+ *
23
+ * Parses `$localize` tagged template literals to extract message IDs and text.
24
+ * Handles the common forms:
25
+ * $localize`:@@messageId:text`
26
+ * $localize`:description@@messageId:text`
27
+ * $localize`text`
28
+ */
29
+ export declare function extractWithRegex(files: string[]): ExtractedMessage[];
30
+ /**
31
+ * Serializes extracted messages into the specified format.
32
+ */
33
+ export declare function serializeMessages(messages: ExtractedMessage[], format: string, sourceLocale: string): string;
@@ -0,0 +1,288 @@
1
+ import { resolve, dirname, extname } from 'node:path';
2
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, } from 'node:fs';
3
+ const FORMAT_EXTENSIONS = {
4
+ json: '.json',
5
+ xliff: '.xlf',
6
+ xliff2: '.xlf',
7
+ xmb: '.xmb',
8
+ };
9
+ /**
10
+ * Vite plugin that extracts i18n messages from compiled JavaScript output.
11
+ *
12
+ * After the client build completes, this plugin scans all `.js` files in the
13
+ * output directory for `$localize` tagged template literals and extracts the
14
+ * message IDs and source text. It then writes the extracted messages to a
15
+ * translation source file.
16
+ *
17
+ * Uses `@angular/localize/tools` MessageExtractor when available,
18
+ * falling back to a regex-based extractor.
19
+ */
20
+ export function i18nExtractPlugin(i18nOptions) {
21
+ let config;
22
+ let isSSRBuild = false;
23
+ const extractConfig = i18nOptions.extract;
24
+ if (!extractConfig) {
25
+ return { name: 'analog-i18n-extract-noop' };
26
+ }
27
+ const format = extractConfig.format ?? 'json';
28
+ return {
29
+ name: 'analog-i18n-extract',
30
+ apply: 'build',
31
+ configResolved(resolvedConfig) {
32
+ config = resolvedConfig;
33
+ isSSRBuild = !!config.build.ssr;
34
+ },
35
+ async closeBundle() {
36
+ // Only run on the client build, not SSR
37
+ if (isSSRBuild) {
38
+ return;
39
+ }
40
+ const outDir = resolve(config.root, config.build.outDir);
41
+ const jsFiles = collectJsFiles(outDir);
42
+ const filesWithLocalize = jsFiles.filter((file) => {
43
+ const content = readFileSync(file, 'utf-8');
44
+ return content.includes('$localize');
45
+ });
46
+ if (filesWithLocalize.length === 0) {
47
+ return;
48
+ }
49
+ let messages;
50
+ try {
51
+ messages = await extractWithLocalizeTools(filesWithLocalize, config.root);
52
+ }
53
+ catch {
54
+ // @angular/localize/tools not available, use regex fallback
55
+ messages = extractWithRegex(filesWithLocalize);
56
+ }
57
+ if (messages.length === 0) {
58
+ return;
59
+ }
60
+ const ext = FORMAT_EXTENSIONS[format] ?? '.json';
61
+ const defaultOutFile = `src/i18n/messages${ext}`;
62
+ const outFile = resolve(config.root, extractConfig.outFile ?? defaultOutFile);
63
+ mkdirSync(dirname(outFile), { recursive: true });
64
+ const output = serializeMessages(messages, format, i18nOptions.defaultLocale);
65
+ writeFileSync(outFile, output, 'utf-8');
66
+ console.log(`\n[@analogjs/platform] Extracted ${messages.length} i18n message(s) to ${outFile}\n`);
67
+ },
68
+ };
69
+ }
70
+ /**
71
+ * Extracts messages using @angular/localize/tools MessageExtractor.
72
+ * Throws if the package is not installed.
73
+ */
74
+ async function extractWithLocalizeTools(files, basePath) {
75
+ // @ts-ignore - @angular/localize/tools is an optional dependency
76
+ const localizeTools = await import('@angular/localize/tools');
77
+ const { MessageExtractor, ɵParsedMessage } = localizeTools;
78
+ const fs = {
79
+ readFile: (path) => readFileSync(path, 'utf-8'),
80
+ readFileBuffer: (path) => readFileSync(path),
81
+ relative: (from, to) => {
82
+ const { relative } = require('node:path');
83
+ return relative(from, to);
84
+ },
85
+ resolve: (...paths) => resolve(...paths),
86
+ exists: (path) => {
87
+ try {
88
+ statSync(path);
89
+ return true;
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ },
95
+ dirname: (path) => dirname(path),
96
+ };
97
+ const logger = {
98
+ debug: () => { },
99
+ info: () => { },
100
+ warn: (msg) => console.warn(msg),
101
+ error: (msg) => console.error(msg),
102
+ level: 0,
103
+ };
104
+ const extractor = new MessageExtractor(fs, logger, {
105
+ basePath,
106
+ useSourceMaps: false,
107
+ });
108
+ const messages = [];
109
+ for (const file of files) {
110
+ try {
111
+ const extracted = extractor.extractMessages(file);
112
+ if (extracted?.messages) {
113
+ for (const msg of extracted.messages) {
114
+ messages.push({
115
+ id: msg.id || msg.customId || msg.messageString,
116
+ text: msg.messageString || msg.text || '',
117
+ description: msg.description,
118
+ });
119
+ }
120
+ }
121
+ }
122
+ catch {
123
+ // Skip files that can't be parsed
124
+ }
125
+ }
126
+ return messages;
127
+ }
128
+ /**
129
+ * Regex-based fallback extractor for when @angular/localize/tools is not available.
130
+ *
131
+ * Parses `$localize` tagged template literals to extract message IDs and text.
132
+ * Handles the common forms:
133
+ * $localize`:@@messageId:text`
134
+ * $localize`:description@@messageId:text`
135
+ * $localize`text`
136
+ */
137
+ export function extractWithRegex(files) {
138
+ const messages = [];
139
+ const seen = new Set();
140
+ // Match $localize`...` or $localize(__makeTemplateObject([...], [...]))
141
+ // The tagged template form: $localize`:[description@@]id:text`
142
+ const taggedTemplateRegex = /\$localize\s*`([^`]*)`/g;
143
+ // Match the metadata block: :[@description@@]id:
144
+ const metadataRegex = /^:((?:([^@]*)@@)?([^:]*)):(.*)$/s;
145
+ for (const file of files) {
146
+ const content = readFileSync(file, 'utf-8');
147
+ let match;
148
+ taggedTemplateRegex.lastIndex = 0;
149
+ while ((match = taggedTemplateRegex.exec(content)) !== null) {
150
+ const body = match[1];
151
+ const metaMatch = metadataRegex.exec(body);
152
+ let id;
153
+ let text;
154
+ let description;
155
+ if (metaMatch) {
156
+ description = metaMatch[2]?.trim() || undefined;
157
+ id = metaMatch[3];
158
+ text = metaMatch[4];
159
+ }
160
+ else {
161
+ // No metadata block — use the text as both id and text
162
+ text = body;
163
+ id = body;
164
+ }
165
+ if (id && !seen.has(id)) {
166
+ seen.add(id);
167
+ messages.push({ id, text, description });
168
+ }
169
+ }
170
+ }
171
+ return messages;
172
+ }
173
+ /**
174
+ * Serializes extracted messages into the specified format.
175
+ */
176
+ export function serializeMessages(messages, format, sourceLocale) {
177
+ switch (format) {
178
+ case 'xliff':
179
+ return serializeXliff1(messages, sourceLocale);
180
+ case 'xliff2':
181
+ return serializeXliff2(messages, sourceLocale);
182
+ case 'xmb':
183
+ return serializeXmb(messages);
184
+ case 'json':
185
+ default:
186
+ return serializeJson(messages);
187
+ }
188
+ }
189
+ function serializeJson(messages) {
190
+ const obj = {};
191
+ for (const msg of messages) {
192
+ obj[msg.id] = msg.text;
193
+ }
194
+ return JSON.stringify(obj, null, 2) + '\n';
195
+ }
196
+ function serializeXliff1(messages, sourceLocale) {
197
+ const units = messages
198
+ .map((msg) => {
199
+ const note = msg.description
200
+ ? `\n <note>${escapeXml(msg.description)}</note>`
201
+ : '';
202
+ return ` <trans-unit id="${escapeXml(msg.id)}" datatype="html">
203
+ <source>${escapeXml(msg.text)}</source>${note}
204
+ </trans-unit>`;
205
+ })
206
+ .join('\n');
207
+ return `<?xml version="1.0" encoding="UTF-8"?>
208
+ <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
209
+ <file source-language="${sourceLocale}" datatype="plaintext" original="ng2.template">
210
+ <body>
211
+ ${units}
212
+ </body>
213
+ </file>
214
+ </xliff>
215
+ `;
216
+ }
217
+ function serializeXliff2(messages, sourceLocale) {
218
+ const units = messages
219
+ .map((msg) => {
220
+ const notes = msg.description
221
+ ? `\n <notes><note>${escapeXml(msg.description)}</note></notes>`
222
+ : '';
223
+ return ` <unit id="${escapeXml(msg.id)}">${notes}
224
+ <segment>
225
+ <source>${escapeXml(msg.text)}</source>
226
+ </segment>
227
+ </unit>`;
228
+ })
229
+ .join('\n');
230
+ return `<?xml version="1.0" encoding="UTF-8"?>
231
+ <xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="${sourceLocale}">
232
+ <file id="ngi18n" original="ng.template">
233
+ ${units}
234
+ </file>
235
+ </xliff>
236
+ `;
237
+ }
238
+ function serializeXmb(messages) {
239
+ const msgs = messages
240
+ .map((msg) => {
241
+ const desc = msg.description
242
+ ? ` desc="${escapeXml(msg.description)}"`
243
+ : '';
244
+ return ` <msg id="${escapeXml(msg.id)}"${desc}>${escapeXml(msg.text)}</msg>`;
245
+ })
246
+ .join('\n');
247
+ return `<?xml version="1.0" encoding="UTF-8"?>
248
+ <!DOCTYPE messagebundle [
249
+ <!ELEMENT messagebundle (msg)*>
250
+ <!ELEMENT msg (#PCDATA)>
251
+ <!ATTLIST msg id CDATA #REQUIRED>
252
+ <!ATTLIST msg desc CDATA #IMPLIED>
253
+ ]>
254
+ <messagebundle>
255
+ ${msgs}
256
+ </messagebundle>
257
+ `;
258
+ }
259
+ function escapeXml(str) {
260
+ return str
261
+ .replace(/&/g, '&amp;')
262
+ .replace(/</g, '&lt;')
263
+ .replace(/>/g, '&gt;')
264
+ .replace(/"/g, '&quot;');
265
+ }
266
+ /**
267
+ * Recursively collects all .js files from a directory.
268
+ */
269
+ function collectJsFiles(dir) {
270
+ const files = [];
271
+ try {
272
+ const entries = readdirSync(dir, { withFileTypes: true });
273
+ for (const entry of entries) {
274
+ const fullPath = resolve(dir, entry.name);
275
+ if (entry.isDirectory()) {
276
+ files.push(...collectJsFiles(fullPath));
277
+ }
278
+ else if (entry.isFile() && extname(entry.name) === '.js') {
279
+ files.push(fullPath);
280
+ }
281
+ }
282
+ }
283
+ catch {
284
+ // Directory doesn't exist yet (e.g., first build)
285
+ }
286
+ return files;
287
+ }
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi1leHRyYWN0LXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYXRmb3JtL3NyYy9saWIvaTE4bi1leHRyYWN0LXBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEQsT0FBTyxFQUNMLFlBQVksRUFDWixhQUFhLEVBQ2IsU0FBUyxFQUNULFdBQVcsRUFDWCxRQUFRLEdBQ1QsTUFBTSxTQUFTLENBQUM7QUFJakIsTUFBTSxpQkFBaUIsR0FBMkI7SUFDaEQsSUFBSSxFQUFFLE9BQU87SUFDYixLQUFLLEVBQUUsTUFBTTtJQUNiLE1BQU0sRUFBRSxNQUFNO0lBQ2QsR0FBRyxFQUFFLE1BQU07Q0FDWixDQUFDO0FBRUY7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxXQUF3QjtJQUN4RCxJQUFJLE1BQXNCLENBQUM7SUFDM0IsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBRXZCLE1BQU0sYUFBYSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7SUFDMUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ25CLE9BQU8sRUFBRSxJQUFJLEVBQUUsMEJBQTBCLEVBQVksQ0FBQztJQUN4RCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUM7SUFFOUMsT0FBTztRQUNMLElBQUksRUFBRSxxQkFBcUI7UUFDM0IsS0FBSyxFQUFFLE9BQU87UUFFZCxjQUFjLENBQUMsY0FBYztZQUMzQixNQUFNLEdBQUcsY0FBYyxDQUFDO1lBQ3hCLFVBQVUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDbEMsQ0FBQztRQUVELEtBQUssQ0FBQyxXQUFXO1lBQ2Ysd0NBQXdDO1lB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
@@ -1,10 +1,10 @@
1
1
  export declare const V18_X_NX_DEVKIT = "^20.0.0";
2
2
  export declare const V18_X_NX_ANGULAR = "^20.0.0";
3
- export declare const V18_X_ANALOG_JS_CONTENT = "^2.5.0-beta.5";
4
- export declare const V18_X_ANALOG_JS_ROUTER = "^2.5.0-beta.5";
3
+ export declare const V18_X_ANALOG_JS_CONTENT = "^2.5.0-beta.51";
4
+ export declare const V18_X_ANALOG_JS_ROUTER = "^2.5.0-beta.51";
5
5
  export declare const V18_X_ANALOG_JS_TRPC = "~0.4.0";
6
- export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.5";
7
- export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.5";
6
+ export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.51";
7
+ export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.51";
8
8
  export declare const V18_X_TRPC_CLIENT = "^10.25.0";
9
9
  export declare const V18_X_TRPC_SERVER = "^10.25.0";
10
10
  export declare const V18_X_ISOMORPHIC_FETCH = "^3.0.0";
@@ -20,7 +20,7 @@ export declare const V18_X_TAILWINDCSS = "^4.1.4";
20
20
  export declare const V18_X_TAILWINDCSS_VITE = "^4.1.4";
21
21
  export declare const V18_X_POSTCSS = "^8.5.3";
22
22
  export declare const V18_X_AUTOPREFIXER = "^10.4.0";
23
- export declare const V18_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.5";
23
+ export declare const V18_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.51";
24
24
  export declare const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = "^19.0.0";
25
25
  export declare const V18_X_NX_VITE = "^21.0.0";
26
26
  export declare const V18_X_NX_LINTER = "^21.0.0";
@@ -5,11 +5,11 @@ exports.V18_X_ZOD = exports.V18_X_VITEST = exports.V18_X_VITE_TSCONFIG_PATHS = e
5
5
  // dependencies
6
6
  exports.V18_X_NX_DEVKIT = '^20.0.0';
7
7
  exports.V18_X_NX_ANGULAR = '^20.0.0';
8
- exports.V18_X_ANALOG_JS_CONTENT = '^2.5.0-beta.5';
9
- exports.V18_X_ANALOG_JS_ROUTER = '^2.5.0-beta.5';
8
+ exports.V18_X_ANALOG_JS_CONTENT = '^2.5.0-beta.51';
9
+ exports.V18_X_ANALOG_JS_ROUTER = '^2.5.0-beta.51';
10
10
  exports.V18_X_ANALOG_JS_TRPC = '~0.4.0';
11
- exports.V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.5';
12
- exports.V18_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.5';
11
+ exports.V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.51';
12
+ exports.V18_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.51';
13
13
  exports.V18_X_TRPC_CLIENT = '^10.25.0';
14
14
  exports.V18_X_TRPC_SERVER = '^10.25.0';
15
15
  exports.V18_X_ISOMORPHIC_FETCH = '^3.0.0';
@@ -26,7 +26,7 @@ exports.V18_X_TAILWINDCSS_VITE = '^4.1.4';
26
26
  exports.V18_X_POSTCSS = '^8.5.3';
27
27
  exports.V18_X_AUTOPREFIXER = '^10.4.0';
28
28
  // devDependencies
29
- exports.V18_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.5';
29
+ exports.V18_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.51';
30
30
  exports.V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = '^19.0.0';
31
31
  exports.V18_X_NX_VITE = '^21.0.0';
32
32
  exports.V18_X_NX_LINTER = '^21.0.0';
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../../../../../../../../packages/nx-plugin/src/generators/app/versions/nx_18_X/versions.ts"],"names":[],"mappings":";;;AAAA,QAAQ;AACR,eAAe;AACF,QAAA,eAAe,GAAG,SAAS,CAAC;AAC5B,QAAA,gBAAgB,GAAG,SAAS,CAAC;AAC7B,QAAA,uBAAuB,GAAG,eAAe,CAAC;AAC1C,QAAA,sBAAsB,GAAG,eAAe,CAAC;AACzC,QAAA,oBAAoB,GAAG,QAAQ,CAAC;AAChC,QAAA,mCAAmC,GAAG,eAAe,CAAC;AACtD,QAAA,8BAA8B,GAAG,eAAe,CAAC;AACjD,QAAA,iBAAiB,GAAG,UAAU,CAAC;AAC/B,QAAA,iBAAiB,GAAG,UAAU,CAAC;AAC/B,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,eAAe,GAAG,QAAQ,CAAC;AAC3B,QAAA,kBAAkB,GAAG,QAAQ,CAAC;AAC9B,QAAA,YAAY,GAAG,SAAS,CAAC;AACzB,QAAA,2BAA2B,GAAG,QAAQ,CAAC;AACvC,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,iBAAiB,GAAG,QAAQ,CAAC;AAC7B,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,aAAa,GAAG,QAAQ,CAAC;AACzB,QAAA,kBAAkB,GAAG,SAAS,CAAC;AAE5C,kBAAkB;AACL,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,kCAAkC,GAAG,SAAS,CAAC;AAC/C,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,eAAe,GAAG,SAAS,CAAC;AAC5B,QAAA,WAAW,GAAG,SAAS,CAAC;AACxB,QAAA,UAAU,GAAG,QAAQ,CAAC;AACtB,QAAA,yBAAyB,GAAG,QAAQ,CAAC;AACrC,QAAA,YAAY,GAAG,QAAQ,CAAC;AACxB,QAAA,SAAS,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../../../../../../../../packages/nx-plugin/src/generators/app/versions/nx_18_X/versions.ts"],"names":[],"mappings":";;;AAAA,QAAQ;AACR,eAAe;AACF,QAAA,eAAe,GAAG,SAAS,CAAC;AAC5B,QAAA,gBAAgB,GAAG,SAAS,CAAC;AAC7B,QAAA,uBAAuB,GAAG,gBAAgB,CAAC;AAC3C,QAAA,sBAAsB,GAAG,gBAAgB,CAAC;AAC1C,QAAA,oBAAoB,GAAG,QAAQ,CAAC;AAChC,QAAA,mCAAmC,GAAG,gBAAgB,CAAC;AACvD,QAAA,8BAA8B,GAAG,gBAAgB,CAAC;AAClD,QAAA,iBAAiB,GAAG,UAAU,CAAC;AAC/B,QAAA,iBAAiB,GAAG,UAAU,CAAC;AAC/B,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,eAAe,GAAG,QAAQ,CAAC;AAC3B,QAAA,kBAAkB,GAAG,QAAQ,CAAC;AAC9B,QAAA,YAAY,GAAG,SAAS,CAAC;AACzB,QAAA,2BAA2B,GAAG,QAAQ,CAAC;AACvC,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,iBAAiB,GAAG,QAAQ,CAAC;AAC7B,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,aAAa,GAAG,QAAQ,CAAC;AACzB,QAAA,kBAAkB,GAAG,SAAS,CAAC;AAE5C,kBAAkB;AACL,QAAA,wBAAwB,GAAG,gBAAgB,CAAC;AAC5C,QAAA,kCAAkC,GAAG,SAAS,CAAC;AAC/C,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,eAAe,GAAG,SAAS,CAAC;AAC5B,QAAA,WAAW,GAAG,SAAS,CAAC;AACxB,QAAA,UAAU,GAAG,QAAQ,CAAC;AACtB,QAAA,yBAAyB,GAAG,QAAQ,CAAC;AACrC,QAAA,YAAY,GAAG,QAAQ,CAAC;AACxB,QAAA,SAAS,GAAG,SAAS,CAAC"}
@@ -1,13 +1,13 @@
1
- export declare const V19_X_ANALOG_JS_ROUTER = "^2.5.0-beta.5";
2
- export declare const V19_X_ANALOG_JS_CONTENT = "^2.5.0-beta.5";
1
+ export declare const V19_X_ANALOG_JS_ROUTER = "^2.5.0-beta.51";
2
+ export declare const V19_X_ANALOG_JS_CONTENT = "^2.5.0-beta.51";
3
3
  export declare const V19_X_MARKED = "^15.0.7";
4
4
  export declare const V19_X_MARKED_GFM_HEADING_ID = "^4.1.1";
5
5
  export declare const V19_X_MARKED_HIGHLIGHT = "^2.2.1";
6
6
  export declare const V19_X_MARKED_MANGLE = "^1.1.10";
7
7
  export declare const V19_X_PRISMJS = "^1.29.0";
8
- export declare const V19_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.5";
9
- export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.5";
10
- export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.5";
8
+ export declare const V19_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.51";
9
+ export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.51";
10
+ export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.51";
11
11
  export declare const V19_X_NX_ANGULAR = "^22.0.0";
12
12
  export declare const V19_X_NX_VITE = "^22.0.0";
13
13
  export declare const V19_X_JSDOM = "^22.0.0";
@@ -2,17 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NX_X_LATEST_VITEST = exports.NX_X_LATEST_VITE = exports.V19_X_VITE = exports.V19_X_VITEST = exports.V19_X_VITE_TSCONFIG_PATHS = exports.V19_X_JSDOM = exports.V19_X_NX_VITE = exports.V19_X_NX_ANGULAR = exports.V19_X_ANALOG_JS_VITEST_ANGULAR = exports.V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = exports.V19_X_ANALOG_JS_PLATFORM = exports.V19_X_PRISMJS = exports.V19_X_MARKED_MANGLE = exports.V19_X_MARKED_HIGHLIGHT = exports.V19_X_MARKED_GFM_HEADING_ID = exports.V19_X_MARKED = exports.V19_X_ANALOG_JS_CONTENT = exports.V19_X_ANALOG_JS_ROUTER = void 0;
4
4
  // V19_X
5
- exports.V19_X_ANALOG_JS_ROUTER = '^2.5.0-beta.5';
6
- exports.V19_X_ANALOG_JS_CONTENT = '^2.5.0-beta.5';
5
+ exports.V19_X_ANALOG_JS_ROUTER = '^2.5.0-beta.51';
6
+ exports.V19_X_ANALOG_JS_CONTENT = '^2.5.0-beta.51';
7
7
  exports.V19_X_MARKED = '^15.0.7';
8
8
  exports.V19_X_MARKED_GFM_HEADING_ID = '^4.1.1';
9
9
  exports.V19_X_MARKED_HIGHLIGHT = '^2.2.1';
10
10
  exports.V19_X_MARKED_MANGLE = '^1.1.10';
11
11
  exports.V19_X_PRISMJS = '^1.29.0';
12
12
  // devDependencies
13
- exports.V19_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.5';
14
- exports.V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.5';
15
- exports.V19_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.5';
13
+ exports.V19_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.51';
14
+ exports.V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.51';
15
+ exports.V19_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.51';
16
16
  exports.V19_X_NX_ANGULAR = '^22.0.0';
17
17
  exports.V19_X_NX_VITE = '^22.0.0';
18
18
  exports.V19_X_JSDOM = '^22.0.0';
@@ -1 +1 @@
1
- {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../../../../../../../packages/nx-plugin/src/utils/versions/ng_19_X/versions.ts"],"names":[],"mappings":";;;AAAA,QAAQ;AACK,QAAA,sBAAsB,GAAG,eAAe,CAAC;AACzC,QAAA,uBAAuB,GAAG,eAAe,CAAC;AAC1C,QAAA,YAAY,GAAG,SAAS,CAAC;AACzB,QAAA,2BAA2B,GAAG,QAAQ,CAAC;AACvC,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,aAAa,GAAG,SAAS,CAAC;AAEvC,kBAAkB;AACL,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,mCAAmC,GAAG,eAAe,CAAC;AACtD,QAAA,8BAA8B,GAAG,eAAe,CAAC;AACjD,QAAA,gBAAgB,GAAG,SAAS,CAAC;AAC7B,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,WAAW,GAAG,SAAS,CAAC;AACxB,QAAA,yBAAyB,GAAG,QAAQ,CAAC;AACrC,QAAA,YAAY,GAAG,QAAQ,CAAC;AACxB,QAAA,UAAU,GAAG,QAAQ,CAAC;AACtB,QAAA,gBAAgB,GAAG,QAAQ,CAAC;AAC5B,QAAA,kBAAkB,GAAG,QAAQ,CAAC"}
1
+ {"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../../../../../../../../packages/nx-plugin/src/utils/versions/ng_19_X/versions.ts"],"names":[],"mappings":";;;AAAA,QAAQ;AACK,QAAA,sBAAsB,GAAG,gBAAgB,CAAC;AAC1C,QAAA,uBAAuB,GAAG,gBAAgB,CAAC;AAC3C,QAAA,YAAY,GAAG,SAAS,CAAC;AACzB,QAAA,2BAA2B,GAAG,QAAQ,CAAC;AACvC,QAAA,sBAAsB,GAAG,QAAQ,CAAC;AAClC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,aAAa,GAAG,SAAS,CAAC;AAEvC,kBAAkB;AACL,QAAA,wBAAwB,GAAG,gBAAgB,CAAC;AAC5C,QAAA,mCAAmC,GAAG,gBAAgB,CAAC;AACvD,QAAA,8BAA8B,GAAG,gBAAgB,CAAC;AAClD,QAAA,gBAAgB,GAAG,SAAS,CAAC;AAC7B,QAAA,aAAa,GAAG,SAAS,CAAC;AAC1B,QAAA,WAAW,GAAG,SAAS,CAAC;AACxB,QAAA,yBAAyB,GAAG,QAAQ,CAAC;AACrC,QAAA,YAAY,GAAG,QAAQ,CAAC;AACxB,QAAA,UAAU,GAAG,QAAQ,CAAC;AACtB,QAAA,gBAAgB,GAAG,QAAQ,CAAC;AAC5B,QAAA,kBAAkB,GAAG,QAAQ,CAAC"}
@@ -23,6 +23,32 @@ export interface PrerenderOptions {
23
23
  /** List of functions that run for each route after pre-rendering is complete. */
24
24
  postRenderingHooks?: ((routes: PrerenderRoute) => Promise<void>)[];
25
25
  }
26
+ export interface I18nOptions {
27
+ /**
28
+ * The default/source locale for the application.
29
+ */
30
+ defaultLocale: string;
31
+ /**
32
+ * List of supported locale identifiers (e.g. ['en', 'fr', 'de']).
33
+ */
34
+ locales: string[];
35
+ /**
36
+ * Extract i18n messages from the build output.
37
+ * When enabled, writes a translation source file after the client build.
38
+ */
39
+ extract?: {
40
+ /**
41
+ * Output format for extracted messages.
42
+ * @default 'json'
43
+ */
44
+ format?: 'json' | 'xliff' | 'xliff2' | 'xmb';
45
+ /**
46
+ * Output file path for extracted messages, relative to project root.
47
+ * @default 'src/i18n/messages.{format extension}'
48
+ */
49
+ outFile?: string;
50
+ };
51
+ }
26
52
  export interface Options {
27
53
  ssr?: boolean;
28
54
  ssrBuildDir?: string;
@@ -77,9 +103,26 @@ export interface Options {
77
103
  * Disable type checking diagnostics by the Angular compiler
78
104
  */
79
105
  disableTypeChecking?: boolean;
106
+ /**
107
+ * Opt into the fast compile path. Skips Angular's template type-checking
108
+ * and routes compilation through an internal single-pass transform.
109
+ */
110
+ fastCompile?: boolean;
111
+ /**
112
+ * Compilation output mode used when `fastCompile` is enabled.
113
+ * - `'full'` (default): Emit final Ivy definitions for application builds.
114
+ * - `'partial'`: Emit partial declarations for library publishing.
115
+ */
116
+ fastCompileMode?: 'full' | 'partial';
80
117
  /**
81
118
  * File replacements
82
119
  */
83
120
  fileReplacements?: PluginOptions['fileReplacements'];
121
+ /**
122
+ * Configuration for runtime i18n support.
123
+ * When set, enables locale detection on SSR and provides
124
+ * the LOCALE injection token.
125
+ */
126
+ i18n?: I18nOptions;
84
127
  }
85
128
  export { PrerenderContentDir, PrerenderContentFile };
@@ -1,13 +1,14 @@
1
1
  import viteNitroPlugin from '@analogjs/vite-plugin-nitro';
2
2
  import angular from '@analogjs/vite-plugin-angular';
3
3
  import { routerPlugin } from './router-plugin.js';
4
- import { ssrBuildPlugin } from './ssr/ssr-build-plugin.js';
4
+ import { ssrBuildPlugin, i18nDefRegistryPlugin, } from './ssr/ssr-build-plugin.js';
5
5
  import { contentPlugin } from './content-plugin.js';
6
6
  import { clearClientPageEndpointsPlugin } from './clear-client-page-endpoint.js';
7
7
  import { ssrXhrBuildPlugin } from './ssr/ssr-xhr-plugin.js';
8
8
  import { depsPlugin } from './deps-plugin.js';
9
9
  import { injectHTMLPlugin } from './ssr/inject-html-plugin.js';
10
10
  import { serverModePlugin } from '../server-mode-plugin.js';
11
+ import { i18nExtractPlugin } from './i18n-extract-plugin.js';
11
12
  export function platformPlugin(opts = {}) {
12
13
  const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];
13
14
  const { ...platformOptions } = {
@@ -52,11 +53,17 @@ export function platformPlugin(opts = {}) {
52
53
  liveReload: platformOptions.liveReload,
53
54
  inlineStylesExtension: platformOptions.inlineStylesExtension,
54
55
  fileReplacements: platformOptions.fileReplacements,
56
+ fastCompile: platformOptions.fastCompile,
57
+ fastCompileMode: platformOptions.fastCompileMode,
55
58
  ...(opts?.vite ?? {}),
56
59
  })),
57
60
  serverModePlugin(),
58
61
  ssrXhrBuildPlugin(),
59
62
  clearClientPageEndpointsPlugin(),
63
+ ...(platformOptions.i18n ? [i18nDefRegistryPlugin()] : []),
64
+ ...(platformOptions.i18n?.extract
65
+ ? [i18nExtractPlugin(platformOptions.i18n)]
66
+ : []),
60
67
  ];
61
68
  }
62
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhdGZvcm0tcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcGxhdGZvcm0vc3JjL2xpYi9wbGF0Zm9ybS1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxlQUFlLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxPQUFPLE1BQU0sK0JBQStCLENBQUM7QUFHcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTVELE1BQU0sVUFBVSxjQUFjLENBQUMsT0FBZ0IsRUFBRTtJQUMvQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM3RSxNQUFNLEVBQUUsR0FBRyxlQUFlLEVBQUUsR0FBRztRQUM3QixHQUFHLEVBQUUsSUFBSTtRQUNULEdBQUcsSUFBSTtLQUNSLENBQUM7SUFFRixJQUFJLFlBQVksR0FBRyxlQUFlLEVBQUUsS0FBSyxDQUFDO0lBRTFDLElBQUksWUFBWSxFQUFFLFVBQVUsRUFBRSxDQUFDO1FBQzdCLFlBQVksR0FBRztZQUNiLEdBQUcsWUFBWTtZQUNmLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLENBQ3JELENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFO2dCQUNmLE9BQU87b0JBQ0wsR0FBRyxNQUFNO29CQUNULENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQ04sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO3dCQUNmLE9BQU8sRUFBRTs0QkFDUCxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPOzRCQUN2QixpQkFBaUIsRUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTO3lCQUM1QztxQkFDVDtpQkFDRixDQUFDO1lBQ0osQ0FBQyxFQUNELFlBQVksQ0FBQyxVQUFVLENBQ3hCO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsR0FBRyxlQUFlLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQztRQUNqRCxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxHQUFHLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3pFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDL0MsR0FBRyxZQUFZLENBQUMsZUFBZSxDQUFDO1FBQ2hDLEdBQUcsYUFBYSxDQUFDLGVBQWUsRUFBRSxPQUFPLEVBQUUsZUFBZSxDQUFDO1FBQzNELEdBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLLEtBQUs7WUFDdkIsQ0FBQyxDQUFDLEVBQUU7WUFDSixDQUFDLENBQUMsT0FBTyxDQUFDO2dCQUNOLEdBQUcsRUFBRSxlQUFlLENBQUMsR0FBRztnQkFDeEIsYUFBYSxFQUFFLGVBQWUsQ0FBQyxhQUFhO2dCQUM1QyxtQkFBbUIsRUFBRSxlQUFlLENBQUMsbUJBQW1CLElBQUksS0FBSztnQkFDakUsT0FBTyxFQUFFO29CQUNQLEdBQUcsQ0FBQyxlQUFlLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztvQkFDbEMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxtQkFBbUIsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQ2hELENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxHQUFHLE9BQU8sZUFBZSxDQUN2QztpQkFDRjtnQkFDRCxxQkFBcUIsRUFBRSxlQUFlLENBQUMscUJBQXFCO2dCQUM1RCxVQUFVLEVBQUUsZUFBZSxDQUFDLFVBQVU7Z0JBQ3RDLHFCQUFxQixFQUFFLGVBQWUsQ0FBQyxxQkFBcUI7Z0JBQzVELGdCQUFnQixFQUFFLGVBQWUsQ0FBQyxnQkFBZ0I7Z0JBQ2xELEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQzthQUN0QixDQUFDLENBQVM7UUFDZixnQkFBZ0IsRUFBRTtRQUNsQixpQkFBaUIsRUFBWTtRQUM3Qiw4QkFBOEIsRUFBWTtLQUMzQyxDQUFDO0FBQ0osQ0FBQyJ9
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhdGZvcm0tcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcGxhdGZvcm0vc3JjL2xpYi9wbGF0Zm9ybS1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxlQUFlLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxPQUFPLE1BQU0sK0JBQStCLENBQUM7QUFHcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFDTCxjQUFjLEVBQ2QscUJBQXFCLEdBQ3RCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU3RCxNQUFNLFVBQVUsY0FBYyxDQUFDLE9BQWdCLEVBQUU7SUFDL0MsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxNQUFNLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDN0UsTUFBTSxFQUFFLEdBQUcsZUFBZSxFQUFFLEdBQUc7UUFDN0IsR0FBRyxFQUFFLElBQUk7UUFDVCxHQUFHLElBQUk7S0FDUixDQUFDO0lBRUYsSUFBSSxZQUFZLEdBQUcsZUFBZSxFQUFFLEtBQUssQ0FBQztJ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
@@ -1,2 +1,15 @@
1
- import { Plugin } from 'vite';
1
+ import { type Plugin } from 'vite';
2
2
  export declare function ssrBuildPlugin(): Plugin;
3
+ /**
4
+ * Vite plugin that patches `@angular/core`'s `getComponentId()` to
5
+ * mirror every compiled component definition to a global Set, bypassing
6
+ * the `ngServerMode` guard that normally prevents registration on the
7
+ * server. The set lives at `globalThis.__ngComponentDefs` and is read by
8
+ * `@analogjs/router`'s SSR render function to null cached `tView`
9
+ * objects between requests so that `$localize` tagged templates in
10
+ * `consts()` re-evaluate with the freshly loaded translations.
11
+ *
12
+ * Only active when the platform's `i18n` option is configured.
13
+ * Only transforms `@angular/core` modules in SSR builds.
14
+ */
15
+ export declare function i18nDefRegistryPlugin(): Plugin;
@@ -2,30 +2,71 @@ import { normalizePath } from 'vite';
2
2
  export function ssrBuildPlugin() {
3
3
  return {
4
4
  name: 'analogjs-ssr-build-plugin',
5
- transform(code, id) {
6
- if (id.includes('zone-node') &&
7
- code.includes('const global = globalThis;')) {
8
- return {
9
- code: code.replace('const global = globalThis;', ''),
10
- };
11
- }
12
- if (id.includes('platform-server')) {
13
- return {
14
- code: code
15
- .replace('new xhr2.XMLHttpRequest', 'new (xhr2.default.XMLHttpRequest || xhr2.default)')
16
- .replaceAll('global.', 'globalThis.')
17
- .replaceAll('global,', 'globalThis,')
18
- .replaceAll(' global[', ' globalThis['),
19
- };
20
- }
21
- // Remove usage of `with()` in sloppy.js file
22
- if (id.includes(normalizePath('domino/lib/sloppy.js'))) {
5
+ transform: {
6
+ filter: {
7
+ id: {
8
+ include: [/zone-node/, /platform-server/, /domino\/lib\/sloppy/],
9
+ },
10
+ },
11
+ handler(code, id) {
12
+ if (id.includes('zone-node') &&
13
+ code.includes('const global = globalThis;')) {
14
+ return {
15
+ code: code.replace('const global = globalThis;', ''),
16
+ };
17
+ }
18
+ if (id.includes('platform-server')) {
19
+ return {
20
+ code: code
21
+ .replace('new xhr2.XMLHttpRequest', 'new (xhr2.default.XMLHttpRequest || xhr2.default)')
22
+ .replaceAll('global.', 'globalThis.')
23
+ .replaceAll('global,', 'globalThis,')
24
+ .replaceAll(' global[', ' globalThis['),
25
+ };
26
+ }
27
+ if (id.includes(normalizePath('domino/lib/sloppy.js'))) {
28
+ return {
29
+ code: code.replace(/with\(/gi, 'if('),
30
+ };
31
+ }
32
+ return;
33
+ },
34
+ },
35
+ };
36
+ }
37
+ /**
38
+ * Vite plugin that patches `@angular/core`'s `getComponentId()` to
39
+ * mirror every compiled component definition to a global Set, bypassing
40
+ * the `ngServerMode` guard that normally prevents registration on the
41
+ * server. The set lives at `globalThis.__ngComponentDefs` and is read by
42
+ * `@analogjs/router`'s SSR render function to null cached `tView`
43
+ * objects between requests so that `$localize` tagged templates in
44
+ * `consts()` re-evaluate with the freshly loaded translations.
45
+ *
46
+ * Only active when the platform's `i18n` option is configured.
47
+ * Only transforms `@angular/core` modules in SSR builds.
48
+ */
49
+ export function i18nDefRegistryPlugin() {
50
+ const DETECT_MARKER = 'GENERATED_COMP_IDS.set(compId, componentDef.type);';
51
+ const RETURN_STMT = 'return compId;\n}';
52
+ return {
53
+ name: 'analogjs-i18n-def-registry',
54
+ enforce: 'post',
55
+ transform: {
56
+ filter: {
57
+ id: /\/@angular\/core\//,
58
+ },
59
+ handler(code, id, options) {
60
+ if (!options?.ssr)
61
+ return;
62
+ if (!code.includes(DETECT_MARKER))
63
+ return;
23
64
  return {
24
- code: code.replace(/with\(/gi, 'if('),
65
+ code: code.replace(RETURN_STMT, '(globalThis.__ngComponentDefs ??= new Set()).add(componentDef);\n' +
66
+ RETURN_STMT),
25
67
  };
26
- }
27
- return;
68
+ },
28
69
  },
29
70
  };
30
71
  }
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NyLWJ1aWxkLXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYXRmb3JtL3NyYy9saWIvc3NyL3Nzci1idWlsZC1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBVSxNQUFNLE1BQU0sQ0FBQztBQUU3QyxNQUFNLFVBQVUsY0FBYztJQUM1QixPQUFPO1FBQ0wsSUFBSSxFQUFFLDJCQUEyQjtRQUNqQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDaEIsSUFDRSxFQUFFLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyw0QkFBNEIsQ0FBQyxFQUMzQyxDQUFDO2dCQUNELE9BQU87b0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxDQUFDO2lCQUNyRCxDQUFDO1lBQ0osQ0FBQztZQUVELElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7Z0JBQ25DLE9BQU87b0JBQ0wsSUFBSSxFQUFFLElBQUk7eUJBQ1AsT0FBTyxDQUNOLHlCQUF5QixFQUN6QixtREFBbUQsQ0FDcEQ7eUJBQ0EsVUFBVSxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUM7eUJBQ3BDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDO3lCQUNwQyxVQUFVLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQztpQkFDMUMsQ0FBQztZQUNKLENBQUM7WUFFRCw2Q0FBNkM7WUFDN0MsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDdkQsT0FBTztvQkFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDO2lCQUN0QyxDQUFDO1lBQ0osQ0FBQztZQUVELE9BQU87UUFDVCxDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMifQ==
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NyLWJ1aWxkLXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYXRmb3JtL3NyYy9saWIvc3NyL3Nzci1idWlsZC1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBcUMsTUFBTSxNQUFNLENBQUM7QUFFeEUsTUFBTSxVQUFVLGNBQWM7SUFDNUIsT0FBTztRQUNMLElBQUksRUFBRSwyQkFBMkI7UUFDakMsU0FBUyxFQUFFO1lBQ1QsTUFBTSxFQUFFO2dCQUNOLEVBQUUsRUFBRTtvQkFDRixPQUFPLEVBQUUsQ0FBQyxXQUFXLEVBQUUsaUJBQWlCLEVBQUUscUJBQXFCLENBQUM7aUJBQ2pFO2FBQ0Y7WUFDRCxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUU7Z0JBQ2QsSUFDRSxFQUFFLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztvQkFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyw0QkFBNEIsQ0FBQyxFQUMzQyxDQUFDO29CQUNELE9BQU87d0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxDQUFDO3FCQUNyRCxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztvQkFDbkMsT0FBTzt3QkFDTCxJQUFJLEVBQUUsSUFBSTs2QkFDUCxPQUFPLENBQ04seUJBQXlCLEVBQ3pCLG1EQUFtRCxDQUNwRDs2QkFDQSxVQUFVLENBQUMsU0FBUyxFQUFFLGFBQWEsQ0FBQzs2QkFDcEMsVUFBVSxDQUFDLFNBQVMsRUFBRSxhQUFhLENBQUM7NkJBQ3BDLFVBQVUsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDO3FCQUMxQyxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDdkQsT0FBTzt3QkFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDO3FCQUN0QyxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsT0FBTztZQUNULENBQUM7U0FDRjtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLE1BQU0sYUFBYSxHQUFHLG9EQUFvRCxDQUFDO0lBQzNFLE1BQU0sV0FBVyxHQUFHLG1CQUFtQixDQUFDO0lBRXhDLE9BQU87UUFDTCxJQUFJLEVBQUUsNEJBQTRCO1FBQ2xDLE9BQU8sRUFBRSxNQUFNO1FBRWYsU0FBUyxFQUFFO1lBQ1QsTUFBTSxFQUFFO2dCQUNOLEVBQUUsRUFBRSxvQkFBb0I7YUFDekI7WUFDRCxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxPQUFPO2dCQUN2QixJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUc7b0JBQUUsT0FBTztnQkFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDO29CQUFFLE9BQU87Z0JBRTFDLE9BQU87b0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQ2hCLFdBQVcsRUFDWCxtRUFBbUU7d0JBQ2pFLFdBQVcsQ0FDZDtpQkFDRixDQUFDO1lBQ0osQ0FBQztTQUNGO0tBQ0YsQ0FBQztBQUNKLENBQUMifQ==