Initial commit

This commit is contained in:
Yuri Sizov
2021-08-22 00:07:47 +03:00
commit 0b3bd1e597
18 changed files with 2456 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
node_modules/
out/
.idea/

41
build/posthtml-include.js Normal file
View File

@@ -0,0 +1,41 @@
import fs from "fs";
import path from "path";
import parser from "posthtml-parser";
export default function(options) {
options = options || {};
options.root = options.root || './';
options.encoding = options.encoding || 'utf-8';
return function posthtmlInclude(tree) {
tree.match({ tag: 'include' }, function(node) {
if (!node.attrs.src) {
return {
tag: false,
content: null
};
}
const src = path.resolve(options.root, node.attrs.src);
const source = fs.readFileSync(src, options.encoding);
const subtree = parser(source);
subtree.match = tree.match;
const content = source.indexOf('include') !== -1? posthtmlInclude(subtree): subtree;
if (tree.messages) {
tree.messages.push({
type: "dependency",
file: src
});
}
return {
tag: false,
content: content
};
});
return tree;
};
};

View File

@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Nothing to see here</title>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,31 @@
import { promises as fs } from 'fs';
import posthtml from 'posthtml';
import include from './posthtml-include';
import { green } from 'colorette';
export default function(options = {}) {
return {
name: 'posthtml',
buildEnd: async () => {
if (!options.src || !options.dest) {
return;
}
const html = await fs.readFile(options.src, { encoding: 'utf-8' });
const plugins = [
include({
root: './src'
})
];
const result = await posthtml(plugins).process(html);
try {
await fs.unlink(options.dest);
} catch (exc) { }
await fs.writeFile(options.dest, result.html, { encoding: 'utf-8' });
console.log(green(`written html template ${options.dest}`))
}
};
}

109
compose.js Normal file
View File

@@ -0,0 +1,109 @@
const fs = require('fs').promises;
const path = require('path');
async function fetchPulls() {
try {
const json = await fs.readFile("pulls.raw.json", {encoding: "utf-8", flag: "r"});
return JSON.parse(json);
} catch (err) {
console.error("Error fetching the pull requests: " + err);
return {};
}
}
async function processPulls() {
const pullsRaw = await fetchPulls();
let teams = {};
let pulls = [];
pullsRaw.forEach((item) => {
// Compile basic information about a PR.
let pr = {
"id": item.id,
"public_id": item.number,
"url": item.html_url,
"diff_url": item.diff_url,
"patch_url": item.patch_url,
"title": item.title,
"state": item.state,
"is_draft": item.draft,
"authored_by": {
"id": item.user.id,
"user": item.user.login,
"avater": item.user.avatar_url,
"url": item.user.html_url,
},
"created_at": item.created_at,
"updated_at": item.updated_at,
"body": item.body,
"target_branch": item.base.ref,
"labels": [],
"milestone": null,
"teams": [],
};
// Add the milestone, if available.
if (item.milestone) {
pr.milestone = {
"id": item.milestone.id,
"title": item.milestone.title,
"url": item.milestone.html_url,
};
}
// Add labels, if available.
item.labels.forEach((labelItem) => {
pr.labels.push({
"id": labelItem.id,
"name": labelItem.name,
"color": "#" + labelItem.color
});
});
pr.labels.sort((a, b) => {
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
return 0;
});
// Add teams, if available.
item.requested_teams.forEach((teamItem) => {
let team = {
"id": teamItem.id,
"name": teamItem.name,
"avatar": `https://avatars.githubusercontent.com/t/${teamItem.id}?s=40&v=4`,
"slug": teamItem.slug,
"full_name": teamItem.name,
"full_slug": teamItem.slug,
};
// Include parent data into full name and slug.
if (teamItem.parent) {
team.full_name = `${teamItem.parent.name}/${team.name}`;
team.full_slug = `${teamItem.parent.slug}/${team.slug}`;
}
// Store the team if it hasn't been stored before.
if (typeof teams[team.id] == "undefined") {
teams[team.id] = team;
}
// Reference the team.
pr.teams.push(team.id);
});
pulls.push(pr);
});
const output = {
"generated_at": Date.now(),
"teams": teams,
"pulls": pulls,
};
fs.writeFile("out/data.json", JSON.stringify(output), { encoding: "utf-8" });
}
processPulls();

941
package-lock.json generated Normal file
View File

