Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@electron/get

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@electron/get - npm Package Compare versions

Comparing version
4.0.3
to
5.0.0
+43
dist/FetchDownloader.d.ts
import { Downloader } from './Downloader.js';
/**
* @category Downloader
*/
export interface Progress {
/** Bytes downloaded so far. */
transferred: number;
/** Total bytes to download, or `null` if the response had no `Content-Length` header. */
total: number | null;
/**
* Ratio of `transferred` to `total` between 0 and 1.
* If `total` is unknown, this is 0 until the download completes, then 1.
*/
percent: number;
}
/**
* @category Downloader
*/
export declare class HTTPError extends Error {
readonly response: Response;
constructor(response: Response);
}
/**
* @category Downloader
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/RequestInit | `RequestInit`} for possible keys/values.
*/
export type FetchDownloaderOptions = RequestInit & {
/** Called on each chunk with the current download {@link Progress}. */
getProgressCallback?: (progress: Progress) => Promise<void>;
/**
* Disables the console progress bar. Setting the `ELECTRON_GET_NO_PROGRESS`
* environment variable to a non-empty value also does this.
*/
quiet?: boolean;
};
/**
* Default {@link Downloader} implemented with the built-in
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API}.
* @category Downloader
*/
export declare class FetchDownloader implements Downloader<FetchDownloaderOptions> {
download(url: string, targetFilePath: string, options?: FetchDownloaderOptions): Promise<void>;
}
import fs from 'graceful-fs';
import path from 'node:path';
import ProgressBar from 'progress';
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';
const PROGRESS_BAR_DELAY_IN_SECONDS = 30;
/**
* @category Downloader
*/
export class HTTPError extends Error {
response;
constructor(response) {
super(`Response code ${response.status} (${response.statusText}) for ${response.url}`);
this.response = response;
this.name = 'HTTPError';
}
}
/**
* Default {@link Downloader} implemented with the built-in
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch API}.
* @category Downloader
*/
export class FetchDownloader {
async download(url, targetFilePath, options = {}) {
const { quiet, getProgressCallback, ...fetchOptions } = options;
let downloadCompleted = false;
let bar;
let progressPercent;
let timeout = undefined;
await fs.promises.mkdir(path.dirname(targetFilePath), { recursive: true });
if (!quiet && !process.env.ELECTRON_GET_NO_PROGRESS) {
const start = new Date();
timeout = setTimeout(() => {
if (!downloadCompleted) {
bar = new ProgressBar(`Downloading ${path.basename(url)}: [:bar] :percent ETA: :eta seconds `, {
curr: progressPercent,
total: 100,
});
// https://github.com/visionmedia/node-progress/issues/159
// eslint-disable-next-line @typescript-eslint/no-explicit-any
bar.start = start;
}
}, PROGRESS_BAR_DELAY_IN_SECONDS * 1000);
}
try {
const response = await fetch(url, fetchOptions);
if (!response.ok) {
throw new HTTPError(response);
}
if (!response.body) {
throw new Error('Response body is empty');
}
const contentLength = response.headers.get('content-length');
const total = contentLength ? parseInt(contentLength, 10) : null;
let transferred = 0;
const onProgress = (percent) => {
progressPercent = percent;
if (bar) {
bar.update(percent);
}
if (getProgressCallback) {
void getProgressCallback({ transferred, total, percent });
}
};
await pipeline(Readable.fromWeb(response.body), async function* (source) {
for await (const chunk of source) {
transferred += chunk.length;
onProgress(total ? transferred / total : 0);
yield chunk;
}
}, fs.createWriteStream(targetFilePath));
onProgress(1);
}
finally {
downloadCompleted = true;
if (timeout) {
clearTimeout(timeout);
}
}
}
}
//# sourceMappingURL=FetchDownloader.js.map
{"version":3,"file":"FetchDownloader.js","sourceRoot":"","sources":["../src/FetchDownloader.ts"],"names":[],"mappings":"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"}
+2
-6

@@ -1,9 +0,5 @@

