thomwolf HF staff commited on
Commit
0326339
·
1 Parent(s): 510e979

pushing code

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .eslintrc.js +47 -0
  2. .gitattributes +2 -0
  3. .github/FUNDING.yml +1 -0
  4. .gitignore +7 -0
  5. .prettierrc +7 -0
  6. CODEOWNERS +2 -0
  7. LICENSE +21 -0
  8. common/api.ts +90 -0
  9. common/api_github.ts +142 -0
  10. common/chart.ts +229 -0
  11. common/utils.ts +142 -0
  12. index.html +108 -17
  13. package.json +53 -0
  14. packages/xy-chart/components/ToolTip.ts +218 -0
  15. packages/xy-chart/index.ts +399 -0
  16. packages/xy-chart/types.ts +8 -0
  17. packages/xy-chart/utils/addFilter.ts +26 -0
  18. packages/xy-chart/utils/addFont.ts +11 -0
  19. packages/xy-chart/utils/drawAxis.ts +105 -0
  20. packages/xy-chart/utils/drawLabels.ts +98 -0
  21. packages/xy-chart/utils/drawLegend.ts +118 -0
  22. packages/xy-chart/utils/drawWatermark.ts +25 -0
  23. packages/xy-chart/utils/getFormatNumber.ts +19 -0
  24. packages/xy-chart/utils/getFormatTimeline.ts +59 -0
  25. plugins/additionBuildPlugin.ts +45 -0
  26. plugins/scripts/copyExtensionFiles.ts +20 -0
  27. plugins/scripts/emptyDist.ts +19 -0
  28. plugins/scripts/generateSitemap.ts +62 -0
  29. pnpm-lock.yaml +2370 -0
  30. postcss.config.js +6 -0
  31. public/blog/add-a-live-star-history-chart-to-your-github-readme.md +89 -0
  32. public/blog/assets/embed-chart-with-iframe.png +3 -0
  33. public/blog/assets/embed-chart-with-svg.png +3 -0
  34. public/blog/assets/github-badges.png +3 -0
  35. public/blog/assets/github-trending-tab/github-home.webp +0 -0
  36. public/blog/assets/github-trending-tab/github-trending-tab.webp +0 -0
  37. public/blog/assets/github-trending-tab/hn.webp +0 -0
  38. public/blog/assets/github-trending-tab/star-history.webp +0 -0
  39. public/blog/assets/github-trending-tab/throw.gif +3 -0
  40. public/blog/assets/how-to-use-github-star-history/add-access-token.webp +0 -0
  41. public/blog/assets/how-to-use-github-star-history/align-timeline.webp +0 -0
  42. public/blog/assets/how-to-use-github-star-history/book.webp +0 -0
  43. public/blog/assets/how-to-use-github-star-history/chrome-extension-working.webp +0 -0
  44. public/blog/assets/how-to-use-github-star-history/chrome-extension.webp +0 -0
  45. public/blog/assets/how-to-use-github-star-history/classic-form.webp +0 -0
  46. public/blog/assets/how-to-use-github-star-history/copy-iframe-readme.webp +0 -0
  47. public/blog/assets/how-to-use-github-star-history/edit-gh-access-token.webp +0 -0
  48. public/blog/assets/how-to-use-github-star-history/embed.webp +0 -0
  49. public/blog/assets/how-to-use-github-star-history/generate-new-token.webp +0 -0
  50. public/blog/assets/how-to-use-github-star-history/gh-readme.webp +0 -0
.eslintrc.js ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ parser: "vue-eslint-parser",
3
+ parserOptions: {
4
+ parser: "@typescript-eslint/parser",
5
+ sourceType: "module",
6
+ },
7
+ plugins: ["vue", "@typescript-eslint", "prettier"],
8
+ extends: [
9
+ "eslint:recommended",
10
+ "plugin:vue/vue3-recommended",
11
+ "@vue/typescript/recommended",
12
+ "plugin:prettier/recommended",
13
+ ],
14
+ rules: {
15
+ "prettier/prettier": [
16
+ "error",
17
+ {
18
+ endOfLine: "auto",
19
+ },
20
+ ],
21
+ "@typescript-eslint/no-empty-interface": "off",
22
+ "@typescript-eslint/no-explicit-any": "off",
23
+ "@typescript-eslint/no-namespace": "off",
24
+ "vue/no-v-html": "off",
25
+ "vue/multi-word-component-names": "off",
26
+ "vue/one-component-per-file": "off",
27
+ "vue/require-default-prop": "off",
28
+ },
29
+ ignorePatterns: ["node_modules", "dist", "public"],
30
+ overrides: [
31
+ {
32
+ files: ["./**/*.js"],
33
+ env: {
34
+ node: true,
35
+ },
36
+ rules: {
37
+ "no-undef": "off",
38
+ },
39
+ },
40
+ {
41
+ files: ["*.vue"],
42
+ rules: {
43
+ "no-undef": "off",
44
+ },
45
+ },
46
+ ],
47
+ };
.gitattributes CHANGED
@@ -4,6 +4,7 @@
4
  *.bz2 filter=lfs diff=lfs merge=lfs -text
5
  *.ckpt filter=lfs diff=lfs merge=lfs -text
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
 
7
  *.gz filter=lfs diff=lfs merge=lfs -text
8
  *.h5 filter=lfs diff=lfs merge=lfs -text
9
  *.joblib filter=lfs diff=lfs merge=lfs -text
@@ -17,6 +18,7 @@
17
  *.ot filter=lfs diff=lfs merge=lfs -text
18
  *.parquet filter=lfs diff=lfs merge=lfs -text
19
  *.pb filter=lfs diff=lfs merge=lfs -text
 
20
  *.pickle filter=lfs diff=lfs merge=lfs -text
21
  *.pkl filter=lfs diff=lfs merge=lfs -text
22
  *.pt filter=lfs diff=lfs merge=lfs -text
 
4
  *.bz2 filter=lfs diff=lfs merge=lfs -text
5
  *.ckpt filter=lfs diff=lfs merge=lfs -text
6
  *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gif filter=lfs diff=lfs merge=lfs -text
8
  *.gz filter=lfs diff=lfs merge=lfs -text
9
  *.h5 filter=lfs diff=lfs merge=lfs -text
10
  *.joblib filter=lfs diff=lfs merge=lfs -text
 
18
  *.ot filter=lfs diff=lfs merge=lfs -text
19
  *.parquet filter=lfs diff=lfs merge=lfs -text
20
  *.pb filter=lfs diff=lfs merge=lfs -text
21
+ *.png filter=lfs diff=lfs merge=lfs -text
22
  *.pickle filter=lfs diff=lfs merge=lfs -text
23
  *.pkl filter=lfs diff=lfs merge=lfs -text
24
  *.pt filter=lfs diff=lfs merge=lfs -text
.github/FUNDING.yml ADDED
@@ -0,0 +1 @@
 
 
1
+ github: [star-history]
.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ node_modules
2
+ .DS_Store
3
+ dist
4
+ dist-ssr
5
+ *.local
6
+ *.env
7
+ .pnpm-debug.log
.prettierrc ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "useTabs": false,
3
+ "tabWidth": 2,
4
+ "singleQuote": false,
5
+ "semi": true,
6
+ "printWidth": 80
7
+ }
CODEOWNERS ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # These owners will be the default owners for everything in the repo.
2
+ * @boojack @d-bytebase
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Bytebase (Hong Kong) Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
common/api.ts ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import axios from "axios";
2
+ import utils from "./utils";
3
+
4
+ const DEFAULT_PER_PAGE = 30;
5
+
6
+ namespace api {
7
+ export async function getRepoStargazers(
8
+ repo: string,
9
+ token?: string,
10
+ ) {
11
+ let url = `https://huggingface.co/api/spaces/${repo}/likers?expand=True`;
12
+
13
+ return axios.get(url, {
14
+ headers: {
15
+ Accept: "application/vnd.github.v3.star+json",
16
+ Authorization: token ? `token ${token}` : "",
17
+ },
18
+ });
19
+ }
20
+
21
+ export async function getRepoStargazersCount(repo: string, token?: string) {
22
+ const { data } = await axios.get(`https://huggingface.co/api/spaces/${repo}`, {
23
+ headers: {
24
+ Accept: "application/vnd.github.v3.star+json",
25
+ Authorization: token ? `token ${token}` : "",
26
+ },
27
+ });
28
+
29
+ return data.likes;
30
+ }
31
+
32
+ export async function getRepoStarRecords(
33
+ repo: string,
34
+ token: string,
35
+ maxRequestAmount: number
36
+ ) {
37
+ const requestPages = await getRepoStargazers(repo, token);
38
+
39
+ // const resArray: string[] = []
40
+ // for (let i = 0; i < requestPages.data.length; ) {
41
+ // resArray.push(requestPages.data[i].likedAt);
42
+ // }
43
+ const resArray: string[] = requestPages.data.map((item: any) => item.likedAt);
44
+
45
+ resArray.sort((a, b) => Date.parse(a) - Date.parse(b));
46
+ const starRecordsMap: Map<string, number> = new Map();
47
+
48
+ for (let i = 0; i < resArray.length; ) {
49
+ starRecordsMap.set(
50
+ utils.getDateString(resArray[i]),
51
+ i + 1
52
+ );
53
+ i += Math.floor(resArray.length / maxRequestAmount) || 1;
54
+ }
55
+
56
+ const starAmount = await getRepoStargazersCount(repo, token);
57
+ starRecordsMap.set(utils.getDateString(Date.now()), starAmount);
58
+
59
+ const starRecords: {
60
+ date: string;
61
+ count: number;
62
+ }[] = [];
63
+
64
+ starRecordsMap.forEach((v, k) => {
65
+ starRecords.push({
66
+ date: k,
67
+ count: v,
68
+ });
69
+ });
70
+
71
+ return starRecords;
72
+ }
73
+
74
+ export async function getRepoLogoUrl(
75
+ repo: string,
76
+ token?: string
77
+ ): Promise<string> {
78
+ const owner = repo.split("/")[0];
79
+ // const { data } = await axios.get(`https://api.github.com/users/${owner}`, {
80
+ // headers: {
81
+ // Accept: "application/vnd.github.v3.star+json",
82
+ // Authorization: token ? `token ${token}` : "",
83
+ // },
84
+ // });
85
+
86
+ return ""; // data.avatar_url;
87
+ }
88
+ }
89
+
90
+ export default api;
common/api_github.ts ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import axios from "axios";
2
+ import utils from "./utils";
3
+
4
+ const DEFAULT_PER_PAGE = 30;
5
+
6
+ namespace api {
7
+ export async function getRepoStargazers(
8
+ repo: string,
9
+ token?: string,
10
+ page?: number
11
+ ) {
12
+ let url = `https://api.github.com/repos/${repo}/stargazers?per_page=${DEFAULT_PER_PAGE}`;
13
+
14
+ if (page !== undefined) {
15
+ url = `${url}&page=${page}`;
16
+ }
17
+ return axios.get(url, {
18
+ headers: {
19
+ Accept: "application/vnd.github.v3.star+json",
20
+ Authorization: token ? `token ${token}` : "",
21
+ },
22
+ });
23
+ }
24
+
25
+ export async function getRepoStargazersCount(repo: string, token?: string) {
26
+ const { data } = await axios.get(`https://api.github.com/repos/${repo}`, {
27
+ headers: {
28
+ Accept: "application/vnd.github.v3.star+json",
29
+ Authorization: token ? `token ${token}` : "",
30
+ },
31
+ });
32
+
33
+ return data.stargazers_count;
34
+ }
35
+
36
+ export async function getRepoStarRecords(
37
+ repo: string,
38
+ token: string,
39
+ maxRequestAmount: number
40
+ ) {
41
+ const patchRes = await getRepoStargazers(repo, token);
42
+
43
+ const headerLink = patchRes.headers["link"] || "";
44
+
45
+ let pageCount = 1;
46
+ const regResult = /next.*&page=(\d*).*last/.exec(headerLink);
47
+
48
+ if (regResult) {
49
+ if (regResult[1] && Number.isInteger(Number(regResult[1]))) {
50
+ pageCount = Number(regResult[1]);
51
+ }
52
+ }
53
+
54
+ if (pageCount === 1 && patchRes?.data?.length === 0) {
55
+ throw {
56
+ status: patchRes.status,
57
+ data: [],
58
+ };
59
+ }
60
+
61
+ const requestPages: number[] = [];
62
+ if (pageCount < maxRequestAmount) {
63
+ requestPages.push(...utils.range(1, pageCount));
64
+ } else {
65
+ utils.range(1, maxRequestAmount).map((i) => {
66
+ requestPages.push(Math.round((i * pageCount) / maxRequestAmount) - 1);
67
+ });
68
+ if (!requestPages.includes(1)) {
69
+ requestPages.unshift(1);
70
+ }
71
+ }
72
+
73
+ const resArray = await Promise.all(
74
+ requestPages.map((page) => {
75
+ return getRepoStargazers(repo, token, page);
76
+ })
77
+ );
78
+
79
+ const starRecordsMap: Map<string, number> = new Map();
80
+
81
+ if (requestPages.length < maxRequestAmount) {
82
+ const starRecordsData: {
83
+ starred_at: string;
84
+ }[] = [];
85
+ resArray.map((res) => {
86
+ const { data } = res;
87
+ starRecordsData.push(...data);
88
+ });
89
+ for (let i = 0; i < starRecordsData.length; ) {
90
+ starRecordsMap.set(
91
+ utils.getDateString(starRecordsData[i].starred_at),
92
+ i + 1
93
+ );
94
+ i += Math.floor(starRecordsData.length / maxRequestAmount) || 1;
95
+ }
96
+ } else {
97
+ resArray.map(({ data }, index) => {
98
+ if (data.length > 0) {
99
+ const starRecord = data[0];
100
+ starRecordsMap.set(
101
+ utils.getDateString(starRecord.starred_at),
102
+ DEFAULT_PER_PAGE * (requestPages[index] - 1)
103
+ );
104
+ }
105
+ });
106
+ }
107
+
108
+ const starAmount = await getRepoStargazersCount(repo, token);
109
+ starRecordsMap.set(utils.getDateString(Date.now()), starAmount);
110
+
111
+ const starRecords: {
112
+ date: string;
113
+ count: number;
114
+ }[] = [];
115
+
116
+ starRecordsMap.forEach((v, k) => {
117
+ starRecords.push({
118
+ date: k,
119
+ count: v,
120
+ });
121
+ });
122
+
123
+ return starRecords;
124
+ }
125
+
126
+ export async function getRepoLogoUrl(
127
+ repo: string,
128
+ token?: string
129
+ ): Promise<string> {
130
+ const owner = repo.split("/")[0];
131
+ const { data } = await axios.get(`https://api.github.com/users/${owner}`, {
132
+ headers: {
133
+ Accept: "application/vnd.github.v3.star+json",
134
+ Authorization: token ? `token ${token}` : "",
135
+ },
136
+ });
137
+
138
+ return data.avatar_url;
139
+ }
140
+ }
141
+
142
+ export default api;
common/chart.ts ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { XYChartData, XYData } from "../packages/xy-chart";
2
+ import { ChartMode, RepoStarData, RepoData } from "../types/chart";
3
+ import api from "./api";
4
+ import utils from "./utils";
5
+
6
+ export const DEFAULT_MAX_REQUEST_AMOUNT = 15;
7
+
8
+ export const getReposStarData = async (
9
+ repos: string[],
10
+ token = "",
11
+ maxRequestAmount = DEFAULT_MAX_REQUEST_AMOUNT
12
+ ): Promise<RepoStarData[]> => {
13
+ const repoStarDataCacheMap = new Map();
14
+
15
+ for (const repo of repos) {
16
+ try {
17
+ const starRecords = await api.getRepoStarRecords(
18
+ repo,
19
+ token,
20
+ maxRequestAmount
21
+ );
22
+ repoStarDataCacheMap.set(repo, starRecords);
23
+ } catch (error: any) {
24
+ let message = "";
25
+ let status = 500;
26
+
27
+ if (error?.response?.status === 404) {
28
+ message = `Repo ${repo} not found`;
29
+ status = 404;
30
+ } else if (error?.response?.status === 403) {
31
+ message = "GitHub API rate limit exceeded";
32
+ status = 403;
33
+ } else if (error?.response?.status === 401) {
34
+ message = "Access Token Unauthorized";
35
+ status = 401;
36
+ } else if (Array.isArray(error?.data) && error.data?.length === 0) {
37
+ message = `Repo ${repo} has no star history`;
38
+ status = 501;
39
+ } else {
40
+ message = "Some unexpected error happened, try again later";
41
+ }
42
+
43
+ return Promise.reject({
44
+ message,
45
+ status,
46
+ repo,
47
+ });
48
+ }
49
+ }
50
+
51
+ const reposStarData: RepoStarData[] = [];
52
+ for (const repo of repos) {
53
+ const records = repoStarDataCacheMap.get(repo);
54
+ if (records) {
55
+ reposStarData.push({
56
+ repo,
57
+ starRecords: records,
58
+ });
59
+ }
60
+ }
61
+
62
+ return reposStarData.sort((d1, d2) => {
63
+ return (
64
+ Math.max(...d2.starRecords.map((s) => s.count)) -
65
+ Math.max(...d1.starRecords.map((s) => s.count))
66
+ );
67
+ });
68
+ };
69
+
70
+ export const getRepoData = async (
71
+ repos: string[],
72
+ token = "",
73
+ maxRequestAmount = DEFAULT_MAX_REQUEST_AMOUNT
74
+ ): Promise<RepoData[]> => {
75
+ const repoDataCacheMap: Map<
76
+ string,
77
+ {
78
+ star: {
79
+ date: string;
80
+ count: number;
81
+ }[];
82
+ logo: string;
83
+ }
84
+ > = new Map();
85
+
86
+ for (const repo of repos) {
87
+ try {
88
+ const starRecords = await api.getRepoStarRecords(
89
+ repo,
90
+ token,
91
+ maxRequestAmount
92
+ );
93
+ const logo = await api.getRepoLogoUrl(repo, token);
94
+ repoDataCacheMap.set(repo, { star: starRecords, logo });
95
+ } catch (error: any) {
96
+ let message = "";
97
+ let status = 500;
98
+
99
+ if (error?.response?.status === 404) {
100
+ message = `Repo ${repo} not found`;
101
+ status = 404;
102
+ } else if (error?.response?.status === 403) {
103
+ message = "GitHub API rate limit exceeded";
104
+ status = 403;
105
+ } else if (error?.response?.status === 401) {
106
+ message = "Access Token Unauthorized";
107
+ status = 401;
108
+ } else if (Array.isArray(error?.data) && error.data?.length === 0) {
109
+ message = `Repo ${repo} has no star history`;
110
+ status = 501;
111
+ } else {
112
+ message = "Some unexpected error happened, try again later";
113
+ }
114
+
115
+ return Promise.reject({
116
+ message,
117
+ status,
118
+ repo,
119
+ });
120
+ }
121
+ }
122
+
123
+ const reposStarData: RepoData[] = [];
124
+ for (const repo of repos) {
125
+ const records = repoDataCacheMap.get(repo);
126
+ if (records) {
127
+ reposStarData.push({
128
+ repo,
129
+ starRecords: records.star,
130
+ logoUrl: records.logo,
131
+ });
132
+ }
133
+ }
134
+
135
+ return reposStarData.sort((d1, d2) => {
136
+ return (
137
+ Math.max(...d2.starRecords.map((s) => s.count)) -
138
+ Math.max(...d1.starRecords.map((s) => s.count))
139
+ );
140
+ });
141
+ };
142
+
143
+ export const convertStarDataToChartData = (
144
+ reposStarData: RepoStarData[],
145
+ chartMode: ChartMode
146
+ ): XYChartData => {
147
+ if (chartMode === "Date") {
148
+ const datasets: XYData[] = reposStarData.map((item) => {
149
+ const { repo, starRecords } = item;
150
+
151
+ return {
152
+ label: repo,
153
+ logo: "",
154
+ data: starRecords.map((item) => {
155
+ return {
156
+ x: new Date(item.date),
157
+ y: Number(item.count),
158
+ };
159
+ }),
160
+ };
161
+ });
162
+
163
+ return {
164
+ datasets,
165
+ };
166
+ } else {
167
+ const datasets: XYData[] = reposStarData.map((item) => {
168
+ const { repo, starRecords } = item;
169
+
170
+ const started = starRecords[0].date;
171
+
172
+ return {
173
+ label: repo,
174
+ logo: "",
175
+ data: starRecords.map((item) => {
176
+ return {
177
+ x:
178
+ utils.getTimeStampByDate(new Date(item.date)) -
179
+ utils.getTimeStampByDate(new Date(started)),
180
+ y: Number(item.count),
181
+ };
182
+ }),
183
+ };
184
+ });
185
+
186
+ return {
187
+ datasets,
188
+ };
189
+ }
190
+ };
191
+
192
+ export const convertDataToChartData = (
193
+ repoData: RepoData[],
194
+ chartMode: ChartMode
195
+ ): XYChartData => {
196
+ if (chartMode === "Date") {
197
+ const datasets: XYData[] = repoData.map(
198
+ ({ repo, starRecords, logoUrl }) => ({
199
+ label: repo,
200
+ logo: logoUrl,
201
+ data: starRecords.map((item) => {
202
+ return {
203
+ x: new Date(item.date),
204
+ y: Number(item.count),
205
+ };
206
+ }),
207
+ })
208
+ );
209
+
210
+ return { datasets };
211
+ } else {
212
+ const datasets: XYData[] = repoData.map(
213
+ ({ repo, starRecords, logoUrl }) => ({
214
+ label: repo,
215
+ logo: logoUrl,
216
+ data: starRecords.map((item) => {
217
+ return {
218
+ x:
219
+ utils.getTimeStampByDate(new Date(item.date)) -
220
+ utils.getTimeStampByDate(new Date(starRecords[0].date)),
221
+ y: Number(item.count),
222
+ };
223
+ }),
224
+ })
225
+ );
226
+
227
+ return { datasets };
228
+ }
229
+ };
common/utils.ts ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ namespace utils {
2
+ export function range(from: number, to: number): number[] {
3
+ const r: number[] = [];
4
+ for (let i = from; i <= to; i++) {
5
+ r.push(i);
6
+ }
7
+ return r;
8
+ }
9
+
10
+ export function getTimeStampByDate(t: Date | number | string): number {
11
+ const d = new Date(t);
12
+
13
+ return d.getTime();
14
+ }
15
+
16
+ export function getDateString(
17
+ t: Date | number | string,
18
+ format = "yyyy/MM/dd hh:mm:ss"
19
+ ): string {
20
+ const d = new Date(getTimeStampByDate(t));
21
+
22
+ const year = d.getFullYear();
23
+ const month = d.getMonth() + 1;
24
+ const date = d.getDate();
25
+ const hours = d.getHours();
26
+ const minutes = d.getMinutes();
27
+ const seconds = d.getSeconds();
28
+
29
+ const formatedString = format
30
+ .replace("yyyy", String(year))
31
+ .replace("MM", String(month))
32
+ .replace("dd", String(date))
33
+ .replace("hh", String(hours))
34
+ .replace("mm", String(minutes))
35
+ .replace("ss", String(seconds));
36
+
37
+ return formatedString;
38
+ }
39
+
40
+ export async function copyTextToClipboard(text: string) {
41
+ if (navigator.clipboard && navigator.clipboard.writeText) {
42
+ try {
43
+ await navigator.clipboard.writeText(text);
44
+ } catch (error: unknown) {
45
+ console.warn("Copy to clipboard failed.", error);
46
+ }
47
+ } else {
48
+ console.warn("Copy to clipboard failed, methods not supports.");
49
+ }
50
+ }
51
+
52
+ export function convertSVGToDataURL(svgElement: SVGSVGElement) {
53
+ const xml = new XMLSerializer().serializeToString(svgElement);
54
+ const encodedData = window.btoa(xml);
55
+ return `data:image/svg+xml;base64,${encodedData}`;
56
+ }
57
+
58
+ export function waitImageLoaded(image: HTMLImageElement): Promise<void> {
59
+ image.loading = "eager";
60
+
61
+ return new Promise((resolve, reject) => {
62
+ image.onload = () => {
63
+ // NOTE: There is image loading problem in Safari, fix it with some trick
64
+ setTimeout(() => {
65
+ resolve();
66
+ }, 200);
67
+ };
68
+ image.onerror = () => {
69
+ reject("Image load failed");
70
+ };
71
+ });
72
+ }
73
+
74
+ export function calcBytes(d: any): number {
75
+ let bytes = 0;
76
+
77
+ if (typeof d === "number") {
78
+ bytes += 8;
79
+ } else if (typeof d === "string") {
80
+ bytes += d.length * 2;
81
+ } else if (typeof d === "boolean") {
82
+ bytes += 1;
83
+ } else if (typeof d === "object") {
84
+ if (Array.isArray(d)) {
85
+ for (const i of d) {
86
+ bytes += calcBytes(i);
87
+ }
88
+ } else {
89
+ for (const k in d) {
90
+ bytes += calcBytes(d[k]);
91
+ }
92
+ }
93
+ }
94
+
95
+ return bytes;
96
+ }
97
+
98
+ export function calcReadingTime(content: string): string {
99
+ const wordsPerMinute = 200;
100
+ const wordAmount = content.split(" ").length;
101
+ if (wordAmount <= 200) {
102
+ return "less than 1 min read";
103
+ }
104
+
105
+ const count = Math.ceil(wordAmount / wordsPerMinute);
106
+ return `${count} min read`;
107
+ }
108
+
109
+ export function getBase64Image(url: string): Promise<string> {
110
+ return new Promise((resolve, reject) => {
111
+ const img = new Image();
112
+ img.src = url;
113
+ img.setAttribute("crossOrigin", "anonymous");
114
+
115
+ img.onload = () => {
116
+ const canvas = document.createElement("canvas");
117
+ canvas.width = img.width;
118
+ canvas.height = img.height;
119
+ const ctx = canvas.getContext("2d");
120
+ if (!ctx) {
121
+ reject("Get canvas context failed.");
122
+ return;
123
+ }
124
+ ctx.drawImage(img, 0, 0);
125
+ const dataURL = canvas.toDataURL("image/png");
126
+ resolve(dataURL);
127
+ };
128
+
129
+ img.onerror = function () {
130
+ reject("The image could not be loaded.");
131
+ };
132
+ });
133
+ }
134
+
135
+ export function absolutifyLink(rel: string): string {
136
+ const anchor = document.createElement("a");
137
+ anchor.setAttribute("href", rel);
138
+ return anchor.href;
139
+ }
140
+ }
141
+
142
+ export default utils;
index.html CHANGED
@@ -1,19 +1,110 @@
1
  <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta
