Version 2.2 (new additions)

- Smarter placeholders
- Merged placeholders with real templates to avoid maintening duplicates
- Moved style/js away from index.html and refactor
- Svg size is now computed again from templates
- Base metrics is now contained in special plugin "base", which can be disabled  part by part if you just want to include a plugin instead
- Reformatted a bit terminal template
- Test now look templates directory
This commit is contained in:
lowlighter
2020-10-24 17:31:37 +02:00
parent 997deed60b
commit 60d02a6d90
22 changed files with 713 additions and 956 deletions

View File

@@ -26,6 +26,9 @@ inputs:
repositories:
description: Number of repositories to use to compute metrics
default: 100
base:
description: Base content to include in metrics (list of comma-separated sections name as string)
default: "header, activity, community, repositories, metadata"
plugin_pagespeed:
description: Enable Google PageSpeed metrics for account attached website
default: no

File diff suppressed because one or more lines are too long

View File

@@ -63,6 +63,14 @@
console.debug = () => null
console.log(`Debug mode | ${debug}`)
//Base elements
let base = (core.getInput("base")||"").split(",").map(part => part.trim())
if (!base.length)
base = conf.settings.plugins.base.parts
for (const part of base)
q[`base.${part}`] = true
console.log(`Base elements | ${base.join(", ")}`)
//Additional plugins
const plugins = {
lines:{enabled:bool(core.getInput("plugin_lines"))},

View File

@@ -46,9 +46,12 @@
const actions = {flush:new Map()}
app.get("/", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
app.get("/index.html", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
app.get("/app.js", limiter, (req, res) => res.sendFile(`${conf.statics}/app.js`))
app.get("/style.css", limiter, (req, res) => res.sendFile(`${conf.statics}/style.css`))
app.get("/favicon.ico", limiter, (req, res) => res.sendStatus(204))
app.get("/plugins.list", limiter, (req, res) => res.status(200).json(enabled))
app.get("/templates.list", limiter, (req, res) => res.status(200).json(templates))
app.get("/plugins.base.parts.list", limiter, (req, res) => res.status(200).json(conf.settings.plugins.base.parts))
app.get("/ejs.min.js", limiter, (req, res) => res.sendFile(`${conf.node_modules}/ejs/ejs.min.js`))
app.get("/axios.min.js", limiter, (req, res) => res.sendFile(`${conf.node_modules}/axios/dist/axios.min.js`))
app.get("/axios.min.map", limiter, (req, res) => res.sendFile(`${conf.node_modules}/axios/dist/axios.min.map`))
@@ -57,8 +60,8 @@
const template = req.query.template || conf.settings.templates.default
if (!(template in Templates))
return res.sendStatus(404)
const {style, placeholder} = conf.templates[template]
res.status(200).json({style, placeholder})
const {style, image} = conf.templates[template]
res.status(200).json({style, image})
})
app.get("/action.flush", limiter, async (req, res) => {
const {token, user} = req.query

151
src/html/app.js Normal file
View File

@@ -0,0 +1,151 @@
;(async function() {
//Init
const url = new URLSearchParams(window.location.search)
const {data:templates} = await axios.get("/templates.list")
const {data:plugins} = await axios.get("/plugins.list")
const {data:base} = await axios.get("/plugins.base.parts.list")
//App
return new Vue({
//Initialization
el:"main",
async mounted() {
await this.load()
},
//Data initialization
data:{
user:url.get("user") || "",
palette:url.get("palette") || "light",
plugins:{
base,
list:plugins,
enabled:{base:Object.fromEntries(base.map(key => [key, true]))},
descriptions:{
pagespeed:"Website performances",
languages:"Most used languages",
followup:"Issues and pull requests",
traffic:"Pages views",
lines:"Lines of code changed",
habits:"Coding habits",
selfskip:"Skip metrics commits",
"base.header":"Header",
"base.activity":"Account activity",
"base.community":"Community stats",
"base.repositories":"Repositories metrics",
"base.metadata":"Metadata",
},
},
templates:{
list:templates,
selected:url.get("template") || templates[0],
loaded:{},
placeholder:"",
descriptions:{
classic:"Classic template",
terminal:"Terminal template",
},
},
generated:{
pending:false,
content:"",
error:false,
},
},
//Computed data
computed:{
//User's repository
repo() {
return `https://github.com/${this.user}/${this.user}`
},
//Endpoint to use for computed metrics
url() {
const plugins = Object.entries(this.plugins.enabled)
.flatMap(([key, value]) => key === "base" ? Object.entries(value).map(([key, value]) => [`base.${key}`, value]) : [[key, value]])
.filter(([key, value]) => /^base[.]\w+$/.test(key) ? !value : value)
.map(([key, value]) => `${key}=${+value}`)
const params = [...(this.templates.selected !== templates[0] ? [`template=${this.templates.selected}`] : []), ...plugins].join("&")
return `${window.location.protocol}//${window.location.host}/${this.user}${params.length ? `?${params}` : ""}`
},
},
//Methods
methods:{
//Load and render image
async load() {
//Load template
const template = this.templates.selected
if (!this.templates.loaded[template]) {
const {data:{image, style}} = await axios.get(`/placeholder.svg?template=${template}`)
this.templates.loaded[template] = {image, style}
}
const {image = "", style = {}} = this.templates.loaded[this.templates.selected] || {}
if (!image)
return this.templates.placeholder = "#"
//Proxifier
const proxify = (target) => typeof target === "object" ? new Proxy(target, {
get(target, property) {
//Primitive conversion
if (property === Symbol.toPrimitive)
return () => "▇"
//Iterables
if (property === Symbol.iterator)
return Reflect.get(target, property)
//Plugins should not be proxified by default as they can be toggled by user
if (/^plugins$/.test(property))
return Reflect.get(target, property)
//Consider no errors on plugins
if (/^error/.test(property))
return undefined
//Proxify recursively
return proxify(property in target ? Reflect.get(target, property) : {})
}
}) : target
//Placeholder data
const data = {
style,
s(_, letter) { return letter === "y" ? "ies" : "s" },
base:this.plugins.enabled.base,
meta:{version:"0.0.0", author:"lowlighter", placeholder:true},
user:proxify({name:`▇▇▇▇`, websiteUrl:`▇▇▇▇▇▇▇▇▇▇▇▇`}),
computed:proxify({
avatar:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mOcOnfpfwAGfgLYttYINwAAAABJRU5ErkJggg==",
registration:"▇ years ago",
calendar:new Array(14).fill({color:"#ebedf0"}),
licenses:{favorite:`▇▇▇▇`},
plugins:Object.fromEntries(Object.entries(this.plugins.enabled).filter(([key, enabled]) => (key !== "base")&&(enabled)).map(([key]) => {
return [key, proxify({
pagespeed:{scores:["Performance", "Accessibility", "Best Practices", "SEO"].map(title => ({title, score:NaN}))},
followup:{issues:{count:0}, pr:{count:0}},
habits:{indents:{style:`▇▇▇`}},
languages:{favorites:new Array(7).fill(null).map((_, x) => ({x, name:`▇▇▇▇`, color:"#ebedf0", value:1/(x+1)}))},
}[key]||{})]
})),
token:{scopes:[]},
}),
}
//Render placeholder
this.templates.placeholder = this.serialize(ejs.render(image, data))
this.generated.content = ""
},
//Generate metrics and flush cache
async generate() {
//Avoid requests spamming
if (this.generated.pending)
return
this.generated.pending = true
//Compute metrics
try {
await axios.get(`/action.flush?&token=${(await axios.get(`/action.flush?user=${this.user}`)).data.token}`)
this.generated.content = this.serialize((await axios.get(this.url)).data)
} catch {
this.generated.error = true
}
finally {
this.generated.pending = false
}
},
//Serialize svg
serialize(svg) {
return `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svg)))}`
},
},
})
})()

View File

@@ -6,274 +6,107 @@
<meta name="description" content="A SVG image generator which includes activity, community and repositories metrics about your GitHub account that you can includes on your profile">
<meta name="author" content="lowlighter">
<link rel="icon" href="data:,">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<!-- Vue app -->
<main :class="[palette]">
<!-- Title -->
<h1><a href="https://github.com/lowlighter/metrics">Generate your metrics !</a></h1>
<!-- Content -->
<template>
<div class="step">
<h2>1. Enter your GitHub username</h2>
<label>
<input type="text" v-model="user" maxlength="39" placeholder="GitHub username" :disabled="generated.pending">
</label>
</div>
<div class="step">
<h2>2. Select a template {{ plugins.list.length ? "and enable additional plugins" : "" }}</h2>
<div class="templates">
<label v-for="template in templates.list" :key="template">
<input type="radio" v-model="templates.selected" :value="template" @change="load" :disabled="generated.pending">
{{ templates.descriptions[template] || template }}
</label>
</div>
<div class="plugins">
<label v-for="plugin in plugins.list" :key="plugin">
<input type="checkbox" v-model="plugins.enabled[plugin]" @change="load" :disabled="generated.pending">
{{ plugins.descriptions[plugin] || plugin }}
</label>
</div>
<div class="cache-notice" v-if="plugins.list.length">
*To reduce server overhead, metrics are cached. Changes may not be reflected until cache expiration.
</div>
<div class="palette">
Generated metrics use transparency and colors which matches both light and dark modes
<div class="palettes">
<label>
<input type="radio" v-model="palette" value="light">
☀️ Light mode
</label>
<label>
<input type="radio" v-model="palette" value="dark">
🌙 Night mode
</label>
<section class="generator">
<!-- Steps panel -->
<section class="steps">
<div class="step">
<h2>1. Enter your GitHub username</h2>
<input type="text" v-model="user" maxlength="39" placeholder="GitHub username" :disabled="generated.pending">
</div>
</div>
</div>
<div class="step">
<h2>3. Generate your metrics</h2>
<template v-if="generated.content">
<img class="metrics" :src="generated.content" alt="metrics">
</template>
<template v-else>
<img class="metrics" :src="templates.placeholder" alt="metrics">
<button @click="generate" :disabled="(!user)||(generated.pending)">{{ generated.pending ? "Generating your metrics..." : user ? "Generate your metrics" : "Enter your GitHub username first" }}</button>
</template>
</div>
<div class="step">
<h2>4. Embed these metrics on your GitHub profile</h2>
<template v-if="user">
Add the markdown below in your <i>README.md</i> at <a :href="repo">{{ user }}/{{ user }}</a>
<div class="code">
![<span class="md-alt">GitHub metrics</span>]({{ url }})
<div class="step">
<h2>2. Select a template</h2>
<div class="templates">
<label v-for="template in templates.list" :key="template">
<input type="radio" v-model="templates.selected" :value="template" @change="load" :disabled="generated.pending">
{{ templates.descriptions[template] || template }}
</label>
</div>
<template v-if="plugins.base.length">
<h3>2.1 Configure base content</h3>
<div class="plugins">
<label v-for="part in plugins.base" :key="part">
<input type="checkbox" v-model="plugins.enabled.base[part]" @change="load" :disabled="generated.pending">
{{ plugins.descriptions[`base.${part}`] || `base.${part}` }}
</label>
</div>
</template>
<template v-if="plugins.list.length">
<h3>2.2 Enable additional plugins</h3>
<div class="plugins">
<label v-for="plugin in plugins.list" :key="plugin">
<input type="checkbox" v-model="plugins.enabled[plugin]" @change="load" :disabled="generated.pending">
{{ plugins.descriptions[plugin] || plugin }}
</label>
</div>
</template>
<div class="palette">
Generated metrics use transparency and colors which can be read on both light and dark modes, so everyone can see your stats whatever their preferred color scheme !
<div class="palettes">
<label>
<input type="radio" v-model="palette" value="light"> ☀️ Light mode
</label>
<label>
<input type="radio" v-model="palette" value="dark"> 🌙 Night mode
</label>
</div>
</div>
</div>
</template>
For even more features, setup <a href="https://github.com/lowlighter/metrics">lowlighter/metrics</a> as a <a href="https://github.com/marketplace/actions/github-metrics-as-svg-image">GitHub action</a> !
</div>
<div class="step">
<h2>3. Generate your metrics</h2>
<template v-if="!user">
Set your username to generate your metrics 🦑
</template>
<div class="preview-inliner">
<template v-if="generated.content">
<img class="metrics preview-inline" :src="generated.content" alt="metrics">
</template>
<template v-else>
<img class="metrics preview-inline" :src="templates.placeholder" alt="metrics">
</template>
</div>
<template v-if="user">
<button @click="generate" :disabled="generated.pending">{{ generated.pending ? "Working on it :)" : "Generate your metrics !" }}</button>
</template>
<div class="error" v-if="generated.error">An error occurred. Please try again later.</div>
</div>
<div class="step">
<h2>4. Embed these metrics on your GitHub profile</h2>
<template v-if="user">
Add the markdown below in your <i>README.md</i> at <a :href="repo">{{ user }}/{{ user }}</a>
<div class="code">
![<span class="md-alt">GitHub metrics</span>]({{ url }})
</div>
</template>
For even more features, setup <a href="https://github.com/lowlighter/metrics">lowlighter/metrics</a> as a <a href="https://github.com/marketplace/actions/github-metrics-as-svg-image">GitHub action</a> !<br>
Enjoying <a href="https://github.com/lowlighter/metrics">metrics</a> ? Consider starring it, a little bit of support is always appreciated 💖 !
</div>
</section>
<!-- Metrics preview -->
<section class="preview">
<template v-if="generated.content">
<img class="metrics" :src="generated.content" alt="metrics">
</template>
<template v-else>
<img class="metrics" :src="templates.placeholder" alt="metrics">
</template>
<div class="error" v-if="generated.error">An error occurred. Please try again later.</div>
</section>
</section>
</template>
</main>
<!-- Scripts -->
<script src="/axios.min.js"></script>
<script src="/ejs.min.js"></script>
<script src="/vue.min.js"></script>
<script>
;(async function() {
const url = new URLSearchParams(window.location.search)
new Vue({
el:"main",
async mounted() {
await this.load()
},
data:{
user:url.get("user") || "",
palette:url.get("palette") || "light",
plugins:{
list:(await axios.get("/plugins.list")).data,
enabled:{},
descriptions:{
pagespeed:"Website performances",
languages:"Most used languages",
followup:"Owned repositories issues and pull requests",
traffic:"Pages views",
lines:"Lines of code changed",
habits:"Coding habits",
selfskip:"Skip metrics commits",
},
},
templates:{
list:(await axios.get("/templates.list")).data,
loaded:{},
selected:url.get("template") || (await axios.get("/templates.list")).data[0],
placeholder:"",
descriptions:{
classic:"Classic template",
terminal:"Terminal template"
},
},
generated:{
pending:false,
content:"",
},
},
computed:{
repo() {
return `https://github.com/${this.user}/${this.user}`
},
url() {
const plugins = Object.entries(this.plugins.enabled)
.filter(([key, value]) => value)
.map(([key, value]) => `${key}=${+value}`)
.join("&")
return `${window.location.protocol}//${window.location.host}/${this.user}?template=${this.templates.selected}${plugins.length ? `&${plugins}` : ""}`
},
},
methods:{
async load() {
const template = this.templates.selected
if (!this.templates.loaded[template]) {
const {data:{placeholder, style}} = await axios.get(`/placeholder.svg?template=${template}`)
this.templates.loaded[template] = {placeholder, style}
}
const {placeholder = "", style = {}} = this.templates.loaded[this.templates.selected] || {}
this.templates.placeholder = placeholder ? this.serialize(ejs.render(placeholder, {plugins:this.plugins.enabled, style})) : "#"
},
async generate() {
this.generated.pending = true
await axios.get(`/action.flush?&token=${(await axios.get(`/action.flush?user=${this.user}`)).data.token}`)
this.generated.content = this.serialize((await axios.get(this.url)).data)
},
serialize(svg) {
return `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svg)))}`
},
},
})
})()
</script>
<style>
body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
padding: 0;
margin: 0;
display: flex;
justify-content: center;
}
main {
background-color: #FFFFFF;
color: #1B1F23;
display: flex;
flex-direction: column;
align-items: center;
padding-bottom: 2rem;
width: 100%;
transition: background-color .3s;
}
h1 {
font-size: 1.6rem;
margin: 1rem 0;
}
h2 {
margin: 1.5rem 0 1rem;
font-size: 1.3rem;
}
a, a:hover, a:visited {
color: #0366D6;
text-decoration: none;
font-style: normal;
outline: none;
}
a:hover {
color: #79B8FF;
transition: color .4s;
cursor: pointer;
}
input, button, select {
border-radius: .5rem;
padding: .25rem .5rem;
outline: none;
border: 1px solid #E1E4E8;
background-color: #FAFBFC;
color: #1B1F23;
text-align: center;
cursor: pointer;
}
input:focus {
outline: none;
}
input[type=text], select, button {
min-width: 50%;
font-size: 1.1rem;
}
option {
text-align: center;
}
label, button {
margin: 1rem;
}
input[disabled], button[disabled], select[disabled] {
opacity: .5;
cursor: not-allowed;
}
.step {
margin-bottom: 1rem;
text-align: center;
max-width: 800px;
}
.plugins, .palettes {
margin-top: 1rem;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.plugins label, .palettes label {
margin: 0 1rem;
}
.code {
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
padding: 1rem;
margin: .5rem 0;
border-radius: .5rem;
background-color: #FAFBFC;
}
.code .md-alt {
color: #6F42C1;
}
.cache-notice {
margin-top: .5rem;
font-size: .9rem;
opacity: .8;
}
img.metrics {
width: 100%;
max-width: 480px;
}
.palette {
margin-top: 1rem;
}
main.dark {
background-color: #181A1B;
color: #D4D1C5;
}
.dark a, .dark a:visited {
color: #4CACEE;
}
.dark input, .dark button {
color: #D4D1C5;
background-color: #1A1C1E;
border-color: #373C3E;
}
.dark .code {
background-color: #1A1C1E;
}
</style>
<script src="/app.js"></script>
</body>
</html>

173
src/html/style.css Normal file
View File

@@ -0,0 +1,173 @@
/* General */
body {
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;
padding: 0;
margin: 0;
display: flex;
justify-content: center;
}
main {
background-color: #FFFFFF;
color: #1B1F23;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
transition: background-color .3s;
}
/* Headlines */
h1 {
font-size: 1.6rem;
margin: 1rem 0;
}
h2 {
margin: 1.5rem 0 1rem;
font-size: 1.3rem;
}
h3 {
margin: .5rem 0 .25rem;
font-size: 1.1rem;
}
/* Links */
a, a:hover, a:visited {
color: #0366D6;
text-decoration: none;
font-style: normal;
outline: none;
}
a:hover {
color: #79B8FF;
transition: color .4s;
cursor: pointer;
}
/* Inputs */
input, button, select {
border-radius: .5rem;
padding: .25rem .5rem;
outline: none;
border: 1px solid #E1E4E8;
background-color: #FAFBFC;
color: #1B1F23;
text-align: center;
cursor: pointer;
}
input:focus {
outline: none;
}
input[type=text], select, button {
min-width: 50%;
font-size: 1.1rem;
}
option {
text-align: center;
}
label, button {
margin: 1rem;
}
label {
padding-right: .25rem;
padding-bottom: .125rem;
}
input[disabled], button[disabled], select[disabled] {
opacity: .5;
cursor: not-allowed;
}
label:hover {
border-radius: .25rem;
background-color: #79B8FF50;
transition: background-color .4s;
cursor: pointer;
}
/* Generator */
.generator {
display: flex;
flex-grow: 1;
width: 100%;
height: 100%;
}
.generator .step {
margin-bottom: 1rem;
text-align: center;
max-width: 800px;
}
.generator .steps {
margin: .5rem 1rem 2rem;
flex-grow: 1;
}
.generator .preview {
display: none;
margin: .5rem 1rem 2rem;
flex-shrink: 0;
}
.generator .preview .metrics {
width: 480px;
}
.generator .preview-inliner {
display: flex;
justify-content: center;
}
.generator .preview-inline .metrics {
width: 100%;
max-width: 480px;
}
@media only screen and (min-width: 1180px) {
.generator .preview-inline {
display: none;
}
.generator .preview {
display: block;
}
}
/* Plugins */
.plugins, .palettes {
margin-top: 1rem;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.plugins label, .palettes label {
margin: 0 1rem;
}
/* Markdown code */
.code {
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
padding: 1rem;
margin: .5rem 0;
border-radius: .5rem;
background-color: #FAFBFC;
word-wrap: break-word;
}
.code .md-alt {
color: #6F42C1;
}
/* Color palette */
.palette {
margin-top: 1rem;
}
main.dark {
background-color: #181A1B;
color: #D4D1C5;
}
.dark a, .dark a:visited {
color: #4CACEE;
}
.dark input, .dark button {
color: #D4D1C5;
background-color: #1A1C1E;
border-color: #373C3E;
}
.dark .code {
background-color: #1A1C1E;
}
/* Error */
.error {
color: #721c24;
background-color: #f8d7da;
padding: .75rem 1.25rem;
border: 1px solid #f5c6cb;
border-radius: .25rem;
display: flex;
justify-content: center;
align-items: center;
}

View File

@@ -31,6 +31,11 @@
)
console.debug(`metrics/compute/${login} > query > success`)
//Base parts
data.base = {}
for (const part of conf.settings.plugins.base.parts)
data.base[part] = (`base.${part}` in q) ? !!q[`base.${part}`] : true
//Template
console.debug(`metrics/compute/${login} > compute`)
const computer = Templates[template].default || Templates[template]

View File

@@ -6,7 +6,6 @@
if (!q.followup)
return computed.plugins.followup = null
console.debug(`metrics/compute/${login}/plugins > followup`)
computed.svg.height += 70
//Plugin execution
pending.push(new Promise(async solve => {

View File

@@ -6,7 +6,6 @@
if (!q.habits)
return computed.plugins.habits = null
console.debug(`metrics/compute/${login}/plugins > habits`)
computed.svg.height += 70
//Parameter override
if (typeof q["habits.from"] === "number") {

View File

@@ -6,7 +6,6 @@
if (!q.languages)
return computed.plugins.languages = null
console.debug(`metrics/compute/${login}/plugins > languages`)
computed.svg.height += 90
//Plugin execution
pending.push(new Promise(async solve => {

View File

@@ -14,7 +14,6 @@
if (!q.lines)
return computed.plugins.lines = null
console.debug(`metrics/compute/${login}/plugins > lines`)
computed.svg.height += 20
//Plugin execution
pending.push(new Promise(async solve => {

View File

@@ -11,7 +11,6 @@
if (!q.pagespeed)
return computed.plugins.pagespeed = null
console.debug(`metrics/compute/${login}/plugins > pagespeed`)
computed.svg.height += 130
//Plugin execution
pending.push(new Promise(async solve => {

View File

@@ -14,7 +14,6 @@
if (!q.traffic)
return computed.plugins.traffic = null
console.debug(`metrics/compute/${login}/plugins > traffic`)
computed.svg.height += !q.lines ? 20 : 0
//Plugin execution
pending.push(new Promise(async solve => {

View File

@@ -28,6 +28,7 @@
conf.settings.templates = {default:"classic", enabled:[]}
if (!conf.settings.plugins)
conf.settings.plugins = {}
conf.settings.plugins.base = {parts:["header", "activity", "community", "repositories", "metadata"]}
if (conf.settings.debug)
logger(conf.settings)
@@ -39,7 +40,7 @@
}
else {
logger(`metrics/setup > load package.json > (missing)`)
conf.package = {version:"<#version>"}
conf.package = {version:"<#version>", author:"lowlighter"}
}
//Load templates
@@ -52,20 +53,19 @@
const files = [
`${templates}/${name}/query.graphql`,
`${templates}/${name}/image.svg`,
`${templates}/${name}/placeholder.svg`,
`${templates}/${name}/style.css`,
]
const [query, image, placeholder, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
conf.templates[name] = {query, image, placeholder, style}
const [query, image, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
conf.templates[name] = {query, image, style}
logger(`metrics/setup > load template [${name}] > success`)
//Debug
if (conf.settings.debug) {
Object.defineProperty(conf.templates, name, {
get() {
logger(`metrics/setup > reload template [${name}]`)
const [query, image, placeholder, style] = files.map(file => `${fs.readFileSync(path.resolve(file))}`)
const [query, image, style] = files.map(file => `${fs.readFileSync(path.resolve(file))}`)
logger(`metrics/setup > reload template [${name}] > success`)
return {query, image, placeholder, style}
return {query, image, style}
}
})
}

View File

@@ -1,4 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" width="<%= computed.svg.width %>" height="<%= computed.svg.height %>">
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="<%= 0
+ (!!base.header)*(16*6)
+ (!!base.metadata)*(16*3)
+ ((!!base.activity)||(!!base.community))*(16*10)
+ (!!base.repositories)*(16*7)
+ ((!!computed.plugins.traffic)||(!!computed.plugins.lines))*(16*2)
+ (!!computed.plugins.followup)*(16*5)
+ (!!computed.plugins.languages)*(16*6)
+ (!!computed.plugins.pagespeed)*(16*9)
+ (!!computed.plugins.habits)*(16*5)
%>">
<style>
<%= style %>
</style>
@@ -6,164 +16,163 @@
<foreignObject x="0" y="0" width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<section>
<h1 class="field">
<img class="avatar" src="data:image/png;base64,<%= computed.avatar %>" width="20" height="20" />
<span><%= user.name || user.login %></span>
</h1>
<div class="row">
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zm.5 4.75a.75.75 0 00-1.5 0v3.5a.75.75 0 00.471.696l2.5 1a.75.75 0 00.557-1.392L8.5 7.742V4.75z"></path></svg>
Joined GitHub <%= computed.registration %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"></path></svg>
Followed by <%= user.followers.totalCount %> user<%= s(user.followers.totalCount) %>
</div>
</section>
<section>
<div class="field calendar">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 <%= computed.calendar.length*15 %> 11" width="<%= computed.calendar.length*15 %>" height="16">
<g>
<% for (const [x, {color}] of Object.entries(computed.calendar)) { %>
<rect class="day" x="<%= x*15 %>" y="0" width="11" height="11" fill="<%= color %>" rx="2" ry="2" />
<% } %>
</g>
</svg>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1 2.5A2.5 2.5 0 013.5 0h8.75a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0V1.5h-8a1 1 0 00-1 1v6.708A2.492 2.492 0 013.5 9h3.25a.75.75 0 010 1.5H3.5a1 1 0 100 2h5.75a.75.75 0 010 1.5H3.5A2.5 2.5 0 011 11.5v-9zm13.23 7.79a.75.75 0 001.06-1.06l-2.505-2.505a.75.75 0 00-1.06 0L9.22 9.229a.75.75 0 001.06 1.061l1.225-1.224v6.184a.75.75 0 001.5 0V9.066l1.224 1.224z"></path></svg>
Contributed to <%= user.repositoriesContributedTo.totalCount %> repositor<%= s(user.repositoriesContributedTo.totalCount, "y") %>
</div>
</section>
</div>
</section>
<% if (base.header) { %>
<section>
<h1 class="field">
<img class="avatar" src="data:image/png;base64,<%= computed.avatar %>" width="20" height="20" />
<span><%= user.name || user.login %></span>
</h1>
<div class="row">
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zm.5 4.75a.75.75 0 00-1.5 0v3.5a.75.75 0 00.471.696l2.5 1a.75.75 0 00.557-1.392L8.5 7.742V4.75z"></path></svg>
Joined GitHub <%= computed.registration %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"></path></svg>
Followed by <%= user.followers.totalCount %> user<%= s(user.followers.totalCount) %>
</div>
</section>
<section>
<div class="field calendar">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 <%= computed.calendar.length*15 %> 11" width="<%= computed.calendar.length*15 %>" height="16">
<g>
<% for (const [x, {color}] of Object.entries(computed.calendar)) { %>
<rect class="day" x="<%= x*15 %>" y="0" width="11" height="11" fill="<%= color %>" rx="2" ry="2" />
<% } %>
</g>
</svg>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1 2.5A2.5 2.5 0 013.5 0h8.75a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0V1.5h-8a1 1 0 00-1 1v6.708A2.492 2.492 0 013.5 9h3.25a.75.75 0 010 1.5H3.5a1 1 0 100 2h5.75a.75.75 0 010 1.5H3.5A2.5 2.5 0 011 11.5v-9zm13.23 7.79a.75.75 0 001.06-1.06l-2.505-2.505a.75.75 0 00-1.06 0L9.22 9.229a.75.75 0 001.06 1.061l1.225-1.224v6.184a.75.75 0 001.5 0V9.066l1.224 1.224z"></path></svg>
Contributed to <%= user.repositoriesContributedTo.totalCount %> repositor<%= s(user.repositoriesContributedTo.totalCount, "y") %>
</div>
</section>
</div>
</section>
<% } %>
<div class="row">
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 1.75a.75.75 0 00-1.5 0v12.5c0 .414.336.75.75.75h14.5a.75.75 0 000-1.5H1.5V1.75zm14.28 2.53a.75.75 0 00-1.06-1.06L10 7.94 7.53 5.47a.75.75 0 00-1.06 0L3.22 8.72a.75.75 0 001.06 1.06L7 7.06l2.47 2.47a.75.75 0 001.06 0l5.25-5.25z"></path></svg>
Activity
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"></path></svg>
<%= computed.commits %> Commit<%= s(computed.commits) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.5 1.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v7.736a.75.75 0 101.5 0V1.75A1.75 1.75 0 0011.25 0h-8.5A1.75 1.75 0 001 1.75v11.5c0 .966.784 1.75 1.75 1.75h3.17a.75.75 0 000-1.5H2.75a.25.25 0 01-.25-.25V1.75zM4.75 4a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5zM4 7.75A.75.75 0 014.75 7h2a.75.75 0 010 1.5h-2A.75.75 0 014 7.75zm11.774 3.537a.75.75 0 00-1.048-1.074L10.7 14.145 9.281 12.72a.75.75 0 00-1.062 1.058l1.943 1.95a.75.75 0 001.055.008l4.557-4.45z"></path></svg>
<%= user.contributionsCollection.totalPullRequestReviewContributions %> Pull request<%= s(user.contributionsCollection.totalPullRequestReviewContributions) %> reviewed
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"></path></svg>
<%= user.contributionsCollection.totalPullRequestContributions %> Pull request<%= s(user.contributionsCollection.totalPullRequestContributions) %> opened
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm9 3a1 1 0 11-2 0 1 1 0 012 0zm-.25-6.25a.75.75 0 00-1.5 0v3.5a.75.75 0 001.5 0v-3.5z"></path></svg>
<%= user.contributionsCollection.totalIssueContributions %> Issue<%= s(user.contributionsCollection.totalIssueContributions) %> opened
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.75 2.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 01.75.75v2.19l2.72-2.72a.75.75 0 01.53-.22h4.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25H2.75zM1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0113.25 12H9.06l-2.573 2.573A1.457 1.457 0 014 13.543V12H2.75A1.75 1.75 0 011 10.25v-7.5z"></path></svg>
<%= user.issueComments.totalCount %> issue comment<%= s(user.issueComments.totalCount) %>
</div>
</section>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path></svg>
Community stats
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"></path></svg>
Following <%= user.following.totalCount %> user<%= s(user.followers.totalCount) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"></path></svg>
Sponsoring <%= computed.sponsorships %> repositor<%= s(computed.sponsorships, "y") %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path></svg>
Starred <%= user.starredRepositories.totalCount %> repositor<%= s(user.starredRepositories.totalCount, "y") %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"></path></svg>
Watching <%= user.watching.totalCount %> repositor<%= s(user.watching.totalCount, "y") %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 14.25c0 .138.112.25.25.25H4v-1.25a.75.75 0 01.75-.75h2.5a.75.75 0 01.75.75v1.25h2.25a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25h-8.5a.25.25 0 00-.25.25v12.5zM1.75 16A1.75 1.75 0 010 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 00.25-.25V8.285a.25.25 0 00-.111-.208l-1.055-.703a.75.75 0 11.832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0114.25 16h-3.5a.75.75 0 01-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 01-.75-.75V14h-1v1.25a.75.75 0 01-.75.75h-3zM3 3.75A.75.75 0 013.75 3h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 3.75zM3.75 6a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM3 9.75A.75.75 0 013.75 9h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 9.75zM7.75 9a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM7 6.75A.75.75 0 017.75 6h.5a.75.75 0 010 1.5h-.5A.75.75 0 017 6.75zM7.75 3a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5z"></path></svg>
Member of <%= user.organizations.totalCount %> organization <%= s(user.organizations.totalCount) %>
</div>
</section>
</div>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path></svg>
<%= user.repositories.totalCount %> Repositor<%= s(user.repositories.totalCount, "y") %>
</h2>
<div class="row">
<% if (base.activity) { %>
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.75.75a.75.75 0 00-1.5 0V2h-.984c-.305 0-.604.08-.869.23l-1.288.737A.25.25 0 013.984 3H1.75a.75.75 0 000 1.5h.428L.066 9.192a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.514 3.514 0 00.686.45A4.492 4.492 0 003 11c.88 0 1.556-.22 2.023-.454a3.515 3.515 0 00.686-.45l.045-.04.016-.015.006-.006.002-.002.001-.002L5.25 9.5l.53.53a.75.75 0 00.154-.838L3.822 4.5h.162c.305 0 .604-.08.869-.23l1.289-.737a.25.25 0 01.124-.033h.984V13h-2.5a.75.75 0 000 1.5h6.5a.75.75 0 000-1.5h-2.5V3.5h.984a.25.25 0 01.124.033l1.29.736c.264.152.563.231.868.231h.162l-2.112 4.692a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.517 3.517 0 00.686.45A4.492 4.492 0 0013 11c.88 0 1.556-.22 2.023-.454a3.512 3.512 0 00.686-.45l.045-.04.01-.01.006-.005.006-.006.002-.002.001-.002-.529-.531.53.53a.75.75 0 00.154-.838L13.823 4.5h.427a.75.75 0 000-1.5h-2.234a.25.25 0 01-.124-.033l-1.29-.736A1.75 1.75 0 009.735 2H8.75V.75zM1.695 9.227c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327l-1.305 2.9zm10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327l-1.305 2.9z"></path></svg>
<% if (computed.licenses.favorite.length) { %>
Prefer <%= computed.licenses.favorite %> license
<% } else { %>
No license preference
<% } %>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 1.75a.75.75 0 00-1.5 0v12.5c0 .414.336.75.75.75h14.5a.75.75 0 000-1.5H1.5V1.75zm14.28 2.53a.75.75 0 00-1.06-1.06L10 7.94 7.53 5.47a.75.75 0 00-1.06 0L3.22 8.72a.75.75 0 001.06 1.06L7 7.06l2.47 2.47a.75.75 0 001.06 0l5.25-5.25z"></path></svg>
Activity
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"></path></svg>
<%= computed.commits %> Commit<%= s(computed.commits) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path></svg>
<%= user.packages.totalCount %> Package <%= s(user.packages.totalCount) %>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.5 1.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v7.736a.75.75 0 101.5 0V1.75A1.75 1.75 0 0011.25 0h-8.5A1.75 1.75 0 001 1.75v11.5c0 .966.784 1.75 1.75 1.75h3.17a.75.75 0 000-1.5H2.75a.25.25 0 01-.25-.25V1.75zM4.75 4a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5zM4 7.75A.75.75 0 014.75 7h2a.75.75 0 010 1.5h-2A.75.75 0 014 7.75zm11.774 3.537a.75.75 0 00-1.048-1.074L10.7 14.145 9.281 12.72a.75.75 0 00-1.062 1.058l1.943 1.95a.75.75 0 001.055.008l4.557-4.45z"></path></svg>
<%= user.contributionsCollection.totalPullRequestReviewContributions %> Pull request<%= s(user.contributionsCollection.totalPullRequestReviewContributions) %> reviewed
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" ><path fill-rule="evenodd" d="M1.75 1.5a.25.25 0 00-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25H1.75zM0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0114.25 16H1.75A1.75 1.75 0 010 14.25V1.75zm9.22 3.72a.75.75 0 000 1.06L10.69 8 9.22 9.47a.75.75 0 101.06 1.06l2-2a.75.75 0 000-1.06l-2-2a.75.75 0 00-1.06 0zM6.78 6.53a.75.75 0 00-1.06-1.06l-2 2a.75.75 0 000 1.06l2 2a.75.75 0 101.06-1.06L5.31 8l1.47-1.47z"></path></svg>
<%= user.gists.totalCount %> Gist <%= s(user.gists.totalCount) %>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"></path></svg>
<%= user.contributionsCollection.totalPullRequestContributions %> Pull request<%= s(user.contributionsCollection.totalPullRequestContributions) %> opened
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm9 3a1 1 0 11-2 0 1 1 0 012 0zm-.25-6.25a.75.75 0 00-1.5 0v3.5a.75.75 0 001.5 0v-3.5z"></path></svg>
<%= user.contributionsCollection.totalIssueContributions %> Issue<%= s(user.contributionsCollection.totalIssueContributions) %> opened
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.75 2.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 01.75.75v2.19l2.72-2.72a.75.75 0 01.53-.22h4.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25H2.75zM1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0113.25 12H9.06l-2.573 2.573A1.457 1.457 0 014 13.543V12H2.75A1.75 1.75 0 011 10.25v-7.5z"></path></svg>
<%= user.issueComments.totalCount %> issue comment<%= s(user.issueComments.totalCount) %>
</div>
<% if (computed.plugins.lines) { %>
<div class="field <%= computed.plugins.lines.error ? 'error' : '' %>">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.72 3.22a.75.75 0 011.06 1.06L2.06 8l3.72 3.72a.75.75 0 11-1.06 1.06L.47 8.53a.75.75 0 010-1.06l4.25-4.25zm6.56 0a.75.75 0 10-1.06 1.06L13.94 8l-3.72 3.72a.75.75 0 101.06 1.06l4.25-4.25a.75.75 0 000-1.06l-4.25-4.25z"></path></svg>
<% if (computed.plugins.lines.error) { %>
<%= computed.plugins.lines.error %>
<% } else { %>
<%= computed.plugins.lines.added %> added, <%= computed.plugins.lines.deleted %> removed
<% } %>
</div>
<% } %>
</section>
<% } %>
<% if (base.community) { %>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"></path></svg>
Community stats
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"></path></svg>
Following <%= user.following.totalCount %> user<%= s(user.followers.totalCount) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"></path></svg>
Sponsoring <%= computed.sponsorships %> repositor<%= s(computed.sponsorships, "y") %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path></svg>
<%= computed.repositories.stargazers %> Stargazer<%= s(computed.repositories.stargazers) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path></svg>
<%= computed.repositories.forks %> Fork<%= s(computed.repositories.forks) %>
Starred <%= user.starredRepositories.totalCount %> repositor<%= s(user.starredRepositories.totalCount, "y") %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"></path></svg>
<%= computed.repositories.watchers %> Watcher<%= s(computed.repositories.watchers) %>
Watching <%= user.watching.totalCount %> repositor<%= s(user.watching.totalCount, "y") %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 14.25c0 .138.112.25.25.25H4v-1.25a.75.75 0 01.75-.75h2.5a.75.75 0 01.75.75v1.25h2.25a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25h-8.5a.25.25 0 00-.25.25v12.5zM1.75 16A1.75 1.75 0 010 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 00.25-.25V8.285a.25.25 0 00-.111-.208l-1.055-.703a.75.75 0 11.832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0114.25 16h-3.5a.75.75 0 01-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 01-.75-.75V14h-1v1.25a.75.75 0 01-.75.75h-3zM3 3.75A.75.75 0 013.75 3h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 3.75zM3.75 6a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM3 9.75A.75.75 0 013.75 9h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 9.75zM7.75 9a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM7 6.75A.75.75 0 017.75 6h.5a.75.75 0 010 1.5h-.5A.75.75 0 017 6.75zM7.75 3a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5z"></path></svg>
Member of <%= user.organizations.totalCount %> organization<%= s(user.organizations.totalCount) %>
</div>
<% if (computed.plugins.traffic) { %>
<div class="field <%= computed.plugins.traffic.error ? 'error' : '' %>">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path></svg>
<% if (computed.plugins.traffic.error) { %>
<%= computed.plugins.traffic.error %>
<% } else { %>
<%= computed.plugins.traffic.views.count %> view<%= s(computed.plugins.traffic.views.count) %> in last two weeks
<% } %>
</div>
<% } %>
</section>
</div>
</section>
<% } %>
</div>
<% if (base.repositories) { %>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"></path></svg>
<%= user.repositories.totalCount %> Repositor<%= s(user.repositories.totalCount, "y") %>
</h2>
<div class="row">
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.75.75a.75.75 0 00-1.5 0V2h-.984c-.305 0-.604.08-.869.23l-1.288.737A.25.25 0 013.984 3H1.75a.75.75 0 000 1.5h.428L.066 9.192a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.514 3.514 0 00.686.45A4.492 4.492 0 003 11c.88 0 1.556-.22 2.023-.454a3.515 3.515 0 00.686-.45l.045-.04.016-.015.006-.006.002-.002.001-.002L5.25 9.5l.53.53a.75.75 0 00.154-.838L3.822 4.5h.162c.305 0 .604-.08.869-.23l1.289-.737a.25.25 0 01.124-.033h.984V13h-2.5a.75.75 0 000 1.5h6.5a.75.75 0 000-1.5h-2.5V3.5h.984a.25.25 0 01.124.033l1.29.736c.264.152.563.231.868.231h.162l-2.112 4.692a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.517 3.517 0 00.686.45A4.492 4.492 0 0013 11c.88 0 1.556-.22 2.023-.454a3.512 3.512 0 00.686-.45l.045-.04.01-.01.006-.005.006-.006.002-.002.001-.002-.529-.531.53.53a.75.75 0 00.154-.838L13.823 4.5h.427a.75.75 0 000-1.5h-2.234a.25.25 0 01-.124-.033l-1.29-.736A1.75 1.75 0 009.735 2H8.75V.75zM1.695 9.227c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327l-1.305 2.9zm10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327l-1.305 2.9z"></path></svg>
<% if (computed.licenses.favorite.length) { %>
Prefer <%= computed.licenses.favorite %> license
<% } else { %>
No license preference
<% } %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"></path></svg>
<%= user.packages.totalCount %> Package<%= s(user.packages.totalCount) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" ><path fill-rule="evenodd" d="M1.75 1.5a.25.25 0 00-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25H1.75zM0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0114.25 16H1.75A1.75 1.75 0 010 14.25V1.75zm9.22 3.72a.75.75 0 000 1.06L10.69 8 9.22 9.47a.75.75 0 101.06 1.06l2-2a.75.75 0 000-1.06l-2-2a.75.75 0 00-1.06 0zM6.78 6.53a.75.75 0 00-1.06-1.06l-2 2a.75.75 0 000 1.06l2 2a.75.75 0 101.06-1.06L5.31 8l1.47-1.47z"></path></svg>
<%= user.gists.totalCount %> Gist<%= s(user.gists.totalCount) %>
</div>
<% if (computed.plugins.lines) { %>
<div class="field <%= computed.plugins.lines.error ? 'error' : '' %>">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.72 3.22a.75.75 0 011.06 1.06L2.06 8l3.72 3.72a.75.75 0 11-1.06 1.06L.47 8.53a.75.75 0 010-1.06l4.25-4.25zm6.56 0a.75.75 0 10-1.06 1.06L13.94 8l-3.72 3.72a.75.75 0 101.06 1.06l4.25-4.25a.75.75 0 000-1.06l-4.25-4.25z"></path></svg>
<% if (computed.plugins.lines.error) { %>
<%= computed.plugins.lines.error %>
<% } else { %>
<%= computed.plugins.lines.added %> added, <%= computed.plugins.lines.deleted %> removed
<% } %>
</div>
<% } %>
</section>
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path></svg>
<%= computed.repositories.stargazers %> Stargazer<%= s(computed.repositories.stargazers) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path></svg>
<%= computed.repositories.forks %> Fork<%= s(computed.repositories.forks) %>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"></path></svg>
<%= computed.repositories.watchers %> Watcher<%= s(computed.repositories.watchers) %>
</div>
<% if (computed.plugins.traffic) { %>
<div class="field <%= computed.plugins.traffic.error ? 'error' : '' %>">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path></svg>
<% if (computed.plugins.traffic.error) { %>
<%= computed.plugins.traffic.error %>
<% } else { %>
<%= computed.plugins.traffic.views.count %> view<%= s(computed.plugins.traffic.views.count) %> in last two weeks
<% } %>
</div>
<% } %>
</section>
</div>
</section>
<% } %>
<% if (computed.plugins.followup) { %>
<div class="row">
@@ -293,10 +302,14 @@
<section class="categories">
<% for (const {score, title} of computed.plugins.pagespeed.scores) { %>
<div class="categorie column">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="50" height="50" class="gauge <%= score >= 0.9 ? 'high' : score >= 0.5 ? 'average' : 'low' %>">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="50" height="50" class="gauge <%= !Number.isNaN(score) ? (score >= 0.9 ? 'high' : score >= 0.5 ? 'average' : 'low') : '' %>">
<circle class="gauge-base" r="53" cx="60" cy="60"></circle>
<circle class="gauge-arc" transform="rotate(-90 60 60)" r="53" cx="60" cy="60" stroke-dasharray="<%= score * 329 %> 329"></circle>
<text x="60" y="60" dominant-baseline="central" ><%= Math.round(score*100) %></text>
<% if (!Number.isNaN(score)) { %>
<circle class="gauge-arc" transform="rotate(-90 60 60)" r="53" cx="60" cy="60" stroke-dasharray="<%= score * 329 %> 329"></circle>
<text x="60" y="60" dominant-baseline="central" ><%= Math.round(score*100) %></text>
<% } else { %>
<text x="60" y="60" dominant-baseline="central" >-</text>
<% } %>
</svg>
<span class="title"><%= title %></span>
</div>
@@ -335,10 +348,12 @@
</section>
<% } %>
<footer>
<span>These metrics <%= !computed.token.scopes.includes("repo") ? "does not include" : "includes" %> private contributions</span>
<span>Last updated <%= new Date() %></span>
</footer>
<% if (base.metadata) { %>
<footer>
<span>These metrics <%= !computed.token.scopes.includes("repo") ? "does not include" : "includes" %> private contributions</span>
<span>Last updated <%= new Date() %></span>
</footer>
<% } %>
</div>
</foreignObject>

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -1,353 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="<%= 355 + (!!plugins.followup)*70 + (!!plugins.habits)*70 + (!!plugins.languages)*90 + ((!!plugins.lines)+(!!plugins.traffic))*20 + (!!plugins.pagespeed)*130 %>">
<style>
<%= style %>
/* Avatar */
.avatar {
background-color: rgba(119,119,119,.62);
border-radius: 50%;
margin: 0 6px;
height: 20px;
width: 20px;
}
/* Placeholder */
.placeholder {
background-color: rgba(119,119,119,.62);
margin: 2px 4px 0px;
height: 12px;
width: 24px;
border-radius: 6px;
}
.placeholder.large {
width: 48px;
}
.placeholder.xlarge {
width: 64px;
}
.placeholder.xxlarge {
margin: 7.2px 0;
width: 96px;
}
.placeholder.inline {
display: inline-block;
}
h2 .placeholder {
background-color: rgba(3,102,214,.62);
}
</style>
<foreignObject x="0" y="0" width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<section>
<h1 class="field">
<div class="avatar"></div>
<span><div class="placeholder xxlarge"></div></span>
</h1>
<div class="row">
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zm.5 4.75a.75.75 0 00-1.5 0v3.5a.75.75 0 00.471.696l2.5 1a.75.75 0 00.557-1.392L8.5 7.742V4.75z"/></svg>
Joined GitHub <div class="placeholder"></div> years ago
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"/></svg>
Followed by <div class="placeholder"></div> users
</div>
</section>
<section>
<div class="field calendar">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 210 11" width="210" height="16">
<g>
<rect class="day" x="0" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="15" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="30" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="45" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="60" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="75" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="90" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="105" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="120" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="135" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="150" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="165" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="180" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
<rect class="day" x="195" y="0" width="11" height="11" fill="#ebedf0" rx="2" ry="2"/>
</g>
</svg>
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1 2.5A2.5 2.5 0 013.5 0h8.75a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0V1.5h-8a1 1 0 00-1 1v6.708A2.492 2.492 0 013.5 9h3.25a.75.75 0 010 1.5H3.5a1 1 0 100 2h5.75a.75.75 0 010 1.5H3.5A2.5 2.5 0 011 11.5v-9zm13.23 7.79a.75.75 0 001.06-1.06l-2.505-2.505a.75.75 0 00-1.06 0L9.22 9.229a.75.75 0 001.06 1.061l1.225-1.224v6.184a.75.75 0 001.5 0V9.066l1.224 1.224z"/></svg>
Contributed to <div class="placeholder"></div> repositories
</div>
</section>
</div>
</section>
<div class="row">
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 1.75a.75.75 0 00-1.5 0v12.5c0 .414.336.75.75.75h14.5a.75.75 0 000-1.5H1.5V1.75zm14.28 2.53a.75.75 0 00-1.06-1.06L10 7.94 7.53 5.47a.75.75 0 00-1.06 0L3.22 8.72a.75.75 0 001.06 1.06L7 7.06l2.47 2.47a.75.75 0 001.06 0l5.25-5.25z"/></svg>
Activity
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"/></svg>
<div class="placeholder"></div> Commits
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.5 1.75a.25.25 0 01.25-.25h8.5a.25.25 0 01.25.25v7.736a.75.75 0 101.5 0V1.75A1.75 1.75 0 0011.25 0h-8.5A1.75 1.75 0 001 1.75v11.5c0 .966.784 1.75 1.75 1.75h3.17a.75.75 0 000-1.5H2.75a.25.25 0 01-.25-.25V1.75zM4.75 4a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5zM4 7.75A.75.75 0 014.75 7h2a.75.75 0 010 1.5h-2A.75.75 0 014 7.75zm11.774 3.537a.75.75 0 00-1.048-1.074L10.7 14.145 9.281 12.72a.75.75 0 00-1.062 1.058l1.943 1.95a.75.75 0 001.055.008l4.557-4.45z"/></svg>
<div class="placeholder"></div> Pull requests reviewed
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"/></svg>
<div class="placeholder"></div> Pull requests opened
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm9 3a1 1 0 11-2 0 1 1 0 012 0zm-.25-6.25a.75.75 0 00-1.5 0v3.5a.75.75 0 001.5 0v-3.5z"/></svg>
<div class="placeholder"></div> Issues opened
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2.75 2.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 01.75.75v2.19l2.72-2.72a.75.75 0 01.53-.22h4.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25H2.75zM1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0113.25 12H9.06l-2.573 2.573A1.457 1.457 0 014 13.543V12H2.75A1.75 1.75 0 011 10.25v-7.5z"></path></svg>
<div class="placeholder"></div> issue comments
</div>
</section>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.75 0A1.75 1.75 0 000 1.75v12.5C0 15.216.784 16 1.75 16h12.5A1.75 1.75 0 0016 14.25V1.75A1.75 1.75 0 0014.25 0H1.75zM1.5 1.75a.25.25 0 01.25-.25h12.5a.25.25 0 01.25.25v12.5a.25.25 0 01-.25.25H1.75a.25.25 0 01-.25-.25V1.75zM11.75 3a.75.75 0 00-.75.75v7.5a.75.75 0 001.5 0v-7.5a.75.75 0 00-.75-.75zm-8.25.75a.75.75 0 011.5 0v5.5a.75.75 0 01-1.5 0v-5.5zM8 3a.75.75 0 00-.75.75v3.5a.75.75 0 001.5 0v-3.5A.75.75 0 008 3z"/></svg>
Community stats
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5.5 3.5a2 2 0 100 4 2 2 0 000-4zM2 5.5a3.5 3.5 0 115.898 2.549 5.507 5.507 0 013.034 4.084.75.75 0 11-1.482.235 4.001 4.001 0 00-7.9 0 .75.75 0 01-1.482-.236A5.507 5.507 0 013.102 8.05 3.49 3.49 0 012 5.5zM11 4a.75.75 0 100 1.5 1.5 1.5 0 01.666 2.844.75.75 0 00-.416.672v.352a.75.75 0 00.574.73c1.2.289 2.162 1.2 2.522 2.372a.75.75 0 101.434-.44 5.01 5.01 0 00-2.56-3.012A3 3 0 0011 4z"/></svg>
Following <div class="placeholder"></div> users
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"/></svg>
Sponsoring <div class="placeholder"></div> repositories
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"/></svg>
Starred <div class="placeholder"></div> repositories
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"/></svg>
Watching <div class="placeholder"></div> repositories
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.5 14.25c0 .138.112.25.25.25H4v-1.25a.75.75 0 01.75-.75h2.5a.75.75 0 01.75.75v1.25h2.25a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25h-8.5a.25.25 0 00-.25.25v12.5zM1.75 16A1.75 1.75 0 010 14.25V1.75C0 .784.784 0 1.75 0h8.5C11.216 0 12 .784 12 1.75v12.5c0 .085-.006.168-.018.25h2.268a.25.25 0 00.25-.25V8.285a.25.25 0 00-.111-.208l-1.055-.703a.75.75 0 11.832-1.248l1.055.703c.487.325.779.871.779 1.456v5.965A1.75 1.75 0 0114.25 16h-3.5a.75.75 0 01-.197-.026c-.099.017-.2.026-.303.026h-3a.75.75 0 01-.75-.75V14h-1v1.25a.75.75 0 01-.75.75h-3zM3 3.75A.75.75 0 013.75 3h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 3.75zM3.75 6a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM3 9.75A.75.75 0 013.75 9h.5a.75.75 0 010 1.5h-.5A.75.75 0 013 9.75zM7.75 9a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5zM7 6.75A.75.75 0 017.75 6h.5a.75.75 0 010 1.5h-.5A.75.75 0 017 6.75zM7.75 3a.75.75 0 000 1.5h.5a.75.75 0 000-1.5h-.5z"></path></svg>
Member of <div class="placeholder"></div> organizations
</div>
</section>
</div>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"/></svg>
<div class="placeholder"></div> Repositories
</h2>
<div class="row">
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.75.75a.75.75 0 00-1.5 0V2h-.984c-.305 0-.604.08-.869.23l-1.288.737A.25.25 0 013.984 3H1.75a.75.75 0 000 1.5h.428L.066 9.192a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.514 3.514 0 00.686.45A4.492 4.492 0 003 11c.88 0 1.556-.22 2.023-.454a3.515 3.515 0 00.686-.45l.045-.04.016-.015.006-.006.002-.002.001-.002L5.25 9.5l.53.53a.75.75 0 00.154-.838L3.822 4.5h.162c.305 0 .604-.08.869-.23l1.289-.737a.25.25 0 01.124-.033h.984V13h-2.5a.75.75 0 000 1.5h6.5a.75.75 0 000-1.5h-2.5V3.5h.984a.25.25 0 01.124.033l1.29.736c.264.152.563.231.868.231h.162l-2.112 4.692a.75.75 0 00.154.838l.53-.53-.53.53v.001l.002.002.002.002.006.006.016.015.045.04a3.517 3.517 0 00.686.45A4.492 4.492 0 0013 11c.88 0 1.556-.22 2.023-.454a3.512 3.512 0 00.686-.45l.045-.04.01-.01.006-.005.006-.006.002-.002.001-.002-.529-.531.53.53a.75.75 0 00.154-.838L13.823 4.5h.427a.75.75 0 000-1.5h-2.234a.25.25 0 01-.124-.033l-1.29-.736A1.75 1.75 0 009.735 2H8.75V.75zM1.695 9.227c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327l-1.305 2.9zm10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327l-1.305 2.9z"/></svg>
Prefer <div class="placeholder large"></div> license
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8.878.392a1.75 1.75 0 00-1.756 0l-5.25 3.045A1.75 1.75 0 001 4.951v6.098c0 .624.332 1.2.872 1.514l5.25 3.045a1.75 1.75 0 001.756 0l5.25-3.045c.54-.313.872-.89.872-1.514V4.951c0-.624-.332-1.2-.872-1.514L8.878.392zM7.875 1.69a.25.25 0 01.25 0l4.63 2.685L8 7.133 3.245 4.375l4.63-2.685zM2.5 5.677v5.372c0 .09.047.171.125.216l4.625 2.683V8.432L2.5 5.677zm6.25 8.271l4.625-2.683a.25.25 0 00.125-.216V5.677L8.75 8.432v5.516z"/></svg>
<div class="placeholder"></div> Packages
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.75 1.5a.25.25 0 00-.25.25v12.5c0 .138.112.25.25.25h12.5a.25.25 0 00.25-.25V1.75a.25.25 0 00-.25-.25H1.75zM0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v12.5A1.75 1.75 0 0114.25 16H1.75A1.75 1.75 0 010 14.25V1.75zm9.22 3.72a.75.75 0 000 1.06L10.69 8 9.22 9.47a.75.75 0 101.06 1.06l2-2a.75.75 0 000-1.06l-2-2a.75.75 0 00-1.06 0zM6.78 6.53a.75.75 0 00-1.06-1.06l-2 2a.75.75 0 000 1.06l2 2a.75.75 0 101.06-1.06L5.31 8l1.47-1.47z"/></svg>
<div class="placeholder"></div> Gists
</div>
<% if (plugins.lines) { %>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.72 3.22a.75.75 0 011.06 1.06L2.06 8l3.72 3.72a.75.75 0 11-1.06 1.06L.47 8.53a.75.75 0 010-1.06l4.25-4.25zm6.56 0a.75.75 0 10-1.06 1.06L13.94 8l-3.72 3.72a.75.75 0 101.06 1.06l4.25-4.25a.75.75 0 000-1.06l-4.25-4.25z"></path></svg>
<div class="placeholder"></div> added, <div class="placeholder"></div> removed
</div>
<% } %>
</section>
<section>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"/></svg>
<div class="placeholder"></div> Stargazers
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"/></svg>
<div class="placeholder"></div> Forks
</div>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M1.679 7.932c.412-.621 1.242-1.75 2.366-2.717C5.175 4.242 6.527 3.5 8 3.5c1.473 0 2.824.742 3.955 1.715 1.124.967 1.954 2.096 2.366 2.717a.119.119 0 010 .136c-.412.621-1.242 1.75-2.366 2.717C10.825 11.758 9.473 12.5 8 12.5c-1.473 0-2.824-.742-3.955-1.715C2.92 9.818 2.09 8.69 1.679 8.068a.119.119 0 010-.136zM8 2c-1.981 0-3.67.992-4.933 2.078C1.797 5.169.88 6.423.43 7.1a1.619 1.619 0 000 1.798c.45.678 1.367 1.932 2.637 3.024C4.329 13.008 6.019 14 8 14c1.981 0 3.67-.992 4.933-2.078 1.27-1.091 2.187-2.345 2.637-3.023a1.619 1.619 0 000-1.798c-.45-.678-1.367-1.932-2.637-3.023C11.671 2.992 9.981 2 8 2zm0 8a2 2 0 100-4 2 2 0 000 4z"/></svg>
<div class="placeholder"></div> Watchers
</div>
<% if (plugins.traffic) { %>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M0 1.75A.75.75 0 01.75 1h4.253c1.227 0 2.317.59 3 1.501A3.744 3.744 0 0111.006 1h4.245a.75.75 0 01.75.75v10.5a.75.75 0 01-.75.75h-4.507a2.25 2.25 0 00-1.591.659l-.622.621a.75.75 0 01-1.06 0l-.622-.621A2.25 2.25 0 005.258 13H.75a.75.75 0 01-.75-.75V1.75zm8.755 3a2.25 2.25 0 012.25-2.25H14.5v9h-3.757c-.71 0-1.4.201-1.992.572l.004-7.322zm-1.504 7.324l.004-5.073-.002-2.253A2.25 2.25 0 005.003 2.5H1.5v9h3.757a3.75 3.75 0 011.994.574z"></path></svg>
<div class="placeholder"></div> views in last two weeks
</div>
<% } %>
</section>
</div>
</section>
<% if (plugins.followup) { %>
<div class="row">
<section class="column">
<h3>Issues</h3>
<svg class="bar" xmlns="http://www.w3.org/2000/svg" width="220" height="8">
<mask id="issues-bar">
<rect x="0" y="0" width="220" height="8" fill="white" rx="5"/>
</mask>
<rect mask="url(#issues-bar)" x="0" y="0" width="220" height="8" fill="#d1d5da"/>
</svg>
<div class="field horizontal fill-width">
<div class="field center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d73a49" fill-rule="evenodd" d="M1.5 8a6.5 6.5 0 0110.65-5.003.75.75 0 00.959-1.153 8 8 0 102.592 8.33.75.75 0 10-1.444-.407A6.5 6.5 0 011.5 8zM8 12a1 1 0 100-2 1 1 0 000 2zm0-8a.75.75 0 01.75.75v3.5a.75.75 0 11-1.5 0v-3.5A.75.75 0 018 4zm4.78 4.28l3-3a.75.75 0 00-1.06-1.06l-2.47 2.47-.97-.97a.749.749 0 10-1.06 1.06l1.5 1.5a.75.75 0 001.06 0z"/></svg>
<div class="placeholder"></div> Closed
</div>
<div class="field center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#28a745" fill-rule="evenodd" d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8zm9 3a1 1 0 11-2 0 1 1 0 012 0zm-.25-6.25a.75.75 0 00-1.5 0v3.5a.75.75 0 001.5 0v-3.5z"/></svg>
<div class="placeholder"></div> Open
</div>
</div>
</section>
<section class="column">
<h3>Pull requests</h3>
<svg class="bar" xmlns="http://www.w3.org/2000/svg" width="220" height="8">
<mask id="pr-bar">
<rect x="0" y="0" width="220" height="8" fill="white" rx="5"/>
</mask>
<rect mask="url(#pr-bar)" x="0" y="0" width="220" height="8" fill="#d1d5da"/>
</svg>
<div class="field horizontal fill-width">
<div class="field center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#6f42c1" fill-rule="evenodd" d="M5 3.254V3.25v.005a.75.75 0 110-.005v.004zm.45 1.9a2.25 2.25 0 10-1.95.218v5.256a2.25 2.25 0 101.5 0V7.123A5.735 5.735 0 009.25 9h1.378a2.251 2.251 0 100-1.5H9.25a4.25 4.25 0 01-3.8-2.346zM12.75 9a.75.75 0 100-1.5.75.75 0 000 1.5zm-8.5 4.5a.75.75 0 100-1.5.75.75 0 000 1.5z"/></svg>
<div class="placeholder"></div> Merged
</div>
<div class="field center">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#28a745" fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"/></svg>
<div class="placeholder"></div> Open
</div>
</div>
</section>
</div>
<% } %>
<% if (plugins.languages) { %>
<section class="column">
<h3>Most used languages</h3>
<svg class="bar" xmlns="http://www.w3.org/2000/svg" width="460" height="8">
<mask id="languages-bar">
<rect x="0" y="0" width="460" height="8" fill="white" rx="5"/>
</mask>
<rect mask="url(#languages-bar)" x="0" y="0" width="460" height="8" fill="#d1d5da"/>
</svg>
<div class="field horizontal horizontal-wrap fill-width">
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
<div class="field center no-wrap language">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill="#d1d5da" fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8z"/></svg>
<div class="placeholder xlarge"></div>
</div>
</div>
</section>
<% } %>
<% if (plugins.pagespeed) { %>
<div class="row">
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M14.064 0a8.75 8.75 0 00-6.187 2.563l-.459.458c-.314.314-.616.641-.904.979H3.31a1.75 1.75 0 00-1.49.833L.11 7.607a.75.75 0 00.418 1.11l3.102.954c.037.051.079.1.124.145l2.429 2.428c.046.046.094.088.145.125l.954 3.102a.75.75 0 001.11.418l2.774-1.707a1.75 1.75 0 00.833-1.49V9.485c.338-.288.665-.59.979-.904l.458-.459A8.75 8.75 0 0016 1.936V1.75A1.75 1.75 0 0014.25 0h-.186zM10.5 10.625c-.088.06-.177.118-.266.175l-2.35 1.521.548 1.783 1.949-1.2a.25.25 0 00.119-.213v-2.066zM3.678 8.116L5.2 5.766c.058-.09.117-.178.176-.266H3.309a.25.25 0 00-.213.119l-1.2 1.95 1.782.547zm5.26-4.493A7.25 7.25 0 0114.063 1.5h.186a.25.25 0 01.25.25v.186a7.25 7.25 0 01-2.123 5.127l-.459.458a15.21 15.21 0 01-2.499 2.02l-2.317 1.5-2.143-2.143 1.5-2.317a15.25 15.25 0 012.02-2.5l.458-.458h.002zM12 5a1 1 0 11-2 0 1 1 0 012 0zm-8.44 9.56a1.5 1.5 0 10-2.12-2.12c-.734.73-1.047 2.332-1.15 3.003a.23.23 0 00.265.265c.671-.103 2.273-.416 3.005-1.148z"></path></svg>
PageSpeed Insights
</h2>
<div class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg>
<div class="placeholder xlarge"></div>
</div>
</section>
</div>
<section>
<div class="row fill-width">
<section class="categories">
<div class="categorie column">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="50" height="50" class="gauge">
<circle class="gauge-base" r="53" cx="60" cy="60"></circle>
<text x="60" y="60" dominant-baseline="central" >-</text>
</svg>
<span class="title">Performance</span>
</div>
<div class="categorie column">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="50" height="50" class="gauge">
<circle class="gauge-base" r="53" cx="60" cy="60"></circle>
<text x="60" y="60" dominant-baseline="central" >-</text>
</svg>
<span class="title">Accessibility</span>
</div>
<div class="categorie column">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="50" height="50" class="gauge">
<circle class="gauge-base" r="53" cx="60" cy="60"></circle>
<text x="60" y="60" dominant-baseline="central" >-</text>
</svg>
<span class="title">Best Practices</span>
</div>
<div class="categorie column">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="50" height="50" class="gauge">
<circle class="gauge-base" r="53" cx="60" cy="60"></circle>
<text x="60" y="60" dominant-baseline="central" >-</text>
</svg>
<span class="title">SEO</span>
</div>
</section>
</div>
</section>
<% } %>
<% if (plugins.habits) { %>
<section>
<h2 class="field">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 01-1.484.211c-.04-.282-.163-.547-.37-.847a8.695 8.695 0 00-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.75.75 0 01-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75zM6 15.25a.75.75 0 01.75-.75h2.5a.75.75 0 010 1.5h-2.5a.75.75 0 01-.75-.75zM5.75 12a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5z"></path></svg>
Coding habits
</h2>
<div class="row">
<ul class="habits">
<li>Use <div class="placeholder inline large"></div> for indents</li>
<li>Mostly push code around <div class="placeholder inline"></div></li>
</ul>
</div>
</section>
<% } %>
</div>
</foreignObject>
</svg>

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -2,7 +2,7 @@
export default async function ({login, q}, {conf, data, rest, graphql, plugins}, {s, pending, imports}) {
//Init
const computed = data.computed = {commits:0, sponsorships:0, licenses:{favorite:"", used:{}}, svg:{height:355, width:480}, token:{}, repositories:{watchers:0, stargazers:0, issues_open:0, issues_closed:0, pr_open:0, pr_merged:0, forks:0}, plugins:{}}
const computed = data.computed = {commits:0, sponsorships:0, licenses:{favorite:"", used:{}}, token:{}, repositories:{watchers:0, stargazers:0, issues_open:0, issues_closed:0, pr_open:0, pr_merged:0, forks:0}, plugins:{}}
const avatar = imports.imgb64(data.user.avatarUrl)
//Plugins
@@ -49,4 +49,7 @@
//Token scopes
computed.token.scopes = (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
//Meta
data.meta = {version:conf.package.version, author:conf.package.author}
}

View File

@@ -1,30 +1,48 @@
<svg xmlns="http://www.w3.org/2000/svg" width="<%= computed.svg.width %>" height="<%= computed.svg.height %>">
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="<%= 48
+ (!!base.header)*(16*5)
+ (!!base.metadata)*(16*9)
+ (!!base.activity)*(16*10)
+ (!!base.community)*(16*9)
+ (!!base.repositories)*(16*13)
+ (!!computed.plugins.traffic)*(16*1)
+ (!!computed.plugins.followup)*(16*6)
+ (!!computed.plugins.lines)*(16*3)
+ (!!computed.plugins.languages)*(16*12)
+ (!!computed.plugins.pagespeed)*(16*10)
%>">
<%
meta.$ = `<span class="ps1-path">${user.login}@metrics</span>:<span class="ps1-location">~</span>${computed.token.scopes.includes("repo") ? "#" : "$"}`
meta.animations = !meta.placeholder ? {stdin:.16, stdout:.28, length:(2+Object.keys(base).length+Object.keys(computed.plugins).length)} : {stdin:0, stdout:0, length:0}
%>
<style>
<%= style %>
.stdin, .stdout {
animation-duration: .2s;
animation-duration: <%= meta.animations.stdin %>s;
}
.stdout {
animation-duration: .2s;
}
<% for (let i = 0; i < 12; i++) { %>
.stdin:nth-of-type(<%= i+1 %>) {
animation-delay: <%= i*.2 %>s;
}
.stdout:nth-of-type(<%= i+2 %>) {
animation-delay: <%= (i+1)*.2 %>s;
}
<% } %>
footer {
animation-delay: <%= 12*.2 %>s;
animation-duration: <%= meta.animations.stdout %>s;
}
<% for (let i = 0, d = 0; i < meta.animations.length; i++, d+=meta.animations.stdin+meta.animations.stdout) { %>
.stdin:nth-of-type(<%= i+1 %>) {
animation-delay: <%= d %>s;
}
.stdout:nth-of-type(<%= i+2 %>) {
animation-delay: <%= d+meta.animations.stdin %>s;
}
<% if (i === meta.animations.length-1) { %>
footer {
animation-delay: <%= d %>s;
}
<% } %>
<% } %>
</style>
<foreignObject x="0" y="0" width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<div class="header">
<span class="title">GitHub metrics</span>
<span class="title">GitHub metrics v<%= meta.version %></span>
<div class="buttons">
<div class="button"></div>
<div class="button"></div>
@@ -32,40 +50,51 @@
</div>
</div>
<pre><span class="banner">GitHub metrics generator <%= meta.version %>
<pre><div style="margin-top:-16px"></div><%# -%>
<% if (base.metadata) { %>
<span class="banner"><%# -%>
GitHub metrics generator <%= meta.version %>
These generated metrics comes with ABSOLUTELY NO WARRANTY,
to the extent permitted by applicable law.
Last generated: <%= new Date().toGMTString() %>
</span>
<div class="stdin"><%- meta.$ %> whoami</div><!--
--><div class="stdout"><!--
--><b><%= user.name || user.login %></b> registered=<%= computed.registration %>, uid=<%= `${user.databaseId}`.substr(-4) %>, gid=<%= user.organizations.totalCount %>, followers=<%= user.followers.totalCount %>
</span><% } -%>
<%# ============================================================= -%>
<% if (base.header) { %>
<div class="stdin"><%- meta.$ %> whoami</div><%# -%>
<div class="stdout"><%# -%>
<b><%= user.name || user.login %></b> registered=<%= computed.registration.match(/^.+? [ym]/)[0].replace(/ /g, "") %>, uid=<%= `${user.databaseId}`.substr(-4) %>, gid=<%= user.organizations.totalCount %>, followers=<%= user.followers.totalCount %>
contributed to <%= user.repositoriesContributedTo.totalCount %> repositor<%= s(user.repositoriesContributedTo.totalCount, "y") %> <b><% for (const [x, {color}] of Object.entries(computed.calendar)) { -%><span style="color:<%= color %>">#</span><% } %></b>
</div>
<div class="stdin"><%- meta.$ %> git status</div><!--
--><div class="stdout"><b>Recent activity</b><!--
--><b><%= `${computed.commits}`.padStart(5) %></b> commit<%= s(computed.commits) %>
</div><% } -%>
<%# ============================================================= -%>
<% if ((base.activity)||(base.community)) { %>
<div class="stdin"><%- meta.$ %> git status</div><%# -%>
<div class="stdout"><%# -%>
<% if (base.activity) { -%>
<b>Recent activity</b>
<b><%= `${computed.commits}`.padStart(5) %></b> commit<%= s(computed.commits) %>
<b><%= `${user.contributionsCollection.totalPullRequestReviewContributions}`.padStart(5) %></b> pull request<%= s(user.contributionsCollection.totalPullRequestReviewContributions) %> reviewed
<b><%= `${user.contributionsCollection.totalPullRequestContributions}`.padStart(5) %></b> pull request<%= s(user.contributionsCollection.totalPullRequestContributions) %> opened
<b><%= `${user.contributionsCollection.totalIssueContributions}`.padStart(5) %></b> issue<%= s(user.contributionsCollection.totalIssueContributions) %> opened
<b><%= `${user.issueComments.totalCount}`.padStart(5) %></b> issue comment<%= s(user.issueComments.totalCount) %>
<% } -%>
<% if ((base.activity)&&(base.community)) { -%>
<% } -%>
<% if (base.community) { -%>
<b>Tracked activity</b>
<b><%= `${user.following.totalCount}`.padStart(5) %></b> user<%= s(user.followers.totalCount) %> followed
<b><%= `${computed.sponsorships}`.padStart(5) %></b> repositor<%= s(computed.sponsorships, "y") %> sponsored
<b><%= `${user.starredRepositories.totalCount}`.padStart(5) %></b> repositor<%= s(user.starredRepositories.totalCount, "y") %> starred
<b><%= `${user.watching.totalCount}`.padStart(5) %></b> repositor<%= s(user.watching.totalCount, "y") %> watched
<% if (computed.plugins.lines) { -%><% if (computed.plugins.lines.error) { -%>
<span class="diff error">@@ <%= computed.plugins.lines.error %> @@</span><% } else { -%>
<span class="diff">@@ -<%= computed.plugins.lines.deleted %> +<%= computed.plugins.lines.added %> @@</span>
<% }} -%></div>
<div class="stdin"><%- meta.$ %> ls -lh github/repositories</div><!--
--><div class="stdout"><!--
-->Total <%= user.repositories.totalCount %> repositor<%= s(user.repositories.totalCount, "y") %>
<% if (computed.plugins.traffic) { -%><% if (computed.plugins.traffic.error) { -%>
<% } -%>
</div><% } -%>
<%# ============================================================= -%>
<% if (base.repositories) { %>
<div class="stdin"><%- meta.$ %> ls -lh github/repositories</div><%# -%>
<div class="stdout"><%# -%>
Total <%= user.repositories.totalCount %> repositor<%= s(user.repositories.totalCount, "y") %>
<% if (computed.plugins.traffic) { if (computed.plugins.traffic.error) { -%>
---- <b> </b> views <span class="error">(<%= computed.plugins.traffic.error %>)</span>
<% } else { -%>
-r-- <b><%= `${computed.plugins.traffic.views.count}`.padStart(5) %></b> views
@@ -75,7 +104,7 @@ Last generated: <%= new Date().toGMTString() %>
-r-- <b><%= `${computed.repositories.watchers}`.padStart(5) %></b> watcher<%= s(computed.repositories.watchers) %>
dr-x <b><%= `${user.packages.totalCount}`.padStart(5) %></b> package<%= s(user.packages.totalCount) %>
dr-x <b><%= `${user.gists.totalCount}`.padStart(5) %></b> gist<%= s(user.gists.totalCount) %>
<% if (computed.plugins.followup) { -%><% if (computed.plugins.followup.error) { -%>
<% if (computed.plugins.followup) { if (computed.plugins.followup.error) { -%>
d--- <b> </b> ISSUES <span class="error">(<%= computed.plugins.followup.error %>)</span>
d--- <b> </b> PULL_REQUESTS <span class="error">(<%= computed.plugins.followup.error %>)</span>
<% } else { -%>
@@ -90,33 +119,39 @@ dr-x <b><%= `${computed.plugins.followup.issues.count}`.padStart(5) %></b> PUL
dr-x LICENSE
-r-- └── <%= computed.licenses.favorite %>
<% } -%>
</div><% if (computed.plugins.languages) { -%><% if (computed.plugins.languages.error) { -%>
<div class="stdin"><%- meta.$ %> locale</div><!--
--><div class="stdout"><!--
--><span class="error"><%= computed.plugins.languages.error %></span>
<% } else { -%>
<div class="stdin"><%- meta.$ %> locale</div><!--
--><div class="stdout"><!--
--><% for (const {name, value} of computed.plugins.languages.favorites) { -%>
<% if (computed.plugins.lines) { if (computed.plugins.lines.error) { %>
<span class="diff error">@@ <%= computed.plugins.lines.error %> @@</span><% } else { %>
<span class="diff">@@ -<%= computed.plugins.lines.deleted %> +<%= computed.plugins.lines.added %> @@</span>
<% }} -%>
</div><% } -%>
<%# ============================================================= -%>
<% if (computed.plugins.languages) { %>
<div class="stdin"><%- meta.$ %> locale</div><%# -%>
<div class="stdout"><%# -%>
<% if (computed.plugins.languages.error) { -%>
<span class="error"><%= computed.plugins.languages.error %></span><%# -%>
<% } else { for (const {name, value} of computed.plugins.languages.favorites) { -%>
<b><%= name.toLocaleUpperCase().padEnd(12) %></b> [<%= "#".repeat(Math.ceil(100*value/5)).padEnd(20) %>] <%= (100*value).toFixed(2).padEnd(5) %>%
<% }} -%></div><% } -%><% if (computed.plugins.pagespeed) { -%><% if (computed.plugins.pagespeed.error) { -%>
<div class="stdin"><%- meta.$ %> curl -I <%= user.websiteUrl %></div><!--
--><div class="stdout"><!--
--><span class="error"><%= computed.plugins.pagespeed.error %></span>
<% } else { -%>
<div class="stdin"><%- meta.$ %> curl -I <%= user.websiteUrl %></div><!--
--><div class="stdout"><!--
--><b>User-Agent</b>: Google PageSpeed API
<% }} -%>
</div><% } -%>
<%# ============================================================= -%>
<% if (computed.plugins.pagespeed) { %>
<div class="stdin"><%- meta.$ %> curl -I <%= user.websiteUrl %></div><%# -%>
<div class="stdout"><%# -%>
<% if (computed.plugins.pagespeed.error) { -%>
<span class="error"><%= computed.plugins.pagespeed.error %></span><% } else { -%>
<b>User-Agent</b>: Google PageSpeed API
<b>Location</b>: <%= user.websiteUrl %>
<% for (const {score, title} of computed.plugins.pagespeed.scores) { -%>
<b><%= `X-${title.replace(/ /g, "-")}` %></b>: <%= Math.round(score*100) %>%
<% }} -%></div><% } -%>
<b><%= `X-${title.replace(/ /g, "-")}` %></b>: <%= !Number.isNaN(score) ? Math.round(score*100) : "-" %>%
<% }} -%>
</div><% } -%>
<%# ============================================================= -%>
<% if (base.metadata) { -%>
<footer>Connection reset by 127.0.0.1</footer><%# -%>
<% } -%></pre>
<footer>Connection reset by 127.0.0.1</footer></pre>
</div>
</foreignObject>
</svg>

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -1,88 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="<%= 640 + 80 + (!!plugins.followup)*(100+32) + (!!plugins.languages)*(170+32) + (!!plugins.lines)*(30+32) + (!!plugins.traffic)*(16+32) + (!!plugins.pagespeed)*(136+32) %>">
<style>
<%= style %>
</style>
<foreignObject x="0" y="0" width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<div class="header">
<span class="title">GitHub metrics</span>
<div class="buttons">
<div class="button"></div>
<div class="button"></div>
<div class="button exit"></div>
</div>
</div>
<pre><span class="banner">GitHub metrics generator X.Y.Z
These generated metrics comes with ABSOLUTELY NO WARRANTY,
to the extent permitted by applicable law.
Last generated: <%= new Date().toGMTString() %>
</span>
<div class="stdin"><span class="ps1-path">▇▇▇▇@metrics</span>:<span class="ps1-location">~</span># whoami</div><!--
--><div class="stdout"><!--
--><b>▇▇▇▇</b> registered=▇▇, uid=▇▇, gid=▇▇, followers=▇▇
contributed to ▇▇ repositories <b style="color:#ebedf0">##############</b>
</div>
<div class="stdin"><span class="ps1-path">▇▇▇▇@metrics</span>:<span class="ps1-location">~</span># git status</div><!--
--><div class="stdout"><b>Recent activity</b><!--
--><b><%= `▇▇`.padStart(5) %></b> commits
<b><%= `▇▇`.padStart(5) %></b> pull requests reviewed
<b><%= `▇▇`.padStart(5) %></b> pull requests opened
<b><%= `▇▇`.padStart(5) %></b> issues opened
<b><%= `▇▇`.padStart(5) %></b> issue comments
<b>Tracked activity</b>
<b><%= `▇▇`.padStart(5) %></b> users followed
<b><%= `▇▇`.padStart(5) %></b> repositories sponsored
<b><%= `▇▇`.padStart(5) %></b> repositories starred
<b><%= `▇▇`.padStart(5) %></b> repositories watched
<% if (plugins.lines) { -%>
<span class="diff">@@ -▇▇ +▇▇ @@</span>
<% } -%></div>
<div class="stdin"><span class="ps1-path">▇▇▇▇@metrics</span>:<span class="ps1-location">~</span># ls -lh github/repositories</div><!--
--><div class="stdout"><!--
-->Total ▇▇ repositories
<% if (plugins.traffic) { -%>
-r-- <b><%= `▇▇`.padStart(5) %></b> views
<% } -%>
-r-- <b><%= `▇▇`.padStart(5) %></b> stargazers
-r-- <b><%= `▇▇`.padStart(5) %></b> forks
-r-- <b><%= `▇▇`.padStart(5) %></b> watchers
dr-x <b><%= `▇▇`.padStart(5) %></b> packages
dr-x <b><%= `▇▇`.padStart(5) %></b> gists
<% if (plugins.followup) { -%>
dr-x <b><%= `▇▇`.padStart(5) %></b> ISSUES
-r-- <b><%= `▇▇`.padStart(5) %></b> ├── open
-r-- <b><%= `▇▇`.padStart(5) %></b> └── closed
dr-x <b><%= `▇▇`.padStart(5) %></b> PULL_REQUESTS
-r-- <b><%= `▇▇`.padStart(5) %></b> ├── open
-r-- <b><%= `▇▇`.padStart(5) %></b> └── merged
<% } -%>
dr-x LICENSE
-r-- └── ▇▇▇▇
</div><% if (plugins.languages) { -%>
<div class="stdin"><span class="ps1-path">▇▇▇▇@metrics</span>:<span class="ps1-location">~</span># locale</div><!--
--><div class="stdout"><!--
--><% for (const value of [0.6, 0.2, 0.1, 0.05, 0.05, 0, 0, 0]) { -%>
<b><%= `▇▇▇▇▇▇`.padEnd(12) %></b> [<%= "#".repeat(Math.ceil(100*value/5)).padEnd(20) %>] ▇%
<% } -%></div><% } -%><% if (plugins.pagespeed) { -%>
<div class="stdin"><span class="ps1-path">▇▇▇▇@metrics</span>:<span class="ps1-location">~</span># curl -I ▇▇▇▇▇▇</div><!--
--><div class="stdout"><!--
--><b>User-Agent</b>: Google PageSpeed API
<b>Location</b>: ▇▇▇▇▇▇
<b>X-Performance</b>: ▇%
<b>X-Accessibility</b>: ▇%
<b>X-Best-Practices</b>: ▇%
<b>X-SEO</b>: ▇%</div><% } -%>
<footer>Connection reset by 127.0.0.1</footer></pre>
</div>
</foreignObject>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -3,33 +3,5 @@
/** Template processor */
export default async function ({login, q}, {conf, data, rest, graphql, plugins}, {s, pending, imports}) {
//Common
await common(...arguments)
const computed = data.computed
await Promise.all(pending)
//Compute image size
computed.svg = {height:640, width:480}
if (computed.plugins.followup)
computed.svg.height += 100
if (computed.plugins.lines)
computed.svg.height += 30
if (computed.plugins.traffic)
computed.svg.height += 16
if (computed.plugins.pagespeed)
computed.svg.height += 136
if (computed.plugins.languages)
computed.svg.height += 170
//Compute registration date
const diff = (Date.now()-(new Date(data.user.createdAt)).getTime())/(365*24*60*60*1000)
const years = Math.floor(diff)
const months = Math.ceil((diff-years)*12)
computed.registration = years ? `${years}y` : `${months}m`
//Meta
data.meta = {
version:conf.package.version,
$:`<span class="ps1-path">${data.user.login}@metrics</span>:<span class="ps1-location">~</span>${computed.token.scopes.includes("repo") ? "#" : "$"}`,
}
await common(...arguments)
}

View File

@@ -12,6 +12,7 @@
//Initialization
const __dirname = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..", "action")
process.on("unhandledRejection", error => { throw error })
const templates = (await fs.promises.readdir(path.join(__dirname, "..", "src/templates"))).filter(name => !/.*[.]mjs$/.test(name))
/** Test function */
export default async function test() {
@@ -22,12 +23,14 @@
//Perform tests
await test.build()
for (const template of [
"classic",
"terminal",
]) {
for (const template of templates) {
for (const q of [
{},
{"base.header":0},
{"base.activity":0},
{"base.community":0},
{"base.repositories":0},
{"base.metadata":0},
{followup:1},
{languages:1},
{followup:1, languages:1},
@@ -36,7 +39,7 @@
{traffic:1},
{selfskip:1},
{pagespeed:1},
{followup:1, languages:1, habits:1, "habits.events":1, lines:1, traffic:1, selfskip:1, pagespeed:1}
{followup:1, languages:1, habits:1, "habits.events":1, lines:1, traffic:1, selfskip:1, pagespeed:1},
]) {
await test.metrics({graphql, rest, q:{template, repositories:1, ...q}})
}
@@ -46,7 +49,7 @@
/** Metrics tests */
test.metrics = async function ({graphql, rest, q}) {
//Preparation
console.log(`### Checking metrics with plugins [${Object.keys(q).filter(key => /^\w+$/.test(key)).join(", ")}]`)
console.log(`### Checking metrics with [${Object.entries(q).map(([key, value]) => `${key}=${value}`).join(", ")}]`)
const plugins = {
lines:{enabled:true},
traffic:{enabled:true},