PHP WebShell

Текущая директория: /opt/BitGoJS/modules/express/dist/test/unit/clientRoutes/lightning

Просмотр файла: lightningSignerRoutes.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_test_1 = require("@bitgo/sdk-test");
const bitgo_1 = require("bitgo");
const sdk_core_1 = require("@bitgo/sdk-core");
const nock = require("nock");
const sinon = require("sinon");
const fs = require("fs");
const lightningSignerFixture_1 = require("./lightningSignerFixture");
const lightningSignerRoutes_1 = require("../../../../src/lightning/lightningSignerRoutes");
describe('Lightning signer routes', () => {
    let bitgo;
    let bgUrl;
    before(async function () {
        if (!nock.isActive()) {
            nock.activate();
        }
        bitgo = sdk_test_1.TestBitGo.decorate(bitgo_1.BitGo, { env: 'test' });
        bitgo.initializeTestVars();
        bgUrl = sdk_core_1.common.Environments[bitgo.getEnv()].uri;
        nock.disableNetConnect();
        nock.enableNetConnect('127.0.0.1');
    });
    after(() => {
        if (nock.isActive()) {
            nock.restore();
        }
    });
    for (const includingOptionalFields of [true, false]) {
        it(`should initialize lightning signer wallet ${includingOptionalFields ? 'with' : 'without'} optional fields`, async () => {
            const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
            const wpWalletnock = nock(bgUrl)
                .get(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`)
                .query({ includeBalance: false })
                .reply(200, lightningSignerFixture_1.apiData.wallet);
            const wpKeychainNocks = [
                nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userKey.id}`).reply(200, lightningSignerFixture_1.apiData.userKey),
                nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.userAuthKey),
                nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.nodeAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.nodeAuthKey),
                nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.userAuthKey),
                nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.nodeAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.nodeAuthKey),
            ];
            const signerInitWalletNock = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url)
                .post(`/v1/initwallet`)
                .reply(200, lightningSignerFixture_1.signerApiData.initWallet);
            const wpWalletUpdateNock = nock(bgUrl).put(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`).reply(200);
            const req = {
                bitgo: bitgo,
                body: includingOptionalFields
                    ? lightningSignerFixture_1.apiData.initWalletRequestBody
                    : { ...lightningSignerFixture_1.apiData.initWalletRequestBody, expressHost: undefined },
                params: {
                    coin: 'tlnbtc',
                    id: 'fakeid',
                },
                config: {
                    lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
                },
            };
            await (0, lightningSignerRoutes_1.handleInitLightningWallet)(req);
            wpWalletUpdateNock.done();
            signerInitWalletNock.done();
            wpKeychainNocks.forEach((s) => s.done());
            wpWalletnock.done();
            readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
            readFileStub.restore();
        });
    }
    for (const addIpCaveatToMacaroon of [true, false]) {
        for (const includeWatchOnlyIp of [true, false]) {
            it(`create signer macaroon ${addIpCaveatToMacaroon ? 'with' : 'without'} including IP caveat when it ${includeWatchOnlyIp ? 'does' : `doesn't`} exist`, async () => {
                const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
                const wpWalletnock = nock(bgUrl)
                    .get(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`)
                    .query({ includeBalance: false })
                    .reply(200, {
                    ...lightningSignerFixture_1.apiData.wallet,
                    ...(includeWatchOnlyIp ? {} : { watchOnlyExternalIp: null }),
                });
                const wpKeychainNocks = [
                    nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.userAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.userAuthKey),
                    nock(bgUrl).get(`/api/v2/tlnbtc/key/${lightningSignerFixture_1.apiData.nodeAuthKey.id}`).reply(200, lightningSignerFixture_1.apiData.nodeAuthKey),
                ];
                const signerMacaroon = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url)
                    .post(`/v1/macaroon`)
                    .reply(200, lightningSignerFixture_1.signerApiData.bakeMacaroon);
                const wpWalletUpdateNock = nock(bgUrl).put(`/api/v2/tlnbtc/wallet/${lightningSignerFixture_1.apiData.wallet.id}`).reply(200);
                const req = {
                    bitgo: bitgo,
                    body: { ...lightningSignerFixture_1.apiData.signerMacaroonRequestBody, addIpCaveatToMacaroon },
                    params: {
                        coin: 'tlnbtc',
                        id: 'fakeid',
                    },
                    config: {
                        lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
                    },
                };
                try {
                    await (0, lightningSignerRoutes_1.handleCreateSignerMacaroon)(req);
                }
                catch (e) {
                    if (!includeWatchOnlyIp || addIpCaveatToMacaroon) {
                        throw e;
                    }
                }
                wpWalletUpdateNock.done();
                signerMacaroon.done();
                wpKeychainNocks.forEach((s) => s.done());
                wpWalletnock.done();
                readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
                readFileStub.restore();
            });
        }
    }
    it('should get signer wallet state', async () => {
        const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
        const walletStateNock = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url)
            .get(`/v1/state`)
            .reply(200, lightningSignerFixture_1.signerApiData.walletState);
        const req = {
            bitgo: bitgo,
            params: {
                coin: 'tlnbtc',
                id: lightningSignerFixture_1.apiData.wallet.id,
            },
            config: {
                lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
            },
        };
        await (0, lightningSignerRoutes_1.handleGetLightningWalletState)(req);
        walletStateNock.done();
        readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
        readFileStub.restore();
    });
    it('should unlock lightning wallet', async () => {
        const readFileStub = sinon.stub(fs.promises, 'readFile').resolves(JSON.stringify(lightningSignerFixture_1.lightningSignerConfigs));
        const unlockwalletNock = nock(lightningSignerFixture_1.lightningSignerConfigs.fakeid.url).post(`/v1/unlockwallet`).reply(200);
        const req = {
            bitgo: bitgo,
            body: lightningSignerFixture_1.apiData.unlockWalletRequestBody,
            params: {
                coin: 'tlnbtc',
                id: 'fakeid',
            },
            config: {
                lightningSignerFileSystemPath: 'lightningSignerFileSystemPath',
            },
        };
        await (0, lightningSignerRoutes_1.handleUnlockLightningWallet)(req);
        unlockwalletNock.done();
        readFileStub.calledOnceWith('lightningSignerFileSystemPath').should.be.true();
        readFileStub.restore();
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nU2lnbmVyUm91dGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2NsaWVudFJvdXRlcy9saWdodG5pbmcvbGlnaHRuaW5nU2lnbmVyUm91dGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOENBQTBEO0FBQzFELGlDQUE4QjtBQUM5Qiw4Q0FBeUM7QUFDekMsNkJBQTZCO0FBRTdCLCtCQUErQjtBQUMvQix5QkFBeUI7QUFFekIscUVBQTBGO0FBQzFGLDJGQUt5RDtBQUV6RCxRQUFRLENBQUMseUJBQXlCLEVBQUUsR0FBRyxFQUFFO0lBQ3ZDLElBQUksS0FBbUIsQ0FBQztJQUN4QixJQUFJLEtBQUssQ0FBQztJQUVWLE1BQU0sQ0FBQyxLQUFLO1FBQ1YsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNwQixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDakI7UUFFRCxLQUFLLEdBQUcsb0JBQVMsQ0FBQyxRQUFRLENBQUMsYUFBSyxFQUFFLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkQsS0FBSyxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFM0IsS0FBSyxHQUFHLGlCQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUVoRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLENBQUMsR0FBRyxFQUFFO1FBQ1QsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDbkIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ2hCO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFFSCxLQUFLLE1BQU0sdUJBQXVCLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUU7UUFDbkQsRUFBRSxDQUFDLDZDQUNELHVCQUF1QixDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQ3JDLGtCQUFrQixFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzdCLE1BQU0sWUFBWSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQywrQ0FBc0IsQ0FBQyxDQUFDLENBQUM7WUFDMUcsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztpQkFDN0IsR0FBRyxDQUFDLHlCQUF5QixnQ0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztpQkFDakQsS0FBSyxDQUFDLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUFDO2lCQUNoQyxLQUFLLENBQUMsR0FBRyxFQUFFLGdDQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFOUIsTUFBTSxlQUFlLEdBQUc7Z0JBQ3RCLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsc0JBQXNCLGdDQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxnQ0FBTyxDQUFDLE9BQU8sQ0FBQztnQkFDdkYsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsZ0NBQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLGdDQUFPLENBQUMsV0FBVyxDQUFDO2dCQUMvRixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLHNCQUFzQixnQ0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsZ0NBQU8sQ0FBQyxXQUFXLENBQUM7Z0JBQy9GLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsc0JBQXNCLGdDQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxnQ0FBTyxDQUFDLFdBQVcsQ0FBQztnQkFDL0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsZ0NBQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLGdDQUFPLENBQUMsV0FBVyxDQUFDO2FBQ2hHLENBQUM7WUFFRixNQUFNLG9CQUFvQixHQUFHLElBQUksQ0FBQywrQ0FBc0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2lCQUNqRSxJQUFJLENBQUMsZ0JBQWdCLENBQUM7aUJBQ3RCLEtBQUssQ0FBQyxHQUFHLEVBQUUsc0NBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUV4QyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMseUJBQXlCLGdDQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRXBHLE1BQU0sR0FBRyxHQUFHO2dCQUNWLEtBQUssRUFBRSxLQUFLO2dCQUNaLElBQUksRUFBRSx1QkFBdUI7b0JBQzNCLENBQUMsQ0FBQyxnQ0FBTyxDQUFDLHFCQUFxQjtvQkFDL0IsQ0FBQyxDQUFDLEVBQUUsR0FBRyxnQ0FBTyxDQUFDLHFCQUFxQixFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUU7Z0JBQ2hFLE1BQU0sRUFBRTtvQkFDTixJQUFJLEVBQUUsUUFBUTtvQkFDZCxFQUFFLEVBQUUsUUFBUTtpQkFDYjtnQkFDRCxNQUFNLEVBQUU7b0JBQ04sNkJBQTZCLEVBQUUsK0JBQStCO2lCQUMvRDthQUM0QixDQUFDO1lBRWhDLE1BQU0sSUFBQSxpREFBeUIsRUFBQyxHQUFHLENBQUMsQ0FBQztZQUVyQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMxQixvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUM1QixlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN6QyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDcEIsWUFBWSxDQUFDLGNBQWMsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDOUUsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0tBQ0o7SUFFRCxLQUFLLE1BQU0scUJBQXFCLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUU7UUFDakQsS0FBSyxNQUFNLGtCQUFrQixJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFO1lBQzlDLEVBQUUsQ0FBQywwQkFBMEIscUJBQXFCLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxnQ0FDckUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FDaEMsUUFBUSxFQUFFLEtBQUssSUFBSSxFQUFFO2dCQUNuQixNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsK0NBQXNCLENBQUMsQ0FBQyxDQUFDO2dCQUMxRyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3FCQUM3QixHQUFHLENBQUMseUJBQXlCLGdDQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDO3FCQUNqRCxLQUFLLENBQUMsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLENBQUM7cUJBQ2hDLEtBQUssQ0FBQyxHQUFHLEVBQUU7b0JBQ1YsR0FBRyxnQ0FBTyxDQUFDLE1BQU07b0JBQ2pCLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLG1CQUFtQixFQUFFLElBQUksRUFBRSxDQUFDO2lCQUM3RCxDQUFDLENBQUM7Z0JBRUwsTUFBTSxlQUFlLEdBQUc7b0JBQ3RCLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsc0JBQXNCLGdDQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxnQ0FBTyxDQUFDLFdBQVcsQ0FBQztvQkFDL0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsZ0NBQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLGdDQUFPLENBQUMsV0FBVyxDQUFDO2lCQUNoRyxDQUFDO2dCQUVGLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQywrQ0FBc0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO3FCQUMzRCxJQUFJLENBQUMsY0FBYyxDQUFDO3FCQUNwQixLQUFLLENBQUMsR0FBRyxFQUFFLHNDQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBRTFDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsZ0NBQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBRXBHLE1BQU0sR0FBRyxHQUFHO29CQUNWLEtBQUssRUFBRSxLQUFLO29CQUNaLElBQUksRUFBRSxFQUFFLEdBQUcsZ0NBQU8sQ0FBQyx5QkFBeUIsRUFBRSxxQkFBcUIsRUFBRTtvQkFDckUsTUFBTSxFQUFFO3dCQUNOLElBQUksRUFBRSxRQUFRO3dCQUNkLEVBQUUsRUFBRSxRQUFRO3FCQUNiO29CQUNELE1BQU0sRUFBRTt3QkFDTiw2QkFBNkIsRUFBRSwrQkFBK0I7cUJBQy9EO2lCQUM0QixDQUFDO2dCQUVoQyxJQUFJO29CQUNGLE1BQU0sSUFBQSxrREFBMEIsRUFBQyxHQUFHLENBQUMsQ0FBQztpQkFDdkM7Z0JBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ1YsSUFBSSxDQUFDLGtCQUFrQixJQUFJLHFCQUFxQixFQUFFO3dCQUNoRCxNQUFNLENBQUMsQ0FBQztxQkFDVDtpQkFDRjtnQkFFRCxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDMUIsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN0QixlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDekMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNwQixZQUFZLENBQUMsY0FBYyxDQUFDLCtCQUErQixDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDOUUsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxDQUFDO1NBQ0o7S0FDRjtJQUVELEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM5QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsK0NBQXNCLENBQUMsQ0FBQyxDQUFDO1FBQzFHLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQywrQ0FBc0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2FBQzVELEdBQUcsQ0FBQyxXQUFXLENBQUM7YUFDaEIsS0FBSyxDQUFDLEdBQUcsRUFBRSxzQ0FBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXpDLE1BQU0sR0FBRyxHQUFHO1lBQ1YsS0FBSyxFQUFFLEtBQUs7WUFDWixNQUFNLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsRUFBRSxFQUFFLGdDQUFPLENBQUMsTUFBTSxDQUFDLEVBQUU7YUFDdEI7WUFDRCxNQUFNLEVBQUU7Z0JBQ04sNkJBQTZCLEVBQUUsK0JBQStCO2FBQy9EO1NBQzRCLENBQUM7UUFFaEMsTUFBTSxJQUFBLHFEQUE2QixFQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXpDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2QixZQUFZLENBQUMsY0FBYyxDQUFDLCtCQUErQixDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5RSxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDekIsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDOUMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLCtDQUFzQixDQUFDLENBQUMsQ0FBQztRQUUxRyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQywrQ0FBc0IsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXJHLE1BQU0sR0FBRyxHQUFHO1lBQ1YsS0FBSyxFQUFFLEtBQUs7WUFDWixJQUFJLEVBQUUsZ0NBQU8sQ0FBQyx1QkFBdUI7WUFDckMsTUFBTSxFQUFFO2dCQUNOLElBQUksRUFBRSxRQUFRO2dCQUNkLEVBQUUsRUFBRSxRQUFRO2FBQ2I7WUFDRCxNQUFNLEVBQUU7Z0JBQ04sNkJBQTZCLEVBQUUsK0JBQStCO2FBQy9EO1NBQzRCLENBQUM7UUFFaEMsTUFBTSxJQUFBLG1EQUEyQixFQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXZDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hCLFlBQVksQ0FBQyxjQUFjLENBQUMsK0JBQStCLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlFLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUN6QixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdEJpdEdvLCBUZXN0Qml0R29BUEkgfSBmcm9tICdAYml0Z28vc2RrLXRlc3QnO1xuaW1wb3J0IHsgQml0R28gfSBmcm9tICdiaXRnbyc7XG5pbXBvcnQgeyBjb21tb24gfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgbm9jayBmcm9tICdub2NrJztcbmltcG9ydCAqIGFzIGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgKiBhcyBzaW5vbiBmcm9tICdzaW5vbic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5cbmltcG9ydCB7IGxpZ2h0bmluZ1NpZ25lckNvbmZpZ3MsIGFwaURhdGEsIHNpZ25lckFwaURhdGEgfSBmcm9tICcuL2xpZ2h0bmluZ1NpZ25lckZpeHR1cmUnO1xuaW1wb3J0IHtcbiAgaGFuZGxlQ3JlYXRlU2lnbmVyTWFjYXJvb24sXG4gIGhhbmRsZUdldExpZ2h0bmluZ1dhbGxldFN0YXRlLFxuICBoYW5kbGVJbml0TGlnaHRuaW5nV2FsbGV0LFxuICBoYW5kbGVVbmxvY2tMaWdodG5pbmdXYWxsZXQsXG59IGZyb20gJy4uLy4uLy4uLy4uL3NyYy9saWdodG5pbmcvbGlnaHRuaW5nU2lnbmVyUm91dGVzJztcblxuZGVzY3JpYmUoJ0xpZ2h0bmluZyBzaWduZXIgcm91dGVzJywgKCkgPT4ge1xuICBsZXQgYml0Z286IFRlc3RCaXRHb0FQSTtcbiAgbGV0IGJnVXJsO1xuXG4gIGJlZm9yZShhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFub2NrLmlzQWN0aXZlKCkpIHtcbiAgICAgIG5vY2suYWN0aXZhdGUoKTtcbiAgICB9XG5cbiAgICBiaXRnbyA9IFRlc3RCaXRHby5kZWNvcmF0ZShCaXRHbywgeyBlbnY6ICd0ZXN0JyB9KTtcbiAgICBiaXRnby5pbml0aWFsaXplVGVzdFZhcnMoKTtcblxuICAgIGJnVXJsID0gY29tbW9uLkVudmlyb25tZW50c1tiaXRnby5nZXRFbnYoKV0udXJpO1xuXG4gICAgbm9jay5kaXNhYmxlTmV0Q29ubmVjdCgpO1xuICAgIG5vY2suZW5hYmxlTmV0Q29ubmVjdCgnMTI3LjAuMC4xJyk7XG4gIH0pO1xuXG4gIGFmdGVyKCgpID0+IHtcbiAgICBpZiAobm9jay5pc0FjdGl2ZSgpKSB7XG4gICAgICBub2NrLnJlc3RvcmUoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgaW5jbHVkaW5nT3B0aW9uYWxGaWVsZHMgb2YgW3RydWUsIGZhbHNlXSkge1xuICAgIGl0KGBzaG91bGQgaW5pdGlhbGl6ZSBsaWdodG5pbmcgc2lnbmVyIHdhbGxldCAke1xuICAgICAgaW5jbHVkaW5nT3B0aW9uYWxGaWVsZHMgPyAnd2l0aCcgOiAnd2l0aG91dCdcbiAgICB9IG9wdGlvbmFsIGZpZWxkc2AsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlYWRGaWxlU3R1YiA9IHNpbm9uLnN0dWIoZnMucHJvbWlzZXMsICdyZWFkRmlsZScpLnJlc29sdmVzKEpTT04uc3RyaW5naWZ5KGxpZ2h0bmluZ1NpZ25lckNvbmZpZ3MpKTtcbiAgICAgIGNvbnN0IHdwV2FsbGV0bm9jayA9IG5vY2soYmdVcmwpXG4gICAgICAgIC5nZXQoYC9hcGkvdjIvdGxuYnRjL3dhbGxldC8ke2FwaURhdGEud2FsbGV0LmlkfWApXG4gICAgICAgIC5xdWVyeSh7IGluY2x1ZGVCYWxhbmNlOiBmYWxzZSB9KVxuICAgICAgICAucmVwbHkoMjAwLCBhcGlEYXRhLndhbGxldCk7XG5cbiAgICAgIGNvbnN0IHdwS2V5Y2hhaW5Ob2NrcyA9IFtcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy9rZXkvJHthcGlEYXRhLnVzZXJLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLnVzZXJLZXkpLFxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEudXNlckF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLnVzZXJBdXRoS2V5KSxcbiAgICAgICAgbm9jayhiZ1VybCkuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy9rZXkvJHthcGlEYXRhLm5vZGVBdXRoS2V5LmlkfWApLnJlcGx5KDIwMCwgYXBpRGF0YS5ub2RlQXV0aEtleSksXG4gICAgICAgIG5vY2soYmdVcmwpLmdldChgL2FwaS92Mi90bG5idGMva2V5LyR7YXBpRGF0YS51c2VyQXV0aEtleS5pZH1gKS5yZXBseSgyMDAsIGFwaURhdGEudXNlckF1dGhLZXkpLFxuICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEubm9kZUF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLm5vZGVBdXRoS2V5KSxcbiAgICAgIF07XG5cbiAgICAgIGNvbnN0IHNpZ25lckluaXRXYWxsZXROb2NrID0gbm9jayhsaWdodG5pbmdTaWduZXJDb25maWdzLmZha2VpZC51cmwpXG4gICAgICAgIC5wb3N0KGAvdjEvaW5pdHdhbGxldGApXG4gICAgICAgIC5yZXBseSgyMDAsIHNpZ25lckFwaURhdGEuaW5pdFdhbGxldCk7XG5cbiAgICAgIGNvbnN0IHdwV2FsbGV0VXBkYXRlTm9jayA9IG5vY2soYmdVcmwpLnB1dChgL2FwaS92Mi90bG5idGMvd2FsbGV0LyR7YXBpRGF0YS53YWxsZXQuaWR9YCkucmVwbHkoMjAwKTtcblxuICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICBiaXRnbzogYml0Z28sXG4gICAgICAgIGJvZHk6IGluY2x1ZGluZ09wdGlvbmFsRmllbGRzXG4gICAgICAgICAgPyBhcGlEYXRhLmluaXRXYWxsZXRSZXF1ZXN0Qm9keVxuICAgICAgICAgIDogeyAuLi5hcGlEYXRhLmluaXRXYWxsZXRSZXF1ZXN0Qm9keSwgZXhwcmVzc0hvc3Q6IHVuZGVmaW5lZCB9LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgICBpZDogJ2Zha2VpZCcsXG4gICAgICAgIH0sXG4gICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgICB9LFxuICAgICAgfSBhcyB1bmtub3duIGFzIGV4cHJlc3MuUmVxdWVzdDtcblxuICAgICAgYXdhaXQgaGFuZGxlSW5pdExpZ2h0bmluZ1dhbGxldChyZXEpO1xuXG4gICAgICB3cFdhbGxldFVwZGF0ZU5vY2suZG9uZSgpO1xuICAgICAgc2lnbmVySW5pdFdhbGxldE5vY2suZG9uZSgpO1xuICAgICAgd3BLZXljaGFpbk5vY2tzLmZvckVhY2goKHMpID0+IHMuZG9uZSgpKTtcbiAgICAgIHdwV2FsbGV0bm9jay5kb25lKCk7XG4gICAgICByZWFkRmlsZVN0dWIuY2FsbGVkT25jZVdpdGgoJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIHJlYWRGaWxlU3R1Yi5yZXN0b3JlKCk7XG4gICAgfSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGFkZElwQ2F2ZWF0VG9NYWNhcm9vbiBvZiBbdHJ1ZSwgZmFsc2VdKSB7XG4gICAgZm9yIChjb25zdCBpbmNsdWRlV2F0Y2hPbmx5SXAgb2YgW3RydWUsIGZhbHNlXSkge1xuICAgICAgaXQoYGNyZWF0ZSBzaWduZXIgbWFjYXJvb24gJHthZGRJcENhdmVhdFRvTWFjYXJvb24gPyAnd2l0aCcgOiAnd2l0aG91dCd9IGluY2x1ZGluZyBJUCBjYXZlYXQgd2hlbiBpdCAke1xuICAgICAgICBpbmNsdWRlV2F0Y2hPbmx5SXAgPyAnZG9lcycgOiBgZG9lc24ndGBcbiAgICAgIH0gZXhpc3RgLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlYWRGaWxlU3R1YiA9IHNpbm9uLnN0dWIoZnMucHJvbWlzZXMsICdyZWFkRmlsZScpLnJlc29sdmVzKEpTT04uc3RyaW5naWZ5KGxpZ2h0bmluZ1NpZ25lckNvbmZpZ3MpKTtcbiAgICAgICAgY29uc3Qgd3BXYWxsZXRub2NrID0gbm9jayhiZ1VybClcbiAgICAgICAgICAuZ2V0KGAvYXBpL3YyL3RsbmJ0Yy93YWxsZXQvJHthcGlEYXRhLndhbGxldC5pZH1gKVxuICAgICAgICAgIC5xdWVyeSh7IGluY2x1ZGVCYWxhbmNlOiBmYWxzZSB9KVxuICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgIC4uLmFwaURhdGEud2FsbGV0LFxuICAgICAgICAgICAgLi4uKGluY2x1ZGVXYXRjaE9ubHlJcCA/IHt9IDogeyB3YXRjaE9ubHlFeHRlcm5hbElwOiBudWxsIH0pLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHdwS2V5Y2hhaW5Ob2NrcyA9IFtcbiAgICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEudXNlckF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLnVzZXJBdXRoS2V5KSxcbiAgICAgICAgICBub2NrKGJnVXJsKS5nZXQoYC9hcGkvdjIvdGxuYnRjL2tleS8ke2FwaURhdGEubm9kZUF1dGhLZXkuaWR9YCkucmVwbHkoMjAwLCBhcGlEYXRhLm5vZGVBdXRoS2V5KSxcbiAgICAgICAgXTtcblxuICAgICAgICBjb25zdCBzaWduZXJNYWNhcm9vbiA9IG5vY2sobGlnaHRuaW5nU2lnbmVyQ29uZmlncy5mYWtlaWQudXJsKVxuICAgICAgICAgIC5wb3N0KGAvdjEvbWFjYXJvb25gKVxuICAgICAgICAgIC5yZXBseSgyMDAsIHNpZ25lckFwaURhdGEuYmFrZU1hY2Fyb29uKTtcblxuICAgICAgICBjb25zdCB3cFdhbGxldFVwZGF0ZU5vY2sgPSBub2NrKGJnVXJsKS5wdXQoYC9hcGkvdjIvdGxuYnRjL3dhbGxldC8ke2FwaURhdGEud2FsbGV0LmlkfWApLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3QgcmVxID0ge1xuICAgICAgICAgIGJpdGdvOiBiaXRnbyxcbiAgICAgICAgICBib2R5OiB7IC4uLmFwaURhdGEuc2lnbmVyTWFjYXJvb25SZXF1ZXN0Qm9keSwgYWRkSXBDYXZlYXRUb01hY2Fyb29uIH0sXG4gICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgICAgIGlkOiAnZmFrZWlkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGg6ICdsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSBhcyB1bmtub3duIGFzIGV4cHJlc3MuUmVxdWVzdDtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGhhbmRsZUNyZWF0ZVNpZ25lck1hY2Fyb29uKHJlcSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoIWluY2x1ZGVXYXRjaE9ubHlJcCB8fCBhZGRJcENhdmVhdFRvTWFjYXJvb24pIHtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgd3BXYWxsZXRVcGRhdGVOb2NrLmRvbmUoKTtcbiAgICAgICAgc2lnbmVyTWFjYXJvb24uZG9uZSgpO1xuICAgICAgICB3cEtleWNoYWluTm9ja3MuZm9yRWFjaCgocykgPT4gcy5kb25lKCkpO1xuICAgICAgICB3cFdhbGxldG5vY2suZG9uZSgpO1xuICAgICAgICByZWFkRmlsZVN0dWIuY2FsbGVkT25jZVdpdGgoJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGl0KCdzaG91bGQgZ2V0IHNpZ25lciB3YWxsZXQgc3RhdGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVhZEZpbGVTdHViID0gc2lub24uc3R1Yihmcy5wcm9taXNlcywgJ3JlYWRGaWxlJykucmVzb2x2ZXMoSlNPTi5zdHJpbmdpZnkobGlnaHRuaW5nU2lnbmVyQ29uZmlncykpO1xuICAgIGNvbnN0IHdhbGxldFN0YXRlTm9jayA9IG5vY2sobGlnaHRuaW5nU2lnbmVyQ29uZmlncy5mYWtlaWQudXJsKVxuICAgICAgLmdldChgL3YxL3N0YXRlYClcbiAgICAgIC5yZXBseSgyMDAsIHNpZ25lckFwaURhdGEud2FsbGV0U3RhdGUpO1xuXG4gICAgY29uc3QgcmVxID0ge1xuICAgICAgYml0Z286IGJpdGdvLFxuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIGNvaW46ICd0bG5idGMnLFxuICAgICAgICBpZDogYXBpRGF0YS53YWxsZXQuaWQsXG4gICAgICB9LFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoOiAnbGlnaHRuaW5nU2lnbmVyRmlsZVN5c3RlbVBhdGgnLFxuICAgICAgfSxcbiAgICB9IGFzIHVua25vd24gYXMgZXhwcmVzcy5SZXF1ZXN0O1xuXG4gICAgYXdhaXQgaGFuZGxlR2V0TGlnaHRuaW5nV2FsbGV0U3RhdGUocmVxKTtcblxuICAgIHdhbGxldFN0YXRlTm9jay5kb25lKCk7XG4gICAgcmVhZEZpbGVTdHViLmNhbGxlZE9uY2VXaXRoKCdsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB1bmxvY2sgbGlnaHRuaW5nIHdhbGxldCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZWFkRmlsZVN0dWIgPSBzaW5vbi5zdHViKGZzLnByb21pc2VzLCAncmVhZEZpbGUnKS5yZXNvbHZlcyhKU09OLnN0cmluZ2lmeShsaWdodG5pbmdTaWduZXJDb25maWdzKSk7XG5cbiAgICBjb25zdCB1bmxvY2t3YWxsZXROb2NrID0gbm9jayhsaWdodG5pbmdTaWduZXJDb25maWdzLmZha2VpZC51cmwpLnBvc3QoYC92MS91bmxvY2t3YWxsZXRgKS5yZXBseSgyMDApO1xuXG4gICAgY29uc3QgcmVxID0ge1xuICAgICAgYml0Z286IGJpdGdvLFxuICAgICAgYm9keTogYXBpRGF0YS51bmxvY2tXYWxsZXRSZXF1ZXN0Qm9keSxcbiAgICAgIHBhcmFtczoge1xuICAgICAgICBjb2luOiAndGxuYnRjJyxcbiAgICAgICAgaWQ6ICdmYWtlaWQnLFxuICAgICAgfSxcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aDogJ2xpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoJyxcbiAgICAgIH0sXG4gICAgfSBhcyB1bmtub3duIGFzIGV4cHJlc3MuUmVxdWVzdDtcblxuICAgIGF3YWl0IGhhbmRsZVVubG9ja0xpZ2h0bmluZ1dhbGxldChyZXEpO1xuXG4gICAgdW5sb2Nrd2FsbGV0Tm9jay5kb25lKCk7XG4gICAgcmVhZEZpbGVTdHViLmNhbGxlZE9uY2VXaXRoKCdsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aCcpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgcmVhZEZpbGVTdHViLnJlc3RvcmUoKTtcbiAgfSk7XG59KTtcbiJdfQ==

Выполнить команду


Для локальной разработки. Не используйте в интернете!