// TODO: Resolve the downloader or default to GotDownloader
// Current thoughts are a dot-file traversal for something like
// ".electron.downloader" which would be a text file with the name of the
// npm module to import() and use as the downloader
import { GotDownloader } from './GotDownloader.js';
import { FetchDownloader } from './FetchDownloader.js';
export async function getDownloaderForSystem() {
return new GotDownloader();
return new FetchDownloader();
}
//# sourceMappingURL=downloader-resolver.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"downloader-resolver.js","sourceRoot":"","sources":["../src/downloader-resolver.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,+DAA+D;AAC/D,yEAAyE;AACzE,mDAAmD;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,IAAI,aAAa,EAAE,CAAC;AAC7B,CAAC"}
{"version":3,"file":"downloader-resolver.js","sourceRoot":"","sources":["../src/downloader-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,OAAO,IAAI,eAAe,EAAE,CAAC;AAC/B,CAAC"}
/**
* Generic interface for the artifact downloader library.
* The default implementation is {@link GotDownloader},
* The default implementation is {@link FetchDownloader},
* but any custom downloader can be passed to `@electron/get` via

@@ -5,0 +5,0 @@ * the {@link ElectronDownloadRequestOptions.downloader} option.

@@ -8,11 +8,8 @@ /**

*
* Supported environment variables are `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`.
*
* @category Utility
* @see {@link https://github.com/gajus/global-agent?tab=readme-ov-file#environment-variables | `global-agent`}
* @see {@link https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent | `EnvHttpProxyAgent`}
* documentation for available environment variables.
*
* @example
* ```sh
* export GLOBAL_AGENT_HTTPS_PROXY="$HTTPS_PROXY"
* ```
*/
export declare function initializeProxy(): void;
import { createRequire } from 'node:module';
import debug from 'debug';
import { getEnv, setEnv } from './utils.js';
const d = debug('@electron/get:proxy');

@@ -13,29 +12,18 @@ const require = createRequire(import.meta.url);

*
* Supported environment variables are `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`.
*
* @category Utility
* @see {@link https://github.com/gajus/global-agent?tab=readme-ov-file#environment-variables | `global-agent`}
* @see {@link https://undici.nodejs.org/#/docs/api/EnvHttpProxyAgent | `EnvHttpProxyAgent`}
* documentation for available environment variables.
*
* @example
* ```sh
* export GLOBAL_AGENT_HTTPS_PROXY="$HTTPS_PROXY"
* ```
*/
export function initializeProxy() {
try {
// See: https://github.com/electron/get/pull/214#discussion_r798845713
const env = getEnv('GLOBAL_AGENT_');
setEnv('GLOBAL_AGENT_HTTP_PROXY', env('HTTP_PROXY'));
setEnv('GLOBAL_AGENT_HTTPS_PROXY', env('HTTPS_PROXY'));
setEnv('GLOBAL_AGENT_NO_PROXY', env('NO_PROXY'));
/**
* TODO: replace global-agent with a hpagent. @BlackHole1
* https://github.com/sindresorhus/got/blob/HEAD/documentation/tips.md#proxying
*/
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('global-agent').bootstrap();
const { EnvHttpProxyAgent, setGlobalDispatcher } = require('undici');
setGlobalDispatcher(new EnvHttpProxyAgent());
}
catch (e) {
d('Could not load either proxy modules, built-in proxy support not available:', e);
d('Could not load undici, built-in proxy support not available:', e);
}
}
//# sourceMappingURL=proxy.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,CAAC,GAAG,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,sEAAsE;QACtE,MAAM,GAAG,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;QAEpC,MAAM,CAAC,yBAAyB,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,0BAA0B,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,uBAAuB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QAEjD;;;WAGG;QACH,iEAAiE;QACjE,OAAO,CAAC,cAAc,CAAC,CAAC,SAAS,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,CAAC,CAAC,4EAA4E,EAAE,CAAC,CAAC,CAAC;IACrF,CAAC;AACH,CAAC"}
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,GAAG,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrE,mBAAmB,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,CAAC,CAAC,8DAA8D,EAAE,CAAC,CAAC,CAAC;IACvE,CAAC;AACH,CAAC"}
import { Downloader } from './Downloader.js';
import { GotDownloader, GotDownloaderOptions } from './GotDownloader.js';
export { Downloader, GotDownloader, GotDownloaderOptions };
import { FetchDownloader, FetchDownloaderOptions, HTTPError, Progress } from './FetchDownloader.js';
export { Downloader, FetchDownloader, FetchDownloaderOptions, HTTPError, Progress };
/**

@@ -136,3 +136,3 @@ * Custom downloaders can implement any set of options.

*
* @see {@link GotDownloaderOptions} for options for the default {@link GotDownloader}.
* @see {@link FetchDownloaderOptions} for options for the default {@link FetchDownloader}.
*/

@@ -146,3 +146,3 @@ downloadOptions?: DownloadOptions;

* A custom {@link Downloader} class used to download artifacts. Defaults to the
* built-in {@link GotDownloader}.
* built-in {@link FetchDownloader}.
*/

@@ -149,0 +149,0 @@ downloader?: Downloader<DownloadOptions>;

@@ -1,3 +0,3 @@

import { GotDownloader } from './GotDownloader.js';
export { GotDownloader };
import { FetchDownloader, HTTPError } from './FetchDownloader.js';
export { FetchDownloader, HTTPError };
export var ElectronDownloadCacheMode;

@@ -4,0 +4,0 @@ (function (ElectronDownloadCacheMode) {

@@ -1,1 +0,1 @@

{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAwB,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAAc,aAAa,EAAwB,CAAC;AA4E3D,MAAM,CAAN,IAAY,yBAoBX;AApBD,WAAY,yBAAyB;IACnC;;;OAGG;IACH,mFAAS,CAAA;IACT;;;OAGG;IACH,iFAAQ,CAAA;IACR;;;OAGG;IACH,mFAAS,CAAA;IACT;;OAEG;IACH,6EAAM,CAAA;AACR,CAAC,EApBW,yBAAyB,KAAzB,yBAAyB,QAoBpC"}
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAA0B,SAAS,EAAY,MAAM,sBAAsB,CAAC;AAEpG,OAAO,EAAc,eAAe,EAA0B,SAAS,EAAY,CAAC;AA4EpF,MAAM,CAAN,IAAY,yBAoBX;AApBD,WAAY,yBAAyB;IACnC;;;OAGG;IACH,mFAAS,CAAA;IACT;;;OAGG;IACH,iFAAQ,CAAA;IACR;;;OAGG;IACH,mFAAS,CAAA;IACT;;OAEG;IACH,6EAAM,CAAA;AACR,CAAC,EApBW,yBAAyB,KAAzB,yBAAyB,QAoBpC"}
{
"name": "@electron/get",
"version": "4.0.3",
"version": "5.0.0",
"type": "module",

@@ -15,8 +15,6 @@ "exports": "./dist/index.js",

"build": "tsc",
"build:docs": "npx typedoc",
"eslint": "eslint --ext .ts src test",
"lint": "npm run prettier && npm run eslint",
"build:docs": "typedoc",
"lint": "oxfmt --check . && oxlint",
"lint:fix": "oxfmt --write . && oxlint --fix",
"prepare": "husky",
"prettier": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
"prettier:write": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"prepublishOnly": "npm run build",

@@ -36,3 +34,2 @@ "test": "vitest run --coverage",

"env-paths": "^3.0.0",
"got": "^14.4.5",
"graceful-fs": "^4.2.11",

@@ -47,28 +44,23 @@ "progress": "^2.0.3",

"@types/graceful-fs": "^4.1.9",
"@types/node": "~22.10.5",
"@types/node": "~22.12.0",
"@types/progress": "^2.0.3",
"@types/semver": "^7.5.8",
"@typescript-eslint/eslint-plugin": "^8.19.1",
"@typescript-eslint/parser": "^8.0.0",
"@vitest/coverage-v8": "3.0.5",
"@vitest/coverage-v8": "^4.1.2",
"esbuild-plugin-file-path-extensions": "^2.1.4",
"eslint": "^8.57.0",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-import": "^2.31.0",
"husky": "^9.1.7",
"lint-staged": "^16.2.7",
"prettier": "^3.4.2",
"typedoc": "~0.25.13",
"typescript": "~5.4.5",
"vitest": "^3.0.5"
"oxfmt": "^0.44.0",
"oxlint": "^1.59.0",
"oxlint-tsgolint": "^0.20.0",
"typedoc": "~0.28.0",
"typescript": "^6.0.2",
"vitest": "^4.1.2"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.ts": [
"eslint --fix",
"prettier --write"
"*.{js,ts}": [
"oxfmt --write",
"oxlint --fix"
],
"*.{json}": [
"oxfmt --write"
]

@@ -85,5 +77,8 @@ },

"optionalDependencies": {
"global-agent": "^3.0.0"
"undici": "^7.24.4"
},
"resolutions": {
"fsevents": "npm:@electron/fsevents@2.3.3-fork"
},
"packageManager": "yarn@4.10.3+sha512.c38cafb5c7bb273f3926d04e55e1d8c9dfa7d9c3ea1f36a4868fa028b9e5f72298f0b7f401ad5eb921749eb012eb1c3bb74bf7503df3ee43fd600d14a018266f"
}

@@ -126,5 +126,5 @@ # @electron/get

By default, the module uses [`got`](https://github.com/sindresorhus/got) as the
downloader. As a result, you can use the same [options](https://github.com/sindresorhus/got#options)
via `downloadOptions`.
By default, the module uses the built-in [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
as the downloader. As a result, you can pass [`RequestInit`](https://developer.mozilla.org/en-US/docs/Web/API/RequestInit)
options via `downloadOptions`.

@@ -136,4 +136,4 @@ ### Progress Bar

`quiet` to `true` in `downloadOptions`. If you need to monitor progress yourself via the API, set
`getProgressCallback` in `downloadOptions`, which has the same function signature as `got`'s
[`downloadProgress` event callback](https://github.com/sindresorhus/got#ondownloadprogress-progress).
`getProgressCallback` in `downloadOptions`, which receives a `Progress` object with `transferred`,
`total`, and `percent` properties.

@@ -140,0 +140,0 @@ ### Proxies

import { Progress as GotProgress, Options as GotOptions } from 'got';
import { Downloader } from './Downloader.js';
/**
* Options for the default [`got`](https://github.com/sindresorhus/got) Downloader implementation.
*
* @category Downloader
* @see {@link https://github.com/sindresorhus/got/tree/v11.8.5?tab=readme-ov-file#options | `got#options`} for possible keys/values.
*/
export type GotDownloaderOptions = GotOptions & {
isStream?: true;
} & {
/**
* if defined, triggers every time `got`'s
* {@link https://github.com/sindresorhus/got/tree/v11.8.5?tab=readme-ov-file#downloadprogress | `downloadProgress``} event callback is triggered.
*/
getProgressCallback?: (progress: GotProgress) => Promise<void>;
/**
* if `true`, disables the console progress bar (setting the `ELECTRON_GET_NO_PROGRESS`
* environment variable to a non-empty value also does this).
*/
quiet?: boolean;
};
/**
* Default {@link Downloader} implemented with {@link https://npmjs.com/package/got | `got`}.
* @category Downloader
*/
export declare class GotDownloader implements Downloader<GotDownloaderOptions> {
download(url: string, targetFilePath: string, options?: Partial<GotDownloaderOptions>): Promise<void>;
}
import got, { HTTPError } from 'got';
import fs from 'graceful-fs';
import path from 'node:path';
import ProgressBar from 'progress';
import { pipeline } from 'node:stream/promises';
const PROGRESS_BAR_DELAY_IN_SECONDS = 30;
/**
* Default {@link Downloader} implemented with {@link https://npmjs.com/package/got | `got`}.
* @category Downloader
*/
export class GotDownloader {
async download(url, targetFilePath, options) {
if (!options) {
options = {};
}
const { quiet, getProgressCallback, ...gotOptions } = options;
let downloadCompleted = false;
let bar;
let progressPercent;
let timeout = undefined;
await fs.promises.mkdir(path.dirname(targetFilePath), { recursive: true });
const writeStream = fs.createWriteStream(targetFilePath);
if (!quiet && !process.env.ELECTRON_GET_NO_PROGRESS) {
const start = new Date();
timeout = setTimeout(() => {
if (!downloadCompleted) {
bar = new ProgressBar(`Downloading ${path.basename(url)}: [:bar] :percent ETA: :eta seconds `, {
curr: progressPercent,
total: 100,
});
// https://github.com/visionmedia/node-progress/issues/159
// eslint-disable-next-line @typescript-eslint/no-explicit-any
bar.start = start;
}
}, PROGRESS_BAR_DELAY_IN_SECONDS * 1000);
}
const downloadStream = got.stream(url, gotOptions);
downloadStream.on('downloadProgress', async (progress) => {
progressPercent = progress.percent;
if (bar) {
bar.update(progress.percent);
}
if (getProgressCallback) {
await getProgressCallback(progress);
}
});
try {
await pipeline(downloadStream, writeStream);
}
catch (error) {
if (error instanceof HTTPError && error.response.statusCode === 404) {
error.message += ` for ${error.response.url}`;
}
throw error;
}
finally {
downloadCompleted = true;
if (timeout) {
clearTimeout(timeout);
}
}
}
}
//# sourceMappingURL=GotDownloader.js.map
{"version":3,"file":"GotDownloader.js","sourceRoot":"","sources":["../src/GotDownloader.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,EAAE,EAAE,SAAS,EAA4D,MAAM,KAAK,CAAC;AAC/F,OAAO,EAAE,MAAM,aAAa,CAAC;AAE7B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,WAAW,MAAM,UAAU,CAAC;AAGnC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,6BAA6B,GAAG,EAAE,CAAC;AAqBzC;;;GAGG;AACH,MAAM,OAAO,aAAa;IACxB,KAAK,CAAC,QAAQ,CACZ,GAAW,EACX,cAAsB,EACtB,OAAuC;QAEvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAG,UAAU,EAAE,GAAG,OAAO,CAAC;QAC9D,IAAI,iBAAiB,GAAG,KAAK,CAAC;QAC9B,IAAI,GAA4B,CAAC;QACjC,IAAI,eAAuB,CAAC;QAC5B,IAAI,OAAO,GAA+B,SAAS,CAAC;QACpD,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;QAEzD,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;YACpD,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;YACzB,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBACxB,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACvB,GAAG,GAAG,IAAI,WAAW,CACnB,eAAe,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,sCAAsC,EACvE;wBACE,IAAI,EAAE,eAAe;wBACrB,KAAK,EAAE,GAAG;qBACX,CACF,CAAC;oBACF,0DAA0D;oBAC1D,8DAA8D;oBAC7D,GAAW,CAAC,KAAK,GAAG,KAAK,CAAC;gBAC7B,CAAC;YACH,CAAC,EAAE,6BAA6B,GAAG,IAAI,CAAC,CAAC;QAC3C,CAAC;QACD,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACnD,cAAc,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,EAAE,QAAkB,EAAE,EAAE;YACjE,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC;YACnC,IAAI,GAAG,EAAE,CAAC;gBACR,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,mBAAmB,EAAE,CAAC;gBACxB,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,SAAS,IAAK,KAAmB,CAAC,QAAQ,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;gBACnF,KAAK,CAAC,OAAO,IAAI,QAAS,KAAmB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC/D,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,iBAAiB,GAAG,IAAI,CAAC;YACzB,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,OAAO,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;CACF"}