7
+ name="description"
8
+ content="View and compare GitHub star history graph of open source projects"
9
+ />
10
+ <meta
11
+ name="google-site-verification"
12
+ content="gWDCNMCQeEt3snNQ8J4NCOmVkz4axYeIp5fH4umVaAs"
13
+ />
14
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
15
+ <meta name="twitter:card" content="summary_large_image" />
16
+ <meta name="twitter:site" content="star-history.com" />
17
+ <meta name="twitter:creator" content="bytebase" />
18
+ <meta name="twitter:title" content="Star History" />
19
+ <meta
20
+ name="twitter:description"
21
+ content="The missing GitHub star history graph."
22
+ />
23
+ <!-- use static image -->
24
+ <meta
25
+ name="twitter:image"
26
+ content="https://star-history.com/star-history.webp"
27
+ />
28
+ <link rel="icon" href="/icon.png" />
29
+ <link rel="apple-touch-icon" href="/icon.png" />
30
+ <link rel="bookmark" href="/icon.png" />
31
+ <link rel="shortcut icon" href="/icon.png" />
32
+ <link
33
+ rel="stylesheet"
34
+ href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"
35
+ crossorigin
36
+ />
37
+ <title>GitHub Star History</title>
38
+ <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin />
39
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
40
+ <link
41
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@100;300;400;500;600;700&display=swap"
42
+ rel="stylesheet"
43
+ crossorigin
44
+ />
45
+ </head>
46
+ <body>
47
+ <div id="app"></div>
48
+ <script type="module" src="./src/main.ts"></script>
49
+ <!-- Global site tag (gtag.js) - Google Analytics -->
50
+ <script
51
+ async
52
+ src="https://www.googletagmanager.com/gtag/js?id=G-ZDH3P2WZ6W"
53
+ ></script>
54
+ <script>
55
+ window.dataLayer = window.dataLayer || [];
56
+ function gtag() {
57
+ dataLayer.push(arguments);
58
+ }
59
+ gtag("js", new Date());
60
+ gtag("config", "G-ZDH3P2WZ6W");
61
+ </script>
62
+ <script
63
+ defer
64
+ data-domain="star-history.com"
65
+ src="https://plausible.io/js/plausible.js"
66
+ ></script>
67
+ <script>
68
+ !(function () {
69
+ var analytics = (window.analytics = window.analytics || []);
70
+ if (!analytics.initialize)
71
+ if (analytics.invoked)
72
+ window.console &&
73
+ console.error &&
74
+ console.error("Segment snippet included twice.");
75
+ else {
76
+ analytics.invoked = !0;
77
+ // NOTE: we only need the identify method to save subscriber's email.
78
+ analytics.methods = ["identify"];
79
+ analytics.factory = function (e) {
80
+ return function () {
81
+ var t = Array.prototype.slice.call(arguments);
82
+ t.unshift(e);
83
+ analytics.push(t);
84
+ return analytics;
85
+ };
86
+ };
87
+ for (var e = 0; e < analytics.methods.length; e++) {
88
+ var key = analytics.methods[e];
89
+ analytics[key] = analytics.factory(key);
90
+ }
91
+ analytics.load = function (key, e) {
92
+ var t = document.createElement("script");
93
+ t.type = "text/javascript";
94
+ t.async = !0;
95
+ t.src =
96
+ "https://cdn.segment.com/analytics.js/v1/" +
97
+ key +
98
+ "/analytics.min.js";
99
+ var n = document.getElementsByTagName("script")[0];
100
+ n.parentNode.insertBefore(t, n);
101
+ analytics._loadOptions = e;
102
+ };
103
+ analytics._writeKey = "CVXXNXv3EzfQPYqHoYvlDDDOXmKa9XOj";
104
+ analytics.SNIPPET_VERSION = "4.15.3";
105
+ analytics.load("CVXXNXv3EzfQPYqHoYvlDDDOXmKa9XOj");
106
+ }
107
+ })();
108
+ </script>
109
+ </body>
110
  </html>