@@ -0,0 +1,941 @@
{
"name": "godot-team-reports",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
"integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/core": {
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz",
"integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==",
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.6.4",
"@babel/helpers": "^7.6.2",
"@babel/parser": "^7.6.4",
"@babel/template": "^7.6.0",
"@babel/traverse": "^7.6.3",
"@babel/types": "^7.6.3",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
"lodash": "^4.17.13",
"resolve": "^1.3.2",
"semver": "^5.4.1",
"source-map": "^0.5.0"
}
},
"@babel/generator": {
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz",
"integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==",
"requires": {
"@babel/types": "^7.6.3",
"jsesc": "^2.5.1",
"lodash": "^4.17.13",
"source-map": "^0.5.0"
}
},
"@babel/helper-create-class-features-plugin": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz",
"integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==",
"requires": {
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-member-expression-to-functions": "^7.5.5",
"@babel/helper-optimise-call-expression": "^7.0.0",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-replace-supers": "^7.5.5",
"@babel/helper-split-export-declaration": "^7.4.4"
}
},
"@babel/helper-function-name": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
"integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
"requires": {
"@babel/helper-get-function-arity": "^7.0.0",
"@babel/template": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"@babel/helper-get-function-arity": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
"integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-member-expression-to-functions": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz",
"integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==",
"requires": {
"@babel/types": "^7.5.5"
}
},
"@babel/helper-module-imports": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz",
"integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==",
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-optimise-call-expression": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz",
"integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==",
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-plugin-utils": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
"integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA=="
},
"@babel/helper-replace-supers": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz",
"integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==",
"requires": {
"@babel/helper-member-expression-to-functions": "^7.5.5",
"@babel/helper-optimise-call-expression": "^7.0.0",
"@babel/traverse": "^7.5.5",
"@babel/types": "^7.5.5"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"requires": {
"@babel/types": "^7.4.4"
}
},
"@babel/helpers": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz",
"integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==",
"requires": {
"@babel/template": "^7.6.0",
"@babel/traverse": "^7.6.2",
"@babel/types": "^7.6.0"
}
},
"@babel/highlight": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
"integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@babel/parser": {
"version": "7.6.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz",
"integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A=="
},
"@babel/plugin-proposal-class-properties": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz",
"integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==",
"requires": {
"@babel/helper-create-class-features-plugin": "^7.5.5",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-proposal-decorators": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.6.0.tgz",
"integrity": "sha512-ZSyYw9trQI50sES6YxREXKu+4b7MAg6Qx2cvyDDYjP2Hpzd3FleOUwC9cqn1+za8d0A2ZU8SHujxFao956efUg==",
"requires": {
"@babel/helper-create-class-features-plugin": "^7.6.0",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-decorators": "^7.2.0"
}
},
"@babel/plugin-syntax-decorators": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz",
"integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==",
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/template": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz",
"integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==",
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.6.0",
"@babel/types": "^7.6.0"
}
},
"@babel/traverse": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz",
"integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==",
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.6.3",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
"@babel/parser": "^7.6.3",
"@babel/types": "^7.6.3",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.13"
}
},
"@babel/types": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz",
"integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==",
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.13",
"to-fast-properties": "^2.0.0"
}
},
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
"requires": {
"@nodelib/fs.stat": "2.0.3",
"run-parallel": "^1.1.9"
}
},
"@nodelib/fs.stat": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA=="
},
"@nodelib/fs.walk": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
"requires": {
"@nodelib/fs.scandir": "2.1.3",
"fastq": "^1.6.0"
}
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
},
"@types/fs-extra": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.0.0.tgz",
"integrity": "sha512-bCtL5v9zdbQW86yexOlXWTEGvLNqWxMFyi7gQA7Gcthbezr2cPSOb8SkESVKA937QD5cIwOFLDFt0MQoXOEr9Q==",
"requires": {
"@types/node": "*"
}
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
"requires": {
"@types/events": "*",
"@types/minimatch": "*",
"@types/node": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
},
"@types/node": {
"version": "12.11.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.1.tgz",
"integrity": "sha512-TJtwsqZ39pqcljJpajeoofYRfeZ7/I/OMUQ5pR4q5wOKf2ocrUvBAZUMhWsOvKx3dVc/aaV5GluBivt0sWqA5A=="
},
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
"integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==",
"requires": {
"@types/node": "*"
}
},
"acorn": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ=="
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"requires": {
"fill-range": "^7.0.1"
}
},
"builtin-modules": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
"integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw=="
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"colorette": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz",
"integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg=="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"convert-source-map": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
"integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
"requires": {
"safe-buffer": "~5.1.1"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
"requires": {
"path-type": "^4.0.0"
}
},
"dom-serializer": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz",
"integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==",
"requires": {
"domelementtype": "^2.0.1",
"entities": "^2.0.0"
},
"dependencies": {
"domelementtype": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
},
"entities": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
}
}
},
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
},
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
"requires": {
"domelementtype": "1"
}
},
"dompurify": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.0.7.tgz",
"integrity": "sha512-S3O0lk6rFJtO01ZTzMollCOGg+WAtCwS3U5E2WSDY/x/sy7q70RjEC4Dmrih5/UqzLLB9XoKJ8KqwBxaNvBu4A=="
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
}
},
"entities": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"fast-glob": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz",
"integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==",
"requires": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.0",
"merge2": "^1.3.0",
"micromatch": "^4.0.2"
}
},
"fastq": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
"integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
"requires": {
"reusify": "^1.0.0"
}
},
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"requires": {
"to-regex-range": "^5.0.1"
}
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
"requires": {
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "11.12.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
"globby": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
"integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
"requires": {
"@types/glob": "^7.1.1",
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.0.3",
"glob": "^7.1.3",
"ignore": "^5.1.1",
"merge2": "^1.2.3",
"slash": "^3.0.0"
}
},
"graceful-fs": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
"integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q=="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"htmlparser2": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
"requires": {
"domelementtype": "^1.3.1",
"domhandler": "^2.3.0",
"domutils": "^1.5.1",
"entities": "^1.1.1",
"inherits": "^2.0.1",
"readable-stream": "^3.1.1"
}
},
"ignore": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
"integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-module": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
"integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE="
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
"is-plain-object": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
"integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
"requires": {
"isobject": "^4.0.0"
}
},
"is-reference": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz",
"integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==",
"requires": {
"@types/estree": "0.0.39"
}
},
"isobject": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
"integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
},
"json5": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz",
"integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==",
"requires": {
"minimist": "^1.2.0"
}
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"requires": {
"graceful-fs": "^4.1.6"
}
},
"lit-element": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.2.1.tgz",
"integrity": "sha512-ipDcgQ1EpW6Va2Z6dWm79jYdimVepO5GL0eYkZrFvdr0OD/1N260Q9DH+K5HXHFrRoC7dOg+ZpED2XE0TgGdXw==",
"requires": {
"lit-html": "^1.0.0"
}
},
"lit-html": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.1.2.tgz",
"integrity": "sha512-FFlUMKHKi+qG1x1iHNZ1hrtc/zHmfYTyrSvs3/wBTvaNtpZjOZGWzU7efGYVpgp6KvWeKF6ql9/KsCq6Z/mEDA=="
},
"lodash": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
},
"magic-string": {
"version": "0.25.4",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.4.tgz",
"integrity": "sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw==",
"requires": {
"sourcemap-codec": "^1.4.4"
}
},
"marked": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
"integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg=="
},
"merge2": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
"integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw=="
},
"micromatch": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
"requires": {
"braces": "^3.0.1",
"picomatch": "^2.0.5"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
},
"path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
},
"picomatch": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz",
"integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA=="
},
"posthtml": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.12.0.tgz",
"integrity": "sha512-aNUEP/SfKUXAt+ghG51LC5MmafChBZeslVe/SSdfKIgLGUVRE68mrMF4V8XbH07ZifM91tCSuxY3eHIFLlecQw==",
"requires": {
"posthtml-parser": "^0.4.1",
"posthtml-render": "^1.1.5"
}
},
"posthtml-parser": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.4.1.tgz",
"integrity": "sha512-h7vXIQ21Ikz2w5wPClPakNP6mJeJCK6BT0GpqnQrNNABdR7/TchNlFyryL1Bz6Ww53YWCKkr6tdZuHlxY1AVdQ==",
"requires": {
"htmlparser2": "^3.9.2",
"object-assign": "^4.1.1"
}
},
"posthtml-render": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz",
"integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w=="
},
"readable-stream": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
"integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"resolve": {
"version": "1.12.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
"integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
"requires": {
"path-parse": "^1.0.6"
}
},
"reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
},
"rollup": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.24.0.tgz",
"integrity": "sha512-PiFETY/rPwodQ8TTC52Nz2DSCYUATznGh/ChnxActCr8rV5FIk3afBUb3uxNritQW/Jpbdn3kq1Rwh1HHYMwdQ==",
"requires": {
"@types/estree": "*",
"@types/node": "*",
"acorn": "^7.1.0"
}
},
"rollup-plugin-babel": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.3.tgz",
"integrity": "sha512-tKzWOCmIJD/6aKNz0H1GMM+lW1q9KyFubbWzGiOG540zxPPifnEAHTZwjo0g991Y+DyOZcLqBgqOdqazYE5fkw==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-plugin-commonjs": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
"integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==",
"requires": {
"estree-walker": "^0.6.1",
"is-reference": "^1.1.2",
"magic-string": "^0.25.2",
"resolve": "^1.11.0",
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-plugin-copy": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.1.0.tgz",
"integrity": "sha512-oVw3ljRV5jv7Yw/6eCEHntVs9Mc+NFglc0iU0J8ei76gldYmtBQ0M/j6WAkZUFVRSrhgfCrEakUllnN87V2f4w==",
"requires": {
"@types/fs-extra": "^8.0.0",
"colorette": "^1.1.0",
"fs-extra": "^8.1.0",
"globby": "10.0.1",
"is-plain-object": "^3.0.0"
}
},
"rollup-plugin-includepaths": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/rollup-plugin-includepaths/-/rollup-plugin-includepaths-0.2.3.tgz",
"integrity": "sha512-4QbSIZPDT+FL4SViEVCRi4cGCA64zQJu7u5qmCkO3ecHy+l9EQBsue15KfCpddfb6Br0q47V/v2+E2YUiqts9g=="
},
"rollup-plugin-node-resolve": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz",
"integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==",
"requires": {
"@types/resolve": "0.0.8",
"builtin-modules": "^3.1.0",
"is-module": "^1.0.0",
"resolve": "^1.11.1",
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-pluginutils": {
"version": "2.8.2",
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
"integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
"requires": {
"estree-walker": "^0.6.1"
}
},
"run-parallel": {
"version": "1.1.9",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
"integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q=="
},
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
},
"sourcemap-codec": {
"version": "1.4.6",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz",
"integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg=="
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
},
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"requires": {
"is-number": "^7.0.0"
}
},
"universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}

