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:
@@ -26,6 +26,9 @@ inputs:
|
|||||||
repositories:
|
repositories:
|
||||||
description: Number of repositories to use to compute metrics
|
description: Number of repositories to use to compute metrics
|
||||||
default: 100
|
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:
|
plugin_pagespeed:
|
||||||
description: Enable Google PageSpeed metrics for account attached website
|
description: Enable Google PageSpeed metrics for account attached website
|
||||||
default: no
|
default: no
|
||||||
|
|||||||
2
action/dist/index.js
vendored
2
action/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -63,6 +63,14 @@
|
|||||||
console.debug = () => null
|
console.debug = () => null
|
||||||
console.log(`Debug mode | ${debug}`)
|
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
|
//Additional plugins
|
||||||
const plugins = {
|
const plugins = {
|
||||||
lines:{enabled:bool(core.getInput("plugin_lines"))},
|
lines:{enabled:bool(core.getInput("plugin_lines"))},
|
||||||
|
|||||||
@@ -46,9 +46,12 @@
|
|||||||
const actions = {flush:new Map()}
|
const actions = {flush:new Map()}
|
||||||
app.get("/", limiter, (req, res) => res.sendFile(`${conf.statics}/index.html`))
|
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("/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("/favicon.ico", limiter, (req, res) => res.sendStatus(204))
|
||||||
app.get("/plugins.list", limiter, (req, res) => res.status(200).json(enabled))
|
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("/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("/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.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`))
|
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
|
const template = req.query.template || conf.settings.templates.default
|
||||||
if (!(template in Templates))
|
if (!(template in Templates))
|
||||||
return res.sendStatus(404)
|
return res.sendStatus(404)
|
||||||
const {style, placeholder} = conf.templates[template]
|
const {style, image} = conf.templates[template]
|
||||||
res.status(200).json({style, placeholder})
|
res.status(200).json({style, image})
|
||||||
})
|
})
|
||||||
app.get("/action.flush", limiter, async (req, res) => {
|
app.get("/action.flush", limiter, async (req, res) => {
|
||||||
const {token, user} = req.query
|
const {token, user} = req.query
|
||||||
|
|||||||
151
src/html/app.js
Normal file
151
src/html/app.js
Normal 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)))}`
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})()
|
||||||
@@ -6,65 +6,78 @@
|
|||||||
<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="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">
|
<meta name="author" content="lowlighter">
|
||||||
<link rel="icon" href="data:,">
|
<link rel="icon" href="data:,">
|
||||||
|
<link rel="stylesheet" href="/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Vue app -->
|
||||||
<main :class="[palette]">
|
<main :class="[palette]">
|
||||||
|
<!-- Title -->
|
||||||
<h1><a href="https://github.com/lowlighter/metrics">Generate your metrics !</a></h1>
|
<h1><a href="https://github.com/lowlighter/metrics">Generate your metrics !</a></h1>
|
||||||
|
<!-- Content -->
|
||||||
<template>
|
<template>
|
||||||
|
<section class="generator">
|
||||||
|
<!-- Steps panel -->
|
||||||
|
<section class="steps">
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<h2>1. Enter your GitHub username</h2>
|
<h2>1. Enter your GitHub username</h2>
|
||||||
<label>
|
|
||||||
<input type="text" v-model="user" maxlength="39" placeholder="GitHub username" :disabled="generated.pending">
|
<input type="text" v-model="user" maxlength="39" placeholder="GitHub username" :disabled="generated.pending">
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<h2>2. Select a template {{ plugins.list.length ? "and enable additional plugins" : "" }}</h2>
|
<h2>2. Select a template</h2>
|
||||||
<div class="templates">
|
<div class="templates">
|
||||||
<label v-for="template in templates.list" :key="template">
|
<label v-for="template in templates.list" :key="template">
|
||||||
<input type="radio" v-model="templates.selected" :value="template" @change="load" :disabled="generated.pending">
|
<input type="radio" v-model="templates.selected" :value="template" @change="load" :disabled="generated.pending">
|
||||||
{{ templates.descriptions[template] || template }}
|
{{ templates.descriptions[template] || template }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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">
|
<div class="plugins">
|
||||||
<label v-for="plugin in plugins.list" :key="plugin">
|
<label v-for="plugin in plugins.list" :key="plugin">
|
||||||
<input type="checkbox" v-model="plugins.enabled[plugin]" @change="load" :disabled="generated.pending">
|
<input type="checkbox" v-model="plugins.enabled[plugin]" @change="load" :disabled="generated.pending">
|
||||||
{{ plugins.descriptions[plugin] || plugin }}
|
{{ plugins.descriptions[plugin] || plugin }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="cache-notice" v-if="plugins.list.length">
|
</template>
|
||||||
*To reduce server overhead, metrics are cached. Changes may not be reflected until cache expiration.
|
|
||||||
</div>
|
|
||||||
<div class="palette">
|
<div class="palette">
|
||||||
Generated metrics use transparency and colors which matches both light and dark modes
|
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">
|
<div class="palettes">
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" v-model="palette" value="light">
|
<input type="radio" v-model="palette" value="light"> ☀️ Light mode
|
||||||
☀️ Light mode
|
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" v-model="palette" value="dark">
|
<input type="radio" v-model="palette" value="dark"> 🌙 Night mode
|
||||||
🌙 Night mode
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="step">
|
<div class="step">
|
||||||
<h2>3. Generate your metrics</h2>
|
<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">
|
<template v-if="generated.content">
|
||||||
<img class="metrics" :src="generated.content" alt="metrics">
|
<img class="metrics preview-inline" :src="generated.content" alt="metrics">
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<img class="metrics" :src="templates.placeholder" alt="metrics">
|
<img class="metrics preview-inline" :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>
|
</template>
|
||||||
</div>
|
</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">
|
<div class="step">
|
||||||
<h2>4. Embed these metrics on your GitHub profile</h2>
|
<h2>4. Embed these metrics on your GitHub profile</h2>
|
||||||
<template v-if="user">
|
<template v-if="user">
|
||||||
@@ -73,207 +86,27 @@
|
|||||||

|

|
||||||
</div>
|
</div>
|
||||||
</template>
|
</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> !
|
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>
|
</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>
|
</template>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
<!-- Scripts -->
|
||||||
<script src="/axios.min.js"></script>
|
<script src="/axios.min.js"></script>
|
||||||
<script src="/ejs.min.js"></script>
|
<script src="/ejs.min.js"></script>
|
||||||
<script src="/vue.min.js"></script>
|
<script src="/vue.min.js"></script>
|
||||||
<script>
|
<script src="/app.js"></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>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
173
src/html/style.css
Normal file
173
src/html/style.css
Normal 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;
|
||||||
|
}
|
||||||
@@ -31,6 +31,11 @@
|
|||||||
)
|
)
|
||||||
console.debug(`metrics/compute/${login} > query > success`)
|
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
|
//Template
|
||||||
console.debug(`metrics/compute/${login} > compute`)
|
console.debug(`metrics/compute/${login} > compute`)
|
||||||
const computer = Templates[template].default || Templates[template]
|
const computer = Templates[template].default || Templates[template]
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
if (!q.followup)
|
if (!q.followup)
|
||||||
return computed.plugins.followup = null
|
return computed.plugins.followup = null
|
||||||
console.debug(`metrics/compute/${login}/plugins > followup`)
|
console.debug(`metrics/compute/${login}/plugins > followup`)
|
||||||
computed.svg.height += 70
|
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async solve => {
|
pending.push(new Promise(async solve => {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
if (!q.habits)
|
if (!q.habits)
|
||||||
return computed.plugins.habits = null
|
return computed.plugins.habits = null
|
||||||
console.debug(`metrics/compute/${login}/plugins > habits`)
|
console.debug(`metrics/compute/${login}/plugins > habits`)
|
||||||
computed.svg.height += 70
|
|
||||||
|
|
||||||
//Parameter override
|
//Parameter override
|
||||||
if (typeof q["habits.from"] === "number") {
|
if (typeof q["habits.from"] === "number") {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
if (!q.languages)
|
if (!q.languages)
|
||||||
return computed.plugins.languages = null
|
return computed.plugins.languages = null
|
||||||
console.debug(`metrics/compute/${login}/plugins > languages`)
|
console.debug(`metrics/compute/${login}/plugins > languages`)
|
||||||
computed.svg.height += 90
|
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async solve => {
|
pending.push(new Promise(async solve => {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
if (!q.lines)
|
if (!q.lines)
|
||||||
return computed.plugins.lines = null
|
return computed.plugins.lines = null
|
||||||
console.debug(`metrics/compute/${login}/plugins > lines`)
|
console.debug(`metrics/compute/${login}/plugins > lines`)
|
||||||
computed.svg.height += 20
|
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async solve => {
|
pending.push(new Promise(async solve => {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
if (!q.pagespeed)
|
if (!q.pagespeed)
|
||||||
return computed.plugins.pagespeed = null
|
return computed.plugins.pagespeed = null
|
||||||
console.debug(`metrics/compute/${login}/plugins > pagespeed`)
|
console.debug(`metrics/compute/${login}/plugins > pagespeed`)
|
||||||
computed.svg.height += 130
|
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async solve => {
|
pending.push(new Promise(async solve => {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
if (!q.traffic)
|
if (!q.traffic)
|
||||||
return computed.plugins.traffic = null
|
return computed.plugins.traffic = null
|
||||||
console.debug(`metrics/compute/${login}/plugins > traffic`)
|
console.debug(`metrics/compute/${login}/plugins > traffic`)
|
||||||
computed.svg.height += !q.lines ? 20 : 0
|
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async solve => {
|
pending.push(new Promise(async solve => {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
conf.settings.templates = {default:"classic", enabled:[]}
|
conf.settings.templates = {default:"classic", enabled:[]}
|
||||||
if (!conf.settings.plugins)
|
if (!conf.settings.plugins)
|
||||||
conf.settings.plugins = {}
|
conf.settings.plugins = {}
|
||||||
|
conf.settings.plugins.base = {parts:["header", "activity", "community", "repositories", "metadata"]}
|
||||||
if (conf.settings.debug)
|
if (conf.settings.debug)
|
||||||
logger(conf.settings)
|
logger(conf.settings)
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger(`metrics/setup > load package.json > (missing)`)
|
logger(`metrics/setup > load package.json > (missing)`)
|
||||||
conf.package = {version:"<#version>"}
|
conf.package = {version:"<#version>", author:"lowlighter"}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Load templates
|
//Load templates
|
||||||
@@ -52,20 +53,19 @@
|
|||||||
const files = [
|
const files = [
|
||||||
`${templates}/${name}/query.graphql`,
|
`${templates}/${name}/query.graphql`,
|
||||||
`${templates}/${name}/image.svg`,
|
`${templates}/${name}/image.svg`,
|
||||||
`${templates}/${name}/placeholder.svg`,
|
|
||||||
`${templates}/${name}/style.css`,
|
`${templates}/${name}/style.css`,
|
||||||
]
|
]
|
||||||
const [query, image, placeholder, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
|
const [query, image, style] = await Promise.all(files.map(async file => `${await fs.promises.readFile(path.resolve(file))}`))
|
||||||
conf.templates[name] = {query, image, placeholder, style}
|
conf.templates[name] = {query, image, style}
|
||||||
logger(`metrics/setup > load template [${name}] > success`)
|
logger(`metrics/setup > load template [${name}] > success`)
|
||||||
//Debug
|
//Debug
|
||||||
if (conf.settings.debug) {
|
if (conf.settings.debug) {
|
||||||
Object.defineProperty(conf.templates, name, {
|
Object.defineProperty(conf.templates, name, {
|
||||||
get() {
|
get() {
|
||||||
logger(`metrics/setup > reload template [${name}]`)
|
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`)
|
logger(`metrics/setup > reload template [${name}] > success`)
|
||||||
return {query, image, placeholder, style}
|
return {query, image, style}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 %>
|
<%= style %>
|
||||||
</style>
|
</style>
|
||||||
@@ -6,14 +16,13 @@
|
|||||||
<foreignObject x="0" y="0" width="100%" height="100%">
|
<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 xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
|
||||||
|
<% if (base.header) { %>
|
||||||
<section>
|
<section>
|
||||||
<h1 class="field">
|
<h1 class="field">
|
||||||
<img class="avatar" src="data:image/png;base64,<%= computed.avatar %>" width="20" height="20" />
|
<img class="avatar" src="data:image/png;base64,<%= computed.avatar %>" width="20" height="20" />
|
||||||
<span><%= user.name || user.login %></span>
|
<span><%= user.name || user.login %></span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="field">
|
<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>
|
<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>
|
||||||
@@ -24,7 +33,6 @@
|
|||||||
Followed by <%= user.followers.totalCount %> user<%= s(user.followers.totalCount) %>
|
Followed by <%= user.followers.totalCount %> user<%= s(user.followers.totalCount) %>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="field calendar">
|
<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">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 <%= computed.calendar.length*15 %> 11" width="<%= computed.calendar.length*15 %>" height="16">
|
||||||
@@ -40,13 +48,12 @@
|
|||||||
Contributed to <%= user.repositoriesContributedTo.totalCount %> repositor<%= s(user.repositoriesContributedTo.totalCount, "y") %>
|
Contributed to <%= user.repositoriesContributedTo.totalCount %> repositor<%= s(user.repositoriesContributedTo.totalCount, "y") %>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<% if (base.activity) { %>
|
||||||
<section>
|
<section>
|
||||||
<h2 class="field">
|
<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>
|
<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>
|
||||||
@@ -73,7 +80,8 @@
|
|||||||
<%= user.issueComments.totalCount %> issue comment<%= s(user.issueComments.totalCount) %>
|
<%= user.issueComments.totalCount %> issue comment<%= s(user.issueComments.totalCount) %>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<% } %>
|
||||||
|
<% if (base.community) { %>
|
||||||
<section>
|
<section>
|
||||||
<h2 class="field">
|
<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>
|
<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>
|
||||||
@@ -100,9 +108,10 @@
|
|||||||
Member of <%= user.organizations.totalCount %> organization<%= s(user.organizations.totalCount) %>
|
Member of <%= user.organizations.totalCount %> organization<%= s(user.organizations.totalCount) %>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<% if (base.repositories) { %>
|
||||||
<section>
|
<section>
|
||||||
<h2 class="field">
|
<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>
|
<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>
|
||||||
@@ -137,7 +146,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<% } %>
|
<% } %>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<div class="field">
|
<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>
|
<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>
|
||||||
@@ -164,6 +172,7 @@
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
<% if (computed.plugins.followup) { %>
|
<% if (computed.plugins.followup) { %>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -293,10 +302,14 @@
|
|||||||
<section class="categories">
|
<section class="categories">
|
||||||
<% for (const {score, title} of computed.plugins.pagespeed.scores) { %>
|
<% for (const {score, title} of computed.plugins.pagespeed.scores) { %>
|
||||||
<div class="categorie column">
|
<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-base" r="53" cx="60" cy="60"></circle>
|
||||||
|
<% 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>
|
<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>
|
<text x="60" y="60" dominant-baseline="central" ><%= Math.round(score*100) %></text>
|
||||||
|
<% } else { %>
|
||||||
|
<text x="60" y="60" dominant-baseline="central" >-</text>
|
||||||
|
<% } %>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="title"><%= title %></span>
|
<span class="title"><%= title %></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -335,10 +348,12 @@
|
|||||||
</section>
|
</section>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
|
<% if (base.metadata) { %>
|
||||||
<footer>
|
<footer>
|
||||||
<span>These metrics <%= !computed.token.scopes.includes("repo") ? "does not include" : "includes" %> private contributions</span>
|
<span>These metrics <%= !computed.token.scopes.includes("repo") ? "does not include" : "includes" %> private contributions</span>
|
||||||
<span>Last updated <%= new Date() %></span>
|
<span>Last updated <%= new Date() %></span>
|
||||||
</footer>
|
</footer>
|
||||||
|
<% } %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
@@ -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 |
@@ -2,7 +2,7 @@
|
|||||||
export default async function ({login, q}, {conf, data, rest, graphql, plugins}, {s, pending, imports}) {
|
export default async function ({login, q}, {conf, data, rest, graphql, plugins}, {s, pending, imports}) {
|
||||||
|
|
||||||
//Init
|
//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)
|
const avatar = imports.imgb64(data.user.avatarUrl)
|
||||||
|
|
||||||
//Plugins
|
//Plugins
|
||||||
@@ -49,4 +49,7 @@
|
|||||||
//Token scopes
|
//Token scopes
|
||||||
computed.token.scopes = (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
|
computed.token.scopes = (await rest.request("HEAD /")).headers["x-oauth-scopes"].split(", ")
|
||||||
|
|
||||||
|
//Meta
|
||||||
|
data.meta = {version:conf.package.version, author:conf.package.author}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
<%= style %>
|
<%= style %>
|
||||||
.stdin, .stdout {
|
.stdin, .stdout {
|
||||||
animation-duration: .2s;
|
animation-duration: <%= meta.animations.stdin %>s;
|
||||||
}
|
}
|
||||||
.stdout {
|
.stdout {
|
||||||
animation-duration: .2s;
|
animation-duration: <%= meta.animations.stdout %>s;
|
||||||
}
|
}
|
||||||
<% for (let i = 0; i < 12; i++) { %>
|
<% for (let i = 0, d = 0; i < meta.animations.length; i++, d+=meta.animations.stdin+meta.animations.stdout) { %>
|
||||||
.stdin:nth-of-type(<%= i+1 %>) {
|
.stdin:nth-of-type(<%= i+1 %>) {
|
||||||
animation-delay: <%= i*.2 %>s;
|
animation-delay: <%= d %>s;
|
||||||
}
|
}
|
||||||
.stdout:nth-of-type(<%= i+2 %>) {
|
.stdout:nth-of-type(<%= i+2 %>) {
|
||||||
animation-delay: <%= (i+1)*.2 %>s;
|
animation-delay: <%= d+meta.animations.stdin %>s;
|
||||||
|
}
|
||||||
|
<% if (i === meta.animations.length-1) { %>
|
||||||
|
footer {
|
||||||
|
animation-delay: <%= d %>s;
|
||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
footer {
|
<% } %>
|
||||||
animation-delay: <%= 12*.2 %>s;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<foreignObject x="0" y="0" width="100%" height="100%">
|
<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 xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<span class="title">GitHub metrics</span>
|
<span class="title">GitHub metrics v<%= meta.version %></span>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<div class="button">─</div>
|
<div class="button">─</div>
|
||||||
<div class="button">□</div>
|
<div class="button">□</div>
|
||||||
@@ -32,40 +50,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</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,
|
These generated metrics comes with ABSOLUTELY NO WARRANTY,
|
||||||
to the extent permitted by applicable law.
|
to the extent permitted by applicable law.
|
||||||
|
|
||||||
Last generated: <%= new Date().toGMTString() %>
|
Last generated: <%= new Date().toGMTString() %>
|
||||||
</span>
|
</span><% } -%>
|
||||||
<div class="stdin"><%- meta.$ %> whoami</div><!--
|
<%# ============================================================= -%>
|
||||||
--><div class="stdout"><!--
|
<% if (base.header) { %>
|
||||||
--><b><%= user.name || user.login %></b> registered=<%= computed.registration %>, uid=<%= `${user.databaseId}`.substr(-4) %>, gid=<%= user.organizations.totalCount %>, followers=<%= user.followers.totalCount %>
|
<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>
|
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><% } -%>
|
||||||
<div class="stdin"><%- meta.$ %> git status</div><!--
|
<%# ============================================================= -%>
|
||||||
--><div class="stdout"><b>Recent activity</b><!--
|
<% if ((base.activity)||(base.community)) { %>
|
||||||
--><b><%= `${computed.commits}`.padStart(5) %></b> commit<%= s(computed.commits) %>
|
<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.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.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.contributionsCollection.totalIssueContributions}`.padStart(5) %></b> issue<%= s(user.contributionsCollection.totalIssueContributions) %> opened
|
||||||
<b><%= `${user.issueComments.totalCount}`.padStart(5) %></b> issue comment<%= s(user.issueComments.totalCount) %>
|
<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>Tracked activity</b>
|
||||||
<b><%= `${user.following.totalCount}`.padStart(5) %></b> user<%= s(user.followers.totalCount) %> followed
|
<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><%= `${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.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
|
<b><%= `${user.watching.totalCount}`.padStart(5) %></b> repositor<%= s(user.watching.totalCount, "y") %> watched
|
||||||
<% if (computed.plugins.lines) { -%><% if (computed.plugins.lines.error) { -%>
|
<% } -%>
|
||||||
|
</div><% } -%>
|
||||||
<span class="diff error">@@ <%= computed.plugins.lines.error %> @@</span><% } else { -%>
|
<%# ============================================================= -%>
|
||||||
|
<% if (base.repositories) { %>
|
||||||
<span class="diff">@@ -<%= computed.plugins.lines.deleted %> +<%= computed.plugins.lines.added %> @@</span>
|
<div class="stdin"><%- meta.$ %> ls -lh github/repositories</div><%# -%>
|
||||||
<% }} -%></div>
|
<div class="stdout"><%# -%>
|
||||||
<div class="stdin"><%- meta.$ %> ls -lh github/repositories</div><!--
|
Total <%= user.repositories.totalCount %> repositor<%= s(user.repositories.totalCount, "y") %>
|
||||||
--><div class="stdout"><!--
|
<% if (computed.plugins.traffic) { if (computed.plugins.traffic.error) { -%>
|
||||||
-->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>
|
---- <b> </b> views <span class="error">(<%= computed.plugins.traffic.error %>)</span>
|
||||||
<% } else { -%>
|
<% } else { -%>
|
||||||
-r-- <b><%= `${computed.plugins.traffic.views.count}`.padStart(5) %></b> views
|
-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) %>
|
-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.packages.totalCount}`.padStart(5) %></b> package<%= s(user.packages.totalCount) %>
|
||||||
dr-x <b><%= `${user.gists.totalCount}`.padStart(5) %></b> gist<%= s(user.gists.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> ISSUES <span class="error">(<%= computed.plugins.followup.error %>)</span>
|
||||||
d--- <b> </b> PULL_REQUESTS <span class="error">(<%= computed.plugins.followup.error %>)</span>
|
d--- <b> </b> PULL_REQUESTS <span class="error">(<%= computed.plugins.followup.error %>)</span>
|
||||||
<% } else { -%>
|
<% } else { -%>
|
||||||
@@ -90,33 +119,39 @@ dr-x <b><%= `${computed.plugins.followup.issues.count}`.padStart(5) %></b> PUL
|
|||||||
dr-x LICENSE
|
dr-x LICENSE
|
||||||
-r-- └── <%= computed.licenses.favorite %>
|
-r-- └── <%= computed.licenses.favorite %>
|
||||||
<% } -%>
|
<% } -%>
|
||||||
</div><% if (computed.plugins.languages) { -%><% if (computed.plugins.languages.error) { -%>
|
<% if (computed.plugins.lines) { if (computed.plugins.lines.error) { %>
|
||||||
|
<span class="diff error">@@ <%= computed.plugins.lines.error %> @@</span><% } else { %>
|
||||||
<div class="stdin"><%- meta.$ %> locale</div><!--
|
<span class="diff">@@ -<%= computed.plugins.lines.deleted %> +<%= computed.plugins.lines.added %> @@</span>
|
||||||
--><div class="stdout"><!--
|
<% }} -%>
|
||||||
--><span class="error"><%= computed.plugins.languages.error %></span>
|
</div><% } -%>
|
||||||
<% } else { -%>
|
<%# ============================================================= -%>
|
||||||
|
<% if (computed.plugins.languages) { %>
|
||||||
<div class="stdin"><%- meta.$ %> locale</div><!--
|
<div class="stdin"><%- meta.$ %> locale</div><%# -%>
|
||||||
--><div class="stdout"><!--
|
<div class="stdout"><%# -%>
|
||||||
--><% for (const {name, value} of computed.plugins.languages.favorites) { -%>
|
<% 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) %>%
|
<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><% } -%>
|
||||||
<div class="stdin"><%- meta.$ %> curl -I <%= user.websiteUrl %></div><!--
|
<%# ============================================================= -%>
|
||||||
--><div class="stdout"><!--
|
<% if (computed.plugins.pagespeed) { %>
|
||||||
--><span class="error"><%= computed.plugins.pagespeed.error %></span>
|
<div class="stdin"><%- meta.$ %> curl -I <%= user.websiteUrl %></div><%# -%>
|
||||||
<% } else { -%>
|
<div class="stdout"><%# -%>
|
||||||
|
<% if (computed.plugins.pagespeed.error) { -%>
|
||||||
<div class="stdin"><%- meta.$ %> curl -I <%= user.websiteUrl %></div><!--
|
<span class="error"><%= computed.plugins.pagespeed.error %></span><% } else { -%>
|
||||||
--><div class="stdout"><!--
|
<b>User-Agent</b>: Google PageSpeed API
|
||||||
--><b>User-Agent</b>: Google PageSpeed API
|
|
||||||
<b>Location</b>: <%= user.websiteUrl %>
|
<b>Location</b>: <%= user.websiteUrl %>
|
||||||
<% for (const {score, title} of computed.plugins.pagespeed.scores) { -%>
|
<% for (const {score, title} of computed.plugins.pagespeed.scores) { -%>
|
||||||
<b><%= `X-${title.replace(/ /g, "-")}` %></b>: <%= Math.round(score*100) %>%
|
<b><%= `X-${title.replace(/ /g, "-")}` %></b>: <%= !Number.isNaN(score) ? Math.round(score*100) : "-" %>%
|
||||||
<% }} -%></div><% } -%>
|
<% }} -%>
|
||||||
|
</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>
|
</div>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 8.1 KiB |
@@ -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 |
@@ -3,33 +3,5 @@
|
|||||||
|
|
||||||
/** Template processor */
|
/** Template processor */
|
||||||
export default async function ({login, q}, {conf, data, rest, graphql, plugins}, {s, pending, imports}) {
|
export default async function ({login, q}, {conf, data, rest, graphql, plugins}, {s, pending, imports}) {
|
||||||
//Common
|
|
||||||
await common(...arguments)
|
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") ? "#" : "$"}`,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
//Initialization
|
//Initialization
|
||||||
const __dirname = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..", "action")
|
const __dirname = path.join(path.dirname(url.fileURLToPath(import.meta.url)), "..", "action")
|
||||||
process.on("unhandledRejection", error => { throw error })
|
process.on("unhandledRejection", error => { throw error })
|
||||||
|
const templates = (await fs.promises.readdir(path.join(__dirname, "..", "src/templates"))).filter(name => !/.*[.]mjs$/.test(name))
|
||||||
|
|
||||||
/** Test function */
|
/** Test function */
|
||||||
export default async function test() {
|
export default async function test() {
|
||||||
@@ -22,12 +23,14 @@
|
|||||||
|
|
||||||
//Perform tests
|
//Perform tests
|
||||||
await test.build()
|
await test.build()
|
||||||
for (const template of [
|
for (const template of templates) {
|
||||||
"classic",
|
|
||||||
"terminal",
|
|
||||||
]) {
|
|
||||||
for (const q of [
|
for (const q of [
|
||||||
{},
|
{},
|
||||||
|
{"base.header":0},
|
||||||
|
{"base.activity":0},
|
||||||
|
{"base.community":0},
|
||||||
|
{"base.repositories":0},
|
||||||
|
{"base.metadata":0},
|
||||||
{followup:1},
|
{followup:1},
|
||||||
{languages:1},
|
{languages:1},
|
||||||
{followup:1, languages:1},
|
{followup:1, languages:1},
|
||||||
@@ -36,7 +39,7 @@
|
|||||||
{traffic:1},
|
{traffic:1},
|
||||||
{selfskip:1},
|
{selfskip:1},
|
||||||
{pagespeed: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}})
|
await test.metrics({graphql, rest, q:{template, repositories:1, ...q}})
|
||||||
}
|
}
|
||||||
@@ -46,7 +49,7 @@
|
|||||||
/** Metrics tests */
|
/** Metrics tests */
|
||||||
test.metrics = async function ({graphql, rest, q}) {
|
test.metrics = async function ({graphql, rest, q}) {
|
||||||
//Preparation
|
//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 = {
|
const plugins = {
|
||||||
lines:{enabled:true},
|
lines:{enabled:true},
|
||||||
traffic:{enabled:true},
|
traffic:{enabled:true},
|
||||||
|
|||||||
Reference in New Issue
Block a user