package.json ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "star_history",
3
+ "version": "1.0.0",
4
+ "description": "The missing GitHub star history graph of GitHub projects",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "build:server": "pnpm i && cd server && pnpm i && pnpm build",
10
+ "build:extension": "vite build --mode extension"
11
+ },
12
+ "dependencies": {
13
+ "@tailwindcss/line-clamp": "^0.4.0",
14
+ "@tailwindcss/typography": "^0.5.1",
15
+ "@vueuse/head": "^1.0.25",
16
+ "axios": "^1.0.0",
17
+ "d3-axis": "^1.0.12",
18
+ "d3-scale": "^3.2.0",
19
+ "d3-selection": "^1.4.1",
20
+ "d3-shape": "^1.3.7",
21
+ "dayjs": "^1.10.7",
22
+ "lodash": "^4.17.21",
23
+ "marked": "^4.0.16",
24
+ "pinia": "^2.0.11",
25
+ "tailwindcss": "^3.0.19",
26
+ "typescript": "^4.4.4",
27
+ "vite": "^2.8.0",
28
+ "vue": "^3.2.47",
29
+ "vue-router": "4",
30
+ "vue-tsc": "^1.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/chrome": "0.0.210",
34
+ "@types/d3-axis": "3.0.2",
35
+ "@types/d3-scale": "4.0.3",
36
+ "@types/d3-selection": "1.4.3",
37
+ "@types/d3-shape": "3.1.0",
38
+ "@types/lodash": "4.14.191",
39
+ "@types/marked": "4.0.7",
40
+ "@types/node": "18.11.10",
41
+ "@typescript-eslint/eslint-plugin": "5.42.0",
42
+ "@typescript-eslint/parser": "5.42.0",
43
+ "@vitejs/plugin-vue": "2.3.4",
44
+ "@vue/eslint-config-typescript": "11.0.2",
45
+ "autoprefixer": "10.4.13",
46
+ "eslint": "8.26.0",
47
+ "eslint-config-prettier": "8.5.0",
48
+ "eslint-plugin-prettier": "4.2.1",
49
+ "eslint-plugin-vue": "9.7.0",
50
+ "postcss": "8.4.19",
51
+ "prettier": "2.7.1"
52
+ }
53
+ }
packages/xy-chart/components/ToolTip.ts ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { D3Selection } from "../types";
2
+
3
+ interface ToolTipConfig {
4
+ selection: D3Selection;
5
+ title: string;
6
+ items: {
7
+ color: string;
8
+ text: string;
9
+ }[];
10
+ position: {
11
+ x: number;
12
+ y: number;
13
+ type: "down_right" | "down_left" | "up_right" | "up_left";
14
+ };
15
+ backgroundColor: string;
16
+ strokeColor: string;
17
+ }
18
+
19
+ class ToolTip {
20
+ public title: string;
21
+ public items: {
22
+ color: string;
23
+ text: string;
24
+ }[];
25
+ public position: {
26
+ x: number;
27
+ y: number;
28
+ type: "down_right" | "down_left" | "up_right" | "up_left";
29
+ };
30
+ public backgroundColor: string;
31
+ public strokeColor: string;
32
+ public filter = "url(#xkcdify)";
33
+ svg: any;
34
+ tipTitle: any;
35
+ tipItems: any;
36
+ tipBackground: any;
37
+
38
+ /**
39
+ *
40
+ * @param {String} parent
41
+ * @param {String} title
42
+ * @param {Array} items
43
+ * @param {Object} position
44
+ * @example
45
+ * {
46
+ * parent: {}, // a d3 selection component
47
+ * title: 'tooltip title',
48
+ * items:[{
49
+ * color: 'red',
50
+ * text: 'tim: 13'
51
+ * }],
52
+ * position: {
53
+ * type: 'upleft'
54
+ * x: 100,
55
+ * y: 230,
56
+ * }
57
+ * }
58
+ */
59
+ constructor({
60
+ selection,
61
+ title,
62
+ items,
63
+ position,
64
+ backgroundColor,
65
+ strokeColor,
66
+ }: ToolTipConfig) {
67
+ this.title = title;
68
+ this.items = items;
69
+ this.position = position;
70
+ this.backgroundColor = backgroundColor;
71
+ this.strokeColor = strokeColor;
72
+
73
+ this.svg = selection
74
+ .append("svg")
75
+ .attr("x", this._getUpLeftX())
76
+ .attr("y", this._getUpLeftY())
77
+ .style("visibility", "hidden");
78
+
79
+ this.tipBackground = this.svg
80
+ .append("rect")
81
+ .style("fill", this.backgroundColor)
82
+ .attr("fill-opacity", 0.9)
83
+ .attr("stroke", strokeColor)
84
+ .attr("stroke-width", 2)
85
+ .attr("rx", 5)
86
+ .attr("ry", 5)
87
+ .attr("filter", this.filter)
88
+ .attr("width", this._getBackgroundWidth())
89
+ .attr("height", this._getBackgroundHeight())
90
+ .attr("x", 5)
91
+ .attr("y", 5);
92
+
93
+ this.tipTitle = this.svg
94
+ .append("text")
95
+ .style("font-size", "15px")
96
+ .style("font-weight", "bold")
97
+ .style("fill", this.strokeColor)
98
+ .attr("x", 15)
99
+ .attr("y", 25)
100
+ .text(title);
101
+
102
+ this.tipItems = items.map((item, i) => {
103
+ const g = this._generateTipItem(item, i);
104
+ return g;
105
+ });
106
+ }
107
+
108
+ show() {
109
+ this.svg.style("visibility", "visible");
110
+ }
111
+
112
+ hide() {
113
+ this.svg.style("visibility", "hidden");
114
+ }
115
+
116
+ // update tooltip position / content
117
+ update({ title, items, position }) {
118
+ if (title && title !== this.title) {
119
+ this.title = title;
120
+ this.tipTitle.text(title);
121
+ }
122
+
123
+ if (items && JSON.stringify(items) !== JSON.stringify(this.items)) {
124
+ this.items = items;
125
+
126
+ this.tipItems.forEach((g) => g.svg.remove());
127
+
128
+ this.tipItems = this.items.map((item, i) => {
129
+ const g = this._generateTipItem(item, i);
130
+ return g;
131
+ });
132
+
133
+ const maxWidth = Math.max(
134
+ ...this.tipItems.map((item) => item.width),
135
+ this.tipTitle.node().getBBox().width
136
+ );
137
+
138
+ this.tipBackground
139
+ .attr("width", maxWidth + 15)
140
+ .attr("height", this._getBackgroundHeight());
141
+ }
142
+
143
+ if (position) {
144
+ this.position = position;
145
+ this.svg.attr("x", this._getUpLeftX());
146
+ this.svg.attr("y", this._getUpLeftY());
147
+ }
148
+ }
149
+
150
+ _generateTipItem(item, i) {
151
+ const svg = this.svg.append("svg");
152
+
153
+ svg
154
+ .append("rect")
155
+ .style("fill", item.color)
156
+ .attr("width", 8)
157
+ .attr("height", 8)
158
+ .attr("rx", 2)
159
+ .attr("ry", 2)
160
+ .attr("filter", this.filter)
161
+ .attr("x", 15)
162
+ .attr("y", 37 + 20 * i);
163
+
164
+ svg
165
+ .append("text")
166
+ .style("font-size", "15px")
167
+ .style("fill", this.strokeColor)
168
+ .attr("x", 15 + 12)
169
+ .attr("y", 37 + 20 * i + 8)
170
+ .text(item.text);
171
+
172
+ const bbox = svg.node().getBBox();
173
+ const width = bbox.width + 15;
174
+ const height = bbox.height + 10;
175
+ return {
176
+ svg,
177
+ width,
178
+ height,
179
+ };
180
+ }
181
+
182
+ _getBackgroundWidth() {
183
+ const maxItemLength = this.items.reduce(
184
+ (pre, cur) => (pre > cur.text.length ? pre : cur.text.length),
185
+ 0
186
+ );
187
+ const maxLength = Math.max(maxItemLength, this.title.length);
188
+
189
+ return maxLength * 7.4 + 25;
190
+ }
191
+
192
+ _getBackgroundHeight() {
193
+ const rows = this.items.length + 1;
194
+ return rows * 20 + 10;
195
+ }
196
+
197
+ _getUpLeftX() {
198
+ if (
199
+ this.position.type === "up_right" ||
200
+ this.position.type === "down_right"
201
+ ) {
202
+ return this.position.x;
203
+ }
204
+ return this.position.x - this._getBackgroundWidth() - 20;
205
+ }
206
+
207
+ _getUpLeftY() {
208
+ if (
209
+ this.position.type === "down_left" ||
210
+ this.position.type === "down_right"
211
+ ) {
212
+ return this.position.y;
213
+ }
214
+ return this.position.y - this._getBackgroundHeight() - 20;
215
+ }
216
+ }
217
+
218
+ export default ToolTip;
packages/xy-chart/index.ts ADDED
@@ -0,0 +1,399 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { scaleLinear, scaleTime } from "d3-scale";
2
+ import { select } from "d3-selection";
3
+ import { line, curveMonotoneX } from "d3-shape";
4
+ import { AxisScale } from "d3-axis";
5
+ import dayjs from "dayjs";
6
+ import { uniq } from "lodash";
7
+ import ToolTip from "./components/ToolTip";
8
+ import { drawXAxis, drawYAxis } from "./utils/drawAxis";
9
+ import addFilter from "./utils/addFilter";
10
+ import addFont from "./utils/addFont";
11
+ import { drawTitle, drawXLabel, drawYLabel } from "./utils/drawLabels";
12
+ import drawLegend from "./utils/drawLegend";
13
+ import { drawWatermark } from "./utils/drawWatermark";
14
+ import getFormatTimeline, {
15
+ getTimestampFormatUnit,
16
+ } from "./utils/getFormatTimeline";
17
+ import { D3Selection } from "./types";
18
+
19
+ const colors = [
20
+ "#dd4528",
21
+ "#28a3dd",
22
+ "#f3db52",
23
+ "#ed84b5",
24
+ "#4ab74e",
25
+ "#9179c0",
26
+ "#8e6d5a",
27
+ "#f19839",
28
+ "#949494",
29
+ ];
30
+
31
+ const darkColors = [
32
+ "#ff6b6b",
33
+ "#48dbfb",
34
+ "#feca57",
35
+ "#ff9ff3",
36
+ "#1dd1a1",
37
+ "#f368e0",
38
+ "#ff9f43",
39
+ "#a4b0be",
40
+ "#576574",
41
+ ];
42
+
43
+ const margin = {
44
+ top: 50,
45
+ right: 30,
46
+ bottom: 50,
47
+ left: 50,
48
+ };
49
+
50
+ interface XYPoint {
51
+ x: Date | number;
52
+ y: number;
53
+ }
54
+
55
+ export interface XYData {
56
+ label: string;
57
+ logo: string;
58
+ data: XYPoint[];
59
+ }
60
+
61
+ export interface XYChartData {
62
+ datasets: XYData[];
63
+ }
64
+
65
+ export interface XYChartConfig {
66
+ title: string;
67
+ xLabel: string;
68
+ yLabel: string;
69
+ data: XYChartData;
70
+ showDots: boolean;
71
+ theme?: "light" | "dark";
72
+ }
73
+
74
+ type XTickLabelType = "Date" | "Number";
75
+
76
+ export interface XYChartOptions {
77
+ envType: "browser" | "node";
78
+ xTickLabelType: XTickLabelType;
79
+ dateFormat?: string;
80
+
81
+ xTickCount: number;
82
+ yTickCount: number;
83
+ showLine: boolean;
84
+ dotSize: number;
85
+ dataColors: string[];
86
+ fontFamily: string;
87
+ backgroundColor: string;
88
+ strokeColor: string;
89
+ chartWidth?: number;
90
+ }
91
+
92
+ const getDefaultOptions = (): XYChartOptions => {
93
+ return {
94
+ envType: "node",
95
+ xTickLabelType: "Date",
96
+ dateFormat: "MMM DD, YYYY",
97
+ xTickCount: 5,
98
+ yTickCount: 5,
99
+ showLine: true,
100
+ dotSize: 0.5,
101
+ dataColors: colors,
102
+ fontFamily: "xkcd",
103
+ backgroundColor: "white",
104
+ strokeColor: "black",
105
+ };
106
+ };
107
+
108
+ const getDarkThemeDefaultOptions = (): XYChartOptions => {
109
+ return {
110
+ ...getDefaultOptions(),
111
+ dataColors: darkColors,
112
+ backgroundColor: "#0d1117",
113
+ strokeColor: "white",
114
+ };
115
+ };
116
+
117
+ const XYChart = (
118
+ svg: SVGSVGElement,
119
+ { title, xLabel, yLabel, data: { datasets }, showDots, theme }: XYChartConfig,
120
+ initialOptions: Partial<XYChartOptions>
121
+ ) => {
122
+ const options: XYChartOptions = {
123
+ ...(theme === 'dark' ? getDarkThemeDefaultOptions() : getDefaultOptions()),
124
+ ...initialOptions,
125
+ };
126
+
127
+ if (title) {
128
+ margin.top = 60;
129
+ }
130
+ if (xLabel) {
131
+ margin.bottom = 50;
132
+ }
133
+ if (yLabel) {
134
+ margin.left = 70;
135
+ }
136
+
137
+ const data = {
138
+ datasets,
139
+ };
140
+
141
+ const filter = "url(#xkcdify)";
142
+ const fontFamily = options.fontFamily || "xkcd";
143
+ const clientWidth =
144
+ Number(svg.clientWidth || svg.getAttribute("width") || "") || 600;
145
+ const clientHeight = (clientWidth * 2) / 3;
146
+
147
+ const d3Selection = select(svg)
148
+ .style("stroke-width", 3)
149
+ .style("font-family", fontFamily)
150
+ .style("background", options.backgroundColor)
151
+ .attr("width", clientWidth)
152
+ .attr("height", clientHeight)
153
+ .attr("preserveAspectRatio", "xMidYMid meet") as D3Selection;
154
+ if (options.envType === "browser") {
155
+ // If in browser, be more responsive.
156
+ d3Selection
157
+ .attr("width", clientWidth <= 600 ? 600 : "100%")
158
+ .attr(
159
+ "viewBox",
160
+ `0 0 ${clientWidth <= 600 ? 600 : clientWidth} ${clientHeight}`
161
+ );
162
+ }
163
+ d3Selection.selectAll("*").remove();
164
+
165
+ addFont(d3Selection);
166
+ addFilter(d3Selection);
167
+
168
+ const chart = d3Selection
169
+ .append("g")
170
+ .attr("transform", `translate(${margin.left},${margin.top})`);
171
+
172
+ const tooltip = new ToolTip({
173
+ selection: d3Selection,
174
+ title: "",
175
+ items: [],
176
+ position: { x: 60, y: 60, type: "up_left" },
177
+ strokeColor: options.strokeColor,
178
+ backgroundColor: options.backgroundColor,
179
+ });
180
+
181
+ if (options.xTickLabelType === "Date") {
182
+ data.datasets.forEach((dataset) => {
183
+ dataset.data.forEach((d) => {
184
+ d.x = dayjs(d.x) as any;
185
+ });
186
+ });
187
+ }
188
+
189
+ const allData: XYPoint[] = [];
190
+ data.datasets.map((d) => allData.push(...d.data));
191
+
192
+ const allXData = allData.map((d) => d.x);
193
+ const allYData = allData.map((d) => d.y);
194
+
195
+ const chartWidth = clientWidth - margin.left - margin.right;
196
+ const chartHeight = clientHeight - margin.top - margin.bottom;
197
+
198
+ // NOTE: Xaxis with date type(default)
199
+ let xScale: AxisScale<number | Date> = scaleTime()
200
+ .domain([
201
+ Math.min(...allXData.map((d) => Number(d))),
202
+ Math.max(...allXData.map((d) => Number(d))),
203
+ ])
204
+ .range([0, chartWidth]);
205
+
206
+ if (options.xTickLabelType === "Number") {
207
+ xScale = scaleLinear()
208
+ .domain([0, Math.max(...allXData.map((d) => Number(d)))])
209
+ .range([0, chartWidth]);
210
+ }
211
+
212
+ const yScale = scaleLinear()
213
+ .domain([Math.min(...allYData), Math.max(...allYData)])
214
+ .range([chartHeight, 0]);
215
+
216
+ const svgChart = chart.append("g").attr("pointer-events", "all");
217
+
218
+ drawWatermark(svgChart, chartWidth, chartHeight);
219
+
220
+ if (title) {
221
+ if (uniq(datasets.map((d) => d.label.split("/")[0])).length === 1) {
222
+ // If all repos have only one unique owner, show logo before graph title.
223
+ drawTitle(
224
+ d3Selection,
225
+ title,
226
+ datasets[0].logo,
227
+ options.strokeColor,
228
+ options.chartWidth
229
+ );
230
+ } else {
231
+ drawTitle(
232
+ d3Selection,
233
+ title,
234
+ "",
235
+ options.strokeColor,
236
+ options.chartWidth
237
+ );
238
+ }
239
+ }
240
+ if (xLabel) {
241
+ drawXLabel(d3Selection, xLabel, options.strokeColor);
242
+ }
243
+ if (yLabel) {
244
+ const maxYData = Math.max(...allYData);
245
+ let offsetY = 24;
246
+ // dynamic offset Y label
247
+ if (maxYData > 100000) {
248
+ offsetY = 2;
249
+ } else if (maxYData > 10000) {
250
+ offsetY = 8;
251
+ } else if (maxYData > 1000) {
252
+ offsetY = 12;
253
+ } else if (maxYData > 100) {
254
+ offsetY = 20;
255
+ }
256
+ drawYLabel(d3Selection, yLabel, options.strokeColor, offsetY);
257
+ }
258
+
259
+ // draw axis
260
+ drawXAxis(svgChart, {
261
+ xScale,
262
+ tickCount: options.xTickCount,
263
+ moveDown: chartHeight,
264
+ fontFamily: fontFamily,
265
+ stroke: options.strokeColor,
266
+ type: options.xTickLabelType,
267
+ });
268
+ drawYAxis(svgChart, {
269
+ yScale,
270
+ tickCount: options.yTickCount,
271
+ fontFamily: fontFamily,
272
+ stroke: options.strokeColor,
273
+ });
274
+
275
+ // draw lines
276
+ if (options.showLine) {
277
+ const drawLine = line<XYPoint>()
278
+ .x((d) => xScale(d.x) || 0)
279
+ .y((d) => yScale(d.y))
280
+ .curve(curveMonotoneX);
281
+
282
+ svgChart
283
+ .selectAll(".xkcd-chart-xyline")
284
+ .data(data.datasets)
285
+ .enter()
286
+ .append("path")
287
+ .attr("class", "xkcd-chart-xyline")
288
+ .attr("d", (d) => drawLine(d.data))
289
+ .attr("fill", "none")
290
+ .attr("stroke", (_, i) => options.dataColors[i])
291
+ .attr("filter", filter);
292
+ }
293
+
294
+ if (showDots) {
295
+ // draw dots
296
+ const dotInitSize =
297
+ 3.5 * (options.dotSize === undefined ? 1 : options.dotSize);
298
+ const dotHoverSize =
299
+ 6 * (options.dotSize === undefined ? 1 : options.dotSize);
300
+ svgChart
301
+ .selectAll(".xkcd-chart-xycircle-group")
302
+ .data(data.datasets)
303
+ .enter()
304
+ .append("g")
305
+ .attr("class", "xkcd-chart-xycircle-group")
306
+ .attr("filter", filter)
307
+ .attr("xy-group-index", (_, i) => i)
308
+ .selectAll(".xkcd-chart-xycircle-circle")
309
+ .data((dataset) => dataset.data)
310
+ .enter()
311
+ .append("circle")
312
+ .attr("class", "chart-tooltip-dot")
313
+ .style("stroke", (_, i, nodes) => {
314
+ const xyGroupIndex = Number(
315
+ select(nodes[i].parentElement).attr("xy-group-index")
316
+ );
317
+ return options.dataColors[xyGroupIndex];
318
+ })
319
+ .style("fill", (_, i, nodes) => {
320
+ const xyGroupIndex = Number(
321
+ select(nodes[i].parentElement).attr("xy-group-index")
322
+ );
323
+ return options.dataColors[xyGroupIndex];
324
+ })
325
+ .attr("r", dotInitSize)
326
+ .attr("cx", (d) => xScale(d.x) || 0)
327
+ .attr("cy", (d) => yScale(d.y))
328
+ .attr("pointer-events", "all")
329
+ .on("mouseover", (d, i, nodes) => {
330
+ const xyGroupIndex = Number(
331
+ select(nodes[i].parentElement).attr("xy-group-index")
332
+ );
333
+ select(nodes[i]).attr("r", dotHoverSize);
334
+
335
+ const tipX = (xScale(d.x) || 0) + margin.left + 5;
336
+ const tipY = yScale(d.y) + margin.top + 5;
337
+ let tooltipPositionType = "down_right";
338
+ if (tipX > chartWidth / 2 && tipY < chartHeight / 2) {
339
+ tooltipPositionType = "down_left";
340
+ } else if (tipX > chartWidth / 2 && tipY > chartHeight / 2) {
341
+ tooltipPositionType = "up_left";
342
+ } else if (tipX < chartWidth / 2 && tipY > chartHeight / 2) {
343
+ tooltipPositionType = "up_right";
344
+ }
345
+
346
+ // NOTE: tooltip title with date type(default)
347
+ let title = dayjs(data.datasets[xyGroupIndex].data[i].x).format(
348
+ options.dateFormat
349
+ );
350
+ if (options.xTickLabelType === "Number") {
351
+ const type = getTimestampFormatUnit(
352
+ Number(
353
+ data.datasets[xyGroupIndex].data[1].x ||
354
+ data.datasets[xyGroupIndex].data[i].x
355
+ )
356
+ );
357
+ title = getFormatTimeline(
358
+ Number(data.datasets[xyGroupIndex].data[i].x),
359
+ type
360
+ );
361
+ }
362
+
363
+ tooltip.update({
364
+ title,
365
+ items: [
366
+ {
367
+ color: options.dataColors[xyGroupIndex],
368
+ text: `${data.datasets[xyGroupIndex].label || ""}: ${d.y}`,
369
+ },
370
+ ],
371
+ position: {
372
+ x: tipX,
373
+ y: tipY,
374
+ type: tooltipPositionType,
375
+ },
376
+ });
377
+ tooltip.show();
378
+ })
379
+ .on("mouseout", (_, i, nodes) => {
380
+ select(nodes[i]).attr("r", dotInitSize);
381
+ tooltip.hide();
382
+ });
383
+ }
384
+
385
+ // draw legend
386
+ const legendItems = data.datasets.map((dataset, i) => ({
387
+ color: options.dataColors[i] || "",
388
+ text: dataset.label,
389
+ logo: dataset.logo,
390
+ }));
391
+
392
+ drawLegend(svgChart, {
393
+ items: legendItems,
394
+ strokeColor: options.strokeColor,
395
+ backgroundColor: options.backgroundColor,
396
+ });
397
+ };
398
+
399
+ export default XYChart;
packages/xy-chart/types.ts ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import { Selection } from "d3-selection";
2
+
3
+ export type D3Selection = Selection<
4
+ SVGSVGElement | SVGGElement,
5
+ unknown,
6
+ null,
7
+ undefined
8
+ >;
packages/xy-chart/utils/addFilter.ts ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { D3Selection } from "../types";
2
+
3
+ const addFilter = (selection: D3Selection) => {
4
+ selection
5
+ .append("filter")
6
+ .attr("id", "xkcdify")
7
+ .attr("filterUnits", "userSpaceOnUse")
8
+ .attr("x", -5)
9
+ .attr("y", -5)
10
+ .attr("width", "100%")
11
+ .attr("height", "100%")
12
+ .call((f) => {
13
+ f.append("feTurbulence")
14
+ .attr("type", "fractalNoise")
15
+ .attr("baseFrequency", "0.05")
16
+ .attr("result", "noise");
17
+ f.append("feDisplacementMap")
18
+ .attr("scale", "5")
19
+ .attr("xChannelSelector", "R")
20
+ .attr("yChannelSelector", "G")
21
+ .attr("in", "SourceGraphic")
22
+ .attr("in2", "noise");
23
+ });
24
+ };
25
+
26
+ export default addFilter;
packages/xy-chart/utils/addFont.ts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { D3Selection } from "../types";
2
+
3
+ const addFont = (selection: D3Selection) => {
4
+ selection.append("defs").append("style").attr("type", "text/css")
5
+ .text(`@font-face {
6
+ font-family: "xkcd";
7
+ src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff');
8
+ }`);
9
+ };
10
+
11
+ export default addFont;
packages/xy-chart/utils/drawAxis.ts ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { axisBottom, axisLeft, AxisScale } from "d3-axis";
2
+ import { D3Selection } from "../types";
3
+ import getFormatNumber, {
4
+ getNumberFormatUnit,
5
+ NumberUnitType,
6
+ } from "./getFormatNumber";
7
+ import getFormatTimeline, {
8
+ DurationUnitType,
9
+ getTimestampFormatUnit,
10
+ } from "./getFormatTimeline";
11
+
12
+ interface DrawXAxisConfig {
13
+ xScale: AxisScale<number | Date>;
14
+ tickCount: number;
15
+ moveDown: number;
16
+ fontFamily: string;
17
+ stroke: string;
18
+ type: "Date" | "Number";
19
+ }
20
+
21
+ export const drawXAxis = (
22
+ selection: D3Selection,
23
+ { xScale, tickCount, moveDown, fontFamily, stroke, type }: DrawXAxisConfig
24
+ ) => {
25
+ const xAxisGenerator = axisBottom(xScale)
26
+ .tickSize(0)
27
+ .tickPadding(6)
28
+ .ticks(tickCount);
29
+
30
+ if (type === "Number") {
31
+ let index = 1;
32
+ let type: DurationUnitType | undefined = undefined;
33
+ xAxisGenerator.tickFormat((d) => {
34
+ const timestamp = Number(d);
35
+ const tickAmount = selection.selectAll(".xaxis > .tick").nodes().length;
36
+ index++;
37
+ if (timestamp === 0 || (tickAmount >= 7 && index % 2 === 0)) {
38
+ return " ";
39
+ }
40
+ if (!type) {
41
+ type = getTimestampFormatUnit(timestamp);
42
+ }
43
+
44
+ return getFormatTimeline(timestamp, type);
45
+ });
46
+ }
47
+
48
+ selection
49
+ .append("g")
50
+ .attr("class", "xaxis")
51
+ .attr("transform", `translate(0,${moveDown})`)
52
+ .call(xAxisGenerator);
53
+
54
+ selection
55
+ .selectAll(".domain")
56
+ .attr("filter", "url(#xkcdify)")
57
+ .style("stroke", stroke);
58
+
59
+ selection
60
+ .selectAll(".xaxis > .tick > text")
61
+ .style("font-family", fontFamily)
62
+ .style("font-size", "16px")
63
+ .style("fill", stroke);
64
+ };
65
+
66
+ interface DrawYAxisConfig {
67
+ yScale: AxisScale<number>;
68
+ tickCount: number;
69
+ fontFamily: string;
70
+ stroke: string;
71
+ }
72
+
73
+ export const drawYAxis = (
74
+ selection: D3Selection,
75
+ { yScale, tickCount, fontFamily, stroke }: DrawYAxisConfig
76
+ ) => {
77
+ let type: NumberUnitType | undefined = undefined;
78
+ const yAxisGenerator = axisLeft(yScale)
79
+ .tickSize(1)
80
+ .tickPadding(6)
81
+ .ticks(tickCount, "s")
82
+ .tickFormat((d) => {
83
+ if (d === 0) {
84
+ return " ";
85
+ }
86
+ if (!type) {
87
+ type = getNumberFormatUnit(d);
88
+ }
89
+
90
+ return getFormatNumber(d, type);
91
+ });
92
+
93
+ selection.append("g").attr("class", "yaxis").call(yAxisGenerator);
94
+
95
+ selection
96
+ .selectAll(".domain")
97
+ .attr("filter", "url(#xkcdify)")
98
+ .style("stroke", stroke);
99
+
100
+ selection
101
+ .selectAll(".yaxis > .tick > text")
102
+ .style("font-family", fontFamily)
103
+ .style("font-size", "16px")
104
+ .style("fill", stroke);
105
+ };
packages/xy-chart/utils/drawLabels.ts ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { D3Selection } from "../types";
2
+
3
+ export const drawTitle = (
4
+ selection: D3Selection,
5
+ text: string,
6
+ logoURL: string,
7
+ color: string,
8
+ chartWidth?: number
9
+ ) => {
10
+ let logoX: string | number = "38%",
11
+ clipX: string | number = "39.5%";
12
+ if (selection.node()?.getBoundingClientRect()) {
13
+ logoX =
14
+ (selection.node()?.getBoundingClientRect().width as number) * 0.5 - 84;
15
+ clipX =
16
+ (selection.node()?.getBoundingClientRect().width as number) * 0.5 - 73;
17
+ }
18
+ if (chartWidth) {
19
+ logoX = chartWidth * 0.5 - 84;
20
+ clipX = chartWidth * 0.5 - 73;
21
+ }
22
+
23
+ selection
24
+ .append("text")
25
+ .style("font-size", "20px")
26
+ .style("font-weight", "bold")
27
+ .style("fill", color)
28
+ .attr("x", "50%")
29
+ .attr("y", 30)
30
+ .attr("text-anchor", "middle")
31
+ .text(text);
32
+ selection
33
+ .append("svg")
34
+ .append("defs")
35
+ .append("clipPath")
36
+ .attr("id", "clip-circle-title")
37
+ .append("circle")
38
+ .attr("r", 11)
39
+ .attr("cx", clipX)
40
+ .attr("cy", 12 + 11);
41
+ if (logoURL) {
42
+ selection
43
+ .append("image")
44
+ .attr("x", logoX)
45
+ .attr("y", 12)
46
+ .attr("height", 22)
47
+ .attr("width", 22)
48
+ .attr("href", logoURL)
49
+ .attr("clip-path", "url(#clip-circle-title)");
50
+ }
51
+ };
52
+
53
+ export const drawXLabel = (
54
+ selection: D3Selection,
55
+ text: string,
56
+ color: string
57
+ ) => {
58
+ selection
59
+ .append("text")
60
+ .style("font-size", "17px")
61
+ .style("fill", color)
62
+ .attr("x", "50%")
63
+ .attr("y", ((selection.attr("height") as unknown as number) || 10) - 10)
64
+ .attr("text-anchor", "middle")
65
+ .text(text);
66
+ };
67
+
68
+ export const drawYLabel = (
69
+ selection: D3Selection,
70
+ text: string,
71
+ color: string,
72
+ offsetY = 6
73
+ ) => {
74
+ selection
75
+ .append("text")
76
+ .attr("text-anchor", "end")
77
+ .attr("dy", ".75em")
78
+ .attr("transform", "rotate(-90)")
79
+ .style("font-size", "17px")
80
+ .style("fill", color)
81
+ .text(text)
82
+ .attr("y", offsetY)
83
+ .call((f) => {
84
+ const defaultTextLength = 100;
85
+ let textLength = defaultTextLength;
86
+ // Because there is no `getComputedTextLength` method in nodejs env,
87
+ // we have to use it after validate function existed.
88
+ if (f.node()?.getComputedTextLength) {
89
+ textLength = f.node()?.getComputedTextLength() as number;
90
+ }
91
+
92
+ const offsetX = Math.floor(
93
+ textLength / 2 -
94
+ ((selection.attr("height") as unknown as number) || 10) / 2
95
+ );
96
+ f.attr("x", offsetX);
97
+ });
98
+ };
packages/xy-chart/utils/drawLegend.ts ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { D3Selection } from "../types";
2
+ import { uniq } from "lodash";
3
+
4
+ interface DrawLegendConfig {
5
+ items: {
6
+ color: string;
7
+ text: string;
8
+ logo: string;
9
+ }[];
10
+ strokeColor: string;
11
+ backgroundColor: string;
12
+ }
13
+
14
+ const drawLegend = (
15
+ selection: D3Selection,
16
+ { items, strokeColor, backgroundColor }: DrawLegendConfig
17
+ ) => {
18
+ const legendXPadding = 7;
19
+ const legendYPadding = 6;
20
+ const xkcdCharWidth = 7;
21
+ const xkcdCharHeight = 20;
22
+ const colorBlockWidth = 8;
23
+ const logoSize = 14;
24
+
25
+ const legend = selection.append("svg");
26
+ const backgroundLayer = legend.append("svg");
27
+ const textLayer = legend.append("svg");
28
+ let maxTextLength = 0;
29
+ // If repos have more than one unique owner, draw logo before legend.
30
+ const shouldDrawLogo =
31
+ uniq(items.map((i) => i.text.split("/")[0])).length > 1;
32
+
33
+ items.forEach((item, i) => {
34
+ // draw color dot
35
+ textLayer
36
+ .append("rect")
37
+ .style("fill", item.color)
38
+ .attr("width", colorBlockWidth)
39
+ .attr("height", colorBlockWidth)
40
+ .attr("rx", 2)
41
+ .attr("ry", 2)
42
+ .attr("filter", "url(#xkcdify)")
43
+ .attr("x", 8 + legendXPadding)
44
+ .attr("y", 17 + xkcdCharHeight * i);
45
+ if (shouldDrawLogo) {
46
+ textLayer
47
+ .append("defs")
48
+ .append("clipPath")
49
+ .attr("id", `clip-circle-title-${item.text}`)
50
+ .append("circle")
51
+ .attr("r", logoSize / 2)
52
+ .attr(
53
+ "cx",
54
+ 8 + legendXPadding + colorBlockWidth + legendXPadding + logoSize / 2
55
+ )
56
+ .attr("cy", 17 + xkcdCharHeight * i - 4 + logoSize / 2);
57
+ textLayer
58
+ .append("image")
59
+ .attr("x", 8 + legendXPadding + colorBlockWidth + legendXPadding)
60
+ .attr("y", 17 + xkcdCharHeight * i - 4)
61
+ .attr("height", logoSize)
62
+ .attr("width", logoSize)
63
+ .attr("href", item.logo)
64
+ .attr("clip-path", `url(#clip-circle-title-${item.text})`);
65
+ }
66
+ // draw text
67
+ textLayer
68
+ .append("text")
69
+ .style("font-size", "15px")
70
+ .style("fill", strokeColor)
71
+ .attr(
72
+ "x",
73
+ 8 +
74
+ legendXPadding +
75
+ colorBlockWidth +
76
+ (shouldDrawLogo ? legendXPadding + logoSize : 0) +
77
+ 6
78
+ )
79
+ .attr("y", 17 + xkcdCharHeight * i + 8)
80
+ .text(item.text);
81
+
82
+ maxTextLength = Math.max(item.text.length, maxTextLength);
83
+ });
84
+
85
+ let bboxWidth =
86
+ maxTextLength * (xkcdCharWidth + 0.5) + colorBlockWidth + legendXPadding;
87
+ // Because there is no `getBBox` method in nodejs env,
88
+ // we have to use it after validate function existed.
89
+ if (textLayer.node()?.getBBox) {
90
+ bboxWidth = textLayer.node()?.getBBox().width as number;
91
+ }
92
+ const backgroundWidth = Math.max(
93
+ bboxWidth + legendXPadding * 2,
94
+ maxTextLength * xkcdCharWidth +
95
+ colorBlockWidth +
96
+ legendXPadding * 2 +
97
+ 6 +
98
+ (shouldDrawLogo ? legendXPadding + logoSize : 0)
99
+ );
100
+ const backgroundHeight = items.length * xkcdCharHeight + legendYPadding * 2;
101
+
102
+ // add background
103
+ backgroundLayer
104
+ .append("rect")
105
+ .style("fill", backgroundColor)
106
+ .attr("fill-opacity", 0.85)
107
+ .attr("stroke", strokeColor)
108
+ .attr("stroke-width", 2)
109
+ .attr("rx", 5)
110
+ .attr("ry", 5)
111
+ .attr("filter", "url(#xkcdify)")
112
+ .attr("width", backgroundWidth)
113
+ .attr("height", backgroundHeight)
114
+ .attr("x", 8)
115
+ .attr("y", 5);
116
+ };
117
+
118
+ export default drawLegend;
packages/xy-chart/utils/drawWatermark.ts ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { D3Selection } from "../types";
2
+
3
+ const iconBase64 =
4
+ "data:image/png;base64,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";
5
+
6
+ export const drawWatermark = (
7
+ selection: D3Selection,
8
+ chartWidth: number,
9
+ chartHeight: number
10
+ ) => {
11
+ selection
12
+ .append("text")
13
+ .style("font-size", "16px")
14
+ .style("fill", "#666666")
15
+ .attr("transform", `translate(${chartWidth - 50},${chartHeight + 40})`)
16
+ .attr("text-anchor", "middle")
17
+ .text("star-history.com");
18
+
19
+ selection
20
+ .append("image")
21
+ .attr("transform", `translate(${chartWidth - 135},${chartHeight + 24})`)
22
+ .attr("height", 20)
23
+ .attr("width", 20)
24
+ .attr("href", iconBase64);
25
+ };
packages/xy-chart/utils/getFormatNumber.ts ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export type NumberUnitType = 1 | 1000;
2
+
3
+ export const getNumberFormatUnit = (n: number): NumberUnitType => {
4
+ if (n >= 300) {
5
+ return 1000;
6
+ }
7
+
8
+ return 1;
9
+ };
10
+
11
+ const getFormatNumber = (n: number, type: NumberUnitType = 1) => {
12
+ if (type === 1) {
13
+ return `${n}`;
14
+ }
15
+
16
+ return `${(n / 1000).toFixed(1)}k`;
17
+ };
18
+
19
+ export default getFormatNumber;
packages/xy-chart/utils/getFormatTimeline.ts ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import dayjs from "dayjs";
2
+ import duration from "dayjs/plugin/duration";
3
+ import relativeTime from "dayjs/plugin/relativeTime";
4
+
5
+ dayjs.extend(duration);
6
+ dayjs.extend(relativeTime);
7
+
8
+ export type DurationUnitType = "day" | "week" | "month" | "year";
9
+
10
+ export const getTimestampFormatUnit = (timestamp: number): DurationUnitType => {
11
+ let timelineUnit: DurationUnitType = "day";
12
+ if (dayjs.duration(timestamp).asYears() > 1) {
13
+ timelineUnit = "year";
14
+ } else if (dayjs.duration(timestamp).asMonths() > 1) {
15
+ timelineUnit = "month";
16
+ } else if (dayjs.duration(timestamp).asWeeks() > 1) {
17
+ timelineUnit = "week";
18
+ }
19
+ return timelineUnit;
20
+ };
21
+
22
+ const getFormatTimeline = (
23
+ timestamp: number,
24
+ type: DurationUnitType = "day"
25
+ ) => {
26
+ if (timestamp === 0) {
27
+ return "day one";
28
+ }
29
+
30
+ const seconds = Math.floor(timestamp / 1000);
31
+ const days = Math.floor(seconds / 60 / 60 / 24);
32
+ const weeks = Math.floor(days / 7);
33
+ const months = (days / 30).toFixed(0);
34
+ const years = (days / 365).toFixed(0);
35
+
36
+ if (type === "day") {
37
+ if (days === 1) {
38
+ return "a day";
39
+ }
40
+ return `${days} days`;
41
+ } else if (type === "week") {
42
+ if (weeks === 1) {
43
+ return "a week";
44
+ }
45
+ return `${weeks} weeks`;
46
+ } else if (type === "month") {
47
+ if (Number(months) === 1) {
48
+ return "a month";
49
+ }
50
+ return `${months} months`;
51
+ } else {
52
+ if (Number(years) === 1) {
53
+ return "a year";
54
+ }
55
+ return `${years} years`;
56
+ }
57
+ };
58
+
59
+ export default getFormatTimeline;
plugins/additionBuildPlugin.ts ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import copyExtensionFiles from "./scripts/copyExtensionFiles";
2
+ import emptyDist from "./scripts/emptyDist";
3
+ import generateSitemap from "./scripts/generateSitemap";
4
+
5
+ const additionBuildPlugin = () => {
6
+ let envCommand = "";
7
+ let envMode = "";
8
+
9
+ return {
10
+ name: "addition-build-plugin",
11
+ config(config, { command, mode }) {
12
+ envCommand = command;
13
+ envMode = mode;
14
+
15
+ if (mode === "extension") {
16
+ config.root = "./src";
17
+ config.publicDir = "../public";
18
+ config.build = {
19
+ ...config.build,
20
+ outDir: "../dist",
21
+ rollupOptions: {
22
+ input: {
23
+ popup: "./src/extension/popup.html",
24
+ },
25
+ },
26
+ };
27
+ }
28
+ },
29
+ buildStart() {
30
+ // Empty the dist folder firstly to make sure the other script can work right.
31
+ emptyDist();
32
+ },
33
+ buildEnd() {
34
+ if (envCommand === "build") {
35
+ if (envMode === "extension") {
36
+ copyExtensionFiles();
37
+ } else {
38
+ generateSitemap();
39
+ }
40
+ }
41
+ },
42
+ };
43
+ };
44
+
45
+ export default additionBuildPlugin;
plugins/scripts/copyExtensionFiles.ts ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { copyFileSync } from "fs";
2
+ import { resolve } from "path";
3
+
4
+ const copyExtensionFiles = () => {
5
+ try {
6
+ copyFileSync(
7
+ resolve(__dirname, "../../src/extension/background.js"),
8
+ resolve(__dirname, "../../dist/background.js")
9
+ );
10
+ copyFileSync(
11
+ resolve(__dirname, "../../src/extension/manifest.json"),
12
+ resolve(__dirname, "../../dist/manifest.json")
13
+ );
14
+ } catch (error) {
15
+ console.error(error);
16
+ throw error;
17
+ }
18
+ };
19
+
20
+ export default copyExtensionFiles;
plugins/scripts/emptyDist.ts ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { existsSync, mkdirSync, rmSync } from "fs";
2
+ import { resolve } from "path";
3
+
4
+ const emptyDist = () => {
5
+ try {
6
+ const distPath = resolve(__dirname, "../../dist");
7
+ if (existsSync(distPath)) {
8
+ rmSync(distPath, {
9
+ recursive: true,
10
+ });
11
+ }
12
+ mkdirSync(distPath);
13
+ } catch (error) {
14
+ console.error(error);
15
+ throw error;
16
+ }
17
+ };
18
+
19
+ export default emptyDist;
plugins/scripts/generateSitemap.ts ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { readFileSync, writeFileSync } from "fs";
2
+ import { resolve } from "path";
3
+
4
+ interface Route {
5
+ url: string;
6
+ name: string;
7
+ }
8
+
9
+ const staticRoutes: Route[] = [
10
+ {
11
+ url: "/",
12
+ name: "Star History",
13
+ },
14
+ {
15
+ url: "/embed",
16
+ name: "Star History",
17
+ },
18
+ {
19
+ url: "/blog",
20
+ name: "Blog List",
21
+ },
22
+ ];
23
+
24
+ const getBlogsRoutes = async (): Promise<Route[]> => {
25
+ const rawdata = readFileSync(
26
+ resolve(__dirname, "../../public/blog/data.json")
27
+ );
28
+ const blogs = JSON.parse(rawdata.toString());
29
+ const blogRoutes: Route[] = [];
30
+
31
+ for (const blog of blogs) {
32
+ blogRoutes.push({
33
+ url: `/blog/${blog.slug}`,
34
+ name: blog.title,
35
+ });
36
+ }
37
+
38
+ return blogRoutes;
39
+ };
40
+
41
+ const generateSitemap = async () => {
42
+ const routes = [...staticRoutes];
43
+ const blogRoutes = await getBlogsRoutes();
44
+ routes.push(...blogRoutes);
45
+ const baseUrl = "https://star-history.com";
46
+ const routeXMLTags: string[] = [];
47
+
48
+ for (const route of routes) {
49
+ routeXMLTags.push(`<url>
50
+ <loc>${baseUrl}${route.url}</loc>
51
+ </url>`);
52
+ }
53
+
54
+ const xml = `<?xml version="1.0" encoding="UTF-8"?>
55
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
56
+ ${routeXMLTags.join("\n")}
57
+ </urlset>`;
58
+
59
+ writeFileSync(resolve(__dirname, "../../public/sitemap.xml"), xml);
60
+ };
61
+
62
+ export default generateSitemap;
pnpm-lock.yaml ADDED
@@ -0,0 +1,2370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ lockfileVersion: '6.0'
2
+
3
+ dependencies:
4
+ '@tailwindcss/line-clamp':
5
+ specifier: ^0.4.0
6
+ version: 0.4.2(tailwindcss@3.0.23)
7
+ '@tailwindcss/typography':
8
+ specifier: ^0.5.1
9
+ version: 0.5.2(tailwindcss@3.0.23)
10
+ '@vueuse/head':
11
+ specifier: ^1.0.25
12
+ version: 1.0.25(vue@3.2.47)
13
+ axios:
14
+ specifier: ^1.0.0
15
+ version: 1.1.3
16
+ d3-axis:
17
+ specifier: ^1.0.12
18
+ version: 1.0.12
19
+ d3-scale:
20
+ specifier: ^3.2.0
21
+ version: 3.3.0
22
+ d3-selection:
23
+ specifier: ^1.4.1
24
+ version: 1.4.2
25
+ d3-shape:
26
+ specifier: ^1.3.7
27
+ version: 1.3.7
28
+ dayjs:
29
+ specifier: ^1.10.7
30
+ version: 1.11.0
31
+ lodash:
32
+ specifier: ^4.17.21
33
+ version: 4.17.21
34
+ marked:
35
+ specifier: ^4.0.16
36
+ version: 4.0.16
37
+ pinia:
38
+ specifier: ^2.0.11
39
+ version: 2.0.12(typescript@4.6.2)(vue@3.2.47)
40
+ tailwindcss:
41
+ specifier: ^3.0.19
42
+ version: 3.0.23(autoprefixer@10.4.13)(postcss@8.4.19)
43
+ typescript:
44
+ specifier: ^4.4.4
45
+ version: 4.6.2
46
+ vite:
47
+ specifier: ^2.8.0
48
+ version: 2.8.6
49
+ vue:
50
+ specifier: ^3.2.47
51
+ version: 3.2.47
52
+ vue-router:
53
+ specifier: '4'
54
+ version: 4.0.14(vue@3.2.47)
55
+ vue-tsc:
56
+ specifier: ^1.0.0
57
+ version: 1.0.9(typescript@4.6.2)
58
+
59
+ devDependencies:
60
+ '@types/chrome':
61
+ specifier: 0.0.210
62
+ version: 0.0.210
63
+ '@types/d3-axis':
64
+ specifier: 3.0.2
65
+ version: 3.0.2
66
+ '@types/d3-scale':
67
+ specifier: 4.0.3
68
+ version: 4.0.3
69
+ '@types/d3-selection':
70
+ specifier: 1.4.3
71
+ version: 1.4.3
72
+ '@types/d3-shape':
73
+ specifier: 3.1.0
74
+ version: 3.1.0
75
+ '@types/lodash':
76
+ specifier: 4.14.191
77
+ version: 4.14.191
78
+ '@types/marked':
79
+ specifier: 4.0.7
80
+ version: 4.0.7
81
+ '@types/node':
82
+ specifier: 18.11.10
83
+ version: 18.11.10
84
+ '@typescript-eslint/eslint-plugin':
85
+ specifier: 5.42.0
86
+ version: 5.42.0(@typescript-eslint/parser@5.42.0)(eslint@8.26.0)(typescript@4.6.2)
87
+ '@typescript-eslint/parser':
88
+ specifier: 5.42.0
89
+ version: 5.42.0(eslint@8.26.0)(typescript@4.6.2)
90
+ '@vitejs/plugin-vue':
91
+ specifier: 2.3.4
92
+ version: 2.3.4(vite@2.8.6)(vue@3.2.47)
93
+ '@vue/eslint-config-typescript':
94
+ specifier: 11.0.2
95
+ version: 11.0.2(eslint-plugin-vue@9.7.0)(eslint@8.26.0)(typescript@4.6.2)
96
+ autoprefixer:
97
+ specifier: 10.4.13
98
+ version: 10.4.13(postcss@8.4.19)
99
+ eslint:
100
+ specifier: 8.26.0
101
+ version: 8.26.0
102
+ eslint-config-prettier:
103
+ specifier: 8.5.0
104
+ version: 8.5.0(eslint@8.26.0)
105
+ eslint-plugin-prettier:
106
+ specifier: 4.2.1
107
+ version: 4.2.1(eslint-config-prettier@8.5.0)(eslint@8.26.0)(prettier@2.7.1)
108
+ eslint-plugin-vue:
109
+ specifier: 9.7.0
110
+ version: 9.7.0(eslint@8.26.0)
111
+ postcss:
112
+ specifier: 8.4.19
113
+ version: 8.4.19
114
+ prettier:
115
+ specifier: 2.7.1
116
+ version: 2.7.1
117
+
118
+ packages:
119
+
120
+ /@babel/code-frame@7.16.7:
121
+ resolution: {integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==}
122
+ engines: {node: '>=6.9.0'}
123
+ dependencies:
124
+ '@babel/highlight': 7.16.10
125
+ dev: false
126
+
127
+ /@babel/helper-validator-identifier@7.16.7:
128
+ resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==}
129
+ engines: {node: '>=6.9.0'}
130
+
131
+ /@babel/highlight@7.16.10:
132
+ resolution: {integrity: sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==}
133
+ engines: {node: '>=6.9.0'}
134
+ dependencies:
135
+ '@babel/helper-validator-identifier': 7.16.7
136
+ chalk: 2.4.2
137
+ js-tokens: 4.0.0
138
+ dev: false
139
+
140
+ /@babel/parser@7.17.8:
141
+ resolution: {integrity: sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==}
142
+ engines: {node: '>=6.0.0'}
143
+ hasBin: true
144
+ dependencies:
145
+ '@babel/types': 7.17.0
146
+
147
+ /@babel/types@7.17.0:
148
+ resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==}
149
+ engines: {node: '>=6.9.0'}
150
+ dependencies:
151
+ '@babel/helper-validator-identifier': 7.16.7
152
+ to-fast-properties: 2.0.0
153
+
154
+ /@eslint/eslintrc@1.3.3:
155
+ resolution: {integrity: sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==}
156
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
157
+ dependencies:
158
+ ajv: 6.12.6
159
+ debug: 4.3.4
160
+ espree: 9.4.0
161
+ globals: 13.17.0
162
+ ignore: 5.2.0
163
+ import-fresh: 3.3.0
164
+ js-yaml: 4.1.0
165
+ minimatch: 3.1.2
166
+ strip-json-comments: 3.1.1
167
+ transitivePeerDependencies:
168
+ - supports-color
169
+ dev: true
170
+
171
+ /@humanwhocodes/config-array@0.11.7:
172
+ resolution: {integrity: sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==}
173
+ engines: {node: '>=10.10.0'}
174
+ dependencies:
175
+ '@humanwhocodes/object-schema': 1.2.1
176
+ debug: 4.3.4
177
+ minimatch: 3.1.2
178
+ transitivePeerDependencies:
179
+ - supports-color
180
+ dev: true
181
+
182
+ /@humanwhocodes/module-importer@1.0.1:
183
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
184
+ engines: {node: '>=12.22'}
185
+ dev: true
186
+
187
+ /@humanwhocodes/object-schema@1.2.1:
188
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
189
+ dev: true
190
+
191
+ /@nodelib/fs.scandir@2.1.5:
192
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
193
+ engines: {node: '>= 8'}
194
+ dependencies:
195
+ '@nodelib/fs.stat': 2.0.5
196
+ run-parallel: 1.2.0
197
+
198
+ /@nodelib/fs.stat@2.0.5:
199
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
200
+ engines: {node: '>= 8'}
201
+
202
+ /@nodelib/fs.walk@1.2.8:
203
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
204
+ engines: {node: '>= 8'}
205
+ dependencies:
206
+ '@nodelib/fs.scandir': 2.1.5
207
+ fastq: 1.13.0
208
+
209
+ /@tailwindcss/line-clamp@0.4.2(tailwindcss@3.0.23):
210
+ resolution: {integrity: sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==}
211
+ peerDependencies:
212
+ tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1'
213
+ dependencies:
214
+ tailwindcss: 3.0.23(autoprefixer@10.4.13)(postcss@8.4.19)
215
+ dev: false
216
+
217
+ /@tailwindcss/typography@0.5.2(tailwindcss@3.0.23):
218
+ resolution: {integrity: sha512-coq8DBABRPFcVhVIk6IbKyyHUt7YTEC/C992tatFB+yEx5WGBQrCgsSFjxHUr8AWXphWckadVJbominEduYBqw==}
219
+ peerDependencies:
220
+ tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || insiders'
221
+ dependencies:
222
+ lodash.castarray: 4.4.0
223
+ lodash.isplainobject: 4.0.6
224
+ lodash.merge: 4.6.2
225
+ tailwindcss: 3.0.23(autoprefixer@10.4.13)(postcss@8.4.19)
226
+ dev: false
227
+
228
+ /@types/chrome@0.0.210:
229
+ resolution: {integrity: sha512-VSjQu1k6a/rAfuqR1Gi/oxHZj4+t6+LG+GobNI3ZWI6DQ+fmphNSF6TrLHG6BYK2bXc9Gb4c1uXFKRRVLaGl5Q==}
230
+ dependencies:
231
+ '@types/filesystem': 0.0.32
232
+ '@types/har-format': 1.2.8
233
+ dev: true
234
+
235
+ /@types/d3-axis@3.0.2:
236
+ resolution: {integrity: sha512-uGC7DBh0TZrU/LY43Fd8Qr+2ja1FKmH07q2FoZFHo1eYl8aj87GhfVoY1saJVJiq24rp1+wpI6BvQJMKgQm8oA==}
237
+ dependencies:
238
+ '@types/d3-selection': 1.4.3
239
+ dev: true
240
+
241
+ /@types/d3-path@1.0.9:
242
+ resolution: {integrity: sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==}
243
+ dev: true
244
+
245
+ /@types/d3-scale@4.0.3:
246
+ resolution: {integrity: sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==}
247
+ dependencies:
248
+ '@types/d3-time': 2.1.1
249
+ dev: true
250
+
251
+ /@types/d3-selection@1.4.3:
252
+ resolution: {integrity: sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==}
253
+ dev: true
254
+
255
+ /@types/d3-shape@3.1.0:
256
+ resolution: {integrity: sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA==}
257
+ dependencies:
258
+ '@types/d3-path': 1.0.9
259
+ dev: true
260
+
261
+ /@types/d3-time@2.1.1:
262
+ resolution: {integrity: sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==}
263
+ dev: true
264
+
265
+ /@types/filesystem@0.0.32:
266
+ resolution: {integrity: sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ==}
267
+ dependencies:
268
+ '@types/filewriter': 0.0.29
269
+ dev: true
270
+
271
+ /@types/filewriter@0.0.29:
272
+ resolution: {integrity: sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ==}
273
+ dev: true
274
+
275
+ /@types/har-format@1.2.8:
276
+ resolution: {integrity: sha512-OP6L9VuZNdskgNN3zFQQ54ceYD8OLq5IbqO4VK91ORLfOm7WdT/CiT/pHEBSQEqCInJ2y3O6iCm/zGtPElpgJQ==}
277
+ dev: true
278
+
279
+ /@types/json-schema@7.0.10:
280
+ resolution: {integrity: sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==}
281
+ dev: true
282
+
283
+ /@types/lodash@4.14.191:
284
+ resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
285
+ dev: true
286
+
287
+ /@types/marked@4.0.7:
288
+ resolution: {integrity: sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==}
289
+ dev: true
290
+
291
+ /@types/node@18.11.10:
292
+ resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==}
293
+ dev: true
294
+
295
+ /@types/parse-json@4.0.0:
296
+ resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
297
+ dev: false
298
+
299
+ /@types/semver@7.3.13:
300
+ resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
301
+ dev: true
302
+
303
+ /@typescript-eslint/eslint-plugin@5.42.0(@typescript-eslint/parser@5.42.0)(eslint@8.26.0)(typescript@4.6.2):
304
+ resolution: {integrity: sha512-5TJh2AgL6+wpL8H/GTSjNb4WrjKoR2rqvFxR/DDTqYNk6uXn8BJMEcncLSpMbf/XV1aS0jAjYwn98uvVCiAywQ==}
305
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
306
+ peerDependencies:
307
+ '@typescript-eslint/parser': ^5.0.0
308
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
309
+ typescript: '*'
310
+ peerDependenciesMeta:
311
+ typescript:
312
+ optional: true
313
+ dependencies:
314
+ '@typescript-eslint/parser': 5.42.0(eslint@8.26.0)(typescript@4.6.2)
315
+ '@typescript-eslint/scope-manager': 5.42.0
316
+ '@typescript-eslint/type-utils': 5.42.0(eslint@8.26.0)(typescript@4.6.2)
317
+ '@typescript-eslint/utils': 5.42.0(eslint@8.26.0)(typescript@4.6.2)
318
+ debug: 4.3.4
319
+ eslint: 8.26.0
320
+ ignore: 5.2.0
321
+ natural-compare-lite: 1.4.0
322
+ regexpp: 3.2.0
323
+ semver: 7.3.7
324
+ tsutils: 3.21.0(typescript@4.6.2)
325
+ typescript: 4.6.2
326
+ transitivePeerDependencies:
327
+ - supports-color
328
+ dev: true
329
+
330
+ /@typescript-eslint/parser@5.42.0(eslint@8.26.0)(typescript@4.6.2):
331
+ resolution: {integrity: sha512-Ixh9qrOTDRctFg3yIwrLkgf33AHyEIn6lhyf5cCfwwiGtkWhNpVKlEZApi3inGQR/barWnY7qY8FbGKBO7p3JA==}
332
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
333
+ peerDependencies:
334
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
335
+ typescript: '*'
336
+ peerDependenciesMeta:
337
+ typescript:
338
+ optional: true
339
+ dependencies:
340
+ '@typescript-eslint/scope-manager': 5.42.0
341
+ '@typescript-eslint/types': 5.42.0
342
+ '@typescript-eslint/typescript-estree': 5.42.0(typescript@4.6.2)
343
+ debug: 4.3.4
344
+ eslint: 8.26.0
345
+ typescript: 4.6.2
346
+ transitivePeerDependencies:
347
+ - supports-color
348
+ dev: true
349
+
350
+ /@typescript-eslint/scope-manager@5.42.0:
351
+ resolution: {integrity: sha512-l5/3IBHLH0Bv04y+H+zlcLiEMEMjWGaCX6WyHE5Uk2YkSGAMlgdUPsT/ywTSKgu9D1dmmKMYgYZijObfA39Wow==}
352
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
353
+ dependencies:
354
+ '@typescript-eslint/types': 5.42.0
355
+ '@typescript-eslint/visitor-keys': 5.42.0
356
+ dev: true
357
+
358
+ /@typescript-eslint/type-utils@5.42.0(eslint@8.26.0)(typescript@4.6.2):
359
+ resolution: {integrity: sha512-HW14TXC45dFVZxnVW8rnUGnvYyRC0E/vxXShFCthcC9VhVTmjqOmtqj6H5rm9Zxv+ORxKA/1aLGD7vmlLsdlOg==}
360
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
361
+ peerDependencies:
362
+ eslint: '*'
363
+ typescript: '*'
364
+ peerDependenciesMeta:
365
+ typescript:
366
+ optional: true
367
+ dependencies:
368
+ '@typescript-eslint/typescript-estree': 5.42.0(typescript@4.6.2)
369
+ '@typescript-eslint/utils': 5.42.0(eslint@8.26.0)(typescript@4.6.2)
370
+ debug: 4.3.4
371
+ eslint: 8.26.0
372
+ tsutils: 3.21.0(typescript@4.6.2)
373
+ typescript: 4.6.2
374
+ transitivePeerDependencies:
375
+ - supports-color
376
+ dev: true
377
+
378
+ /@typescript-eslint/types@5.42.0:
379
+ resolution: {integrity: sha512-t4lzO9ZOAUcHY6bXQYRuu+3SSYdD9TS8ooApZft4WARt4/f2Cj/YpvbTe8A4GuhT4bNW72goDMOy7SW71mZwGw==}
380
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
381
+ dev: true
382
+
383
+ /@typescript-eslint/typescript-estree@5.42.0(typescript@4.6.2):
384
+ resolution: {integrity: sha512-2O3vSq794x3kZGtV7i4SCWZWCwjEtkWfVqX4m5fbUBomOsEOyd6OAD1qU2lbvV5S8tgy/luJnOYluNyYVeOTTg==}
385
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
386
+ peerDependencies:
387
+ typescript: '*'
388
+ peerDependenciesMeta:
389
+ typescript:
390
+ optional: true
391
+ dependencies:
392
+ '@typescript-eslint/types': 5.42.0
393
+ '@typescript-eslint/visitor-keys': 5.42.0
394
+ debug: 4.3.4
395
+ globby: 11.1.0
396
+ is-glob: 4.0.3
397
+ semver: 7.3.7
398
+ tsutils: 3.21.0(typescript@4.6.2)
399
+ typescript: 4.6.2
400
+ transitivePeerDependencies:
401
+ - supports-color
402
+ dev: true
403
+
404
+ /@typescript-eslint/utils@5.42.0(eslint@8.26.0)(typescript@4.6.2):
405
+ resolution: {integrity: sha512-JZ++3+h1vbeG1NUECXQZE3hg0kias9kOtcQr3+JVQ3whnjvKuMyktJAAIj6743OeNPnGBmjj7KEmiDL7qsdnCQ==}
406
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
407
+ peerDependencies:
408
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
409
+ dependencies:
410
+ '@types/json-schema': 7.0.10
411
+ '@types/semver': 7.3.13
412
+ '@typescript-eslint/scope-manager': 5.42.0
413
+ '@typescript-eslint/types': 5.42.0
414
+ '@typescript-eslint/typescript-estree': 5.42.0(typescript@4.6.2)
415
+ eslint: 8.26.0
416
+ eslint-scope: 5.1.1
417
+ eslint-utils: 3.0.0(eslint@8.26.0)
418
+ semver: 7.3.7
419
+ transitivePeerDependencies:
420
+ - supports-color
421
+ - typescript
422
+ dev: true
423
+
424
+ /@typescript-eslint/visitor-keys@5.42.0:
425
+ resolution: {integrity: sha512-QHbu5Hf/2lOEOwy+IUw0GoSCuAzByTAWWrOTKzTzsotiUnWFpuKnXcAhC9YztAf2EElQ0VvIK+pHJUPkM0q7jg==}
426
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
427
+ dependencies:
428
+ '@typescript-eslint/types': 5.42.0
429
+ eslint-visitor-keys: 3.3.0
430
+ dev: true
431
+
432
+ /@unhead/dom@1.0.21:
433
+ resolution: {integrity: sha512-rwVz7NWMdQ8kSTXv/WOhB0eTWYFD2SQwQ/J109IEqNUN9X3pIwcvdvlXMCG+qhJGFyiIgOl2X+W0cE+u/IiLVA==}
434
+ dependencies:
435
+ '@unhead/schema': 1.0.21
436
+ dev: false
437
+
438
+ /@unhead/schema@1.0.21:
439
+ resolution: {integrity: sha512-amYg6vJ37xUhnL6bvL4S3lz6yDs5lWeqJu63/3a5bxH3Dq0WPJ+kdhpUXI+4enoNaWvLvm860WXUOtKr5D+DMg==}
440
+ dependencies:
441
+ '@zhead/schema': 1.1.0
442
+ hookable: 5.4.2
443
+ dev: false
444
+
445
+ /@unhead/ssr@1.0.21:
446
+ resolution: {integrity: sha512-QWy+vKZWVb+XfHl/B/rEoniMGFpDjXiYBkjJZyuf+9By8DzQUscMaTv14neW1ZR6pq56c4B7Tp1N3Lve8SW+rA==}
447
+ dependencies:
448
+ '@unhead/schema': 1.0.21
449
+ dev: false
450
+
451
+ /@unhead/vue@1.0.21(vue@3.2.47):
452
+ resolution: {integrity: sha512-UCwgY4MbQEnFUo+/xmzBPK3PjC+oeCCzSsgK6eLk3vUC8Cuarrvw06wy8s0cO94DkpAi56Ih9oRWA16a/tih1A==}
453
+ peerDependencies:
454
+ vue: '>=2.7 || >=3'
455
+ dependencies:
456
+ '@unhead/schema': 1.0.21
457
+ hookable: 5.4.2
458
+ vue: 3.2.47
459
+ dev: false
460
+
461
+ /@vitejs/plugin-vue@2.3.4(vite@2.8.6)(vue@3.2.47):
462
+ resolution: {integrity: sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==}
463
+ engines: {node: '>=12.0.0'}
464
+ peerDependencies:
465
+ vite: ^2.5.10
466
+ vue: ^3.2.25
467
+ dependencies:
468
+ vite: 2.8.6
469
+ vue: 3.2.47
470
+ dev: true
471
+
472
+ /@volar/language-core@1.0.9:
473
+ resolution: {integrity: sha512-5Fty3slLet6svXiJw2YxhYeo6c7wFdtILrql5bZymYLM+HbiZtJbryW1YnUEKAP7MO9Mbeh+TNH4Z0HFxHgIqw==}
474
+ dependencies:
475
+ '@volar/source-map': 1.0.9
476
+ '@vue/reactivity': 3.2.41
477
+ muggle-string: 0.1.0
478
+ dev: false
479
+
480
+ /@volar/source-map@1.0.9:
481
+ resolution: {integrity: sha512-fazB/vy5ZEJ3yKx4fabJyGNI3CBkdLkfEIRVu6+1P3VixK0Mn+eqyUIkLBrzGYaeFM3GybhCLCvsVdNz0Fu/CQ==}
482
+ dependencies:
483
+ muggle-string: 0.1.0
484
+ dev: false
485
+
486
+ /@volar/typescript@1.0.9:
487
+ resolution: {integrity: sha512-dVziu+ShQUWuMukM6bvK2v2O446/gG6l1XkTh2vfkccw1IzjfbiP1TWQoNo1ipTfZOtu5YJGYAx+o5HNrGXWfQ==}
488
+ dependencies:
489
+ '@volar/language-core': 1.0.9
490
+ dev: false
491
+
492
+ /@volar/vue-language-core@1.0.9:
493
+ resolution: {integrity: sha512-tofNoR8ShPFenHT1YVMuvoXtXWwoQE+fiXVqSmW0dSKZqEDjWQ3YeXSd0a6aqyKaIbvR7kWWGp34WbpQlwf9Ww==}
494
+ dependencies:
495
+ '@volar/language-core': 1.0.9
496
+ '@volar/source-map': 1.0.9
497
+ '@vue/compiler-dom': 3.2.41
498
+ '@vue/compiler-sfc': 3.2.41
499
+ '@vue/reactivity': 3.2.41
500
+ '@vue/shared': 3.2.41
501
+ minimatch: 5.1.0
502
+ vue-template-compiler: 2.7.13
503
+ dev: false
504
+
505
+ /@volar/vue-typescript@1.0.9:
506
+ resolution: {integrity: sha512-ZLe4y9YNbviACa7uAMCilzxA76gbbSlKfjspXBzk6fCobd8QCIig+VyDYcjANIlm2HhgSCX8jYTzhCKlegh4mw==}
507
+ dependencies:
508
+ '@volar/typescript': 1.0.9
509
+ '@volar/vue-language-core': 1.0.9
510
+ dev: false
511
+
512
+ /@vue/compiler-core@3.2.41:
513
+ resolution: {integrity: sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==}
514
+ dependencies:
515
+ '@babel/parser': 7.17.8
516
+ '@vue/shared': 3.2.41
517
+ estree-walker: 2.0.2
518
+ source-map: 0.6.1
519
+ dev: false
520
+
521
+ /@vue/compiler-core@3.2.47:
522
+ resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==}
523
+ dependencies:
524
+ '@babel/parser': 7.17.8
525
+ '@vue/shared': 3.2.47
526
+ estree-walker: 2.0.2
527
+ source-map: 0.6.1
528
+
529
+ /@vue/compiler-dom@3.2.41:
530
+ resolution: {integrity: sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==}
531
+ dependencies:
532
+ '@vue/compiler-core': 3.2.41
533
+ '@vue/shared': 3.2.41
534
+ dev: false
535
+
536
+ /@vue/compiler-dom@3.2.47:
537
+ resolution: {integrity: sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==}
538
+ dependencies:
539
+ '@vue/compiler-core': 3.2.47
540
+ '@vue/shared': 3.2.47
541
+
542
+ /@vue/compiler-sfc@3.2.41:
543
+ resolution: {integrity: sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==}
544
+ dependencies:
545
+ '@babel/parser': 7.17.8
546
+ '@vue/compiler-core': 3.2.41
547
+ '@vue/compiler-dom': 3.2.41
548
+ '@vue/compiler-ssr': 3.2.41
549
+ '@vue/reactivity-transform': 3.2.41
550
+ '@vue/shared': 3.2.41
551
+ estree-walker: 2.0.2
552
+ magic-string: 0.25.9
553
+ postcss: 8.4.19
554
+ source-map: 0.6.1
555
+ dev: false
556
+
557
+ /@vue/compiler-sfc@3.2.47:
558
+ resolution: {integrity: sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==}
559
+ dependencies:
560
+ '@babel/parser': 7.17.8
561
+ '@vue/compiler-core': 3.2.47
562
+ '@vue/compiler-dom': 3.2.47
563
+ '@vue/compiler-ssr': 3.2.47
564
+ '@vue/reactivity-transform': 3.2.47
565
+ '@vue/shared': 3.2.47
566
+ estree-walker: 2.0.2
567
+ magic-string: 0.25.9
568
+ postcss: 8.4.19
569
+ source-map: 0.6.1
570
+
571
+ /@vue/compiler-ssr@3.2.41:
572
+ resolution: {integrity: sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==}
573
+ dependencies:
574
+ '@vue/compiler-dom': 3.2.41
575
+ '@vue/shared': 3.2.41
576
+ dev: false
577
+
578
+ /@vue/compiler-ssr@3.2.47:
579
+ resolution: {integrity: sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==}
580
+ dependencies:
581
+ '@vue/compiler-dom': 3.2.47
582
+ '@vue/shared': 3.2.47
583
+
584
+ /@vue/devtools-api@6.1.3:
585
+ resolution: {integrity: sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==}
586
+ dev: false
587
+
588
+ /@vue/eslint-config-typescript@11.0.2(eslint-plugin-vue@9.7.0)(eslint@8.26.0)(typescript@4.6.2):
589
+ resolution: {integrity: sha512-EiKud1NqlWmSapBFkeSrE994qpKx7/27uCGnhdqzllYDpQZroyX/O6bwjEpeuyKamvLbsGdO6PMR2faIf+zFnw==}
590
+ engines: {node: ^14.17.0 || >=16.0.0}
591
+ peerDependencies:
592
+ eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
593
+ eslint-plugin-vue: ^9.0.0
594
+ typescript: '*'
595
+ peerDependenciesMeta:
596
+ typescript:
597
+ optional: true
598
+ dependencies:
599
+ '@typescript-eslint/eslint-plugin': 5.42.0(@typescript-eslint/parser@5.42.0)(eslint@8.26.0)(typescript@4.6.2)
600
+ '@typescript-eslint/parser': 5.42.0(eslint@8.26.0)(typescript@4.6.2)
601
+ eslint: 8.26.0
602
+ eslint-plugin-vue: 9.7.0(eslint@8.26.0)
603
+ typescript: 4.6.2
604
+ vue-eslint-parser: 9.1.0(eslint@8.26.0)
605
+ transitivePeerDependencies:
606
+ - supports-color
607
+ dev: true
608
+
609
+ /@vue/reactivity-transform@3.2.41:
610
+ resolution: {integrity: sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==}
611
+ dependencies:
612
+ '@babel/parser': 7.17.8
613
+ '@vue/compiler-core': 3.2.41
614
+ '@vue/shared': 3.2.41
615
+ estree-walker: 2.0.2
616
+ magic-string: 0.25.9
617
+ dev: false
618
+
619
+ /@vue/reactivity-transform@3.2.47:
620
+ resolution: {integrity: sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==}
621
+ dependencies:
622
+ '@babel/parser': 7.17.8
623
+ '@vue/compiler-core': 3.2.47
624
+ '@vue/shared': 3.2.47
625
+ estree-walker: 2.0.2
626
+ magic-string: 0.25.9
627
+
628
+ /@vue/reactivity@3.2.41:
629
+ resolution: {integrity: sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==}
630
+ dependencies:
631
+ '@vue/shared': 3.2.41
632
+ dev: false
633
+
634
+ /@vue/reactivity@3.2.47:
635
+ resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==}
636
+ dependencies:
637
+ '@vue/shared': 3.2.47
638
+
639
+ /@vue/runtime-core@3.2.47:
640
+ resolution: {integrity: sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==}
641
+ dependencies:
642
+ '@vue/reactivity': 3.2.47
643
+ '@vue/shared': 3.2.47
644
+
645
+ /@vue/runtime-dom@3.2.47:
646
+ resolution: {integrity: sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==}
647
+ dependencies:
648
+ '@vue/runtime-core': 3.2.47
649
+ '@vue/shared': 3.2.47
650
+ csstype: 2.6.20
651
+
652
+ /@vue/server-renderer@3.2.47(vue@3.2.47):
653
+ resolution: {integrity: sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==}
654
+ peerDependencies:
655
+ vue: 3.2.47
656
+ dependencies:
657
+ '@vue/compiler-ssr': 3.2.47
658
+ '@vue/shared': 3.2.47
659
+ vue: 3.2.47
660
+
661
+ /@vue/shared@3.2.41:
662
+ resolution: {integrity: sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==}
663
+ dev: false
664
+
665
+ /@vue/shared@3.2.47:
666
+ resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==}
667
+
668
+ /@vueuse/head@1.0.25(vue@3.2.47):
669
+ resolution: {integrity: sha512-ACfRqD3bbh92cIzDDR1CmqShXCXhQv/EUUcaDMYaexA4ulorYHd+2Yo5/ljoS4jDoMgsqBSP0XJZT3nySMB5gw==}
670
+ peerDependencies:
671
+ vue: '>=2.7 || >=3'
672
+ dependencies:
673
+ '@unhead/dom': 1.0.21
674
+ '@unhead/schema': 1.0.21
675
+ '@unhead/ssr': 1.0.21
676
+ '@unhead/vue': 1.0.21(vue@3.2.47)
677
+ vue: 3.2.47
678
+ dev: false
679
+
680
+ /@zhead/schema@1.1.0:
681
+ resolution: {integrity: sha512-hEtK+hUAKS3w1+F++m6EeZ6bWeLDXraqN2nCyRVIP5vvR3bWjXVP9OM9x7Pmn7Hp6T7FKmsG2C8rvouQU2806w==}
682
+ dev: false
683
+
684
+ /acorn-jsx@5.3.2(acorn@8.8.0):
685
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
686
+ peerDependencies:
687
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
688
+ dependencies:
689
+ acorn: 8.8.0
690
+ dev: true
691
+
692
+ /acorn-node@1.8.2:
693
+ resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==}
694
+ dependencies:
695
+ acorn: 7.4.1
696
+ acorn-walk: 7.2.0
697
+ xtend: 4.0.2
698
+ dev: false
699
+
700
+ /acorn-walk@7.2.0:
701
+ resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
702
+ engines: {node: '>=0.4.0'}
703
+ dev: false
704
+
705
+ /acorn@7.4.1:
706
+ resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
707
+ engines: {node: '>=0.4.0'}
708
+ hasBin: true
709
+ dev: false
710
+
711
+ /acorn@8.8.0:
712
+ resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
713
+ engines: {node: '>=0.4.0'}
714
+ hasBin: true
715
+ dev: true
716
+
717
+ /ajv@6.12.6:
718
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
719
+ dependencies:
720
+ fast-deep-equal: 3.1.3
721
+ fast-json-stable-stringify: 2.1.0
722
+ json-schema-traverse: 0.4.1
723
+ uri-js: 4.4.1
724
+ dev: true
725
+
726
+ /ansi-regex@5.0.1:
727
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
728
+ engines: {node: '>=8'}
729
+ dev: true
730
+
731
+ /ansi-styles@3.2.1:
732
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
733
+ engines: {node: '>=4'}
734
+ dependencies:
735
+ color-convert: 1.9.3
736
+ dev: false
737
+
738
+ /ansi-styles@4.3.0:
739
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
740
+ engines: {node: '>=8'}
741
+ dependencies:
742
+ color-convert: 2.0.1
743
+
744
+ /anymatch@3.1.2:
745
+ resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==}
746
+ engines: {node: '>= 8'}
747
+ dependencies:
748
+ normalize-path: 3.0.0
749
+ picomatch: 2.3.1
750
+ dev: false
751
+
752
+ /arg@5.0.1:
753
+ resolution: {integrity: sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==}
754
+ dev: false
755
+
756
+ /argparse@2.0.1:
757
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
758
+ dev: true
759
+
760
+ /array-union@2.1.0:
761
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
762
+ engines: {node: '>=8'}
763
+ dev: true
764
+
765
+ /asynckit@0.4.0:
766
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
767
+ dev: false
768
+
769
+ /autoprefixer@10.4.13(postcss@8.4.19):
770
+ resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==}
771
+ engines: {node: ^10 || ^12 || >=14}
772
+ hasBin: true
773
+ peerDependencies:
774
+ postcss: ^8.1.0
775
+ dependencies:
776
+ browserslist: 4.21.4
777
+ caniuse-lite: 1.0.30001427
778
+ fraction.js: 4.2.0
779
+ normalize-range: 0.1.2
780
+ picocolors: 1.0.0
781
+ postcss: 8.4.19
782
+ postcss-value-parser: 4.2.0
783
+
784
+ /axios@1.1.3:
785
+ resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
786
+ dependencies:
787
+ follow-redirects: 1.15.2
788
+ form-data: 4.0.0
789
+ proxy-from-env: 1.1.0
790
+ transitivePeerDependencies:
791
+ - debug
792
+ dev: false
793
+
794
+ /balanced-match@1.0.2:
795
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
796
+
797
+ /binary-extensions@2.2.0:
798
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
799
+ engines: {node: '>=8'}
800
+ dev: false
801
+
802
+ /boolbase@1.0.0:
803
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
804
+ dev: true
805
+
806
+ /brace-expansion@1.1.11:
807
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
808
+ dependencies:
809
+ balanced-match: 1.0.2
810
+ concat-map: 0.0.1
811
+ dev: true
812
+
813
+ /brace-expansion@2.0.1:
814
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
815
+ dependencies:
816
+ balanced-match: 1.0.2
817
+ dev: false
818
+
819
+ /braces@3.0.2:
820
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
821
+ engines: {node: '>=8'}
822
+ dependencies:
823
+ fill-range: 7.0.1
824
+
825
+ /browserslist@4.21.4:
826
+ resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==}
827
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
828
+ hasBin: true
829
+ dependencies:
830
+ caniuse-lite: 1.0.30001427
831
+ electron-to-chromium: 1.4.256
832
+ node-releases: 2.0.6
833
+ update-browserslist-db: 1.0.9(browserslist@4.21.4)
834
+
835
+ /callsites@3.1.0:
836
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
837
+ engines: {node: '>=6'}
838
+
839
+ /camelcase-css@2.0.1:
840
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
841
+ engines: {node: '>= 6'}
842
+ dev: false
843
+
844
+ /caniuse-lite@1.0.30001427:
845
+ resolution: {integrity: sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==}
846
+
847
+ /chalk@2.4.2:
848
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
849
+ engines: {node: '>=4'}
850
+ dependencies:
851
+ ansi-styles: 3.2.1
852
+ escape-string-regexp: 1.0.5
853
+ supports-color: 5.5.0
854
+ dev: false
855
+
856
+ /chalk@4.1.2:
857
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
858
+ engines: {node: '>=10'}
859
+ dependencies:
860
+ ansi-styles: 4.3.0
861
+ supports-color: 7.2.0
862
+
863
+ /chokidar@3.5.3:
864
+ resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
865
+ engines: {node: '>= 8.10.0'}
866
+ dependencies:
867
+ anymatch: 3.1.2
868
+ braces: 3.0.2
869
+ glob-parent: 5.1.2
870
+ is-binary-path: 2.1.0
871
+ is-glob: 4.0.3
872
+ normalize-path: 3.0.0
873
+ readdirp: 3.6.0
874
+ optionalDependencies:
875
+ fsevents: 2.3.2
876
+ dev: false
877
+
878
+ /color-convert@1.9.3:
879
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
880
+ dependencies:
881
+ color-name: 1.1.3
882
+ dev: false
883
+
884
+ /color-convert@2.0.1:
885
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
886
+ engines: {node: '>=7.0.0'}
887
+ dependencies:
888
+ color-name: 1.1.4
889
+
890
+ /color-name@1.1.3:
891
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
892
+ dev: false
893
+
894
+ /color-name@1.1.4:
895
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
896
+
897
+ /combined-stream@1.0.8:
898
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
899
+ engines: {node: '>= 0.8'}
900
+ dependencies:
901
+ delayed-stream: 1.0.0
902
+ dev: false
903
+
904
+ /concat-map@0.0.1:
905
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
906
+ dev: true
907
+
908
+ /cosmiconfig@7.0.1:
909
+ resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==}
910
+ engines: {node: '>=10'}
911
+ dependencies:
912
+ '@types/parse-json': 4.0.0
913
+ import-fresh: 3.3.0
914
+ parse-json: 5.2.0
915
+ path-type: 4.0.0
916
+ yaml: 1.10.2
917
+ dev: false
918
+
919
+ /cross-spawn@7.0.3:
920
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
921
+ engines: {node: '>= 8'}
922
+ dependencies:
923
+ path-key: 3.1.1
924
+ shebang-command: 2.0.0
925
+ which: 2.0.2
926
+ dev: true
927
+
928
+ /cssesc@3.0.0:
929
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
930
+ engines: {node: '>=4'}
931
+ hasBin: true
932
+
933
+ /csstype@2.6.20:
934
+ resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==}
935
+
936
+ /d3-array@2.12.1:
937
+ resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==}
938
+ dependencies:
939
+ internmap: 1.0.1
940
+ dev: false
941
+
942
+ /d3-axis@1.0.12:
943
+ resolution: {integrity: sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==}
944
+ dev: false
945
+
946
+ /d3-color@2.0.0:
947
+ resolution: {integrity: sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==}
948
+ dev: false
949
+
950
+ /d3-format@2.0.0:
951
+ resolution: {integrity: sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==}
952
+ dev: false
953
+
954
+ /d3-interpolate@2.0.1:
955
+ resolution: {integrity: sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==}
956
+ dependencies:
957
+ d3-color: 2.0.0
958
+ dev: false
959
+
960
+ /d3-path@1.0.9:
961
+ resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==}
962
+ dev: false
963
+
964
+ /d3-scale@3.3.0:
965
+ resolution: {integrity: sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==}
966
+ dependencies:
967
+ d3-array: 2.12.1
968
+ d3-format: 2.0.0
969
+ d3-interpolate: 2.0.1
970
+ d3-time: 2.1.1
971
+ d3-time-format: 3.0.0
972
+ dev: false
973
+
974
+ /d3-selection@1.4.2:
975
+ resolution: {integrity: sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==}
976
+ dev: false
977
+
978
+ /d3-shape@1.3.7:
979
+ resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==}
980
+ dependencies:
981
+ d3-path: 1.0.9
982
+ dev: false
983
+
984
+ /d3-time-format@3.0.0:
985
+ resolution: {integrity: sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==}
986
+ dependencies:
987
+ d3-time: 2.1.1
988
+ dev: false
989
+
990
+ /d3-time@2.1.1:
991
+ resolution: {integrity: sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==}
992
+ dependencies:
993
+ d3-array: 2.12.1
994
+ dev: false
995
+
996
+ /dayjs@1.11.0:
997
+ resolution: {integrity: sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==}
998
+ dev: false
999
+
1000
+ /de-indent@1.0.2:
1001
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
1002
+ dev: false
1003
+
1004
+ /debug@4.3.4:
1005
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
1006
+ engines: {node: '>=6.0'}
1007
+ peerDependencies:
1008
+ supports-color: '*'
1009
+ peerDependenciesMeta:
1010
+ supports-color:
1011
+ optional: true
1012
+ dependencies:
1013
+ ms: 2.1.2
1014
+ dev: true
1015
+
1016
+ /deep-is@0.1.4:
1017
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
1018
+ dev: true
1019
+
1020
+ /defined@1.0.0:
1021
+ resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=}
1022
+ dev: false
1023
+
1024
+ /delayed-stream@1.0.0:
1025
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
1026
+ engines: {node: '>=0.4.0'}
1027
+ dev: false
1028
+
1029
+ /detective@5.2.0:
1030
+ resolution: {integrity: sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==}
1031
+ engines: {node: '>=0.8.0'}
1032
+ hasBin: true
1033
+ dependencies:
1034
+ acorn-node: 1.8.2
1035
+ defined: 1.0.0
1036
+ minimist: 1.2.5
1037
+ dev: false
1038
+
1039
+ /didyoumean@1.2.2:
1040
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
1041
+ dev: false
1042
+
1043
+ /dir-glob@3.0.1:
1044
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
1045
+ engines: {node: '>=8'}
1046
+ dependencies:
1047
+ path-type: 4.0.0
1048
+ dev: true
1049
+
1050
+ /dlv@1.1.3:
1051
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
1052
+ dev: false
1053
+
1054
+ /doctrine@3.0.0:
1055
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
1056
+ engines: {node: '>=6.0.0'}
1057
+ dependencies:
1058
+ esutils: 2.0.3
1059
+ dev: true
1060
+
1061
+ /electron-to-chromium@1.4.256:
1062
+ resolution: {integrity: sha512-x+JnqyluoJv8I0U9gVe+Sk2st8vF0CzMt78SXxuoWCooLLY2k5VerIBdpvG7ql6GKI4dzNnPjmqgDJ76EdaAKw==}
1063
+
1064
+ /error-ex@1.3.2:
1065
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
1066
+ dependencies:
1067
+ is-arrayish: 0.2.1
1068
+ dev: false
1069
+
1070
+ /esbuild-android-64@0.14.27:
1071
+ resolution: {integrity: sha512-LuEd4uPuj/16Y8j6kqy3Z2E9vNY9logfq8Tq+oTE2PZVuNs3M1kj5Qd4O95ee66yDGb3isaOCV7sOLDwtMfGaQ==}
1072
+ engines: {node: '>=12'}
1073
+ cpu: [x64]
1074
+ os: [android]
1075
+ requiresBuild: true
1076
+ optional: true
1077
+
1078
+ /esbuild-android-arm64@0.14.27:
1079
+ resolution: {integrity: sha512-E8Ktwwa6vX8q7QeJmg8yepBYXaee50OdQS3BFtEHKrzbV45H4foMOeEE7uqdjGQZFBap5VAqo7pvjlyA92wznQ==}
1080
+ engines: {node: '>=12'}
1081
+ cpu: [arm64]
1082
+ os: [android]
1083
+ requiresBuild: true
1084
+ optional: true
1085
+
1086
+ /esbuild-darwin-64@0.14.27:
1087
+ resolution: {integrity: sha512-czw/kXl/1ZdenPWfw9jDc5iuIYxqUxgQ/Q+hRd4/3udyGGVI31r29LCViN2bAJgGvQkqyLGVcG03PJPEXQ5i2g==}
1088
+ engines: {node: '>=12'}
1089
+ cpu: [x64]
1090
+ os: [darwin]
1091
+ requiresBuild: true
1092
+ optional: true
1093
+
1094
+ /esbuild-darwin-arm64@0.14.27:
1095
+ resolution: {integrity: sha512-BEsv2U2U4o672oV8+xpXNxN9bgqRCtddQC6WBh4YhXKDcSZcdNh7+6nS+DM2vu7qWIWNA4JbRG24LUUYXysimQ==}
1096
+ engines: {node: '>=12'}
1097
+ cpu: [arm64]
1098
+ os: [darwin]
1099
+ requiresBuild: true
1100
+ optional: true
1101
+
1102
+ /esbuild-freebsd-64@0.14.27:
1103
+ resolution: {integrity: sha512-7FeiFPGBo+ga+kOkDxtPmdPZdayrSzsV9pmfHxcyLKxu+3oTcajeZlOO1y9HW+t5aFZPiv7czOHM4KNd0tNwCA==}
1104
+ engines: {node: '>=12'}
1105
+ cpu: [x64]
1106
+ os: [freebsd]
1107
+ requiresBuild: true
1108
+ optional: true
1109
+
1110
+ /esbuild-freebsd-arm64@0.14.27:
1111
+ resolution: {integrity: sha512-8CK3++foRZJluOWXpllG5zwAVlxtv36NpHfsbWS7TYlD8S+QruXltKlXToc/5ZNzBK++l6rvRKELu/puCLc7jA==}
1112
+ engines: {node: '>=12'}
1113
+ cpu: [arm64]
1114
+ os: [freebsd]
1115
+ requiresBuild: true
1116
+ optional: true
1117
+
1118
+ /esbuild-linux-32@0.14.27:
1119
+ resolution: {integrity: sha512-qhNYIcT+EsYSBClZ5QhLzFzV5iVsP1YsITqblSaztr3+ZJUI+GoK8aXHyzKd7/CKKuK93cxEMJPpfi1dfsOfdw==}
1120
+ engines: {node: '>=12'}
1121
+ cpu: [ia32]
1122
+ os: [linux]
1123
+ requiresBuild: true
1124
+ optional: true
1125
+
1126
+ /esbuild-linux-64@0.14.27:
1127
+ resolution: {integrity: sha512-ESjck9+EsHoTaKWlFKJpPZRN26uiav5gkI16RuI8WBxUdLrrAlYuYSndxxKgEn1csd968BX/8yQZATYf/9+/qg==}
1128
+ engines: {node: '>=12'}
1129
+ cpu: [x64]
1130
+ os: [linux]
1131
+ requiresBuild: true
1132
+ optional: true
1133
+
1134
+ /esbuild-linux-arm64@0.14.27:
1135
+ resolution: {integrity: sha512-no6Mi17eV2tHlJnqBHRLekpZ2/VYx+NfGxKcBE/2xOMYwctsanCaXxw4zapvNrGE9X38vefVXLz6YCF8b1EHiQ==}
1136
+ engines: {node: '>=12'}
1137
+ cpu: [arm64]
1138
+ os: [linux]
1139
+ requiresBuild: true
1140
+ optional: true
1141
+
1142
+ /esbuild-linux-arm@0.14.27:
1143
+ resolution: {integrity: sha512-JnnmgUBdqLQO9hoNZQqNHFWlNpSX82vzB3rYuCJMhtkuaWQEmQz6Lec1UIxJdC38ifEghNTBsF9bbe8dFilnCw==}
1144
+ engines: {node: '>=12'}
1145
+ cpu: [arm]
1146
+ os: [linux]
1147
+ requiresBuild: true
1148
+ optional: true
1149
+
1150
+ /esbuild-linux-mips64le@0.14.27:
1151
+ resolution: {integrity: sha512-NolWP2uOvIJpbwpsDbwfeExZOY1bZNlWE/kVfkzLMsSgqeVcl5YMen/cedRe9mKnpfLli+i0uSp7N+fkKNU27A==}
1152
+ engines: {node: '>=12'}
1153
+ cpu: [mips64el]
1154
+ os: [linux]
1155
+ requiresBuild: true
1156
+ optional: true
1157
+
1158
+ /esbuild-linux-ppc64le@0.14.27:
1159
+ resolution: {integrity: sha512-/7dTjDvXMdRKmsSxKXeWyonuGgblnYDn0MI1xDC7J1VQXny8k1qgNp6VmrlsawwnsymSUUiThhkJsI+rx0taNA==}
1160
+ engines: {node: '>=12'}
1161
+ cpu: [ppc64]
1162
+ os: [linux]
1163
+ requiresBuild: true
1164
+ optional: true
1165
+
1166
+ /esbuild-linux-riscv64@0.14.27:
1167
+ resolution: {integrity: sha512-D+aFiUzOJG13RhrSmZgrcFaF4UUHpqj7XSKrIiCXIj1dkIkFqdrmqMSOtSs78dOtObWiOrFCDDzB24UyeEiNGg==}
1168
+ engines: {node: '>=12'}
1169
+ cpu: [riscv64]
1170
+ os: [linux]
1171
+ requiresBuild: true
1172
+ optional: true
1173
+
1174
+ /esbuild-linux-s390x@0.14.27:
1175
+ resolution: {integrity: sha512-CD/D4tj0U4UQjELkdNlZhQ8nDHU5rBn6NGp47Hiz0Y7/akAY5i0oGadhEIg0WCY/HYVXFb3CsSPPwaKcTOW3bg==}
1176
+ engines: {node: '>=12'}
1177
+ cpu: [s390x]
1178
+ os: [linux]
1179
+ requiresBuild: true
1180
+ optional: true
1181
+
1182
+ /esbuild-netbsd-64@0.14.27:
1183
+ resolution: {integrity: sha512-h3mAld69SrO1VoaMpYl3a5FNdGRE/Nqc+E8VtHOag4tyBwhCQXxtvDDOAKOUQexBGca0IuR6UayQ4ntSX5ij1Q==}
1184
+ engines: {node: '>=12'}
1185
+ cpu: [x64]
1186
+ os: [netbsd]
1187
+ requiresBuild: true
1188
+ optional: true
1189
+
1190
+ /esbuild-openbsd-64@0.14.27:
1191
+ resolution: {integrity: sha512-xwSje6qIZaDHXWoPpIgvL+7fC6WeubHHv18tusLYMwL+Z6bEa4Pbfs5IWDtQdHkArtfxEkIZz77944z8MgDxGw==}
1192
+ engines: {node: '>=12'}
1193
+ cpu: [x64]
1194
+ os: [openbsd]
1195
+ requiresBuild: true
1196
+ optional: true
1197
+
1198
+ /esbuild-sunos-64@0.14.27:
1199
+ resolution: {integrity: sha512-/nBVpWIDjYiyMhuqIqbXXsxBc58cBVH9uztAOIfWShStxq9BNBik92oPQPJ57nzWXRNKQUEFWr4Q98utDWz7jg==}
1200
+ engines: {node: '>=12'}
1201
+ cpu: [x64]
1202
+ os: [sunos]
1203
+ requiresBuild: true
1204
+ optional: true
1205
+
1206
+ /esbuild-windows-32@0.14.27:
1207
+ resolution: {integrity: sha512-Q9/zEjhZJ4trtWhFWIZvS/7RUzzi8rvkoaS9oiizkHTTKd8UxFwn/Mm2OywsAfYymgUYm8+y2b+BKTNEFxUekw==}
1208
+ engines: {node: '>=12'}
1209
+ cpu: [ia32]
1210
+ os: [win32]
1211
+ requiresBuild: true
1212
+ optional: true
1213
+
1214
+ /esbuild-windows-64@0.14.27:
1215
+ resolution: {integrity: sha512-b3y3vTSl5aEhWHK66ngtiS/c6byLf6y/ZBvODH1YkBM+MGtVL6jN38FdHUsZasCz9gFwYs/lJMVY9u7GL6wfYg==}
1216
+ engines: {node: '>=12'}
1217
+ cpu: [x64]
1218
+ os: [win32]
1219
+ requiresBuild: true
1220
+ optional: true
1221
+
1222
+ /esbuild-windows-arm64@0.14.27:
1223
+ resolution: {integrity: sha512-I/reTxr6TFMcR5qbIkwRGvldMIaiBu2+MP0LlD7sOlNXrfqIl9uNjsuxFPGEG4IRomjfQ5q8WT+xlF/ySVkqKg==}
1224
+ engines: {node: '>=12'}
1225
+ cpu: [arm64]
1226
+ os: [win32]
1227
+ requiresBuild: true
1228
+ optional: true
1229
+
1230
+ /esbuild@0.14.27:
1231
+ resolution: {integrity: sha512-MZQt5SywZS3hA9fXnMhR22dv0oPGh6QtjJRIYbgL1AeqAoQZE+Qn5ppGYQAoHv/vq827flj4tIJ79Mrdiwk46Q==}
1232
+ engines: {node: '>=12'}
1233
+ hasBin: true
1234
+ requiresBuild: true
1235
+ optionalDependencies:
1236
+ esbuild-android-64: 0.14.27
1237
+ esbuild-android-arm64: 0.14.27
1238
+ esbuild-darwin-64: 0.14.27
1239
+ esbuild-darwin-arm64: 0.14.27
1240
+ esbuild-freebsd-64: 0.14.27
1241
+ esbuild-freebsd-arm64: 0.14.27
1242
+ esbuild-linux-32: 0.14.27
1243
+ esbuild-linux-64: 0.14.27
1244
+ esbuild-linux-arm: 0.14.27
1245
+ esbuild-linux-arm64: 0.14.27
1246
+ esbuild-linux-mips64le: 0.14.27
1247
+ esbuild-linux-ppc64le: 0.14.27
1248
+ esbuild-linux-riscv64: 0.14.27
1249
+ esbuild-linux-s390x: 0.14.27
1250
+ esbuild-netbsd-64: 0.14.27
1251
+ esbuild-openbsd-64: 0.14.27
1252
+ esbuild-sunos-64: 0.14.27
1253
+ esbuild-windows-32: 0.14.27
1254
+ esbuild-windows-64: 0.14.27
1255
+ esbuild-windows-arm64: 0.14.27
1256
+
1257
+ /escalade@3.1.1:
1258
+ resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
1259
+ engines: {node: '>=6'}
1260
+
1261
+ /escape-string-regexp@1.0.5:
1262
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
1263
+ engines: {node: '>=0.8.0'}
1264
+ dev: false
1265
+
1266
+ /escape-string-regexp@4.0.0:
1267
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
1268
+ engines: {node: '>=10'}
1269
+ dev: true
1270
+
1271
+ /eslint-config-prettier@8.5.0(eslint@8.26.0):
1272
+ resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
1273
+ hasBin: true
1274
+ peerDependencies:
1275
+ eslint: '>=7.0.0'
1276
+ dependencies:
1277
+ eslint: 8.26.0
1278
+ dev: true
1279
+
1280
+ /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.5.0)(eslint@8.26.0)(prettier@2.7.1):
1281
+ resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
1282
+ engines: {node: '>=12.0.0'}
1283
+ peerDependencies:
1284
+ eslint: '>=7.28.0'
1285
+ eslint-config-prettier: '*'
1286
+ prettier: '>=2.0.0'
1287
+ peerDependenciesMeta:
1288
+ eslint-config-prettier:
1289
+ optional: true
1290
+ dependencies:
1291
+ eslint: 8.26.0
1292
+ eslint-config-prettier: 8.5.0(eslint@8.26.0)
1293
+ prettier: 2.7.1
1294
+ prettier-linter-helpers: 1.0.0
1295
+ dev: true
1296
+
1297
+ /eslint-plugin-vue@9.7.0(eslint@8.26.0):
1298
+ resolution: {integrity: sha512-DrOO3WZCZEwcLsnd3ohFwqCoipGRSTKTBTnLwdhqAbYZtzWl0o7D+D8ZhlmiZvABKTEl8AFsqH1GHGdybyoQmw==}
1299
+ engines: {node: ^14.17.0 || >=16.0.0}
1300
+ peerDependencies:
1301
+ eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
1302
+ dependencies:
1303
+ eslint: 8.26.0
1304
+ eslint-utils: 3.0.0(eslint@8.26.0)
1305
+ natural-compare: 1.4.0
1306
+ nth-check: 2.1.1
1307
+ postcss-selector-parser: 6.0.9
1308
+ semver: 7.3.7
1309
+ vue-eslint-parser: 9.1.0(eslint@8.26.0)
1310
+ xml-name-validator: 4.0.0
1311
+ transitivePeerDependencies:
1312
+ - supports-color
1313
+ dev: true
1314
+
1315
+ /eslint-scope@5.1.1:
1316
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
1317
+ engines: {node: '>=8.0.0'}
1318
+ dependencies:
1319
+ esrecurse: 4.3.0
1320
+ estraverse: 4.3.0
1321
+ dev: true
1322
+
1323
+ /eslint-scope@7.1.1:
1324
+ resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==}
1325
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1326
+ dependencies:
1327
+ esrecurse: 4.3.0
1328
+ estraverse: 5.3.0
1329
+ dev: true
1330
+
1331
+ /eslint-utils@3.0.0(eslint@8.26.0):
1332
+ resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
1333
+ engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
1334
+ peerDependencies:
1335
+ eslint: '>=5'
1336
+ dependencies:
1337
+ eslint: 8.26.0
1338
+ eslint-visitor-keys: 2.1.0
1339
+ dev: true
1340
+
1341
+ /eslint-visitor-keys@2.1.0:
1342
+ resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
1343
+ engines: {node: '>=10'}
1344
+ dev: true
1345
+
1346
+ /eslint-visitor-keys@3.3.0:
1347
+ resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
1348
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1349
+ dev: true
1350
+
1351
+ /eslint@8.26.0:
1352
+ resolution: {integrity: sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==}
1353
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1354
+ hasBin: true
1355
+ dependencies:
1356
+ '@eslint/eslintrc': 1.3.3
1357
+ '@humanwhocodes/config-array': 0.11.7
1358
+ '@humanwhocodes/module-importer': 1.0.1
1359
+ '@nodelib/fs.walk': 1.2.8
1360
+ ajv: 6.12.6
1361
+ chalk: 4.1.2
1362
+ cross-spawn: 7.0.3
1363
+ debug: 4.3.4
1364
+ doctrine: 3.0.0
1365
+ escape-string-regexp: 4.0.0
1366
+ eslint-scope: 7.1.1
1367
+ eslint-utils: 3.0.0(eslint@8.26.0)
1368
+ eslint-visitor-keys: 3.3.0
1369
+ espree: 9.4.0
1370
+ esquery: 1.4.0
1371
+ esutils: 2.0.3
1372
+ fast-deep-equal: 3.1.3
1373
+ file-entry-cache: 6.0.1
1374
+ find-up: 5.0.0
1375
+ glob-parent: 6.0.2
1376
+ globals: 13.17.0
1377
+ grapheme-splitter: 1.0.4
1378
+ ignore: 5.2.0
1379
+ import-fresh: 3.3.0
1380
+ imurmurhash: 0.1.4
1381
+ is-glob: 4.0.3
1382
+ is-path-inside: 3.0.3
1383
+ js-sdsl: 4.1.4
1384
+ js-yaml: 4.1.0
1385
+ json-stable-stringify-without-jsonify: 1.0.1
1386
+ levn: 0.4.1
1387
+ lodash.merge: 4.6.2
1388
+ minimatch: 3.1.2
1389
+ natural-compare: 1.4.0
1390
+ optionator: 0.9.1
1391
+ regexpp: 3.2.0
1392
+ strip-ansi: 6.0.1
1393
+ strip-json-comments: 3.1.1
1394
+ text-table: 0.2.0
1395
+ transitivePeerDependencies:
1396
+ - supports-color
1397
+ dev: true
1398
+
1399
+ /espree@9.4.0:
1400
+ resolution: {integrity: sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==}
1401
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
1402
+ dependencies:
1403
+ acorn: 8.8.0
1404
+ acorn-jsx: 5.3.2(acorn@8.8.0)
1405
+ eslint-visitor-keys: 3.3.0
1406
+ dev: true
1407
+
1408
+ /esquery@1.4.0:
1409
+ resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
1410
+ engines: {node: '>=0.10'}
1411
+ dependencies:
1412
+ estraverse: 5.3.0
1413
+ dev: true
1414
+
1415
+ /esrecurse@4.3.0:
1416
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
1417
+ engines: {node: '>=4.0'}
1418
+ dependencies:
1419
+ estraverse: 5.3.0
1420
+ dev: true
1421
+
1422
+ /estraverse@4.3.0:
1423
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
1424
+ engines: {node: '>=4.0'}
1425
+ dev: true
1426
+
1427
+ /estraverse@5.3.0:
1428
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
1429
+ engines: {node: '>=4.0'}
1430
+ dev: true
1431
+
1432
+ /estree-walker@2.0.2:
1433
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
1434
+
1435
+ /esutils@2.0.3:
1436
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1437
+ engines: {node: '>=0.10.0'}
1438
+ dev: true
1439
+
1440
+ /fast-deep-equal@3.1.3:
1441
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
1442
+ dev: true
1443
+
1444
+ /fast-diff@1.2.0:
1445
+ resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
1446
+ dev: true
1447
+
1448
+ /fast-glob@3.2.11:
1449
+ resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
1450
+ engines: {node: '>=8.6.0'}
1451
+ dependencies:
1452
+ '@nodelib/fs.stat': 2.0.5
1453
+ '@nodelib/fs.walk': 1.2.8
1454
+ glob-parent: 5.1.2
1455
+ merge2: 1.4.1
1456
+ micromatch: 4.0.4
1457
+
1458
+ /fast-json-stable-stringify@2.1.0:
1459
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
1460
+ dev: true
1461
+
1462
+ /fast-levenshtein@2.0.6:
1463
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
1464
+ dev: true
1465
+
1466
+ /fastq@1.13.0:
1467
+ resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
1468
+ dependencies:
1469
+ reusify: 1.0.4
1470
+
1471
+ /file-entry-cache@6.0.1:
1472
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
1473
+ engines: {node: ^10.12.0 || >=12.0.0}
1474
+ dependencies:
1475
+ flat-cache: 3.0.4
1476
+ dev: true
1477
+
1478
+ /fill-range@7.0.1:
1479
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
1480
+ engines: {node: '>=8'}
1481
+ dependencies:
1482
+ to-regex-range: 5.0.1
1483
+
1484
+ /find-up@5.0.0:
1485
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
1486
+ engines: {node: '>=10'}
1487
+ dependencies:
1488
+ locate-path: 6.0.0
1489
+ path-exists: 4.0.0
1490
+ dev: true
1491
+
1492
+ /flat-cache@3.0.4:
1493
+ resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
1494
+ engines: {node: ^10.12.0 || >=12.0.0}
1495
+ dependencies:
1496
+ flatted: 3.2.5
1497
+ rimraf: 3.0.2
1498
+ dev: true
1499
+
1500
+ /flatted@3.2.5:
1501
+ resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
1502
+ dev: true
1503
+
1504
+ /follow-redirects@1.15.2:
1505
+ resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
1506
+ engines: {node: '>=4.0'}
1507
+ peerDependencies:
1508
+ debug: '*'
1509
+ peerDependenciesMeta:
1510
+ debug:
1511
+ optional: true
1512
+ dev: false
1513
+
1514
+ /form-data@4.0.0:
1515
+ resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
1516
+ engines: {node: '>= 6'}
1517
+ dependencies:
1518
+ asynckit: 0.4.0
1519
+ combined-stream: 1.0.8
1520
+ mime-types: 2.1.35
1521
+ dev: false
1522
+
1523
+ /fraction.js@4.2.0:
1524
+ resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
1525
+
1526
+ /fs.realpath@1.0.0:
1527
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
1528
+ dev: true
1529
+
1530
+ /fsevents@2.3.2:
1531
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
1532
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
1533
+ os: [darwin]
1534
+ requiresBuild: true
1535
+ optional: true
1536
+
1537
+ /function-bind@1.1.1:
1538
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
1539
+
1540
+ /glob-parent@5.1.2:
1541
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
1542
+ engines: {node: '>= 6'}
1543
+ dependencies:
1544
+ is-glob: 4.0.3
1545
+
1546
+ /glob-parent@6.0.2:
1547
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
1548
+ engines: {node: '>=10.13.0'}
1549
+ dependencies:
1550
+ is-glob: 4.0.3
1551
+
1552
+ /glob@7.2.0:
1553
+ resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==}
1554
+ dependencies:
1555
+ fs.realpath: 1.0.0
1556
+ inflight: 1.0.6
1557
+ inherits: 2.0.4
1558
+ minimatch: 3.1.2
1559
+ once: 1.4.0
1560
+ path-is-absolute: 1.0.1
1561
+ dev: true
1562
+
1563
+ /globals@13.17.0:
1564
+ resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==}
1565
+ engines: {node: '>=8'}
1566
+ dependencies:
1567
+ type-fest: 0.20.2
1568
+ dev: true
1569
+
1570
+ /globby@11.1.0:
1571
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
1572
+ engines: {node: '>=10'}
1573
+ dependencies:
1574
+ array-union: 2.1.0
1575
+ dir-glob: 3.0.1
1576
+ fast-glob: 3.2.11
1577
+ ignore: 5.2.0
1578
+ merge2: 1.4.1
1579
+ slash: 3.0.0
1580
+ dev: true
1581
+
1582
+ /grapheme-splitter@1.0.4:
1583
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
1584
+ dev: true
1585
+
1586
+ /has-flag@3.0.0:
1587
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
1588
+ engines: {node: '>=4'}
1589
+ dev: false
1590
+
1591
+ /has-flag@4.0.0:
1592
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
1593
+ engines: {node: '>=8'}
1594
+
1595
+ /has@1.0.3:
1596
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
1597
+ engines: {node: '>= 0.4.0'}
1598
+ dependencies:
1599
+ function-bind: 1.1.1
1600
+
1601
+ /he@1.2.0:
1602
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
1603
+ hasBin: true
1604
+ dev: false
1605
+
1606
+ /hookable@5.4.2:
1607
+ resolution: {integrity: sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg==}
1608
+ dev: false
1609
+
1610
+ /ignore@5.2.0:
1611
+ resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
1612
+ engines: {node: '>= 4'}
1613
+ dev: true
1614
+
1615
+ /import-fresh@3.3.0:
1616
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
1617
+ engines: {node: '>=6'}
1618
+ dependencies:
1619
+ parent-module: 1.0.1
1620
+ resolve-from: 4.0.0
1621
+
1622
+ /imurmurhash@0.1.4:
1623
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
1624
+ engines: {node: '>=0.8.19'}
1625
+ dev: true
1626
+
1627
+ /inflight@1.0.6:
1628
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
1629
+ dependencies:
1630
+ once: 1.4.0
1631
+ wrappy: 1.0.2
1632
+ dev: true
1633
+
1634
+ /inherits@2.0.4:
1635
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
1636
+ dev: true
1637
+
1638
+ /internmap@1.0.1:
1639
+ resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
1640
+ dev: false
1641
+
1642
+ /is-arrayish@0.2.1:
1643
+ resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
1644
+ dev: false
1645
+
1646
+ /is-binary-path@2.1.0:
1647
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
1648
+ engines: {node: '>=8'}
1649
+ dependencies:
1650
+ binary-extensions: 2.2.0
1651
+ dev: false
1652
+
1653
+ /is-core-module@2.8.1:
1654
+ resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
1655
+ dependencies:
1656
+ has: 1.0.3
1657
+
1658
+ /is-extglob@2.1.1:
1659
+ resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
1660
+ engines: {node: '>=0.10.0'}
1661
+
1662
+ /is-glob@4.0.3:
1663
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1664
+ engines: {node: '>=0.10.0'}
1665
+ dependencies:
1666
+ is-extglob: 2.1.1
1667
+
1668
+ /is-number@7.0.0:
1669
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1670
+ engines: {node: '>=0.12.0'}
1671
+
1672
+ /is-path-inside@3.0.3:
1673
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
1674
+ engines: {node: '>=8'}
1675
+ dev: true
1676
+
1677
+ /isexe@2.0.0:
1678
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1679
+ dev: true
1680
+
1681
+ /js-sdsl@4.1.4:
1682
+ resolution: {integrity: sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==}
1683
+ dev: true
1684
+
1685
+ /js-tokens@4.0.0:
1686
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1687
+ dev: false
1688
+
1689
+ /js-yaml@4.1.0:
1690
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
1691
+ hasBin: true
1692
+ dependencies:
1693
+ argparse: 2.0.1
1694
+ dev: true
1695
+
1696
+ /json-parse-even-better-errors@2.3.1:
1697
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
1698
+ dev: false
1699
+
1700
+ /json-schema-traverse@0.4.1:
1701
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
1702
+ dev: true
1703
+
1704
+ /json-stable-stringify-without-jsonify@1.0.1:
1705
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
1706
+ dev: true
1707
+
1708
+ /levn@0.4.1:
1709
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
1710
+ engines: {node: '>= 0.8.0'}
1711
+ dependencies:
1712
+ prelude-ls: 1.2.1
1713
+ type-check: 0.4.0
1714
+ dev: true
1715
+
1716
+ /lilconfig@2.0.4:
1717
+ resolution: {integrity: sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==}
1718
+ engines: {node: '>=10'}
1719
+ dev: false
1720
+
1721
+ /lines-and-columns@1.2.4:
1722
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
1723
+ dev: false
1724
+
1725
+ /locate-path@6.0.0:
1726
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
1727
+ engines: {node: '>=10'}
1728
+ dependencies:
1729
+ p-locate: 5.0.0
1730
+ dev: true
1731
+
1732
+ /lodash.castarray@4.4.0:
1733
+ resolution: {integrity: sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=}
1734
+ dev: false
1735
+
1736
+ /lodash.isplainobject@4.0.6:
1737
+ resolution: {integrity: sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=}
1738
+ dev: false
1739
+
1740
+ /lodash.merge@4.6.2:
1741
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
1742
+
1743
+ /lodash@4.17.21:
1744
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
1745
+
1746
+ /lru-cache@6.0.0:
1747
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
1748
+ engines: {node: '>=10'}
1749
+ dependencies:
1750
+ yallist: 4.0.0
1751
+ dev: true
1752
+
1753
+ /magic-string@0.25.9:
1754
+ resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
1755
+ dependencies:
1756
+ sourcemap-codec: 1.4.8
1757
+
1758
+ /marked@4.0.16:
1759
+ resolution: {integrity: sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==}
1760
+ engines: {node: '>= 12'}
1761
+ hasBin: true
1762
+ dev: false
1763
+
1764
+ /merge2@1.4.1:
1765
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1766
+ engines: {node: '>= 8'}
1767
+
1768
+ /micromatch@4.0.4:
1769
+ resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==}
1770
+ engines: {node: '>=8.6'}
1771
+ dependencies:
1772
+ braces: 3.0.2
1773
+ picomatch: 2.3.1
1774
+
1775
+ /mime-db@1.52.0:
1776
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
1777
+ engines: {node: '>= 0.6'}
1778
+ dev: false
1779
+
1780
+ /mime-types@2.1.35:
1781
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
1782
+ engines: {node: '>= 0.6'}
1783
+ dependencies:
1784
+ mime-db: 1.52.0
1785
+ dev: false
1786
+
1787
+ /minimatch@3.1.2:
1788
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1789
+ dependencies:
1790
+ brace-expansion: 1.1.11
1791
+ dev: true
1792
+
1793
+ /minimatch@5.1.0:
1794
+ resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==}
1795
+ engines: {node: '>=10'}
1796
+ dependencies:
1797
+ brace-expansion: 2.0.1
1798
+ dev: false
1799
+
1800
+ /minimist@1.2.5:
1801
+ resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
1802
+ dev: false
1803
+
1804
+ /ms@2.1.2:
1805
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
1806
+ dev: true
1807
+
1808
+ /muggle-string@0.1.0:
1809
+ resolution: {integrity: sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg==}
1810
+ dev: false
1811
+
1812
+ /nanoid@3.3.4:
1813
+ resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
1814
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1815
+ hasBin: true
1816
+
1817
+ /natural-compare-lite@1.4.0:
1818
+ resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
1819
+ dev: true
1820
+
1821
+ /natural-compare@1.4.0:
1822
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1823
+ dev: true
1824
+
1825
+ /node-releases@2.0.6:
1826
+ resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
1827
+
1828
+ /normalize-path@3.0.0:
1829
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
1830
+ engines: {node: '>=0.10.0'}
1831
+ dev: false
1832
+
1833
+ /normalize-range@0.1.2:
1834
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
1835
+ engines: {node: '>=0.10.0'}
1836
+
1837
+ /nth-check@2.1.1:
1838
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
1839
+ dependencies:
1840
+ boolbase: 1.0.0
1841
+ dev: true
1842
+
1843
+ /object-hash@2.2.0:
1844
+ resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
1845
+ engines: {node: '>= 6'}
1846
+ dev: false
1847
+
1848
+ /once@1.4.0:
1849
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1850
+ dependencies:
1851
+ wrappy: 1.0.2
1852
+ dev: true
1853
+
1854
+ /optionator@0.9.1:
1855
+ resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
1856
+ engines: {node: '>= 0.8.0'}
1857
+ dependencies:
1858
+ deep-is: 0.1.4
1859
+ fast-levenshtein: 2.0.6
1860
+ levn: 0.4.1
1861
+ prelude-ls: 1.2.1
1862
+ type-check: 0.4.0
1863
+ word-wrap: 1.2.3
1864
+ dev: true
1865
+
1866
+ /p-limit@3.1.0:
1867
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1868
+ engines: {node: '>=10'}
1869
+ dependencies:
1870
+ yocto-queue: 0.1.0
1871
+ dev: true
1872
+
1873
+ /p-locate@5.0.0:
1874
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1875
+ engines: {node: '>=10'}
1876
+ dependencies:
1877
+ p-limit: 3.1.0
1878
+ dev: true
1879
+
1880
+ /parent-module@1.0.1:
1881
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1882
+ engines: {node: '>=6'}
1883
+ dependencies:
1884
+ callsites: 3.1.0
1885
+
1886
+ /parse-json@5.2.0:
1887
+ resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
1888
+ engines: {node: '>=8'}
1889
+ dependencies:
1890
+ '@babel/code-frame': 7.16.7
1891
+ error-ex: 1.3.2
1892
+ json-parse-even-better-errors: 2.3.1
1893
+ lines-and-columns: 1.2.4
1894
+ dev: false
1895
+
1896
+ /path-exists@4.0.0:
1897
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1898
+ engines: {node: '>=8'}
1899
+ dev: true
1900
+
1901
+ /path-is-absolute@1.0.1:
1902
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
1903
+ engines: {node: '>=0.10.0'}
1904
+ dev: true
1905
+
1906
+ /path-key@3.1.1:
1907
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1908
+ engines: {node: '>=8'}
1909
+ dev: true
1910
+
1911
+ /path-parse@1.0.7:
1912
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1913
+
1914
+ /path-type@4.0.0:
1915
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
1916
+ engines: {node: '>=8'}
1917
+
1918
+ /picocolors@1.0.0:
1919
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
1920
+
1921
+ /picomatch@2.3.1:
1922
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1923
+ engines: {node: '>=8.6'}
1924
+
1925
+ /pinia@2.0.12(typescript@4.6.2)(vue@3.2.47):
1926
+ resolution: {integrity: sha512-tUeuYGFrLU5irmGyRAIxp35q1OTcZ8sKpGT4XkPeVcG35W4R6cfXDbCGexzmVqH5lTQJJTXXbNGutIu9yS5yew==}
1927
+ peerDependencies:
1928
+ '@vue/composition-api': ^1.4.0
1929
+ typescript: '>=4.4.4'
1930
+ vue: ^2.6.14 || ^3.2.0
1931
+ peerDependenciesMeta:
1932
+ '@vue/composition-api':
1933
+ optional: true
1934
+ typescript:
1935
+ optional: true
1936
+ dependencies:
1937
+ '@vue/devtools-api': 6.1.3
1938
+ typescript: 4.6.2
1939
+ vue: 3.2.47
1940
+ vue-demi: 0.12.4(vue@3.2.47)
1941
+ dev: false
1942
+
1943
+ /postcss-js@4.0.0(postcss@8.4.19):
1944
+ resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
1945
+ engines: {node: ^12 || ^14 || >= 16}
1946
+ peerDependencies:
1947
+ postcss: ^8.3.3
1948
+ dependencies:
1949
+ camelcase-css: 2.0.1
1950
+ postcss: 8.4.19
1951
+ dev: false
1952
+
1953
+ /postcss-load-config@3.1.3:
1954
+ resolution: {integrity: sha512-5EYgaM9auHGtO//ljHH+v/aC/TQ5LHXtL7bQajNAUBKUVKiYE8rYpFms7+V26D9FncaGe2zwCoPQsFKb5zF/Hw==}
1955
+ engines: {node: '>= 10'}
1956
+ peerDependencies:
1957
+ ts-node: '>=9.0.0'
1958
+ peerDependenciesMeta:
1959
+ ts-node:
1960
+ optional: true
1961
+ dependencies:
1962
+ lilconfig: 2.0.4
1963
+ yaml: 1.10.2
1964
+ dev: false
1965
+
1966
+ /postcss-nested@5.0.6(postcss@8.4.19):
1967
+ resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==}
1968
+ engines: {node: '>=12.0'}
1969
+ peerDependencies:
1970
+ postcss: ^8.2.14
1971
+ dependencies:
1972
+ postcss: 8.4.19
1973
+ postcss-selector-parser: 6.0.9
1974
+ dev: false
1975
+
1976
+ /postcss-selector-parser@6.0.9:
1977
+ resolution: {integrity: sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==}
1978
+ engines: {node: '>=4'}
1979
+ dependencies:
1980
+ cssesc: 3.0.0
1981
+ util-deprecate: 1.0.2
1982
+
1983
+ /postcss-value-parser@4.2.0:
1984
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
1985
+
1986
+ /postcss@8.4.19:
1987
+ resolution: {integrity: sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==}
1988
+ engines: {node: ^10 || ^12 || >=14}
1989
+ dependencies:
1990
+ nanoid: 3.3.4
1991
+ picocolors: 1.0.0
1992
+ source-map-js: 1.0.2
1993
+
1994
+ /prelude-ls@1.2.1:
1995
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
1996
+ engines: {node: '>= 0.8.0'}
1997
+ dev: true
1998
+
1999
+ /prettier-linter-helpers@1.0.0:
2000
+ resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
2001
+ engines: {node: '>=6.0.0'}
2002
+ dependencies:
2003
+ fast-diff: 1.2.0
2004
+ dev: true
2005
+
2006
+ /prettier@2.7.1:
2007
+ resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
2008
+ engines: {node: '>=10.13.0'}
2009
+ hasBin: true
2010
+ dev: true
2011
+
2012
+ /proxy-from-env@1.1.0:
2013
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
2014
+ dev: false
2015
+
2016
+ /punycode@2.1.1:
2017
+ resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
2018
+ engines: {node: '>=6'}
2019
+ dev: true
2020
+
2021
+ /queue-microtask@1.2.3:
2022
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
2023
+
2024
+ /quick-lru@5.1.1:
2025
+ resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
2026
+ engines: {node: '>=10'}
2027
+ dev: false
2028
+
2029
+ /readdirp@3.6.0:
2030
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
2031
+ engines: {node: '>=8.10.0'}
2032
+ dependencies:
2033
+ picomatch: 2.3.1
2034
+ dev: false
2035
+
2036
+ /regexpp@3.2.0:
2037
+ resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
2038
+ engines: {node: '>=8'}
2039
+ dev: true
2040
+
2041
+ /resolve-from@4.0.0:
2042
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
2043
+ engines: {node: '>=4'}
2044
+
2045
+ /resolve@1.22.0:
2046
+ resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==}
2047
+ hasBin: true
2048
+ dependencies:
2049
+ is-core-module: 2.8.1
2050
+ path-parse: 1.0.7
2051
+ supports-preserve-symlinks-flag: 1.0.0
2052
+
2053
+ /reusify@1.0.4:
2054
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
2055
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
2056
+
2057
+ /rimraf@3.0.2:
2058
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
2059
+ hasBin: true
2060
+ dependencies:
2061
+ glob: 7.2.0
2062
+ dev: true
2063
+
2064
+ /rollup@2.70.1:
2065
+ resolution: {integrity: sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==}
2066
+ engines: {node: '>=10.0.0'}
2067
+ hasBin: true
2068
+ optionalDependencies:
2069
+ fsevents: 2.3.2
2070
+
2071
+ /run-parallel@1.2.0:
2072
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
2073
+ dependencies:
2074
+ queue-microtask: 1.2.3
2075
+
2076
+ /semver@7.3.7:
2077
+ resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==}
2078
+ engines: {node: '>=10'}
2079
+ hasBin: true
2080
+ dependencies:
2081
+ lru-cache: 6.0.0
2082
+ dev: true
2083
+
2084
+ /shebang-command@2.0.0:
2085
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
2086
+ engines: {node: '>=8'}
2087
+ dependencies:
2088
+ shebang-regex: 3.0.0
2089
+ dev: true
2090
+
2091
+ /shebang-regex@3.0.0:
2092
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
2093
+ engines: {node: '>=8'}
2094
+ dev: true
2095
+
2096
+ /slash@3.0.0:
2097
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
2098
+ engines: {node: '>=8'}
2099
+ dev: true
2100
+
2101
+ /source-map-js@1.0.2:
2102
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
2103
+ engines: {node: '>=0.10.0'}
2104
+
2105
+ /source-map@0.6.1:
2106
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
2107
+ engines: {node: '>=0.10.0'}
2108
+
2109
+ /sourcemap-codec@1.4.8:
2110
+ resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
2111
+
2112
+ /strip-ansi@6.0.1:
2113
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
2114
+ engines: {node: '>=8'}
2115
+ dependencies:
2116
+ ansi-regex: 5.0.1
2117
+ dev: true
2118
+
2119
+ /strip-json-comments@3.1.1:
2120
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
2121
+ engines: {node: '>=8'}
2122
+ dev: true
2123
+
2124
+ /supports-color@5.5.0:
2125
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
2126
+ engines: {node: '>=4'}
2127
+ dependencies:
2128
+ has-flag: 3.0.0
2129
+ dev: false
2130
+
2131
+ /supports-color@7.2.0:
2132
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
2133
+ engines: {node: '>=8'}
2134
+ dependencies:
2135
+ has-flag: 4.0.0
2136
+
2137
+ /supports-preserve-symlinks-flag@1.0.0:
2138
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
2139
+ engines: {node: '>= 0.4'}
2140
+
2141
+ /tailwindcss@3.0.23(autoprefixer@10.4.13)(postcss@8.4.19):
2142
+ resolution: {integrity: sha512-+OZOV9ubyQ6oI2BXEhzw4HrqvgcARY38xv3zKcjnWtMIZstEsXdI9xftd1iB7+RbOnj2HOEzkA0OyB5BaSxPQA==}
2143
+ engines: {node: '>=12.13.0'}
2144
+ hasBin: true
2145
+ peerDependencies:
2146
+ autoprefixer: ^10.0.2
2147
+ postcss: ^8.0.9
2148
+ dependencies:
2149
+ arg: 5.0.1
2150
+ autoprefixer: 10.4.13(postcss@8.4.19)
2151
+ chalk: 4.1.2
2152
+ chokidar: 3.5.3
2153
+ color-name: 1.1.4
2154
+ cosmiconfig: 7.0.1
2155
+ detective: 5.2.0
2156
+ didyoumean: 1.2.2
2157
+ dlv: 1.1.3
2158
+ fast-glob: 3.2.11
2159
+ glob-parent: 6.0.2
2160
+ is-glob: 4.0.3
2161
+ normalize-path: 3.0.0
2162
+ object-hash: 2.2.0
2163
+ postcss: 8.4.19
2164
+ postcss-js: 4.0.0(postcss@8.4.19)
2165
+ postcss-load-config: 3.1.3
2166
+ postcss-nested: 5.0.6(postcss@8.4.19)
2167
+ postcss-selector-parser: 6.0.9
2168
+ postcss-value-parser: 4.2.0
2169
+ quick-lru: 5.1.1
2170
+ resolve: 1.22.0
2171
+ transitivePeerDependencies:
2172
+ - ts-node
2173
+ dev: false
2174
+
2175
+ /text-table@0.2.0:
2176
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
2177
+ dev: true
2178
+
2179
+ /to-fast-properties@2.0.0:
2180
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
2181
+ engines: {node: '>=4'}
2182
+
2183
+ /to-regex-range@5.0.1:
2184
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
2185
+ engines: {node: '>=8.0'}
2186
+ dependencies:
2187
+ is-number: 7.0.0
2188
+
2189
+ /tslib@1.14.1:
2190
+ resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
2191
+ dev: true
2192
+
2193
+ /tsutils@3.21.0(typescript@4.6.2):
2194
+ resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
2195
+ engines: {node: '>= 6'}
2196
+ peerDependencies:
2197
+ typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
2198
+ dependencies:
2199
+ tslib: 1.14.1
2200
+ typescript: 4.6.2
2201
+ dev: true
2202
+
2203
+ /type-check@0.4.0:
2204
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
2205
+ engines: {node: '>= 0.8.0'}
2206
+ dependencies:
2207
+ prelude-ls: 1.2.1
2208
+ dev: true
2209
+
2210
+ /type-fest@0.20.2:
2211
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
2212
+ engines: {node: '>=10'}
2213
+ dev: true
2214
+
2215
+ /typescript@4.6.2:
2216
+ resolution: {integrity: sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==}
2217
+ engines: {node: '>=4.2.0'}
2218
+ hasBin: true
2219
+
2220
+ /update-browserslist-db@1.0.9(browserslist@4.21.4):
2221
+ resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==}
2222
+ hasBin: true
2223
+ peerDependencies:
2224
+ browserslist: '>= 4.21.0'
2225
+ dependencies:
2226
+ browserslist: 4.21.4
2227
+ escalade: 3.1.1
2228
+ picocolors: 1.0.0
2229
+
2230
+ /uri-js@4.4.1:
2231
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
2232
+ dependencies:
2233
+ punycode: 2.1.1
2234
+ dev: true
2235
+
2236
+ /util-deprecate@1.0.2:
2237
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
2238
+
2239
+ /vite@2.8.6:
2240
+ resolution: {integrity: sha512-e4H0QpludOVKkmOsRyqQ7LTcMUDF3mcgyNU4lmi0B5JUbe0ZxeBBl8VoZ8Y6Rfn9eFKYtdXNPcYK97ZwH+K2ug==}
2241
+ engines: {node: '>=12.2.0'}
2242
+ hasBin: true
2243
+ peerDependencies:
2244
+ less: '*'
2245
+ sass: '*'
2246
+ stylus: '*'
2247
+ peerDependenciesMeta:
2248
+ less:
2249
+ optional: true
2250
+ sass:
2251
+ optional: true
2252
+ stylus:
2253
+ optional: true
2254
+ dependencies:
2255
+ esbuild: 0.14.27
2256
+ postcss: 8.4.19
2257
+ resolve: 1.22.0
2258
+ rollup: 2.70.1
2259
+ optionalDependencies:
2260
+ fsevents: 2.3.2
2261
+
2262
+ /vue-demi@0.12.4(vue@3.2.47):
2263
+ resolution: {integrity: sha512-ztPDkFt0TSUdoq1ZI6oD730vgztBkiByhUW7L1cOTebiSBqSYfSQgnhYakYigBkyAybqCTH7h44yZuDJf2xILQ==}
2264
+ engines: {node: '>=12'}
2265
+ hasBin: true
2266
+ requiresBuild: true
2267
+ peerDependencies:
2268
+ '@vue/composition-api': ^1.0.0-rc.1
2269
+ vue: ^3.0.0-0 || ^2.6.0
2270
+ peerDependenciesMeta:
2271
+ '@vue/composition-api':
2272
+ optional: true
2273
+ dependencies:
2274
+ vue: 3.2.47
2275
+ dev: false
2276
+
2277
+ /vue-eslint-parser@9.1.0(eslint@8.26.0):
2278
+ resolution: {integrity: sha512-NGn/iQy8/Wb7RrRa4aRkokyCZfOUWk19OP5HP6JEozQFX5AoS/t+Z0ZN7FY4LlmWc4FNI922V7cvX28zctN8dQ==}
2279
+ engines: {node: ^14.17.0 || >=16.0.0}
2280
+ peerDependencies:
2281
+ eslint: '>=6.0.0'
2282
+ dependencies:
2283
+ debug: 4.3.4
2284
+ eslint: 8.26.0
2285
+ eslint-scope: 7.1.1
2286
+ eslint-visitor-keys: 3.3.0
2287
+ espree: 9.4.0
2288
+ esquery: 1.4.0
2289
+ lodash: 4.17.21
2290
+ semver: 7.3.7
2291
+ transitivePeerDependencies:
2292
+ - supports-color
2293
+ dev: true
2294
+
2295
+ /vue-router@4.0.14(vue@3.2.47):
2296
+ resolution: {integrity: sha512-wAO6zF9zxA3u+7AkMPqw9LjoUCjSxfFvINQj3E/DceTt6uEz1XZLraDhdg2EYmvVwTBSGlLYsUw8bDmx0754Mw==}
2297
+ peerDependencies:
2298
+ vue: ^3.2.0
2299
+ dependencies:
2300
+ '@vue/devtools-api': 6.1.3
2301
+ vue: 3.2.47
2302
+ dev: false
2303
+
2304
+ /vue-template-compiler@2.7.13:
2305
+ resolution: {integrity: sha512-jYM6TClwDS9YqP48gYrtAtaOhRKkbYmbzE+Q51gX5YDr777n7tNI/IZk4QV4l/PjQPNh/FVa/E92sh/RqKMrog==}
2306
+ dependencies:
2307
+ de-indent: 1.0.2
2308
+ he: 1.2.0
2309
+ dev: false
2310
+
2311
+ /vue-tsc@1.0.9(typescript@4.6.2):
2312
+ resolution: {integrity: sha512-vRmHD1K6DmBymNhoHjQy/aYKTRQNLGOu2/ESasChG9Vy113K6CdP0NlhR0bzgFJfv2eFB9Ez/9L5kIciUajBxQ==}
2313
+ hasBin: true
2314
+ peerDependencies:
2315
+ typescript: '*'
2316
+ dependencies:
2317
+ '@volar/vue-language-core': 1.0.9
2318
+ '@volar/vue-typescript': 1.0.9
2319
+ typescript: 4.6.2
2320
+ dev: false
2321
+
2322
+ /vue@3.2.47:
2323
+ resolution: {integrity: sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==}
2324
+ dependencies:
2325
+ '@vue/compiler-dom': 3.2.47
2326
+ '@vue/compiler-sfc': 3.2.47
2327
+ '@vue/runtime-dom': 3.2.47
2328
+ '@vue/server-renderer': 3.2.47(vue@3.2.47)
2329
+ '@vue/shared': 3.2.47
2330
+
2331
+ /which@2.0.2:
2332
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
2333
+ engines: {node: '>= 8'}
2334
+ hasBin: true
2335
+ dependencies:
2336
+ isexe: 2.0.0
2337
+ dev: true
2338
+
2339
+ /word-wrap@1.2.3:
2340
+ resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
2341
+ engines: {node: '>=0.10.0'}
2342
+ dev: true
2343
+
2344
+ /wrappy@1.0.2:
2345
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
2346
+ dev: true
2347
+
2348
+ /xml-name-validator@4.0.0:
2349
+ resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
2350
+ engines: {node: '>=12'}
2351
+ dev: true
2352
+
2353
+ /xtend@4.0.2:
2354
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
2355
+ engines: {node: '>=0.4'}
2356
+ dev: false
2357
+
2358
+ /yallist@4.0.0:
2359
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
2360
+ dev: true
2361
+
2362
+ /yaml@1.10.2:
2363
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
2364
+ engines: {node: '>= 6'}
2365
+ dev: false
2366
+
2367
+ /yocto-queue@0.1.0:
2368
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
2369
+ engines: {node: '>=10'}
2370
+ dev: true
postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
public/blog/add-a-live-star-history-chart-to-your-github-readme.md ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Add a live star-history chart to your GitHub README
2
+
3
+ ![star-history-svg-example](/blog/assets/star-history-svg-example.png)
4
+ Now we support embedding a live star history chart into your GitHub README.  Above is the screenshot from our own [GitHub start history repo](https://github.com/star-history/star-history).
5
+
6
+ This feature is quite handy.  A snippet would appear after querying the repository from our star-history.com main page; the only thing you need to do is simply copy that snippet into your GitHub README markdown file.
7
+ ![star-history-embed-block](/blog/assets/star-history-embed-block.png)
8
+ Under the hood, it's actually a long story about developing this embedded star history chart.  It all starts from an issue 6 years ago.
9
+
10
+ ## An issue from 6 years ago
11
+
12
+ In 2016, a user opened an [issue](https://github.com/star-history/star-history/issues/35) asking to embed GitHub star-history chart into their own website.  But due to the development resource and API token limitations, it was dismissed.
13
+ ![old-embed-issue](/blog/assets/old-embed-issue.png)
14
+ Recently, we resumed the development effort and after completing a major refactoring of [star-history](https://star-history.com/blog/introducing-the-new-star-history-com), we are ready to tackle this.  Our first improvement is to introduce the embeddable GitHub star-history chart using `<iframe />`.
15
+
16
+ ## Embed with `<iframe />`
17
+
18
+ After looking through the popular web-side embedding implementations, we decide to use `<iframe />` as the embedded block container.  It can display original charts on a webpage without implementing a backend server.  And `<iframe />` is also interactive with real-time data.
19
+
20
+ Because GitHub API imposes a strict rate limit on the anonymous callers, we need users to provide their self-generated tokens to overcome that limit.
21
+
22
+ ### Step-to-step guide to use `iframe` embed
23
+
24
+ 1. Open [star-history.com](https://star-history.com) and query for a repository;
25
+
26
+ 2. Click the `Embed` button below the chart;
27
+
28
+ 3. Input your personal access token;
29
+ ![embed-chart-with-svg](/blog/assets/embed-chart-with-iframe.png)
30
+
31
+ 4. Click the `Copy` button, then paste it into your websites or blogs;
32
+
33
+ ## Live chart image in SVG format
34
+
35
+ The iframe-based embed block is a decent improvement, while it still has some flaws:
36
+
37
+ 1. One commonly used case is to embed the GitHub star-history chart into the repository README file, so that it can be displayed on the repo's front page. However, the GitHub markdown flavor disallows rendering `<iframe />`, which makes it impossible to directly embed star-history charts there.
38
+ 2. We require users to provide their personal access tokens.  Though star-history never stores the token on our own server (we don't have a server at all), the token itself could be found if someone views the webpage source code.  This limits the usage since it's not fully secure unless adding the chart to a trusted platform, i.e. the internal dashboard of a team.
39
+
40
+ ### Inspiration
41
+
42
+ We noticed that many open source projects have badges on their README
43
+ ![github-badges](/blog/assets/github-badges.png)
44
+ After thorough research, we figured that those badges are dynamically generated SVG images.
45
+
46
+ Coincidentally, star-history also generates the SVG chart image.  If we can return this SVG image by a link, then we can achieve a similar result as those generated badges.
47
+
48
+ ### Implementation
49
+
50
+ star-history has always been a single-page application (SPA) without backend code. In order to offer this feature, we have to add the backend logic to serve the image request. To reuse the SVG generation code, we choose nodejs to create a service returning the live star history chart SVG.
51
+
52
+ To avoid GitHub request rate limit, we create a token pool for polling requests. Those tokens are donated by our community members. If you would like to donate one, please follow this guide: [Donate GitHub Personal Access Token for star-history.com](https://github.com/star-history/star-history/wiki/Donate-your-GitHub-Personal-Access-Token)
53
+
54
+ This is an example link to get the live SVG image for our star-history project: [https://api.star-history.com/svg?repos=star-history/star-history](https://api.star-history.com/svg?repos=star-history/star-history)
55
+ ![star-history-api-svg](/blog/assets/star-history-api-svg.png)
56
+
57
+ ### Step-to-step guide to add the chart to your GitHub README
58
+
59
+ 1. Open [star-history.com](https://star-history.com) and query for a repository;
60
+
61
+ 2. Scroll the page below the action buttons;
62
+ ![embed-chart-with-svg](/blog/assets/embed-chart-with-svg.png)
63
+ 3. Click the `Copy` button;
64
+
65
+ 4. Paste the code into your repository's README;
66
+
67
+ 5. Everything is done. 😎
68
+
69
+ ## Running on [render](http://render.com)
70
+
71
+ The existing star-history frontend is a static site and is running on [render.com](http://render.com/).  As you can see, we have added the API server which is a Web Service type serving the live star history SVG image request.
72
+ ![render-overview](/blog/assets/render-overview.png)
73
+ Here is the render's monitoring view and it's been running fine so far
74
+ ![render-usage](/blog/assets/render-usage.png)
75
+
76
+ ## Conclusion
77
+
78
+ We provide two ways to embed the real-time star history chart into the web pages.
79
+
80
+ - If you want to put an auto-sizeable and interactive chart on your private network, you should try the embedded chart with `<iframe />`.
81
+ - If you want to show a static chart with update-to-date star history data to the public, such as putting it on the GitHub repository README, you should use the image link such as `https://api.star-history.com/svg?repos=star-history/star-history&type=Date`
82
+
83
+ ---
84
+
85
+ Check out examples below of using SVG embed charts in GitHub repository README and organization README.
86
+
87
+ - [https://github.com/star-history/star-history#star-history](https://github.com/star-history/star-history#star-history)
88
+ - [https://github.com/bytebase/bytebase#star-history](https://github.com/bytebase/bytebase#star-history)
89
+ - [https://github.com/bytebase](https://github.com/bytebase)
public/blog/assets/embed-chart-with-iframe.png ADDED

Git LFS Details

  • SHA256: b319819cf5b058f9a844e13140ea366a77f526cab48fa0386b3b1582c167a4f2
  • Pointer size: 131 Bytes
  • Size of remote file: 211 kB
public/blog/assets/embed-chart-with-svg.png ADDED

Git LFS Details

  • SHA256: 69dbba7cd2f3403ccc989a3a169db48cdf4dd553162335baac10f706fa6416cf
  • Pointer size: 131 Bytes
  • Size of remote file: 315 kB
public/blog/assets/github-badges.png ADDED

Git LFS Details

  • SHA256: 2e0ada7bba65ac6f8545850314b205563237a3080b50e31f4ae5eae4ab31c112
  • Pointer size: 132 Bytes
  • Size of remote file: 1.19 MB
public/blog/assets/github-trending-tab/github-home.webp ADDED
public/blog/assets/github-trending-tab/github-trending-tab.webp ADDED
public/blog/assets/github-trending-tab/hn.webp ADDED
public/blog/assets/github-trending-tab/star-history.webp ADDED
public/blog/assets/github-trending-tab/throw.gif ADDED

Git LFS Details

  • SHA256: a671b5a0e4bee4bbb70fc6492957faaa64f38da381ef7c3a3c4d51a111fd0af6
  • Pointer size: 132 Bytes
  • Size of remote file: 1.38 MB
public/blog/assets/how-to-use-github-star-history/add-access-token.webp ADDED
public/blog/assets/how-to-use-github-star-history/align-timeline.webp ADDED
public/blog/assets/how-to-use-github-star-history/book.webp ADDED
public/blog/assets/how-to-use-github-star-history/chrome-extension-working.webp ADDED
public/blog/assets/how-to-use-github-star-history/chrome-extension.webp ADDED
public/blog/assets/how-to-use-github-star-history/classic-form.webp ADDED
public/blog/assets/how-to-use-github-star-history/copy-iframe-readme.webp ADDED
public/blog/assets/how-to-use-github-star-history/edit-gh-access-token.webp ADDED
public/blog/assets/how-to-use-github-star-history/embed.webp ADDED
public/blog/assets/how-to-use-github-star-history/generate-new-token.webp ADDED
public/blog/assets/how-to-use-github-star-history/gh-readme.webp ADDED