26
package.json Normal file
View File

@@ -0,0 +1,26 @@
{
"name": "godot-team-reports",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "./node_modules/.bin/rollup -c",
"compose": "node ./compose.js"
},
"author": "Yuri Sizov <yuris@humnom.net>",
"private": true,
"dependencies": {
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.6.0",
"dompurify": "^2.0.7",
"lit-element": "^2.2.1",
"marked": "^0.7.0",
"posthtml": "^0.12.0",
"rollup": "^1.24.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-copy": "^3.1.0",
"rollup-plugin-includepaths": "^0.2.3",
"rollup-plugin-node-resolve": "^5.2.0"
}
}

116
rollup.config.js Normal file
View File

@@ -0,0 +1,116 @@
import { promises as fs } from 'fs';
import path from 'path';
import nodeResolve from 'rollup-plugin-node-resolve';
import includePaths from 'rollup-plugin-includepaths'
import commonjs from 'rollup-plugin-commonjs';
import copy from 'rollup-plugin-copy';
import posthtmlTemplate from './build/rollup-posthtml-template';
import babel from 'rollup-plugin-babel';
const INPUT_ROOT = 'src';
const INPUT_PATHS_ROOT = path.join(INPUT_ROOT, 'paths');
const INPUT_SHARED_ROOT = path.join(INPUT_ROOT, 'shared');
const INPUT_STATIC_ROOT = path.join(INPUT_ROOT, 'static');
const ENTRY_FILE_NAME = 'entry.js';
const TEMPLATE_FILE_NAME = 'template.html';
const GLOBAL_FILE_NAME = 'global.js';
const OUTPUT_ROOT = 'out';
const OUTPUT_STYLES = path.join(OUTPUT_ROOT, 'styles');
const OUTPUT_STYLES_SHARED = path.join(OUTPUT_STYLES, 'shared');
const OUTPUT_SCRIPTS = path.join(OUTPUT_ROOT, 'scripts');
const OUTPUT_SCRIPTS_SHARED = path.join(OUTPUT_SCRIPTS, 'shared');
const generateConfig = async () => {
let configs = [];
getGlobalConfig(configs);
await getPathsConfigs(configs);
return configs;
};
const getGlobalConfig = (configs) => {
const globalScriptPath = path.join(INPUT_SHARED_ROOT, 'scripts', GLOBAL_FILE_NAME);
const outputPath = path.join(OUTPUT_SCRIPTS_SHARED, GLOBAL_FILE_NAME);
const sharedStylesGlob = path.join(INPUT_SHARED_ROOT, 'styles/**/*.css').replace(/\\/g, '/'); // Windows path not supported by copy plugin
const staticGlob = path.join(INPUT_STATIC_ROOT, '/**/*.*').replace(/\\/g, '/'); // Windows path not supported by copy plugin
configs.push({
input: globalScriptPath,
output: {
name: 'global',
file: outputPath,
format: 'iife'
},
plugins: [
nodeResolve(),
copy({
targets: [
{ src: sharedStylesGlob, dest: OUTPUT_STYLES_SHARED },
{ src: staticGlob, dest: OUTPUT_ROOT },
],
verbose: true
})
]
})
};
const getPathsConfigs = async (configs) => {
try {
// Collect paths to process
const paths = await fs.readdir(INPUT_PATHS_ROOT);
for (const itemPath of paths) {
const itemRoot = path.join(INPUT_PATHS_ROOT, itemPath);
const itemFiles = await fs.readdir(itemRoot);
if (itemFiles.indexOf(ENTRY_FILE_NAME) < 0) {
throw Error(`Missing entry script for "${itemPath}" path`);
}
if (itemFiles.indexOf(TEMPLATE_FILE_NAME) < 0) {
throw Error(`Missing HTML template for "${itemPath}" path`);
}
const entryPath = path.join(itemRoot, ENTRY_FILE_NAME);
const templatePath = path.join(itemRoot, TEMPLATE_FILE_NAME).replace(/\\/g, '/'); // Windows path not supported by copy plugin
const bundlePath = path.join(OUTPUT_ROOT, 'scripts', `${itemPath}.js`);
const htmlPath = path.join(OUTPUT_ROOT, `${itemPath}.html`);
configs.push({
input: entryPath,
output: {
name: itemPath,
file: bundlePath,
format: 'iife'
},
plugins: [
babel({
exclude: 'node_modules/**',
plugins: [
[ '@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true } ],
'@babel/plugin-proposal-class-properties'
]
}),
includePaths({
paths: [ './' ]
}),
nodeResolve(),
commonjs({
sourceMap: false
}),
posthtmlTemplate({
src: templatePath,
dest: htmlPath
})
]
})
}
} catch (exc) {
console.error(exc);
}
};
export default generateConfig();

259
src/paths/index/entry.js Normal file
View File

@@ -0,0 +1,259 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
import PageContent from 'src/shared/components/PageContent';
import TeamTab from "src/shared/components/TeamTab";
import PullRequestItem from "src/shared/components/PullRequestItem";
@customElement('entry-component')
export default class EntryComponent extends LitElement {
static get styles() {
return css`
/** Colors and variables **/
:host {
--teams-border-color: #515c6c;
--pulls-background-color: #191d23;
--pulls-toolbar-color: #222c3d;
}
@media (prefers-color-scheme: dark) {
:host {
--teams-border-color: #515c6c;
--pulls-background-color: #191d23;
--pulls-toolbar-color: #222c3d;
}
}
/** Component styling **/
:host {
}
:host p {
line-height: 22px;
}
:host .teams {
display: flex;
padding: 24px 0;
}
:host .team-tabs {
border-right: 2px solid var(--teams-border-color);
width: 240px;
}
:host .team-tabs h4 {
margin: 0 0 12px 0;
}
:host .team-pulls {
background-color: var(--pulls-background-color);
border-radius: 0 4px 4px 0;
flex-grow: 1;
padding: 8px 12px;
max-width: 760px;
}
:host .team-pulls-toolbar {
background: var(--pulls-toolbar-color);
border-radius: 4px;
display: flex;
flex-direction: row;
justify-content: space-between;
font-size: 14px;
padding: 10px 14px;
margin-bottom: 6px;
}
:host .pulls-sort-action {
color: var(--link-font-color);
cursor: pointer;
}
:host .pulls-sort-action:hover {
color: var(--link-font-color-hover);
}
:host .pulls-sort-action--active,
:host .pulls-sort-action--active:hover {
color: var(--link-font-color-inactive);
cursor: default;
}
`;
}
@property({ type: Date }) generated_at = null;
@property({ type: Object }) teams = {};
@property({ type: Array }) pulls = [];
constructor() {
super();
this._entryRequested = false;
this._selectedTeam = -1;
this._sortBy = "age";
this._requestData();
}
performUpdate() {
this._requestData();
super.performUpdate();
}
async _requestData() {
if (this._entryRequested) {
return;
}
this._entryRequested = true;
const data = await greports.api.getData();
if (data) {
this.generated_at = data.generated_at;
this.teams = data.teams;
this.pulls = data.pulls;
const teams = Object.values(this.teams);
teams.sort((a, b) => {
if (a.full_name > b.full_name) return 1;
if (a.full_name < b.full_name) return -1;
return 0;
});
if (teams.length) {
this._selectedTeam = teams.length ? teams[0].id : -1;
}
} else {
this.generated_at = null;
this.teams = {};
this.pulls = [];
this._selectedTeam = -1;
}
}
onTabClicked(tabId, event) {
this._selectedTeam = tabId;
this.requestUpdate();
}
onSortClicked(sortOrder, event) {
this._sortBy = sortOrder;
this.requestUpdate();
}
render(){
let teams = Object.values(this.teams);
teams.sort((a, b) => {
if (a.full_name > b.full_name) return 1;
if (a.full_name < b.full_name) return -1;
return 0;
});
let pulls = [];
if (this._selectedTeam >= 0) {
this.pulls.forEach((pull) => {
if (pull.teams.includes(this._selectedTeam)) {
pulls.push(pull);
}
});
}
pulls.sort((a, b) => {
if (this._sortBy === "stale") {
if (a.updated_at > b.updated_at) return 1;
if (a.updated_at < b.updated_at) return -1;
return 0;
} else { // "age" is default.
if (a.created_at > b.created_at) return 1;
if (a.created_at < b.created_at) return -1;
return 0;
}
});
return html`
<page-content>
<h1>
Godot Team Reports
</h1>
<p>
This page lists all open pull-requests (PRs) assigned to every core maintenance team.
<br/>
Contributors are encouraged to collaborate and clear the backlog by giving these PRs a proper look
and either accepting or rejecting them.
<br/>
Positively reviewed PRs are open to be merged by responsible maintainers.
</p>
<div class="teams">
<div class="team-tabs">
<h4>Teams:</h4>
${teams.map((item) => {
return html`
<gr-team-tab
.id="${item.id}"
.name="${item.name}"
.avatar="${item.avatar}"
?active="${this._selectedTeam === item.id}"
@click="${this.onTabClicked.bind(this, item.id)}"
/>
`;
})}
</div>
<div class="team-pulls">
<div class="team-pulls-toolbar">
<span>
<span>PRs to review: </span>
<strong>${pulls.length}</strong>
</span>
<span class="pulls-sort">
<span>Sort by: </span>
<span
class="pulls-sort-action ${(this._sortBy === "age" ? "pulls-sort-action--active" : "")}"
title="Show older PRs first"
@click="${this.onSortClicked.bind(this, "age")}"
>
Age
</span> |
<span
class="pulls-sort-action ${(this._sortBy === "stale" ? "pulls-sort-action--active" : "")}"
title="Show least recently updated PRs first"
@click="${this.onSortClicked.bind(this, "stale")}"
>
Stale
</span>
</span>
</div>
${pulls.map((item) => {
let other_teams = [];
item.teams.forEach((teamId) => {
if (teamId !== this._selectedTeam) {
other_teams.push(
this.teams[teamId].name
);
}
});
return html`
<gr-pull-request
.id="${item.public_id}"
.title="${item.title}"
.url="${item.url}"
?draft="${item.is_draft}"
.labels="${item.labels}"
.milestone="${item.milestone}"
.branch="${item.target_branch}"
.created_at="${item.created_at}"
.updated_at="${item.updated_at}"
.diff_url="${item.diff_url}"
.patch_url="${item.patch_url}"
.teams="${other_teams}"
/>
`;
})}
</div>
</div>
</page-content>
`;
}
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<include src="shared/partials/head_content.html"></include>
<title>Godot Team Reports</title>
<meta name="description" content="Godot engine reports for maintainer teams">
<meta name="keywords" content="godot, godot engine, gamedev, project management">
<script src="scripts/index.js"></script>
</head>
<body>
<entry-component></entry-component>
<include src="shared/partials/body_content.html"></include>
</body>
</html>

View File

@@ -0,0 +1,21 @@
import { LitElement, html, css, customElement } from 'lit-element';
@customElement('page-content')
export default class PageContent extends LitElement {
static get styles() {
return css`
:host {
display: block;
margin: 0 auto;
padding: 0 12px;
max-width: 1024px;
}
`;
}
render(){
return html`
<slot></slot>
`;
}
}

View File

@@ -0,0 +1,339 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
@customElement('gr-pull-request')
export default class PullRequestItem extends LitElement {
static get styles() {
return css`
/** Colors and variables **/
:host {
--pr-border-color: #0d1117;
--draft-font-color: #e0c537;
--draft-background-color: #1e313c;
--stats-background-color: #0f1316;
--meta-font-color: #929da0;
--review-team-color: #8491ab;
--stat-temp0-color: #000000;
--stat-temp1-color: #000000;
--stat-temp2-color: #000000;
--stat-temp3-color: #000000;
--stat-temp4-color: #000000;
--stat-temp5-color: #000000;
--stat-temp6-color: #000000;
--stat-temp7-color: #000000;
--stat-temp8-color: #000000;
--stat-temp9-color: #000000;
}
@media (prefers-color-scheme: dark) {
:host {
--pr-border-color: #0d1117;
--draft-font-color: #e0c537;
--draft-background-color: #1e313c;
--stats-background-color: #0f1316;
--meta-font-color: #929da0;
--review-team-color: #8491ab;
--stat-temp0-color: #ffffff;
--stat-temp1-color: #f0ed7e;
--stat-temp2-color: #f5d94a;
--stat-temp3-color: #f8b71e;
--stat-temp4-color: #f38c06;
--stat-temp5-color: #f06009;
--stat-temp6-color: #e33b07;
--stat-temp7-color: #e6240e;
--stat-temp8-color: #b31605;
--stat-temp9-color: #d3001c;
}
}
/** Component styling **/
:host {
border-bottom: 3px solid var(--pr-border-color);
display: block;
padding: 14px 12px 20px 12px;
}
:host a {
color: var(--link-font-color);
text-decoration: none;
}
:host a:hover {
color: var(--link-font-color-hover);
}
:host .pr-title {
display: block;
font-size: 20px;
margin-top: 6px;
margin-bottom: 12px;
}
:host .pr-title > span:nth-of-type(2) {
color: var(--g-font-color);
}
:host .pr-title-draft {
background-color: var(--draft-background-color);
border-radius: 6px 6px;
color: var(--draft-font-color);
font-size: 16px;
padding: 1px 6px;
vertical-align: super;
}
:host .pr-meta {
color: var(--meta-font-color);
display: flex;
flex-direction: row;
justify-content: space-between;
font-size: 13px;
}
:host .pr-labels {
display: flex;
flex-flow: column wrap;
padding: 4px 0;
max-height: 60px;
}
:host .pr-label {
padding-right: 8px;
}
:host .pr-label-dot {
border-radius: 4px;
display: inline-block;
width: 8px;
height: 8px;
}
:host .pr-label-name {
}
:host .pr-time {
}
:host .pr-time-value {
border-bottom: 1px dashed var(--g-font-color);
cursor: help;
}
:host .pr-stats {
background-color: var(--stats-background-color);
border-radius: 4px;
display: flex;
justify-content: space-around;
padding: 10px 6px;
margin-top: 12px;
}
:host .pr-stat + .pr-stat {
margin-left: 12px;
}
:host .pr-stat--temp0 {
color: var(--stat-temp0-color);
}
:host .pr-stat--temp1 {
color: var(--stat-temp1-color);
}
:host .pr-stat--temp2 {
color: var(--stat-temp2-color);
}
:host .pr-stat--temp3 {
color: var(--stat-temp3-color);
}
:host .pr-stat--temp4 {
color: var(--stat-temp4-color);
}
:host .pr-stat--temp5 {
color: var(--stat-temp5-color);
}
:host .pr-stat--temp6 {
color: var(--stat-temp6-color);
}
:host .pr-stat--temp7 {
color: var(--stat-temp7-color);
}
:host .pr-stat--temp8 {
color: var(--stat-temp8-color);
}
:host .pr-stat--temp9 {
color: var(--stat-temp9-color);
}
:host .pr-review {
display: flex;
justify-content: space-between;
font-size: 13px;
margin-top: 14px;
}
:host .pr-review-teams {
max-width: 50%;
}
:host .pr-review-team {
color: var(--review-team-color);
white-space: nowrap;
}
:host .pr-review-team + .pr-review-team:before {
content: "· ";
white-space: break-spaces;
}
`;
}
@property({ type: Number }) id = -1;
@property({ type: String, reflect: true }) title = '';
@property({ type: String, reflect: true }) url = '';
@property({ type: String, reflect: true }) diff_url = '';
@property({ type: String, reflect: true }) patch_url = '';
@property({ type: Boolean }) draft = false;
@property({ type: Array }) labels = [];
@property({ type: String, reflect: true }) milestone = '';
@property({ type: String, reflect: true }) branch = '';
@property({ type: String }) created_at = '';
@property({ type: String }) updated_at = '';
@property({ type: Array }) teams = [];
getStatTemp(value, factor) {
let temp = Math.floor(value / factor);
if (temp > 9) {
temp = 9;
}
return temp;
}
render(){
const created_days = greports.format.getDaysSince(this.created_at);
const stale_days = greports.format.getDaysSince(this.updated_at);
return html`
<div class="pr-container">
<a
class="pr-title"
href="${this.url}"
target="_blank"
>
<span>#${this.id}</span> <span>${this.title}</span>
${(this.draft ? html`
<span class="pr-title-draft">draft</span>
` : '')}
</a>
<div class="pr-meta">
<div class="pr-labels">
${this.labels.map((item) => {
return html`
<span
class="pr-label"
>
<span
class="pr-label-dot"
style="background-color: ${item.color}"
></span>
<span
class="pr-label-name"
>
${item.name}
</span>
</span>
`;
})}
</div>
<div class="pr-milestone">
<div>
<span>milestone: </span>
${(this.milestone != null) ? html`
<a
href="${this.milestone.url}"
target="_blank"
>
${this.milestone.title}
</a>
` : html`
<span>none</span>
`}
</div>
<div>
<span>branch: </span>
<span>${this.branch}</span>
</div>
</div>
<div class="pr-timing">
<div class="pr-time">
<span>created at: </span>
<span
class="pr-time-value"
title="${greports.format.formatTimestamp(this.created_at)}"
>
${greports.format.formatDate(this.created_at)}
</span>
</div>
<div class="pr-time">
<span>updated at: </span>
<span
class="pr-time-value"
title="${greports.format.formatTimestamp(this.updated_at)}"
>
${greports.format.formatDate(this.updated_at)}
</span>
</div>
</div>
</div>
<div class="pr-stats">
<div class="pr-stat">
<span>lifetime: </span>
<span
class="pr-stat--temp${this.getStatTemp(created_days, 14)}"
>
${greports.format.formatDays(created_days)}
</span>
</div>
<div class="pr-stat">
<span>stale for: </span>
<span
class="pr-stat--temp${this.getStatTemp(stale_days, 14)}"
>
${greports.format.formatDays(stale_days)}
</span>
</div>
</div>
<div class="pr-review">
<div class="pr-review-teams">
${(this.teams.length > 0) ? html`
<span>also awaiting reviews from: </span>
${this.teams.map((item) => {
return html`
<span class="pr-review-team">${item}</span>
`;
})}
` : ''}
</div>
<div class="pr-download">
<span>download changelog: </span>
<a
href="${this.diff_url}"
target="_blank"
>
diff
</a> |
<a
href="${this.patch_url}"
target="_blank"
>
patch
</a>
</div>
</div>
</div>
`;
}
}

View File

@@ -0,0 +1,81 @@
import { LitElement, html, css, customElement, property } from 'lit-element';
@customElement('gr-team-tab')
export default class TeamTab extends LitElement {
static get styles() {
return css`
/** Colors and variables **/
:host {
--tab-hover-background-color: rgba(0, 0, 0, 0.14);
--tab-active-background-color: #2c3c55;
--tab-active-border-color: #397adf;
}
@media (prefers-color-scheme: dark) {
:host {
--tab-hover-background-color: rgba(255, 255, 255, 0.14);
--tab-active-background-color: #2c3c55;
--tab-active-border-color: #397adf;
}
}
/** Component styling **/
:host {
max-width: 240px;
}
:host .tab-container {
border-left: 5px solid transparent;
cursor: pointer;
display: flex;
flex-direction: row;
padding: 2px 12px;
}
:host .tab-container:hover {
background-color: var(--tab-hover-background-color);
}
:host .tab-container--active {
background-color: var(--tab-active-background-color);
border-left: 5px solid var(--tab-active-border-color);
}
:host .tab-icon {
display: inline-block;
width: 16px;
height: 16px;
}
:host .tab-title {
color: var(--g-font-color);
font-size: 13px;
padding-left: 12px;
white-space: nowrap;
}
`;
}
@property({ type: Number }) id = -1;
@property({ type: String, reflect: true }) name = '';
@property({ type: String, reflect: true }) avatar = '';
@property({ type: Boolean, reflect: true }) active = false;
render(){
const classList = [ "tab-container" ];
if (this.active) {
classList.push("tab-container--active");
}
return html`
<div class="${classList.join(" ")}">
<div
class="tab-icon"
style="background-image: url('${this.avatar}')"
></div>
<span
class="tab-title"
>
${this.name}
</span>
</div>
`;
}
}

View File

View File

@@ -0,0 +1,9 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500i,700,900&display=swap&subset=latin-ext" rel="stylesheet">
<link rel="icon" type="image/png" href="favicon.png" />
<link href="styles/shared/normalize.css" rel="stylesheet">
<link href="styles/shared/global.css" rel="stylesheet">
<script src="scripts/shared/global.js"></script>

View File

@@ -0,0 +1,61 @@
const READING_SPEED = 200;
// API Interaction
const ReportsAPI = {
async get(path = '/') {
const res = await fetch(`${path}`);
if (res.status !== 200) {
return null;
}
return await res.json();
},
async getData() {
return await this.get("/data.json");
},
};
// Content helpers
const ReportsFormatter = {
formatDate(dateString) {
const options = {
year: 'numeric', month: 'long', day: 'numeric'
};
const dateFormatter = new Intl.DateTimeFormat('en-US', options);
const date = new Date(dateString);
return dateFormatter.format(date);
},
formatTimestamp(timeString) {
const options = {
year: 'numeric', month: 'long', day: 'numeric',
hour: 'numeric', hour12: false, minute: 'numeric',
timeZone: 'UTC', timeZoneName: 'short'
};
const dateFormatter = new Intl.DateTimeFormat('en-US', options);
const date = new Date(timeString);
return dateFormatter.format(date);
},
getDaysSince(dateString) {
const date = new Date(dateString);
const msBetween = (new Date()) - date;
const days = Math.floor(msBetween / (1000 * 60 * 60 * 24));
return days;
},
formatDays(days) {
return days + " " + (days !== 0 ? "days" : "day")
},
};
const ReportsSingleton = {
api: ReportsAPI,
format: ReportsFormatter
};
window.greports = ReportsSingleton;

View File

@@ -0,0 +1,45 @@
/** Colors and variables **/
:root {
--g-background-color: #fcfcfa;
--g-font-color: #121314;
--g-font-size: 15px;
--g-font-weight: 400;
--g-line-height: 20px;
--link-font-color: #1d6dff;
--link-font-color-hover: #1051c9;
--link-font-color-inactive: #1051c9;
}
@media (prefers-color-scheme: dark) {
:root {
--g-background-color: #0d1117;
--g-font-color: rgba(228, 228, 232, 0.9);
--link-font-color: #367df7;
--link-font-color-hover: #6391ec;
--link-font-color-inactive: #abbdcc;
}
}
/** General styling **/
html {}
body {
background: var(--g-background-color);
color: var(--g-font-color);
font-family: 'Roboto', sans-serif;
font-size: var(--g-font-size);
font-weight: var(--g-font-weight);
line-height: var(--g-line-height);
min-width: 380px;
}
a {
color: var(--link-font-color);
font-weight: 700;
text-decoration: none;
}
a:hover {
color: var(--link-font-color-hover);
}

349
src/shared/styles/normalize.css vendored Normal file
View File

@@ -0,0 +1,349 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}