mirror of
https://github.com/ful1e5/apple_cursor.git
synced 2025-05-14 23:24:48 -04:00
Merge branch 'dev'
This commit is contained in:
commit
53ffa7e256
66 changed files with 768 additions and 499 deletions
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "apple_cursor_bitmapper",
|
||||
"version": "1.1.6",
|
||||
"version": "1.2.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"render": "yarn ts-node src/index.ts"
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
import path from "path";
|
||||
import { readdirSync, existsSync } from "fs";
|
||||
import { Colors } from "./core/types";
|
||||
|
||||
// Directory resolve
|
||||
const projectRoot = path.resolve(__dirname, "../../");
|
||||
|
||||
const outDir = path.resolve(projectRoot, "bitmaps");
|
||||
const staticSvgDir = path.resolve(projectRoot, "svg", "static");
|
||||
const animatedSvgDir = path.resolve(projectRoot, "svg", "animated");
|
||||
|
||||
// Generate a svg list
|
||||
if (!existsSync(staticSvgDir) || !existsSync(animatedSvgDir)) {
|
||||
throw new Error("svg directory not found");
|
||||
interface Config {
|
||||
themeName: string;
|
||||
color: Colors;
|
||||
}
|
||||
|
||||
const staticCursors = readdirSync(staticSvgDir).map((f) =>
|
||||
path.resolve(staticSvgDir, f)
|
||||
);
|
||||
const animatedCursors = readdirSync(animatedSvgDir).map((f) =>
|
||||
path.resolve(animatedSvgDir, f)
|
||||
);
|
||||
const black = "#000000";
|
||||
const white = "#FFFFFF";
|
||||
|
||||
export { staticCursors, animatedCursors, outDir };
|
||||
const config: Config[] = [
|
||||
{
|
||||
themeName: "macOSBigSur",
|
||||
color: {
|
||||
base: black,
|
||||
outline: white,
|
||||
},
|
||||
},
|
||||
{
|
||||
themeName: "macOSBigSur-White",
|
||||
color: {
|
||||
base: white,
|
||||
outline: black,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export { config };
|
||||
|
|
155
bitmapper/src/core/BitmapsGenerator.ts
Normal file
155
bitmapper/src/core/BitmapsGenerator.ts
Normal file
|
@ -0,0 +1,155 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
import puppeteer, { Browser, ElementHandle, Page } from "puppeteer";
|
||||
|
||||
import { frameNumber } from "./util/frameNumber";
|
||||
import { matchImages } from "./util/matchImages";
|
||||
import { toHTML } from "./util/toHTML";
|
||||
|
||||
class BitmapsGenerator {
|
||||
/**
|
||||
* Generate Png files from svg code.
|
||||
* @param themeName Give name, So all bitmaps files are organized in one directory.
|
||||
* @param bitmapsDir `absolute` or `relative` path, Where `.png` files will store.
|
||||
*/
|
||||
constructor(private bitmapsDir: string) {
|
||||
this.bitmapsDir = path.resolve(bitmapsDir);
|
||||
this.createDir(this.bitmapsDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create directory if it doesn't exists.
|
||||
* @param dirPath directory `absolute` path.
|
||||
*/
|
||||
private createDir(dirPath: string) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
fs.mkdirSync(dirPath, { recursive: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare headless browser.
|
||||
*/
|
||||
public async getBrowser(): Promise<Browser> {
|
||||
return await puppeteer.launch({
|
||||
ignoreDefaultArgs: ["--no-sandbox"],
|
||||
headless: true,
|
||||
});
|
||||
}
|
||||
|
||||
private async getSvgElement(
|
||||
page: Page,
|
||||
content: string
|
||||
): Promise<ElementHandle<Element>> {
|
||||
if (!content) {
|
||||
throw new Error(`${content} File Read error`);
|
||||
}
|
||||
|
||||
const html = toHTML(content);
|
||||
await page.setContent(html, { timeout: 0 });
|
||||
|
||||
const svg = await page.$("#container svg");
|
||||
|
||||
if (!svg) {
|
||||
throw new Error("svg element not found!");
|
||||
}
|
||||
return svg;
|
||||
}
|
||||
|
||||
public async generateStatic(browser: Browser, content: string, key: string) {
|
||||
const page = await browser.newPage();
|
||||
const svg = await this.getSvgElement(page, content);
|
||||
|
||||
const out = path.resolve(this.bitmapsDir, `${key}.png`);
|
||||
|
||||
await svg.screenshot({ omitBackground: true, path: out });
|
||||
await page.close();
|
||||
}
|
||||
|
||||
private async screenshot(
|
||||
element: ElementHandle<Element>
|
||||
): Promise<Buffer | string> {
|
||||
const buffer = await element.screenshot({
|
||||
encoding: "binary",
|
||||
omitBackground: true,
|
||||
});
|
||||
|
||||
if (!buffer) {
|
||||
throw new Error("SVG element screenshot not working");
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private async stopAnimation(page: Page) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send("Animation.setPlaybackRate", {
|
||||
playbackRate: 0,
|
||||
});
|
||||
}
|
||||
|
||||
private async resumeAnimation(page: Page, playbackRate: number) {
|
||||
const client = await page.target().createCDPSession();
|
||||
await client.send("Animation.setPlaybackRate", {
|
||||
playbackRate,
|
||||
});
|
||||
}
|
||||
|
||||
private async saveFrameImage(key: string, frame: Buffer | string) {
|
||||
const out_path = path.resolve(this.bitmapsDir, key);
|
||||
fs.writeFileSync(out_path, frame);
|
||||
}
|
||||
|
||||
public async generateAnimated(
|
||||
browser: Browser,
|
||||
content: string,
|
||||
key: string,
|
||||
options?: {
|
||||
playbackRate?: number;
|
||||
diff?: number;
|
||||
frameLimit?: number;
|
||||
framePadding?: number;
|
||||
}
|
||||
) {
|
||||
const opt = Object.assign(
|
||||
{ playbackRate: 0.1, diff: 0, frameLimit: 300, framePadding: 4 },
|
||||
options
|
||||
);
|
||||
|
||||
const page = await browser.newPage();
|
||||
const svg = await this.getSvgElement(page, content);
|
||||
await this.stopAnimation(page);
|
||||
|
||||
let index = 1;
|
||||
let breakRendering = false;
|
||||
let prevImg: Buffer | string;
|
||||
|
||||
// Rendering frames till `imgN` matched to `imgN-1` (When Animation is done)
|
||||
while (!breakRendering) {
|
||||
if (index > opt.frameLimit) {
|
||||
throw new Error("Reached the frame limit.");
|
||||
}
|
||||
|
||||
await this.resumeAnimation(page, opt.playbackRate);
|
||||
const img: string | Buffer = await this.screenshot(svg);
|
||||
await this.stopAnimation(page);
|
||||
|
||||
if (index > 1) {
|
||||
// @ts-ignore
|
||||
const diff = matchImages(prevImg, img);
|
||||
if (diff <= opt.diff) {
|
||||
breakRendering = !breakRendering;
|
||||
}
|
||||
}
|
||||
const number = frameNumber(index, opt.framePadding);
|
||||
const frame = `${key}-${number}.png`;
|
||||
|
||||
this.saveFrameImage(frame, img);
|
||||
|
||||
prevImg = img;
|
||||
++index;
|
||||
}
|
||||
await page.close();
|
||||
}
|
||||
}
|
||||
export { BitmapsGenerator };
|
77
bitmapper/src/core/SVGHandler/SvgDirectoryParser.ts
Normal file
77
bitmapper/src/core/SVGHandler/SvgDirectoryParser.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
interface Svg {
|
||||
key: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
class SvgDirectoryParser {
|
||||
/**
|
||||
* Manage and Parse SVG file path in `absolute` fashion.
|
||||
* This Parser look svg files as below fashion:
|
||||
* `
|
||||
* <@svgDir>/static
|
||||
* <@svgDir>/animated
|
||||
* `
|
||||
* @param svgDir is relative/absolute path, Where `SVG` files are stored.
|
||||
*/
|
||||
semiAnimated: boolean = false;
|
||||
constructor(private svgDir: string) {
|
||||
if (!fs.existsSync(this.svgDir)) {
|
||||
throw new Error(`SVG files not found in ${this.svgDir}`);
|
||||
}
|
||||
}
|
||||
|
||||
private readData(f: string): Svg {
|
||||
const content = fs.readFileSync(f, "utf-8");
|
||||
const key = path.basename(f, ".svg");
|
||||
return { content, key };
|
||||
}
|
||||
|
||||
/**
|
||||
* Return absolute paths array of SVG files data located inside '@svgDir/static'
|
||||
*/
|
||||
public getStatic(): Svg[] {
|
||||
const staticDir = path.resolve(this.svgDir, "static");
|
||||
|
||||
if (!fs.existsSync(staticDir)) {
|
||||
console.log(`${this.svgDir} contains semi-animated .svg files`);
|
||||
this.semiAnimated = true;
|
||||
return [];
|
||||
} else {
|
||||
const svgs = fs
|
||||
.readdirSync(staticDir)
|
||||
.map((f) => this.readData(path.resolve(staticDir, f)));
|
||||
|
||||
if (svgs.length == 0) {
|
||||
throw new Error("Static Cursors directory is empty");
|
||||
}
|
||||
return svgs;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return absolute paths array of SVG files data located inside '@svgDir/animated'
|
||||
*/
|
||||
public getAnimated(): Svg[] {
|
||||
const animatedDir = path.resolve(this.svgDir, "animated");
|
||||
|
||||
if (!fs.existsSync(animatedDir)) {
|
||||
throw new Error("Animated Cursors directory not found");
|
||||
}
|
||||
|
||||
const svgs = fs
|
||||
.readdirSync(animatedDir)
|
||||
.map((f) => this.readData(path.resolve(animatedDir, f)));
|
||||
|
||||
if (svgs.length == 0 && this.semiAnimated) {
|
||||
throw new Error(
|
||||
`Can't parse svg directory ${this.svgDir} as semi-animated theme`
|
||||
);
|
||||
}
|
||||
|
||||
return svgs;
|
||||
}
|
||||
}
|
||||
|
||||
export { SvgDirectoryParser };
|
52
bitmapper/src/core/SVGHandler/colorSvg.ts
Normal file
52
bitmapper/src/core/SVGHandler/colorSvg.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import { Colors } from "../types";
|
||||
|
||||
/**
|
||||
* Default Key Colors for generating colored svg.
|
||||
* base="#00FF00" (Green)
|
||||
* outline="#0000FF" (Blue)
|
||||
* watch.background="#FF0000" (Red)
|
||||
* */
|
||||
const defaultKeyColors: Colors = {
|
||||
base: "#00FF00",
|
||||
outline: "#0000FF",
|
||||
watch: {
|
||||
background: "#FF0000",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Customize colors of svg code.
|
||||
* @param {string} content SVG code.
|
||||
* @param {Colors} colors Customize colors.
|
||||
* @param {Colors} [keys] Colors Key, That was written SVG code.
|
||||
* @returns {string} SVG code with colors.
|
||||
*/
|
||||
const colorSvg = (
|
||||
content: string,
|
||||
colors: Colors,
|
||||
keys: Colors = defaultKeyColors
|
||||
): string => {
|
||||
content = content
|
||||
.replace(new RegExp(keys.base, "ig"), colors.base)
|
||||
.replace(new RegExp(keys.outline, "ig"), colors.outline);
|
||||
|
||||
try {
|
||||
// === trying to replace `watch` color ===
|
||||
|
||||
if (!colors.watch?.background) {
|
||||
throw new Error("");
|
||||
}
|
||||
const { background: b } = colors.watch;
|
||||
content = content.replace(new RegExp(keys.watch!.background, "ig"), b); // Watch Background
|
||||
} catch (error) {
|
||||
// === on error => replace `watch` color as `base` ===
|
||||
|
||||
content = content.replace(
|
||||
new RegExp(keys.watch!.background, "ig"),
|
||||
colors.base
|
||||
);
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
export { colorSvg };
|
4
bitmapper/src/core/SVGHandler/index.ts
Normal file
4
bitmapper/src/core/SVGHandler/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { colorSvg } from "./colorSvg";
|
||||
import { SvgDirectoryParser } from "./SvgDirectoryParser";
|
||||
|
||||
export { colorSvg, SvgDirectoryParser };
|
4
bitmapper/src/core/index.ts
Normal file
4
bitmapper/src/core/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { BitmapsGenerator } from "./BitmapsGenerator";
|
||||
import * as SVGHandler from "./SVGHandler";
|
||||
|
||||
export { BitmapsGenerator, SVGHandler };
|
20
bitmapper/src/core/types.ts
Normal file
20
bitmapper/src/core/types.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Hex Colors in string Format.
|
||||
*
|
||||
* `Example: `"#FFFFFF"
|
||||
*/
|
||||
type HexColor = string;
|
||||
|
||||
/**
|
||||
* @Colors expect `base`, `outline` & `watch-background` colors in **HexColor** Format.
|
||||
* @default background is `base` color.
|
||||
*/
|
||||
type Colors = {
|
||||
base: HexColor;
|
||||
outline: HexColor;
|
||||
watch?: {
|
||||
background: HexColor;
|
||||
};
|
||||
};
|
||||
|
||||
export { Colors };
|
|
@ -1,127 +1,37 @@
|
|||
import fs from "fs";
|
||||
import path from "path";
|
||||
import puppeteer, { ElementHandle, Page } from "puppeteer";
|
||||
|
||||
import { animatedCursors, outDir, staticCursors } from "./config";
|
||||
import { frameNumber } from "./utils/frameNumber";
|
||||
import { matchImages } from "./utils/matchImages";
|
||||
import { toHTML } from "./utils/toHTML";
|
||||
import { BitmapsGenerator, SVGHandler } from "./core";
|
||||
import { config } from "./config";
|
||||
|
||||
const getSVGElement = async (page: Page) => {
|
||||
const svg = await page.$("#container svg");
|
||||
|
||||
if (!svg) {
|
||||
throw new Error("svg element not found!");
|
||||
}
|
||||
return svg;
|
||||
};
|
||||
|
||||
const screenshot = async (element: ElementHandle<Element>): Promise<Buffer> => {
|
||||
return element.screenshot({
|
||||
omitBackground: true,
|
||||
encoding: "binary",
|
||||
});
|
||||
};
|
||||
|
||||
const stopAnimation = async (page: Page) => {
|
||||
// @ts-ignore
|
||||
await page._client.send("Animation.setPlaybackRate", {
|
||||
playbackRate: 0,
|
||||
});
|
||||
};
|
||||
|
||||
const resumeAnimation = async (page: Page, playbackRate: number = 0.1) => {
|
||||
// @ts-ignore
|
||||
await page._client.send("Animation.setPlaybackRate", {
|
||||
playbackRate,
|
||||
});
|
||||
};
|
||||
|
||||
const saveFrameImage = (key: string, frame: Buffer) => {
|
||||
const out_path = path.resolve(outDir, key);
|
||||
fs.writeFileSync(out_path, frame, { encoding: "binary" });
|
||||
};
|
||||
const root = path.resolve(__dirname, "../../");
|
||||
const svgDir = path.resolve(root, "svg");
|
||||
|
||||
const main = async () => {
|
||||
const browser = await puppeteer.launch({
|
||||
ignoreDefaultArgs: ["--single-process", "--no-sandbox"],
|
||||
headless: true,
|
||||
});
|
||||
for (const { themeName, color } of config) {
|
||||
console.log("=>", themeName);
|
||||
|
||||
if (!fs.existsSync(outDir)) {
|
||||
fs.mkdirSync(outDir);
|
||||
} else {
|
||||
throw new Error(`out directory '${outDir}' already exists.`);
|
||||
}
|
||||
const bitmapsDir = path.resolve(root, "bitmaps", themeName);
|
||||
const svg = new SVGHandler.SvgDirectoryParser(svgDir);
|
||||
|
||||
for (const svgFilePath of staticCursors) {
|
||||
const svgData = fs.readFileSync(svgFilePath, "utf-8");
|
||||
if (!svgData) {
|
||||
throw new Error(`${svgFilePath} File Read error`);
|
||||
const png = new BitmapsGenerator(bitmapsDir);
|
||||
const browser = await png.getBrowser();
|
||||
|
||||
for (let { key, content } of svg.getStatic()) {
|
||||
console.log(" -> Saving", key, "...");
|
||||
|
||||
content = SVGHandler.colorSvg(content, color);
|
||||
await png.generateStatic(browser, content, key);
|
||||
}
|
||||
|
||||
const page = await browser.newPage();
|
||||
const html = toHTML(svgData);
|
||||
for (let { key, content } of svg.getAnimated()) {
|
||||
console.log(" -> Saving", key, "...");
|
||||
|
||||
await page.setContent(html);
|
||||
const svg = await getSVGElement(page);
|
||||
|
||||
const key = `${path.basename(svgFilePath, ".svg")}.png`;
|
||||
const out = path.join(outDir, key);
|
||||
|
||||
console.log("Saving", key, "...");
|
||||
await svg.screenshot({ omitBackground: true, path: out });
|
||||
await page.close();
|
||||
}
|
||||
|
||||
for (const svgFilePath of animatedCursors) {
|
||||
const svgData = fs.readFileSync(svgFilePath, "utf8");
|
||||
if (!svgData) {
|
||||
throw new Error(`${svgFilePath} File Read error`);
|
||||
content = SVGHandler.colorSvg(content, color);
|
||||
await png.generateAnimated(browser, content, key);
|
||||
}
|
||||
|
||||
const page = await browser.newPage();
|
||||
const html = toHTML(svgData);
|
||||
|
||||
await page.setContent(html);
|
||||
const svg = await getSVGElement(page);
|
||||
await stopAnimation(page);
|
||||
|
||||
let index = 1;
|
||||
const frameLimit = 300;
|
||||
let breakRendering = false;
|
||||
let prevImg: Buffer;
|
||||
|
||||
// Rendering frames till `imgN` matched to `imgN-1` (When Animation is done)
|
||||
while (!breakRendering) {
|
||||
if (index > frameLimit) {
|
||||
throw new Error("Reached the frame limit.");
|
||||
}
|
||||
|
||||
resumeAnimation(page);
|
||||
const img = await screenshot(svg);
|
||||
stopAnimation(page);
|
||||
|
||||
if (index > 1) {
|
||||
// @ts-ignore
|
||||
const diff = matchImages(prevImg, img);
|
||||
if (diff <= 100) {
|
||||
breakRendering = !breakRendering;
|
||||
}
|
||||
}
|
||||
const frame = frameNumber(index, 3);
|
||||
const key = `${path.basename(svgFilePath, ".svg")}-${frame}.png`;
|
||||
|
||||
console.log("Saving", key, "...");
|
||||
saveFrameImage(key, img);
|
||||
|
||||
prevImg = img;
|
||||
++index;
|
||||
}
|
||||
|
||||
await page.close();
|
||||
await browser.close();
|
||||
}
|
||||
await browser.close();
|
||||
};
|
||||
|
||||
main();
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
defer-to-connect "^1.0.1"
|
||||
|
||||
"@types/node@*":
|
||||
version "14.14.37"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e"
|
||||
integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==
|
||||
version "16.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.1.tgz#c6b9198178da504dfca1fd0be9b2e1002f1586f0"
|
||||
integrity sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A==
|
||||
|
||||
"@types/pixelmatch@^5.2.2":
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/pixelmatch/-/pixelmatch-5.2.2.tgz#3403238d4b920bf2255fb6cbf9a098bef796ce62"
|
||||
integrity sha512-ndpfW/H8+SAiI3wt+f8DlHGgB7OeBdgFgBJ6v/1l3SpJ0MCn9wtXFb4mUccMujN5S4DMmAh7MVy1O3WcXrHUKw==
|
||||
version "5.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pixelmatch/-/pixelmatch-5.2.4.tgz#ca145cc5ede1388c71c68edf2d1f5190e5ddd0f6"
|
||||
integrity sha512-HDaSHIAv9kwpMN7zlmwfTv6gax0PiporJOipcrGsVNF3Ba+kryOZc0Pio5pn6NhisgWr7TaajlPEKTbTAypIBQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
|
@ -34,16 +34,16 @@
|
|||
"@types/node" "*"
|
||||
|
||||
"@types/puppeteer@^5.4.2":
|
||||
version "5.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.3.tgz#cdca84aa7751d77448d8a477dbfa0af1f11485f2"
|
||||
integrity sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==
|
||||
version "5.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-5.4.4.tgz#e92abeccc4f46207c3e1b38934a1246be080ccd0"
|
||||
integrity sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/yauzl@^2.9.1":
|
||||
version "2.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af"
|
||||
integrity sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a"
|
||||
integrity sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
|
@ -81,10 +81,10 @@ ansi-styles@^4.1.0:
|
|||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
anymatch@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
|
||||
integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
@ -95,9 +95,9 @@ arg@^4.1.0:
|
|||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
base64-js@^1.3.1:
|
||||
version "1.5.1"
|
||||
|
@ -153,9 +153,9 @@ buffer-crc32@~0.2.3:
|
|||
integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer@^5.2.1, buffer@^5.5.0:
|
||||
version "5.7.1"
|
||||
|
@ -192,19 +192,19 @@ chalk@^3.0.0:
|
|||
supports-color "^7.1.0"
|
||||
|
||||
chokidar@^3.2.2:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
|
||||
integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
|
||||
integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
|
||||
dependencies:
|
||||
anymatch "~3.1.1"
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.0"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.5.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.1"
|
||||
fsevents "~2.3.2"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.4"
|
||||
|
@ -268,9 +268,9 @@ crypto-random-string@^2.0.0:
|
|||
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
|
||||
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
|
||||
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
|
@ -392,7 +392,7 @@ fs.realpath@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
fsevents@~2.3.1:
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
@ -411,7 +411,7 @@ get-stream@^5.1.0:
|
|||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
glob-parent@~5.1.0:
|
||||
glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
|
@ -419,9 +419,9 @@ glob-parent@~5.1.0:
|
|||
is-glob "^4.0.1"
|
||||
|
||||
glob@^7.1.3:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
version "7.1.7"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
|
||||
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
|
@ -455,9 +455,9 @@ got@^9.6.0:
|
|||
url-parse-lax "^3.0.0"
|
||||
|
||||
graceful-fs@^4.1.2:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
||||
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
|
@ -695,9 +695,9 @@ node-fetch@^2.6.1:
|
|||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
nodemon@^2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.7.tgz#6f030a0a0ebe3ea1ba2a38f71bf9bab4841ced32"
|
||||
integrity sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.12.tgz#5dae4e162b617b91f1873b3bfea215dd71e144d5"
|
||||
integrity sha512-egCTmNZdObdBxUBw6ZNwvZ/xzk24CKRs5K6d+5zbmrMr7rOpPmfPeF6OxM3DDpaRx331CQRFEktn+wrFFfBSOA==
|
||||
dependencies:
|
||||
chokidar "^3.2.2"
|
||||
debug "^3.2.6"
|
||||
|
@ -784,9 +784,9 @@ pend@~1.2.0:
|
|||
integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA=
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
|
||||
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
|
||||
|
||||
pixelmatch@^5.2.1:
|
||||
version "5.2.1"
|
||||
|
@ -884,10 +884,10 @@ readable-stream@^3.1.1, readable-stream@^3.4.0:
|
|||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readdirp@~3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
|
||||
integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
|
@ -1092,9 +1092,9 @@ typedarray-to-buffer@^3.1.5:
|
|||
is-typedarray "^1.0.0"
|
||||
|
||||
typescript@^4.1.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
|
||||
integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
|
||||
version "4.3.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
|
||||
integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
|
||||
|
||||
unbzip2-stream@^1.3.3:
|
||||
version "1.4.3"
|
||||
|
@ -1172,9 +1172,15 @@ write-file-atomic@^3.0.0:
|
|||
typedarray-to-buffer "^3.1.5"
|
||||
|
||||
ws@^7.2.3:
|
||||
<<<<<<< HEAD
|
||||
version "7.4.6"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
|
||||
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
|
||||
=======
|
||||
version "7.5.3"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74"
|
||||
integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==
|
||||
>>>>>>> dev
|
||||
|
||||
xdg-basedir@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue