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([email protected])
7
+ '@tailwindcss/typography':
8
+ specifier: ^0.5.1
9
+ version: 0.5.2([email protected])
10
+ '@vueuse/head':
11
+ specifier: ^1.0.25
12
+ version: 1.0.25([email protected])
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
40
+ tailwindcss:
41
+ specifier: ^3.0.19
42
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([email protected])
55
+ vue-tsc:
56
+ specifier: ^1.0.0
57
+ version: 1.0.9([email protected])
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/[email protected])([email protected])([email protected])
87
+ '@typescript-eslint/parser':
88
+ specifier: 5.42.0
89
90
+ '@vitejs/plugin-vue':
91
+ specifier: 2.3.4
92
93
+ '@vue/eslint-config-typescript':
94
+ specifier: 11.0.2
95
96
+ autoprefixer:
97
+ specifier: 10.4.13
98
+ version: 10.4.13([email protected])
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([email protected])
105
+ eslint-plugin-prettier:
106
+ specifier: 4.2.1
107
108
+ eslint-plugin-vue:
109
+ specifier: 9.7.0
110
+ version: 9.7.0([email protected])
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/[email protected]:
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/[email protected]:
128
+ resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==}
129
+ engines: {node: '>=6.9.0'}
130
+
131
+ /@babel/[email protected]:
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/[email protected]:
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/[email protected]:
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/[email protected]:
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/[email protected]:
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/[email protected]:
183
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
184
+ engines: {node: '>=12.22'}
185
+ dev: true
186
+
187
+ /@humanwhocodes/[email protected]:
188
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
189
+ dev: true
190
+
191
+ /@nodelib/[email protected]:
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/[email protected]:
199
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
200
+ engines: {node: '>= 8'}
201
+
202
+ /@nodelib/[email protected]:
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
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([email protected])([email protected])
215
+ dev: false
216
+
217
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([email protected])([email protected])
226
+ dev: false
227
+
228
+ /@types/[email protected]:
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/[email protected]:
236
+ resolution: {integrity: sha512-uGC7DBh0TZrU/LY43Fd8Qr+2ja1FKmH07q2FoZFHo1eYl8aj87GhfVoY1saJVJiq24rp1+wpI6BvQJMKgQm8oA==}
237
+ dependencies:
238
+ '@types/d3-selection': 1.4.3
239
+ dev: true
240
+
241
+ /@types/[email protected]:
242
+ resolution: {integrity: sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==}
243
+ dev: true
244
+
245
+ /@types/[email protected]:
246
+ resolution: {integrity: sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==}
247
+ dependencies:
248
+ '@types/d3-time': 2.1.1
249
+ dev: true
250
+
251
+ /@types/[email protected]:
252
+ resolution: {integrity: sha512-GjKQWVZO6Sa96HiKO6R93VBE8DUW+DDkFpIMf9vpY5S78qZTlRRSNUsHr/afDpF7TvLDV7VxrUFOWW7vdIlYkA==}
253
+ dev: true
254
+
255
+ /@types/[email protected]:
256
+ resolution: {integrity: sha512-jYIYxFFA9vrJ8Hd4Se83YI6XF+gzDL1aC5DCsldai4XYYiVNdhtpGbA/GM6iyQ8ayhSp3a148LY34hy7A4TxZA==}
257
+ dependencies:
258
+ '@types/d3-path': 1.0.9
259
+ dev: true
260
+
261
+ /@types/[email protected]:
262
+ resolution: {integrity: sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==}
263
+ dev: true
264
+
265
+ /@types/[email protected]:
266
+ resolution: {integrity: sha512-Yuf4jR5YYMR2DVgwuCiP11s0xuVRyPKmz8vo6HBY3CGdeMj8af93CFZX+T82+VD1+UqHOxTq31lO7MI7lepBtQ==}
267
+ dependencies:
268
+ '@types/filewriter': 0.0.29
269
+ dev: true
270
+
271
+ /@types/[email protected]:
272
+ resolution: {integrity: sha512-BsPXH/irW0ht0Ji6iw/jJaK8Lj3FJemon2gvEqHKpCdDCeemHa+rI3WBGq5z7cDMZgoLjY40oninGxqk+8NzNQ==}
273
+ dev: true
274
+
275
+ /@types/[email protected]:
276
+ resolution: {integrity: sha512-OP6L9VuZNdskgNN3zFQQ54ceYD8OLq5IbqO4VK91ORLfOm7WdT/CiT/pHEBSQEqCInJ2y3O6iCm/zGtPElpgJQ==}
277
+ dev: true
278
+
279
+ /@types/[email protected]:
280
+ resolution: {integrity: sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==}
281
+ dev: true
282
+
283
+ /@types/[email protected]:
284
+ resolution: {integrity: sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==}
285
+ dev: true
286
+
287
+ /@types/[email protected]:
288
+ resolution: {integrity: sha512-eEAhnz21CwvKVW+YvRvcTuFKNU9CV1qH+opcgVK3pIMI6YZzDm6gc8o2vHjldFk6MGKt5pueSB7IOpvpx5Qekw==}
289
+ dev: true
290
+
291
+ /@types/[email protected]:
292
+ resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==}
293
+ dev: true
294
+
295
+ /@types/[email protected]:
296
+ resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==}
297
+ dev: false
298
+
299
+ /@types/[email protected]:
300
+ resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==}
301
+ dev: true
302
+
303
+ /@typescript-eslint/[email protected](@typescript-eslint/[email protected])([email protected])([email protected]):
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([email protected])([email protected])
315
+ '@typescript-eslint/scope-manager': 5.42.0
316
+ '@typescript-eslint/type-utils': 5.42.0([email protected])([email protected])
317
+ '@typescript-eslint/utils': 5.42.0([email protected])([email protected])
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([email protected])
325
+ typescript: 4.6.2
326
+ transitivePeerDependencies:
327
+ - supports-color
328
+ dev: true
329
+
330
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([email protected])
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/[email protected]:
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
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([email protected])
369
+ '@typescript-eslint/utils': 5.42.0([email protected])([email protected])
370
+ debug: 4.3.4
371
+ eslint: 8.26.0
372
+ tsutils: 3.21.0([email protected])
373
+ typescript: 4.6.2
374
+ transitivePeerDependencies:
375
+ - supports-color
376
+ dev: true
377
+
378
+ /@typescript-eslint/[email protected]:
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/[email protected]([email protected]):
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([email protected])
399
+ typescript: 4.6.2
400
+ transitivePeerDependencies:
401
+ - supports-color
402
+ dev: true
403
+
404
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([email protected])
415
+ eslint: 8.26.0
416
+ eslint-scope: 5.1.1
417
+ eslint-utils: 3.0.0([email protected])
418
+ semver: 7.3.7
419
+ transitivePeerDependencies:
420
+ - supports-color
421
+ - typescript
422
+ dev: true
423
+
424
+ /@typescript-eslint/[email protected]:
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/[email protected]:
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/[email protected]:
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/[email protected]:
446
+ resolution: {integrity: sha512-QWy+vKZWVb+XfHl/B/rEoniMGFpDjXiYBkjJZyuf+9By8DzQUscMaTv14neW1ZR6pq56c4B7Tp1N3Lve8SW+rA==}
447
+ dependencies:
448
+ '@unhead/schema': 1.0.21
449
+ dev: false
450
+
451
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
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/[email protected]:
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/[email protected]:
481
+ resolution: {integrity: sha512-fazB/vy5ZEJ3yKx4fabJyGNI3CBkdLkfEIRVu6+1P3VixK0Mn+eqyUIkLBrzGYaeFM3GybhCLCvsVdNz0Fu/CQ==}
482
+ dependencies:
483
+ muggle-string: 0.1.0
484
+ dev: false
485
+
486
+ /@volar/[email protected]:
487
+ resolution: {integrity: sha512-dVziu+ShQUWuMukM6bvK2v2O446/gG6l1XkTh2vfkccw1IzjfbiP1TWQoNo1ipTfZOtu5YJGYAx+o5HNrGXWfQ==}
488
+ dependencies:
489
+ '@volar/language-core': 1.0.9
490
+ dev: false
491
+
492
+ /@volar/[email protected]:
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/[email protected]:
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
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
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
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
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
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
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
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
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
585
+ resolution: {integrity: sha512-79InfO2xHv+WHIrH1bHXQUiQD/wMls9qBk6WVwGCbdwP7/3zINtvqPNMtmSHXsIKjvUAHc8L0ouOj6ZQQRmcXg==}
586
+ dev: false
587
+
588
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/[email protected])([email protected])([email protected])
600
+ '@typescript-eslint/parser': 5.42.0([email protected])([email protected])
601
+ eslint: 8.26.0
602
+ eslint-plugin-vue: 9.7.0([email protected])
603
+ typescript: 4.6.2
604
+ vue-eslint-parser: 9.1.0([email protected])
605
+ transitivePeerDependencies:
606
+ - supports-color
607
+ dev: true
608
+
609
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
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
629
+ resolution: {integrity: sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==}
630
+ dependencies:
631
+ '@vue/shared': 3.2.41
632
+ dev: false
633
+
634
635
+ resolution: {integrity: sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==}
636
+ dependencies:
637
+ '@vue/shared': 3.2.47
638
+
639
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
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
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
662
+ resolution: {integrity: sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw==}
663
+ dev: false
664
+
665
666
+ resolution: {integrity: sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==}
667
+
668
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([email protected])
677
+ vue: 3.2.47
678
+ dev: false
679
+
680
+ /@zhead/[email protected]:
681
+ resolution: {integrity: sha512-hEtK+hUAKS3w1+F++m6EeZ6bWeLDXraqN2nCyRVIP5vvR3bWjXVP9OM9x7Pmn7Hp6T7FKmsG2C8rvouQU2806w==}
682
+ dev: false
683
+
684
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
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
701
+ resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
702
+ engines: {node: '>=0.4.0'}
703
+ dev: false
704
+
705
706
+ resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
707
+ engines: {node: '>=0.4.0'}
708
+ hasBin: true
709
+ dev: false
710
+
711
712
+ resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
713
+ engines: {node: '>=0.4.0'}
714
+ hasBin: true
715
+ dev: true
716
+
717
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
727
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
728
+ engines: {node: '>=8'}
729
+ dev: true
730
+
731
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
739
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
740
+ engines: {node: '>=8'}
741
+ dependencies:
742
+ color-convert: 2.0.1
743
+
744
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
753
+ resolution: {integrity: sha512-e0hDa9H2Z9AwFkk2qDlwhoMYE4eToKarchkQHovNdLTCYMHZHeRjI71crOh+dio4K6u1IcwubQqo79Ga4CyAQA==}
754
+ dev: false
755
+
756
757
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
758
+ dev: true
759
+
760
761
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
762
+ engines: {node: '>=8'}
763
+ dev: true
764
+
765
766
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
767
+ dev: false
768
+
769
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
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
795
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
796
+
797
798
+ resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
799
+ engines: {node: '>=8'}
800
+ dev: false
801
+
802
803
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
804
+ dev: true
805
+
806
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
814
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
815
+ dependencies:
816
+ balanced-match: 1.0.2
817
+ dev: false
818
+
819
820
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
821
+ engines: {node: '>=8'}
822
+ dependencies:
823
+ fill-range: 7.0.1
824
+
825
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([email protected])
834
+
835
836
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
837
+ engines: {node: '>=6'}
838
+
839
840
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
841
+ engines: {node: '>= 6'}
842
+ dev: false
843
+
844
845
+ resolution: {integrity: sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==}
846
+
847
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
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
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
879
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
880
+ dependencies:
881
+ color-name: 1.1.3
882
+ dev: false
883
+
884
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
891
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
892
+ dev: false
893
+
894
895
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
896
+
897
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
905
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
906
+ dev: true
907
+
908
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
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
929
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
930
+ engines: {node: '>=4'}
931
+ hasBin: true
932
+
933
934
+ resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==}
935
+
936
937
+ resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==}
938
+ dependencies:
939
+ internmap: 1.0.1
940
+ dev: false
941
+
942
943
+ resolution: {integrity: sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==}
944
+ dev: false
945
+
946
947
+ resolution: {integrity: sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==}
948
+ dev: false
949
+
950
951
+ resolution: {integrity: sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==}
952
+ dev: false
953
+
954
955
+ resolution: {integrity: sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==}
956
+ dependencies:
957
+ d3-color: 2.0.0
958
+ dev: false
959
+
960
961
+ resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==}
962
+ dev: false
963
+
964
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
975
+ resolution: {integrity: sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg==}
976
+ dev: false
977
+
978
979
+ resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==}
980
+ dependencies:
981
+ d3-path: 1.0.9
982
+ dev: false
983
+
984
985
+ resolution: {integrity: sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==}
986
+ dependencies:
987
+ d3-time: 2.1.1
988
+ dev: false
989
+
990
991
+ resolution: {integrity: sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==}
992
+ dependencies:
993
+ d3-array: 2.12.1
994
+ dev: false
995
+
996
997
+ resolution: {integrity: sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug==}
998
+ dev: false
999
+
1000
1001
+ resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
1002
+ dev: false
1003
+
1004
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
1017
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
1018
+ dev: true
1019
+
1020
1021
+ resolution: {integrity: sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=}
1022
+ dev: false
1023
+
1024
1025
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
1026
+ engines: {node: '>=0.4.0'}
1027
+ dev: false
1028
+
1029
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
1040
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
1041
+ dev: false
1042
+
1043
1044
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
1045
+ engines: {node: '>=8'}
1046
+ dependencies:
1047
+ path-type: 4.0.0
1048
+ dev: true
1049
+
1050
1051
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
1052
+ dev: false
1053
+
1054
1055
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
1056
+ engines: {node: '>=6.0.0'}
1057
+ dependencies:
1058
+ esutils: 2.0.3
1059
+ dev: true
1060
+
1061
1062
+ resolution: {integrity: sha512-x+JnqyluoJv8I0U9gVe+Sk2st8vF0CzMt78SXxuoWCooLLY2k5VerIBdpvG7ql6GKI4dzNnPjmqgDJ76EdaAKw==}
1063
+
1064
1065
+ resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
1066
+ dependencies:
1067
+ is-arrayish: 0.2.1
1068
+ dev: false
1069
+
1070
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
1079
+ resolution: {integrity: sha512-E8Ktwwa6vX8q7QeJmg8yepBYXaee50OdQS3BFtEHKrzbV45H4foMOeEE7uqdjGQZFBap5VAqo7pvjlyA92wznQ==}
1080
+ engines: {node: '>=12'}
1081
+ cpu: [arm64]
1082
+ os: [android]
1083
+ requiresBuild: true
1084
+ optional: true
1085
+
1086
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
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
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
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
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
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
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
1143
+ resolution: {integrity: sha512-JnnmgUBdqLQO9hoNZQqNHFWlNpSX82vzB3rYuCJMhtkuaWQEmQz6Lec1UIxJdC38ifEghNTBsF9bbe8dFilnCw==}
1144
+ engines: {node: '>=12'}
1145
+ cpu: [arm]
1146
+ os: [linux]
1147
+ requiresBuild: true
1148
+ optional: true
1149
+
1150
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
1159
+ resolution: {integrity: sha512-/7dTjDvXMdRKmsSxKXeWyonuGgblnYDn0MI1xDC7J1VQXny8k1qgNp6VmrlsawwnsymSUUiThhkJsI+rx0taNA==}
1160
+ engines: {node: '>=12'}
1161
+ cpu: [ppc64]
1162
+ os: [linux]
1163
+ requiresBuild: true
1164
+ optional: true
1165
+
1166
1167
+ resolution: {integrity: sha512-D+aFiUzOJG13RhrSmZgrcFaF4UUHpqj7XSKrIiCXIj1dkIkFqdrmqMSOtSs78dOtObWiOrFCDDzB24UyeEiNGg==}
1168
+ engines: {node: '>=12'}
1169
+ cpu: [riscv64]
1170
+ os: [linux]
1171
+ requiresBuild: true
1172
+ optional: true
1173
+
1174
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
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
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
1199
+ resolution: {integrity: sha512-/nBVpWIDjYiyMhuqIqbXXsxBc58cBVH9uztAOIfWShStxq9BNBik92oPQPJ57nzWXRNKQUEFWr4Q98utDWz7jg==}
1200
+ engines: {node: '>=12'}
1201
+ cpu: [x64]
1202
+ os: [sunos]
1203
+ requiresBuild: true
1204
+ optional: true
1205
+
1206
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
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
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
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
1258
+ resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
1259
+ engines: {node: '>=6'}
1260
+
1261
1262
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
1263
+ engines: {node: '>=0.8.0'}
1264
+ dev: false
1265
+
1266
1267
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
1268
+ engines: {node: '>=10'}
1269
+ dev: true
1270
+
1271
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
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([email protected])
1293
+ prettier: 2.7.1
1294
+ prettier-linter-helpers: 1.0.0
1295
+ dev: true
1296
+
1297
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([email protected])
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([email protected])
1310
+ xml-name-validator: 4.0.0
1311
+ transitivePeerDependencies:
1312
+ - supports-color
1313
+ dev: true
1314
+
1315
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
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
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
1342
+ resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
1343
+ engines: {node: '>=10'}
1344
+ dev: true
1345
+
1346
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
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([email protected])
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
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([email protected])
1405
+ eslint-visitor-keys: 3.3.0
1406
+ dev: true
1407
+
1408
1409
+ resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
1410
+ engines: {node: '>=0.10'}
1411
+ dependencies:
1412
+ estraverse: 5.3.0
1413
+ dev: true
1414
+
1415
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
1423
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
1424
+ engines: {node: '>=4.0'}
1425
+ dev: true
1426
+
1427
1428
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
1429
+ engines: {node: '>=4.0'}
1430
+ dev: true
1431
+
1432
1433
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
1434
+
1435
1436
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1437
+ engines: {node: '>=0.10.0'}
1438
+ dev: true
1439
+
1440
1441
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
1442
+ dev: true
1443
+
1444
1445
+ resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==}
1446
+ dev: true
1447
+
1448
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
1459
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
1460
+ dev: true
1461
+
1462
1463
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
1464
+ dev: true
1465
+
1466
1467
+ resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
1468
+ dependencies:
1469
+ reusify: 1.0.4
1470
+
1471
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
1479
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
1480
+ engines: {node: '>=8'}
1481
+ dependencies:
1482
+ to-regex-range: 5.0.1
1483
+
1484
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
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
1501
+ resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==}
1502
+ dev: true
1503
+
1504
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
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
1524
+ resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
1525
+
1526
1527
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
1528
+ dev: true
1529
+
1530
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
1538
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
1539
+
1540
1541
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
1542
+ engines: {node: '>= 6'}
1543
+ dependencies:
1544
+ is-glob: 4.0.3
1545
+
1546
1547
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
1548
+ engines: {node: '>=10.13.0'}
1549
+ dependencies:
1550
+ is-glob: 4.0.3
1551
+
1552
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
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
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
1583
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
1584
+ dev: true
1585
+
1586
1587
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
1588
+ engines: {node: '>=4'}
1589
+ dev: false
1590
+
1591
1592
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
1593
+ engines: {node: '>=8'}
1594
+
1595
1596
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
1597
+ engines: {node: '>= 0.4.0'}
1598
+ dependencies:
1599
+ function-bind: 1.1.1
1600
+
1601
1602
+ resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
1603
+ hasBin: true
1604
+ dev: false
1605
+
1606
1607
+ resolution: {integrity: sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg==}
1608
+ dev: false
1609
+
1610
1611
+ resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
1612
+ engines: {node: '>= 4'}
1613
+ dev: true
1614
+
1615
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
1623
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
1624
+ engines: {node: '>=0.8.19'}
1625
+ dev: true
1626
+
1627
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
1635
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
1636
+ dev: true
1637
+
1638
1639
+ resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
1640
+ dev: false
1641
+
1642
1643
+ resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=}
1644
+ dev: false
1645
+
1646
1647
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
1648
+ engines: {node: '>=8'}
1649
+ dependencies:
1650
+ binary-extensions: 2.2.0
1651
+ dev: false
1652
+
1653
1654
+ resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==}
1655
+ dependencies:
1656
+ has: 1.0.3
1657
+
1658
1659
+ resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=}
1660
+ engines: {node: '>=0.10.0'}
1661
+
1662
1663
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1664
+ engines: {node: '>=0.10.0'}
1665
+ dependencies:
1666
+ is-extglob: 2.1.1
1667
+
1668
1669
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1670
+ engines: {node: '>=0.12.0'}
1671
+
1672
1673
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
1674
+ engines: {node: '>=8'}
1675
+ dev: true
1676
+
1677
1678
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1679
+ dev: true
1680
+
1681
1682
+ resolution: {integrity: sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==}
1683
+ dev: true
1684
+
1685
1686
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1687
+ dev: false
1688
+
1689
1690
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
1691
+ hasBin: true
1692
+ dependencies:
1693
+ argparse: 2.0.1
1694
+ dev: true
1695
+
1696
1697
+ resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
1698
+ dev: false
1699
+
1700
1701
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
1702
+ dev: true
1703
+
1704
1705
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
1706
+ dev: true
1707
+
1708
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
1717
+ resolution: {integrity: sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==}
1718
+ engines: {node: '>=10'}
1719
+ dev: false
1720
+
1721
1722
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
1723
+ dev: false
1724
+
1725
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
1733
+ resolution: {integrity: sha1-wCUTUV4wna3dTCTGDP3c9ZdtkRU=}
1734
+ dev: false
1735
+
1736
1737
+ resolution: {integrity: sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=}
1738
+ dev: false
1739
+
1740
1741
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
1742
+
1743
1744
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
1745
+
1746
1747
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
1748
+ engines: {node: '>=10'}
1749
+ dependencies:
1750
+ yallist: 4.0.0
1751
+ dev: true
1752
+
1753
1754
+ resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
1755
+ dependencies:
1756
+ sourcemap-codec: 1.4.8
1757
+
1758
1759
+ resolution: {integrity: sha512-wahonIQ5Jnyatt2fn8KqF/nIqZM8mh3oRu2+l5EANGMhu6RFjiSG52QNE2eWzFMI94HqYSgN184NurgNG6CztA==}
1760
+ engines: {node: '>= 12'}
1761
+ hasBin: true
1762
+ dev: false
1763
+
1764
1765
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1766
+ engines: {node: '>= 8'}
1767
+
1768
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
1776
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
1777
+ engines: {node: '>= 0.6'}
1778
+ dev: false
1779
+
1780
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
1788
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1789
+ dependencies:
1790
+ brace-expansion: 1.1.11
1791
+ dev: true
1792
+
1793
1794
+ resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==}
1795
+ engines: {node: '>=10'}
1796
+ dependencies:
1797
+ brace-expansion: 2.0.1
1798
+ dev: false
1799
+
1800
1801
+ resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==}
1802
+ dev: false
1803
+
1804
1805
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
1806
+ dev: true
1807
+
1808
1809
+ resolution: {integrity: sha512-Tr1knR3d2mKvvWthlk7202rywKbiOm4rVFLsfAaSIhJ6dt9o47W4S+JMtWhd/PW9Wrdew2/S2fSvhz3E2gkfEg==}
1810
+ dev: false
1811
+
1812
1813
+ resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
1814
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1815
+ hasBin: true
1816
+
1817
1818
+ resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
1819
+ dev: true
1820
+
1821
1822
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
1823
+ dev: true
1824
+
1825
1826
+ resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
1827
+
1828
1829
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
1830
+ engines: {node: '>=0.10.0'}
1831
+ dev: false
1832
+
1833
1834
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
1835
+ engines: {node: '>=0.10.0'}
1836
+
1837
1838
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
1839
+ dependencies:
1840
+ boolbase: 1.0.0
1841
+ dev: true
1842
+
1843
1844
+ resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
1845
+ engines: {node: '>= 6'}
1846
+ dev: false
1847
+
1848
1849
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1850
+ dependencies:
1851
+ wrappy: 1.0.2
1852
+ dev: true
1853
+
1854
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
1867
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1868
+ engines: {node: '>=10'}
1869
+ dependencies:
1870
+ yocto-queue: 0.1.0
1871
+ dev: true
1872
+
1873
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
1881
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1882
+ engines: {node: '>=6'}
1883
+ dependencies:
1884
+ callsites: 3.1.0
1885
+
1886
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
1897
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1898
+ engines: {node: '>=8'}
1899
+ dev: true
1900
+
1901
1902
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
1903
+ engines: {node: '>=0.10.0'}
1904
+ dev: true
1905
+
1906
1907
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1908
+ engines: {node: '>=8'}
1909
+ dev: true
1910
+
1911
1912
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
1913
+
1914
1915
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
1916
+ engines: {node: '>=8'}
1917
+
1918
1919
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
1920
+
1921
1922
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1923
+ engines: {node: '>=8.6'}
1924
+
1925
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([email protected])
1941
+ dev: false
1942
+
1943
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
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
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
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
1984
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
1985
+
1986
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
1995
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
1996
+ engines: {node: '>= 0.8.0'}
1997
+ dev: true
1998
+
1999
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
2007
+ resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
2008
+ engines: {node: '>=10.13.0'}
2009
+ hasBin: true
2010
+ dev: true
2011
+
2012
2013
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
2014
+ dev: false
2015
+
2016
2017
+ resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
2018
+ engines: {node: '>=6'}
2019
+ dev: true
2020
+
2021
2022
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
2023
+
2024
2025
+ resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
2026
+ engines: {node: '>=10'}
2027
+ dev: false
2028
+
2029
2030
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
2031
+ engines: {node: '>=8.10.0'}
2032
+ dependencies:
2033
+ picomatch: 2.3.1
2034
+ dev: false
2035
+
2036
2037
+ resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
2038
+ engines: {node: '>=8'}
2039
+ dev: true
2040
+
2041
2042
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
2043
+ engines: {node: '>=4'}
2044
+
2045
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
2054
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
2055
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
2056
+
2057
2058
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
2059
+ hasBin: true
2060
+ dependencies:
2061
+ glob: 7.2.0
2062
+ dev: true
2063
+
2064
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
2072
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
2073
+ dependencies:
2074
+ queue-microtask: 1.2.3
2075
+
2076
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
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
2092
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
2093
+ engines: {node: '>=8'}
2094
+ dev: true
2095
+
2096
2097
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
2098
+ engines: {node: '>=8'}
2099
+ dev: true
2100
+
2101
2102
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
2103
+ engines: {node: '>=0.10.0'}
2104
+
2105
2106
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
2107
+ engines: {node: '>=0.10.0'}
2108
+
2109
2110
+ resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
2111
+
2112
2113
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
2114
+ engines: {node: '>=8'}
2115
+ dependencies:
2116
+ ansi-regex: 5.0.1
2117
+ dev: true
2118
+
2119
2120
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
2121
+ engines: {node: '>=8'}
2122
+ dev: true
2123
+
2124
2125
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
2126
+ engines: {node: '>=4'}
2127
+ dependencies:
2128
+ has-flag: 3.0.0
2129
+ dev: false
2130
+
2131
2132
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
2133
+ engines: {node: '>=8'}
2134
+ dependencies:
2135
+ has-flag: 4.0.0
2136
+
2137
2138
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
2139
+ engines: {node: '>= 0.4'}
2140
+
2141
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([email protected])
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([email protected])
2165
+ postcss-load-config: 3.1.3
2166
+ postcss-nested: 5.0.6([email protected])
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
2176
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
2177
+ dev: true
2178
+
2179
2180
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
2181
+ engines: {node: '>=4'}
2182
+
2183
2184
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
2185
+ engines: {node: '>=8.0'}
2186
+ dependencies:
2187
+ is-number: 7.0.0
2188
+
2189
2190
+ resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
2191
+ dev: true
2192
+
2193
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
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
2211
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
2212
+ engines: {node: '>=10'}
2213
+ dev: true
2214
+
2215
2216
+ resolution: {integrity: sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==}
2217
+ engines: {node: '>=4.2.0'}
2218
+ hasBin: true
2219
+
2220
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
2231
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
2232
+ dependencies:
2233
+ punycode: 2.1.1
2234
+ dev: true
2235
+
2236
2237
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
2238
+
2239
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
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
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
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
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
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
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([email protected])
2329
+ '@vue/shared': 3.2.47
2330
+
2331
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
2340
+ resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
2341
+ engines: {node: '>=0.10.0'}
2342
+ dev: true
2343
+
2344
2345
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
2346
+ dev: true
2347
+
2348
2349
+ resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
2350
+ engines: {node: '>=12'}
2351
+ dev: true
2352
+
2353
2354
+ resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
2355
+ engines: {node: '>=0.4'}
2356
+ dev: false
2357
+
2358
2359
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
2360
+ dev: true
2361
+
2362
2363
+ resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
2364
+ engines: {node: '>= 6'}
2365
+ dev: false
2366
+
2367
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