Merge branch 'main' into rei/hacky_embed
|
@ -1,18 +1,28 @@
|
|||
const {render} = require("pinski/plugins")
|
||||
const constants = require("../utils/constants")
|
||||
const {fetchChannel} = require("../utils/youtube")
|
||||
const {getUser} = require("../utils/getuser")
|
||||
const converters = require("../utils/converters")
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
route: `/channel/(${constants.regex.ucid})`, methods: ["GET"], code: async ({req, fill, url}) => {
|
||||
const id = fill[0]
|
||||
route: `/(c|channel|user)/(.+)`, methods: ["GET"], code: async ({req, fill, url}) => {
|
||||
const path = fill[0]
|
||||
const id = fill[1]
|
||||
const user = getUser(req)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
const data = await fetchChannel(id, settings.instance)
|
||||
const subscribed = user.isSubscribed(id)
|
||||
const data = await fetchChannel(path, id, settings.instance)
|
||||
const instanceOrigin = settings.instance
|
||||
|
||||
// problem with the channel? fetchChannel has collected the necessary information for us.
|
||||
// we can render a skeleton page, display the message, and provide the option to unsubscribe.
|
||||
if (data.error) {
|
||||
const statusCode = data.missing ? 410 : 500
|
||||
const subscribed = user.isSubscribed(id)
|
||||
return render(statusCode, "pug/channel-error.pug", {settings, data, subscribed, instanceOrigin})
|
||||
}
|
||||
|
||||
// everything is fine
|
||||
|
||||
// normalise info, apply watched status
|
||||
if (!data.second__subCountText && data.subCount) {
|
||||
data.second__subCountText = converters.subscriberCountToText(data.subCount)
|
||||
|
@ -24,7 +34,8 @@ module.exports = [
|
|||
video.watched = watchedVideos.includes(video.videoId)
|
||||
})
|
||||
}
|
||||
return render(200, "pug/channel.pug", {url, data, subscribed, instanceOrigin})
|
||||
const subscribed = user.isSubscribed(data.authorId)
|
||||
return render(200, "pug/channel.pug", {settings, data, subscribed, instanceOrigin})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -9,8 +9,7 @@ const {Matcher, PatternCompileError} = require("../utils/matcher")
|
|||
const filterMaxLength = 160
|
||||
const regexpEnabledText = constants.server_setup.allow_regexp_filters ? "" : "not"
|
||||
|
||||
function getCategories(req) {
|
||||
const user = getUser(req)
|
||||
function getCategories(user) {
|
||||
const filters = user.getFilters()
|
||||
|
||||
// Sort filters into categories for display. Titles are already sorted.
|
||||
|
@ -39,7 +38,9 @@ function getCategories(req) {
|
|||
module.exports = [
|
||||
{
|
||||
route: "/filters", methods: ["GET"], code: async ({req, url}) => {
|
||||
const categories = getCategories(req)
|
||||
const user = getUser(req)
|
||||
const categories = getCategories(user)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
let referrer = url.searchParams.get("referrer") || null
|
||||
|
||||
let type = null
|
||||
|
@ -54,7 +55,7 @@ module.exports = [
|
|||
label = url.searchParams.get("label")
|
||||
}
|
||||
|
||||
return render(200, "pug/filters.pug", {categories, type, contents, label, referrer, filterMaxLength, regexpEnabledText})
|
||||
return render(200, "pug/filters.pug", {settings, categories, type, contents, label, referrer, filterMaxLength, regexpEnabledText})
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -100,8 +101,10 @@ module.exports = [
|
|||
return true
|
||||
}, state => {
|
||||
const {type, contents, label, compileError} = state
|
||||
const categories = getCategories(req)
|
||||
return render(400, "pug/filters.pug", {categories, type, contents, label, compileError, filterMaxLength, regexpEnabledText})
|
||||
const user = getUser(req)
|
||||
const categories = getCategories(user)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
return render(400, "pug/filters.pug", {settings, categories, type, contents, label, compileError, filterMaxLength, regexpEnabledText})
|
||||
})
|
||||
.last(state => {
|
||||
const {type, contents, label} = state
|
||||
|
|
|
@ -23,10 +23,9 @@ module.exports = [
|
|||
const token = user.token
|
||||
|
||||
if (add) {
|
||||
await fetchChannel(ucid, settings.instance)
|
||||
await fetchChannel("channel", ucid, settings.instance)
|
||||
db.prepare(
|
||||
"INSERT INTO Subscriptions (token, ucid) VALUES (?, ?)"
|
||||
+ " ON CONFLICT (token, ucid) DO UPDATE SET channel_missing = 0"
|
||||
).run(token, ucid)
|
||||
} else {
|
||||
db.prepare("DELETE FROM Subscriptions WHERE token = ? AND ucid = ?").run(token, ucid)
|
||||
|
@ -41,7 +40,6 @@ module.exports = [
|
|||
}),
|
||||
content: "Success, redirecting..."
|
||||
}
|
||||
return redirect(params.get("referrer"), 303)
|
||||
} else {
|
||||
return {
|
||||
statusCode: 200,
|
||||
|
|
25
api/pages.js
|
@ -1,16 +1,35 @@
|
|||
const {render} = require("pinski/plugins")
|
||||
const {getUser} = require("../utils/getuser")
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
route: "/", methods: ["GET"], code: async ({req}) => {
|
||||
const userAgent = req.headers["user-agent"] || ""
|
||||
const mobile = userAgent.toLowerCase().includes("mobile")
|
||||
return render(200, "pug/home.pug", {mobile})
|
||||
const user = getUser(req)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
return render(200, "pug/home.pug", {settings, mobile})
|
||||
}
|
||||
},
|
||||
{
|
||||
route: "/js-licenses", methods: ["GET"], code: async () => {
|
||||
return render(200, "pug/js-licenses.pug")
|
||||
route: "/(?:js-)?licenses", methods: ["GET"], code: async ({req}) => {
|
||||
const user = getUser(req)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
return render(200, "pug/licenses.pug", {settings})
|
||||
}
|
||||
},
|
||||
{
|
||||
route: "/cant-think", methods: ["GET"], code: async ({req}) => {
|
||||
const user = getUser(req)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
return render(200, "pug/cant-think.pug", {settings})
|
||||
}
|
||||
},
|
||||
{
|
||||
route: "/privacy", methods: ["GET"], code: async ({req}) => {
|
||||
const user = getUser(req)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
return render(200, "pug/privacy.pug", {settings})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -26,7 +26,7 @@ module.exports = [
|
|||
const filters = user.getFilters()
|
||||
results = converters.applyVideoFilters(results, filters).videos
|
||||
|
||||
return render(200, "pug/search.pug", {url, query, results, instanceOrigin})
|
||||
return render(200, "pug/search.pug", {settings, url, query, results, instanceOrigin})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -7,6 +7,17 @@ const validate = require("../utils/validate")
|
|||
const V = validate.V
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
route: "/api/settings", methods: ["GET"], code: async ({req}) => {
|
||||
const user = getUser(req)
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
return {
|
||||
statusCode: 200,
|
||||
contentType: "application/json",
|
||||
content: settings
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
route: "/settings", methods: ["GET"], code: async ({req}) => {
|
||||
const user = getUser(req)
|
||||
|
|
|
@ -11,12 +11,14 @@ module.exports = [
|
|||
let hasSubscriptions = false
|
||||
let videos = []
|
||||
let channels = []
|
||||
let missingChannelCount = 0
|
||||
let refreshed = null
|
||||
if (user.token) {
|
||||
// trigger a background refresh, needed if they came back from being inactive
|
||||
refresher.skipWaiting()
|
||||
// get channels
|
||||
channels = db.prepare(`SELECT Channels.* FROM Channels INNER JOIN Subscriptions ON Channels.ucid = Subscriptions.ucid WHERE token = ? ORDER BY name`).all(user.token)
|
||||
missingChannelCount = channels.reduce((a, c) => a + c.missing, 0)
|
||||
// get refreshed status
|
||||
refreshed = db.prepare(`SELECT min(refreshed) as min, max(refreshed) as max, count(refreshed) as count FROM Channels INNER JOIN Subscriptions ON Channels.ucid = Subscriptions.ucid WHERE token = ?`).get(user.token)
|
||||
// get watched videos
|
||||
|
@ -37,7 +39,7 @@ module.exports = [
|
|||
}
|
||||
const settings = user.getSettingsOrDefaults()
|
||||
const instanceOrigin = settings.instance
|
||||
return render(200, "pug/subscriptions.pug", {url, settings, hasSubscriptions, videos, channels, refreshed, timeToPastText, instanceOrigin})
|
||||
return render(200, "pug/subscriptions.pug", {url, settings, hasSubscriptions, videos, channels, missingChannelCount, refreshed, timeToPastText, instanceOrigin})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -111,7 +111,7 @@ module.exports = [
|
|||
// Check if playback is allowed
|
||||
const videoTakedownInfo = db.prepare("SELECT id, org, url FROM TakedownVideos WHERE id = ?").get(id)
|
||||
if (videoTakedownInfo) {
|
||||
return render(451, "pug/takedown-video.pug", videoTakedownInfo)
|
||||
return render(451, "pug/takedown-video.pug", Object.assign({settings}, videoTakedownInfo))
|
||||
}
|
||||
|
||||
// Media fragment
|
||||
|
@ -129,7 +129,7 @@ module.exports = [
|
|||
// Work out how to fetch the video
|
||||
if (req.method === "GET") {
|
||||
if (settings.local) { // skip to the local fetching page, which will then POST video data in a moment
|
||||
return render(200, "pug/local-video.pug", {id})
|
||||
return render(200, "pug/local-video.pug", {settings, id})
|
||||
}
|
||||
var instanceOrigin = settings.instance
|
||||
var outURL = `${instanceOrigin}/api/v1/videos/${id}`
|
||||
|
@ -153,7 +153,7 @@ module.exports = [
|
|||
// automatically add the entry to the videos list, so it won't be fetched again
|
||||
const args = {id, ...channelTakedownInfo}
|
||||
db.prepare("INSERT INTO TakedownVideos (id, org, url) VALUES (@id, @org, @url)").run(args)
|
||||
return render(451, "pug/takedown-video.pug", channelTakedownInfo)
|
||||
return render(451, "pug/takedown-video.pug", Object.assign({settings}, channelTakedownInfo))
|
||||
}
|
||||
|
||||
// process stream list ordering
|
||||
|
@ -225,7 +225,7 @@ module.exports = [
|
|||
// Create appropriate formatted message
|
||||
const message = render(0, `pug/errors/${errorType}.pug`, locals).content
|
||||
|
||||
return render(500, "pug/video.pug", {video: {videoId: id}, error: true, message})
|
||||
return render(500, "pug/video.pug", {video: {videoId: id}, error: true, message, settings})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ const prepared = {
|
|||
channel_refreshed_update: db.prepare(
|
||||
"UPDATE Channels SET refreshed = ? WHERE ucid = ?"
|
||||
),
|
||||
unsubscribe_all_from_channel: db.prepare(
|
||||
"UPDATE Subscriptions SET channel_missing = 1 WHERE ucid = ?"
|
||||
channel_mark_as_missing: db.prepare(
|
||||
"UPDATE Channels SET missing = 1, missing_reason = ? WHERE ucid = ?"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class RefreshQueue {
|
|||
// get the next set of scheduled channels to refresh
|
||||
const afterTime = Date.now() - constants.caching.seen_token_subscriptions_eligible
|
||||
const channels = db.prepare(
|
||||
"SELECT DISTINCT Subscriptions.ucid FROM SeenTokens INNER JOIN Subscriptions ON SeenTokens.token = Subscriptions.token AND SeenTokens.seen > ? WHERE Subscriptions.channel_missing = 0 ORDER BY SeenTokens.seen DESC"
|
||||
"SELECT DISTINCT Subscriptions.ucid FROM SeenTokens INNER JOIN Subscriptions ON SeenTokens.token = Subscriptions.token INNER JOIN Channels ON Channels.ucid = Subscriptions.ucid WHERE Channels.missing = 0 AND SeenTokens.seen > ? ORDER BY SeenTokens.seen DESC"
|
||||
).pluck().all(afterTime)
|
||||
this.addLast(channels)
|
||||
this.lastLoadTime = Date.now()
|
||||
|
@ -72,11 +72,12 @@ class Refresher {
|
|||
this.refreshQueue = new RefreshQueue()
|
||||
this.state = this.sym.ACTIVE
|
||||
this.waitingTimeout = null
|
||||
this.lastFakeNotFoundTime = 0
|
||||
this.next()
|
||||
}
|
||||
|
||||
refreshChannel(ucid) {
|
||||
return fetch(`${constants.server_setup.local_instance_origin}/api/v1/channels/${ucid}/latest`).then(res => res.json()).then(root => {
|
||||
return fetch(`${constants.server_setup.local_instance_origin}/api/v1/channels/${ucid}/latest`).then(res => res.json()).then(/** @param {any} root */ root => {
|
||||
if (Array.isArray(root)) {
|
||||
root.forEach(video => {
|
||||
// organise
|
||||
|
@ -89,11 +90,24 @@ class Refresher {
|
|||
prepared.channel_refreshed_update.run(Date.now(), ucid)
|
||||
// console.log(`updated ${root.length} videos for channel ${ucid}`)
|
||||
} else if (root.identifier === "PUBLISHED_DATES_NOT_PROVIDED") {
|
||||
return [] // nothing we can do. skip this iteration.
|
||||
// nothing we can do. skip this iteration.
|
||||
} else if (root.identifier === "NOT_FOUND") {
|
||||
// the channel does not exist. we should unsubscribe all users so we don't try again.
|
||||
// console.log(`channel ${ucid} does not exist, unsubscribing all users`)
|
||||
prepared.unsubscribe_all_from_channel.run(ucid)
|
||||
// YouTube sometimes returns not found for absolutely no reason.
|
||||
// There is no way to distinguish between a fake missing channel and a real missing channel without requesting the real endpoint.
|
||||
// These fake missing channels often happen in bursts, which is why there is a cooldown.
|
||||
const timeSinceLastFakeNotFound = Date.now() - this.lastFakeNotFoundTime
|
||||
if (timeSinceLastFakeNotFound >= constants.caching.subscriptions_refesh_fake_not_found_cooldown) {
|
||||
// We'll request the real endpoint to verify.
|
||||
fetch(`${constants.server_setup.local_instance_origin}/api/v1/channels/${ucid}`).then(res => res.json()).then(/** @param {any} root */ root => {
|
||||
if (root.error && (root.identifier === "NOT_FOUND" || root.identifier === "ACCOUNT_TERMINATED")) {
|
||||
// The channel is really gone, and we should mark it as missing for everyone.
|
||||
prepared.channel_mark_as_missing.run(root.error, ucid)
|
||||
} else {
|
||||
// The channel is not actually gone and YouTube is trolling us.
|
||||
this.lastFakeNotFoundTime = Date.now()
|
||||
}
|
||||
})
|
||||
} // else youtube is currently trolling us, skip this until later.
|
||||
} else {
|
||||
throw new Error(root.error)
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 225 B After Width: | Height: | Size: 225 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="8" viewBox="0 0 5.821 2.117"><path d="M1.269.53l.767.793h.161L2.964.53h.211v.265L2.117 1.852 1.058.794V.529z" fill="#202020" paint-order="markers stroke fill"/></svg>
|
After Width: | Height: | Size: 226 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 6.615 6.615"><path d="M2.64 0s-.03.94-.424 1.215C1.823 1.49.885.894.885.894L.112 2.232.109 2.23l.003.002c.01.006.797.499.838.974.042.478-.944.992-.944.992l.77 1.34s.83-.442 1.265-.24c.435.204.387 1.314.387 1.314l1.546.003s.032-.94.425-1.215c.393-.275 1.331.321 1.331.321l.775-1.338s-.798-.496-.84-.974c-.041-.478.944-.993.944-.993l-.77-1.34s-.83.443-1.265.24C4.14 1.113 4.187.002 4.187.002zm.688 2.25a1.106 1.106 0 110 2.211 1.106 1.106 0 010-2.21z" fill="#c4c4c4" paint-order="fill markers stroke"/></svg>
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 6.615 6.615"><title>Settings</title><path d="M2.64 0s-.03.94-.424 1.215C1.823 1.49.885.894.885.894L.112 2.232.109 2.23l.003.002c.01.006.797.499.838.974.042.478-.944.992-.944.992l.77 1.34s.83-.442 1.265-.24c.435.204.387 1.314.387 1.314l1.546.003s.032-.94.425-1.215c.393-.275 1.331.321 1.331.321l.775-1.338s-.798-.496-.84-.974c-.041-.478.944-.993.944-.993l-.77-1.34s-.83.443-1.265.24C4.14 1.113 4.187.002 4.187.002zm.688 2.25a1.106 1.106 0 110 2.211 1.106 1.106 0 010-2.21z" paint-order="fill markers stroke"/></svg>
|
||||
|
|
Before Width: | Height: | Size: 582 B After Width: | Height: | Size: 611 B |
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="25" viewBox="0 0 7.937 6.615"><path d="M2.373 0h3.191a.52.52 0 01.521.521H1.852A.52.52 0 012.373 0zm-.91.794h5.011c.371 0 .67.298.67.67v.123l-6.35-.016v-.108c0-.37.298-.67.67-.67zm-.405 1.058C.472 1.852 0 2.184 0 2.77v2.868c0 .586.472.977 1.058.977H6.88c.586 0 1.059-.39 1.059-.977V2.77c0-.586-.473-.918-1.059-.918zM5.3 4.017c.167.099.19.276.012.366l-2.098.985c-.131.077-.304-.002-.302-.19V3.29c0-.203.18-.333.34-.245z" fill="#c4c4c4" paint-order="fill markers stroke"/></svg>
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="30" height="25" viewBox="0 0 7.937 6.615"><title>Subscriptions</title><path d="M2.373 0h3.191a.52.52 0 01.521.521H1.852A.52.52 0 012.373 0zm-.91.794h5.011c.371 0 .67.298.67.67v.123l-6.35-.016v-.108c0-.37.298-.67.67-.67zm-.405 1.058C.472 1.852 0 2.184 0 2.77v2.868c0 .586.472.977 1.058.977H6.88c.586 0 1.059-.39 1.059-.977V2.77c0-.586-.473-.918-1.059-.918zM5.3 4.017c.167.099.19.276.012.366l-2.098.985c-.131.077-.304-.002-.302-.19V3.29c0-.203.18-.333.34-.245z" paint-order="fill markers stroke"/></svg>
|
||||
|
|
Before Width: | Height: | Size: 535 B After Width: | Height: | Size: 569 B |
|
@ -5,22 +5,21 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.12.11",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
|
||||
"integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
|
||||
"version": "7.15.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
|
||||
"integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w=="
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.12.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.13.tgz",
|
||||
"integrity": "sha512-z7n7ybOUzaRc3wwqLpAX8UFIXsrVXUJhtNGBwAnLz6d1KUapqyq7ad2La8gZ6CXhHmGAIL32cop8Tst4/PNWLw=="
|
||||
"version": "7.16.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.6.tgz",
|
||||
"integrity": "sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.12.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz",
|
||||
"integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==",
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz",
|
||||
"integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.12.11",
|
||||
"lodash": "^4.17.19",
|
||||
"@babel/helper-validator-identifier": "^7.15.7",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -35,9 +34,9 @@
|
|||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
|
||||
"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||
"requires": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
|
@ -49,9 +48,9 @@
|
|||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
|
||||
"integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
|
||||
"requires": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^2.0.6"
|
||||
|
@ -76,18 +75,18 @@
|
|||
}
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"better-sqlite3": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.1.0.tgz",
|
||||
"integrity": "sha512-FV/snQ8F/kyqhdxsevzbojVtMowDWOfe1A5N3lYu1KJwoho2t7JgITmdlSc7DkOh3Zq65I+ZyeNWXQrkLEDFTg==",
|
||||
"version": "7.4.5",
|
||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-7.4.5.tgz",
|
||||
"integrity": "sha512-mybC3dgrtJeHkIRGP36tST7wjBlIMgTRAXhhO4bMpPZ17EG23FZxZeFcwKWy6o8mV1SKQFnQNyeAZlQpGrgheQ==",
|
||||
"requires": {
|
||||
"bindings": "^1.5.0",
|
||||
"prebuild-install": "^5.3.3",
|
||||
"tar": "4.4.10"
|
||||
"prebuild-install": "^7.0.0",
|
||||
"tar": "^6.1.11"
|
||||
}
|
||||
},
|
||||
"binary-extensions": {
|
||||
|
@ -104,9 +103,9 @@
|
|||
}
|
||||
},
|
||||
"bl": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
|
||||
"integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"requires": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
|
@ -134,12 +133,12 @@
|
|||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
|
||||
"integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"requires": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"call-bind": {
|
||||
|
@ -160,18 +159,18 @@
|
|||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
|
||||
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
||||
"integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
|
||||
"requires": {
|
||||
"anymatch": "~3.1.1",
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.1",
|
||||
"glob-parent": "~5.1.0",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.5.0"
|
||||
"readdirp": "~3.6.0"
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
|
@ -204,16 +203,16 @@
|
|||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"requires": {
|
||||
"mimic-response": "^2.0.0"
|
||||
"mimic-response": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
|
@ -227,9 +226,9 @@
|
|||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
|
||||
},
|
||||
"denque": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
|
||||
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
|
||||
"integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw=="
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
|
@ -273,17 +272,17 @@
|
|||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
|
||||
"integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"requires": {
|
||||
"minipass": "^2.6.0"
|
||||
"minipass": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz",
|
||||
"integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==",
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"optional": true
|
||||
},
|
||||
"function-bind": {
|
||||
|
@ -307,9 +306,9 @@
|
|||
}
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz",
|
||||
"integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
|
||||
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
|
@ -322,9 +321,9 @@
|
|||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
|
@ -338,9 +337,17 @@
|
|||
}
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
|
||||
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
|
||||
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
|
||||
},
|
||||
"has-tostringtag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
|
||||
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
|
||||
"requires": {
|
||||
"has-symbols": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
|
@ -348,9 +355,14 @@
|
|||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.1.13",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
||||
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"immutable": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
|
||||
"integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
|
@ -358,9 +370,9 @@
|
|||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
|
||||
},
|
||||
"is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
|
@ -371,9 +383,9 @@
|
|||
}
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
|
||||
"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
|
||||
"integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
|
@ -401,9 +413,9 @@
|
|||
}
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
|
||||
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
|
@ -419,12 +431,12 @@
|
|||
"integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
|
||||
},
|
||||
"is-regex": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz",
|
||||
"integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==",
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
|
||||
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.2",
|
||||
"has-symbols": "^1.0.1"
|
||||
"has-tostringtag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
|
@ -446,20 +458,23 @@
|
|||
"promise": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.5.0.tgz",
|
||||
"integrity": "sha512-ft3WayFSFUVBuJj7BMLKAQcSlItKtfjsKDDsii3rqFDAZ7t11zRe8ASw/GlmivGwVUYtwkQrxiGGpL6gFvB0ag=="
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
|
@ -467,20 +482,20 @@
|
|||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
|
||||
"integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
|
||||
"version": "3.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
|
||||
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
|
||||
"integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"requires": {
|
||||
"minipass": "^2.9.0"
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mixin-deep": {
|
||||
|
@ -489,12 +504,9 @@
|
|||
"integrity": "sha512-imbHQNRglyaplMmjBLL3V5R6Bfq5oM+ivds3SKgc6oRtzErEnBUUc5No11Z2pilkUvl42gJvi285xTNswcKCMA=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||
},
|
||||
"mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
|
@ -507,22 +519,20 @@
|
|||
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.19.1",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.1.tgz",
|
||||
"integrity": "sha512-HbtmIuByq44yhAzK7b9j/FelKlHYISKQn0mtvcBrU5QBkhoCMp5bu8Hv5AI34DcKfOAcJBcOEMwLlwO62FFu9A==",
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.5.0.tgz",
|
||||
"integrity": "sha512-LtHvNIBgOy5mO8mPEUtkCW/YCRWYEKshIvqhe1GHHyXEHEB5mgICyYnAcl4qan3uFeRROErKGzatFHPf6kDxWw==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
"semver": "^7.3.5"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
|
||||
},
|
||||
"noop-logger": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
|
||||
"integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
|
@ -559,45 +569,43 @@
|
|||
}
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
|
||||
"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg=="
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
|
||||
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw=="
|
||||
},
|
||||
"pinski": {
|
||||
"version": "git+https://git.sr.ht/~cadence/nodejs-pinski#210be3cfacbd93d44e104698a29abd39494a6271",
|
||||
"from": "git+https://git.sr.ht/~cadence/nodejs-pinski#210be3cfacbd93d44e104698a29abd39494a6271",
|
||||
"version": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725",
|
||||
"from": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725",
|
||||
"requires": {
|
||||
"mime": "^2.4.6",
|
||||
"pug": "^3.0.0",
|
||||
"sass": "^1.26.10",
|
||||
"ws": "^7.3.1"
|
||||
"mime": "^2.5.2",
|
||||
"pug": "^3.0.2",
|
||||
"sass": "^1.35.1",
|
||||
"ws": "^7.4.6"
|
||||
}
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "5.3.5",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.5.tgz",
|
||||
"integrity": "sha512-YmMO7dph9CYKi5IR/BzjOJlRzpxGGVo1EsLSUZ0mt/Mq0HWZIHOKHHcHdT69yG54C9m6i45GpItwRHpk0Py7Uw==",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.0.tgz",
|
||||
"integrity": "sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA==",
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.3",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"napi-build-utils": "^1.0.1",
|
||||
"node-abi": "^2.7.0",
|
||||
"noop-logger": "^0.1.1",
|
||||
"node-abi": "^3.3.0",
|
||||
"npmlog": "^4.0.1",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^3.0.3",
|
||||
"simple-get": "^4.0.0",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"which-pm-runs": "^1.0.0"
|
||||
"tunnel-agent": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
|
@ -614,17 +622,17 @@
|
|||
}
|
||||
},
|
||||
"pug": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pug/-/pug-3.0.0.tgz",
|
||||
"integrity": "sha512-inmsJyFBSHZaiGLaguoFgJGViX0If6AcfcElimvwj9perqjDpUpw79UIEDZbWFmoGVidh08aoE+e8tVkjVJPCw==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz",
|
||||
"integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==",
|
||||
"requires": {
|
||||
"pug-code-gen": "^3.0.0",
|
||||
"pug-code-gen": "^3.0.2",
|
||||
"pug-filters": "^4.0.0",
|
||||
"pug-lexer": "^5.0.0",
|
||||
"pug-lexer": "^5.0.1",
|
||||
"pug-linker": "^4.0.0",
|
||||
"pug-load": "^3.0.0",
|
||||
"pug-parser": "^6.0.0",
|
||||
"pug-runtime": "^3.0.0",
|
||||
"pug-runtime": "^3.0.1",
|
||||
"pug-strip-comments": "^2.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -639,9 +647,9 @@
|
|||
}
|
||||
},
|
||||
"pug-code-gen": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.1.tgz",
|
||||
"integrity": "sha512-xJIGvmXTQlkJllq6hqxxjRWcay2F9CU69TuAuiVZgHK0afOhG5txrQOcZyaPHBvSWCU/QQOqEp5XCH94rRZpBQ==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz",
|
||||
"integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==",
|
||||
"requires": {
|
||||
"constantinople": "^4.0.1",
|
||||
"doctypes": "^1.1.0",
|
||||
|
@ -671,9 +679,9 @@
|
|||
}
|
||||
},
|
||||
"pug-lexer": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.0.tgz",
|
||||
"integrity": "sha512-52xMk8nNpuyQ/M2wjZBN5gXQLIylaGkAoTk5Y1pBhVqaopaoj8Z0iVzpbFZAqitL4RHNVDZRnJDsqEYe99Ti0A==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
|
||||
"integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
|
||||
"requires": {
|
||||
"character-parser": "^2.2.0",
|
||||
"is-expression": "^4.0.0",
|
||||
|
@ -708,9 +716,9 @@
|
|||
}
|
||||
},
|
||||
"pug-runtime": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.0.tgz",
|
||||
"integrity": "sha512-GoEPcmQNnaTsePEdVA05bDpY+Op5VLHKayg08AQiqJBWU/yIaywEYv7TetC5dEQS3fzBBoyb2InDcZEg3mPTIA=="
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
|
||||
"integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg=="
|
||||
},
|
||||
"pug-strip-comments": {
|
||||
"version": "2.0.0",
|
||||
|
@ -760,19 +768,19 @@
|
|||
}
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
|
||||
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"requires": {
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
|
||||
"integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
||||
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
|
||||
"requires": {
|
||||
"is-core-module": "^2.1.0",
|
||||
"is-core-module": "^2.2.0",
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
|
@ -782,17 +790,22 @@
|
|||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"sass": {
|
||||
"version": "1.32.6",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.32.6.tgz",
|
||||
"integrity": "sha512-1bcDHDcSqeFtMr0JXI3xc/CXX6c4p0wHHivJdru8W7waM7a1WjKMm4m/Z5sY7CbVw4Whi2Chpcw6DFfSWwGLzQ==",
|
||||
"version": "1.45.1",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.45.1.tgz",
|
||||
"integrity": "sha512-pwPRiq29UR0o4X3fiQyCtrESldXvUQAAE0QmcJTpsI4kuHHcLzZ54M1oNBVIXybQv8QF2zfkpFcTxp8ta97dUA==",
|
||||
"requires": {
|
||||
"chokidar": ">=2.0.0 <4.0.0"
|
||||
"chokidar": ">=3.0.0 <4.0.0",
|
||||
"immutable": "^4.0.0",
|
||||
"source-map-js": ">=0.6.2 <2.0.0"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
"version": "7.3.5",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
|
@ -800,9 +813,9 @@
|
|||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz",
|
||||
"integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ=="
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.1",
|
||||
|
@ -810,15 +823,20 @@
|
|||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz",
|
||||
"integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==",
|
||||
"requires": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"decompress-response": "^6.0.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"source-map-js": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
|
||||
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
|
@ -851,36 +869,42 @@
|
|||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.10",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
|
||||
"integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
|
||||
"version": "6.1.11",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
|
||||
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"fs-minipass": "^1.2.5",
|
||||
"minipass": "^2.3.5",
|
||||
"minizlib": "^1.2.1",
|
||||
"mkdirp": "^0.5.0",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.3"
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^3.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"tar-fs": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.0.tgz",
|
||||
"integrity": "sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
|
||||
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
|
||||
"requires": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.0.0"
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.3.tgz",
|
||||
"integrity": "sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"requires": {
|
||||
"bl": "^4.0.1",
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
|
@ -917,6 +941,11 @@
|
|||
"resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ="
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
|
@ -935,17 +964,26 @@
|
|||
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
||||
"integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
|
||||
},
|
||||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||
"requires": {
|
||||
"string-width": "^1.0.2 || 2"
|
||||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"with": {
|
||||
|
@ -965,14 +1003,14 @@
|
|||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz",
|
||||
"integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA=="
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
|
||||
"integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
"author": "",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^7.1.0",
|
||||
"better-sqlite3": "^7.4.5",
|
||||
"cookie": "^0.4.1",
|
||||
"denque": "^1.4.1",
|
||||
"denque": "^1.5.1",
|
||||
"mixin-deep": "^2.0.1",
|
||||
"node-fetch": "^2.6.0",
|
||||
"pinski": "git+https://git.sr.ht/~cadence/nodejs-pinski#210be3cfacbd93d44e104698a29abd39494a6271"
|
||||
"node-fetch": "^2.6.6",
|
||||
"pinski": "git+https://git.sr.ht/~cadence/nodejs-pinski#e22095172a061a8271e28272e2e481d541ea6725"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ mixin leave(index, prefix="No more?", final)
|
|||
a(href="/search?q=cats+being+cute") [BLISS]
|
||||
|
||||
block content
|
||||
include includes/video-list-item
|
||||
main.cant-think-page
|
||||
- let src = constants.server_setup.cant_think_narration_url
|
||||
if src
|
||||
|
@ -71,3 +72,8 @@ block content
|
|||
p You know what you must do.
|
||||
p.ultimatum: a(href="#i-understand").border-look I know what I must do.
|
||||
a#i-understand
|
||||
|
||||
p.the-end Well, looks like you reached the end of the content.#[br]You know what happens now.
|
||||
h3 Recommended videos
|
||||
+video_list_item("related-video", {videoId: "jKKCF_Bqtw4", title: "dopamine review", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "84,651 views", second__lengthText: "3:10"})
|
||||
+video_list_item("related-video", {videoId: "gLYWLobR248", title: "I Watch My YouTube Videos At 2x Speed", author: "Jreg", authorId: "UCGSGPehp0RWfca-kENgBJ9Q", viewCountText: "125,625 views", second__lengthText: "2:24"})
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
extends includes/layout
|
||||
|
||||
include includes/video-list-item
|
||||
include includes/subscribe-button
|
||||
|
||||
block head
|
||||
title= `${data.row ? data.row.name : "Deleted channel"} - CloudTube`
|
||||
script(type="module" src=getStaticURL("html", "/static/js/channel.js"))
|
||||
|
||||
block content
|
||||
main.channel-page
|
||||
if data.row
|
||||
.channel-data
|
||||
.info
|
||||
- const iconURL = data.row.icon_url
|
||||
if iconURL
|
||||
.logo
|
||||
img(src=iconURL alt="").thumbnail-image
|
||||
.about
|
||||
h1.name= data.row.name
|
||||
+subscribe_button(data.ucid, subscribed, `/channel/${data.ucid}`).subscribe-button.base-border-look
|
||||
|
||||
.channel-error
|
||||
div= data.message
|
||||
|
||||
if data.missing && subscribed
|
||||
.you-should-unsubscribe To remove this channel from your subscriptions list, click Unsubscribe.
|
|
@ -3,7 +3,8 @@ html
|
|||
head
|
||||
meta(charset="utf-8")
|
||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||
link(rel="stylesheet" type="text/css" href=getStaticURL("sass", "/main.sass"))
|
||||
- const theme = settings && ["dark", "light", "edgeless-light"][settings.theme] || "dark"
|
||||
link(rel="stylesheet" type="text/css" href=getStaticURL("sass", `/${theme}.sass`))
|
||||
script(type="module" src=getStaticURL("html", "/static/js/focus.js"))
|
||||
block head
|
||||
|
||||
|
@ -15,13 +16,9 @@ html
|
|||
.links
|
||||
a(href="/").link.home CloudTube
|
||||
a(href="/subscriptions" title="Subscriptions").link.icon-link
|
||||
svg(width=30 height=25)
|
||||
image(href=getStaticURL("html", "/static/images/subscriptions.svg") alt="Subscriptions.").icon
|
||||
title Subscriptions
|
||||
!= icons.get("subscriptions")
|
||||
a(href="/settings" title="Settings").link.icon-link
|
||||
svg(width=25 height=25)
|
||||
image(href=getStaticURL("html", "/static/images/settings.svg") alt="Settings.").icon
|
||||
title Settings
|
||||
!= icons.get("settings")
|
||||
form(method="get" action="/search").search-form
|
||||
input(type="text" placeholder="Search" aria-label="Search a video" name="q" autocomplete="off" value=query).search
|
||||
|
||||
|
|
|
@ -36,6 +36,16 @@ block content
|
|||
form(method="post" action="/settings")
|
||||
+fieldset("Settings")
|
||||
|
||||
+select({
|
||||
id: "theme",
|
||||
label: "Theme",
|
||||
options: [
|
||||
{value: "0", text: "Standard dark"},
|
||||
{value: "1", text: "Standard light"},
|
||||
{value: "2", text: "Edgeless light"}
|
||||
]
|
||||
})
|
||||
|
||||
+input({
|
||||
id: "instance",
|
||||
label: "Instance",
|
||||
|
|
|
@ -11,12 +11,24 @@ block content
|
|||
if hasSubscriptions
|
||||
section
|
||||
details.channels-details
|
||||
summary #{channels.length} subscriptions
|
||||
summary
|
||||
| #{channels.length} subscriptions
|
||||
if missingChannelCount === 1
|
||||
= ` - ${missingChannelCount} channel is gone`
|
||||
else if missingChannelCount > 1
|
||||
= ` - ${missingChannelCount} channels are gone`
|
||||
.channels-list
|
||||
for channel in channels
|
||||
a(href=`/channel/${channel.ucid}`).channel-item
|
||||
img(src=channel.icon_url width=512 height=512 alt="").thumbnail
|
||||
span.name= channel.name
|
||||
div
|
||||
div.name= channel.name
|
||||
if channel.missing
|
||||
div.missing-reason
|
||||
if channel.missing_reason
|
||||
= channel.missing_reason
|
||||
else
|
||||
| This channel appears to be deleted or terminated. Click to check it.
|
||||
|
||||
if refreshed
|
||||
section
|
||||
|
@ -31,8 +43,8 @@ block content
|
|||
|
||||
if settings.save_history
|
||||
input(type="checkbox" id="watched-videos-display")
|
||||
.watched-videos-display-container
|
||||
label(for="watched-videos-display").watched-videos-display-label Hide watched videos
|
||||
.checkbox-hider__container
|
||||
label(for="watched-videos-display").checkbox-hider__label Hide watched videos
|
||||
|
||||
each video in videos
|
||||
+video_list_item("subscriptions-video", video, instanceOrigin, {showMarkWatched: settings.save_history && !video.watched})
|
||||
|
|
|
@ -21,6 +21,7 @@ block content
|
|||
noscript
|
||||
meta(http-equiv="refresh" content=`${video.lengthSeconds+5};url=/watch?v=${first.videoId}&continuous=1&session-watched=${sessionWatchedNext}`)
|
||||
.video-page(class={
|
||||
"video-page--recommended-side": settings.recommended_mode === 0,
|
||||
"video-page--recommended-below": settings.recommended_mode === 1,
|
||||
"video-page--recommended-hidden": settings.recommended_mode === 2
|
||||
})
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
@use "themes/dark" as *
|
||||
@use "includes/main" with ($_theme: $theme)
|
||||
|
||||
@use "theme-modules/edgeless" with ($_theme: $theme)
|
||||
|
||||
// navigation shadow
|
||||
.main-nav
|
||||
position: relative // needed for box shadow to overlap related videos section
|
||||
box-shadow: 0px 0px 20px 5px rgba(0, 0, 0, 0.1)
|
|
@ -0,0 +1,4 @@
|
|||
@use "themes/edgeless-light" as *
|
||||
@use "includes/main" with ($_theme: $theme)
|
||||
|
||||
@use "theme-modules/edgeless" with ($_theme: $theme)
|
|
@ -1,8 +1,10 @@
|
|||
@use "colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
body
|
||||
background-color: c.$bg-dark
|
||||
color: c.$fg-main
|
||||
background-color: map.get($_theme, "bg-2")
|
||||
color: map.get($_theme, "fg-main")
|
||||
font-family: "Bariol", sans-serif
|
||||
font-size: 18px
|
||||
margin: 0
|
||||
|
@ -13,13 +15,13 @@ body
|
|||
flex-direction: column
|
||||
|
||||
a
|
||||
color: c.$link
|
||||
color: map.get($_theme, "link")
|
||||
|
||||
pre, code
|
||||
font-size: 0.88em
|
||||
|
||||
code
|
||||
background: c.$bg-darker
|
||||
background: map.get($_theme, "bg-1")
|
||||
padding: 3px 5px
|
||||
border-radius: 4px
|
||||
|
||||
|
@ -32,7 +34,7 @@ button
|
|||
cursor: pointer
|
||||
|
||||
::placeholder
|
||||
color: #c4c4c4
|
||||
color: map.get($_theme, "placeholder")
|
||||
opacity: 1
|
||||
|
||||
// focus section
|
||||
|
@ -48,19 +50,20 @@ button
|
|||
|
||||
select:-moz-focusring
|
||||
color: transparent
|
||||
text-shadow: 0 0 0 c.$fg-bright
|
||||
text-shadow: 0 0 0 map.get($_theme, "fg-bright")
|
||||
|
||||
body.show-focus
|
||||
a, select, button, input, video, summary
|
||||
&:focus
|
||||
outline: 2px dotted #ddd
|
||||
outline: 2px dotted map.get($_theme, "fg-main")
|
||||
|
||||
video
|
||||
background-color: black
|
||||
|
||||
details
|
||||
background-color: c.$bg-accent-x
|
||||
background-color: map.get($_theme, "bg-3")
|
||||
padding: 12px
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
border-radius: 8px
|
||||
|
||||
summary
|
||||
|
@ -68,20 +71,22 @@ details
|
|||
line-height: 1
|
||||
margin-bottom: 0
|
||||
user-select: none
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
&[open] summary
|
||||
margin-bottom: 16px
|
||||
padding-bottom: 12px
|
||||
border-bottom: 1px solid map.get($_theme, "edge-grey")
|
||||
margin-bottom: 8px
|
||||
|
||||
table
|
||||
background-color: c.$bg-darker
|
||||
background-color: map.get($_theme, "bg-1")
|
||||
|
||||
table, td, th
|
||||
border: 1px solid c.$edge-grey
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
border-collapse: collapse
|
||||
|
||||
td, th
|
||||
padding: 4px 8px
|
||||
|
||||
thead, tr:nth-child(even)
|
||||
background-color: c.$bg-darkest
|
||||
background-color: map.get($_theme, "bg-0")
|
|
@ -1,10 +1,12 @@
|
|||
$_theme: () !default
|
||||
|
||||
@use "sass:selector"
|
||||
@use "colors.sass" as c
|
||||
@use "sass:map"
|
||||
|
||||
@mixin button-base
|
||||
-webkit-appearance: none
|
||||
-moz-appearance: none
|
||||
color: c.$fg-bright
|
||||
color: map.get($_theme, "fg-bright")
|
||||
border: none
|
||||
border-radius: 4px
|
||||
padding: 8px
|
||||
|
@ -14,7 +16,7 @@
|
|||
|
||||
@at-root #{selector.unify(&, "select")}
|
||||
padding: 8px 27px 8px 8px
|
||||
background: url(/static/images/arrow-down-wide.svg) right 53% no-repeat c.$bg-accent-x
|
||||
background: map.get($_theme, "image-dropdown") right 53% no-repeat map.get($_theme, "bg-4")
|
||||
|
||||
@at-root #{selector.unify(&, "a")}
|
||||
padding: 7px 8px
|
||||
|
@ -31,12 +33,12 @@
|
|||
@mixin button-bg
|
||||
@include button-base
|
||||
|
||||
background-color: c.$bg-accent-x
|
||||
background-color: map.get($_theme, "bg-4")
|
||||
|
||||
@mixin border-button
|
||||
@include button-bg
|
||||
|
||||
border: 1px solid c.$edge-grey
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
|
||||
@mixin button-size
|
||||
margin: 4px
|
||||
|
@ -44,10 +46,10 @@
|
|||
|
||||
@mixin button-hover
|
||||
&:hover
|
||||
background-color: c.$bg-accent
|
||||
background-color: map.get($_theme, "bg-3")
|
||||
|
||||
&:active
|
||||
background-color: c.$bg-dark
|
||||
background-color: map.get($_theme, "bg-2")
|
||||
|
||||
.base-border-look
|
||||
@include border-button
|
||||
|
@ -62,13 +64,13 @@
|
|||
@include button-size
|
||||
-webkit-appearance: none
|
||||
-moz-appearance: none
|
||||
color: c.$fg-bright
|
||||
color: map.get($_theme, "fg-bright")
|
||||
text-decoration: none
|
||||
line-height: 1.25
|
||||
margin: 0
|
||||
padding: 8px 20px
|
||||
background: c.$bg-accent
|
||||
border: solid c.$bg-darker
|
||||
background: map.get($_theme, "bg-3")
|
||||
border: solid map.get($_theme, "edge-grey")
|
||||
border-width: 1px 0px 0px
|
||||
text-align: left
|
||||
|
||||
|
@ -76,7 +78,7 @@
|
|||
border-width: 1px 0px 1px
|
||||
|
||||
&:hover
|
||||
background: c.$bg-accent-x
|
||||
background: map.get($_theme, "bg-4")
|
||||
|
||||
&:active
|
||||
background: c.$bg-darker
|
||||
background: map.get($_theme, "bg-1")
|
|
@ -1,5 +1,7 @@
|
|||
$_theme: () !default
|
||||
|
||||
@use "sass:list"
|
||||
@use "colors.sass" as c
|
||||
@use "sass:map"
|
||||
|
||||
.cant-think-page
|
||||
.main-nav
|
||||
|
@ -9,13 +11,14 @@
|
|||
text-align: left
|
||||
max-width: 572px
|
||||
padding-top: 40px
|
||||
margin-bottom: 12vh
|
||||
border-radius: 0px 0px 16px 16px
|
||||
box-sizing: border-box
|
||||
|
||||
.page-narration
|
||||
background-color: c.$bg-accent
|
||||
border: 1px solid #aaa
|
||||
color: #fff
|
||||
background-color: map.get($_theme, "bg-3")
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
color: map.get($_theme, "fg-bright")
|
||||
border-radius: 0
|
||||
padding: 16px
|
||||
margin: 40px auto 60px
|
||||
|
@ -28,7 +31,7 @@
|
|||
|
||||
.leave
|
||||
margin: 26px 32px !important
|
||||
color: #aaa
|
||||
color: map.get($_theme, "fg-dim")
|
||||
|
||||
$sizes: 14px 16px 21px 30px 72px
|
||||
@each $size in $sizes
|
||||
|
@ -37,7 +40,7 @@
|
|||
|
||||
&.leave__final
|
||||
font-weight: bold
|
||||
color: #f2f2f2
|
||||
color: map.get($_theme, "fg-bright")
|
||||
text-align: center
|
||||
|
||||
.leave__actions
|
||||
|
@ -54,6 +57,12 @@
|
|||
.ultimatum
|
||||
margin-top: 32px !important
|
||||
|
||||
.the-end
|
||||
margin: 120px 0px 1em !important
|
||||
|
||||
.thumbnail__more
|
||||
display: none
|
||||
|
||||
#i-understand
|
||||
display: flex
|
||||
height: 20px
|
||||
|
@ -65,6 +74,7 @@
|
|||
|
||||
&:target
|
||||
position: fixed
|
||||
z-index: 1
|
||||
top: 0
|
||||
bottom: 0
|
||||
left: 0
|
|
@ -1,6 +1,8 @@
|
|||
@use "colors.sass" as c
|
||||
@use "video-list-item.sass" as *
|
||||
@use "_dimensions.sass" as dimensions
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "_dimensions" as dimensions
|
||||
@use "video-list-item" as *
|
||||
|
||||
.channel-page
|
||||
padding: 40px 20px 20px
|
||||
|
@ -17,7 +19,7 @@
|
|||
align-self: flex-start
|
||||
|
||||
.channel-data
|
||||
background-color: c.$bg-darker
|
||||
background-color: map.get($_theme, "bg-1")
|
||||
padding: 24px
|
||||
margin: 12px 0px 24px
|
||||
border-radius: 8px
|
||||
|
@ -44,11 +46,11 @@
|
|||
.name
|
||||
font-size: 30px
|
||||
font-weight: normal
|
||||
color: c.$fg-bright
|
||||
color: map.get($_theme, "fg-bright")
|
||||
margin: 0
|
||||
|
||||
.subscribers
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
font-size: 18px
|
||||
|
||||
.subscribe-form
|
||||
|
@ -61,7 +63,8 @@
|
|||
line-height: 1
|
||||
border-radius: 8px
|
||||
font-size: 22px
|
||||
background-color: c.$power-deep
|
||||
background-color: map.get($_theme, "power-deep")
|
||||
color: map.get($_theme, "power-fg")
|
||||
border: none
|
||||
|
||||
.description
|
||||
|
@ -71,6 +74,19 @@
|
|||
.channel-video
|
||||
@include channel-video
|
||||
|
||||
.channel-error
|
||||
background-color: map.get($_theme, "bg-1")
|
||||
padding: 24px
|
||||
margin: 12px 0px 24px
|
||||
border-radius: 8px
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
font-size: 20px
|
||||
color: map.get($_theme, "fg-warning")
|
||||
|
||||
.you-should-unsubscribe
|
||||
margin-top: 20px
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
.about-description // class provided by youtube
|
||||
pre
|
||||
font-size: inherit
|
|
@ -1,10 +1,12 @@
|
|||
@use "colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
@mixin filter-notice
|
||||
margin-top: 24px
|
||||
padding: 12px
|
||||
border-radius: 8px
|
||||
background-color: c.$bg-darker
|
||||
background-color: map.get($_theme, "bg-1")
|
||||
white-space: pre-line
|
||||
|
||||
.filters-page
|
||||
|
@ -20,23 +22,23 @@
|
|||
|
||||
.filter-confirmation-notice
|
||||
@include filter-notice
|
||||
color: c.$fg-warning
|
||||
color: map.get($_theme, "fg-warning")
|
||||
|
||||
.filter-compile-error
|
||||
@include filter-notice
|
||||
|
||||
&__header
|
||||
color: c.$fg-warning
|
||||
color: map.get($_theme, "fg-warning")
|
||||
|
||||
&__trace
|
||||
background-color: c.$bg-darkest
|
||||
background-color: map.get($_theme, "bg-0")
|
||||
padding: 6px
|
||||
|
||||
.save-filter
|
||||
margin-top: 12px
|
||||
|
||||
.border-look
|
||||
background-color: c.$bg-darker
|
||||
background-color: map.get($_theme, "bg-1")
|
||||
font-size: 22px
|
||||
padding: 7px 16px 8px
|
||||
font-size: 24px
|
||||
|
@ -48,17 +50,17 @@
|
|||
.filter
|
||||
display: flex
|
||||
padding: 5px 0
|
||||
border-top: 1px solid c.$edge-grey
|
||||
border-top: 1px solid map.get($_theme, "edge-grey")
|
||||
|
||||
&:last-child
|
||||
border-bottom: 1px solid c.$edge-grey
|
||||
border-bottom: 1px solid map.get($_theme, "edge-grey")
|
||||
|
||||
&__details
|
||||
flex: 1
|
||||
|
||||
&__type
|
||||
font-size: 15px
|
||||
color: c.$fg-dim
|
||||
color: map.get($_theme, "fg-dim")
|
||||
|
||||
&__remove
|
||||
flex-shrink: 0
|
|
@ -1,4 +1,6 @@
|
|||
@use "./colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
.footer__container
|
||||
flex: 1
|
||||
|
@ -10,9 +12,10 @@
|
|||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
background-color: c.$bg-darkest
|
||||
background-color: map.get($_theme, "bg-dim")
|
||||
margin: 40px 0 0
|
||||
padding: 10px 10px 30px
|
||||
border-top: 1px solid map.get($_theme, "edge-grey")
|
||||
|
||||
.footer__cols
|
||||
display: flex
|
|
@ -1,7 +1,9 @@
|
|||
@use "colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
@mixin disabled
|
||||
background-color: c.$bg-dark
|
||||
background-color: map.get($_theme, "bg-2")
|
||||
color: #808080
|
||||
|
||||
fieldset
|
||||
|
@ -20,7 +22,7 @@ fieldset
|
|||
font-size: 28px
|
||||
font-weight: bold
|
||||
padding: 0
|
||||
border-bottom: 1px solid #333
|
||||
border-bottom: 1px solid map.get($_theme, "edge-grey") // TODO: originally contrasted more
|
||||
line-height: 1.56
|
||||
|
||||
@media screen and (max-width: 400px)
|
||||
|
@ -36,7 +38,7 @@ fieldset
|
|||
position: relative
|
||||
padding-bottom: 5px
|
||||
margin-bottom: 5px
|
||||
border-bottom: 1px solid #999
|
||||
border-bottom: 1px solid map.get($_theme, "edge-grey")
|
||||
|
||||
@media screen and (max-width: 400px)
|
||||
flex-direction: column
|
||||
|
@ -52,7 +54,7 @@ fieldset
|
|||
&__label
|
||||
grid-area: label
|
||||
padding: 8px 8px 8px 0px
|
||||
color: #fff
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
&__input
|
||||
grid-area: input
|
||||
|
@ -63,7 +65,7 @@ fieldset
|
|||
white-space: pre-line
|
||||
margin: 12px 0px 18px
|
||||
font-size: 16px
|
||||
color: #ccc
|
||||
color: map.get($_theme, "fg-dim")
|
||||
line-height: 1.2
|
||||
|
||||
//
|
||||
|
@ -79,7 +81,7 @@ fieldset
|
|||
width: 16px
|
||||
height: 16px
|
||||
padding: 0px
|
||||
border: 1px solid #666
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
border-radius: 3px
|
||||
margin-left: 8px
|
||||
position: relative
|
||||
|
@ -101,6 +103,20 @@ fieldset
|
|||
@include acts-like-button
|
||||
cursor: pointer
|
||||
|
||||
.checkbox-hider__container
|
||||
position: relative
|
||||
display: grid // why does the default not work???
|
||||
top: -42px
|
||||
background: map.get($_theme, "bg-3")
|
||||
line-height: 1
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
border-radius: 8px
|
||||
margin-bottom: -18px
|
||||
|
||||
.checkbox-hider__label
|
||||
padding: 12px 0px 12px 32px
|
||||
cursor: pointer
|
||||
|
||||
@mixin checkbox-hider($base)
|
||||
##{$base}
|
||||
position: relative
|
||||
|
@ -110,18 +126,17 @@ fieldset
|
|||
height: 42px
|
||||
margin: 0
|
||||
|
||||
.#{$base}-container
|
||||
position: relative
|
||||
display: grid // why does the default not work???
|
||||
top: -42px
|
||||
background: c.$bg-accent-x
|
||||
line-height: 1
|
||||
border-radius: 8px
|
||||
margin-bottom: -18px
|
||||
/*
|
||||
automatically add these styles too
|
||||
this means that components based off this can either add the .checkbox-hider__container class, or they can add the .base-name-container class,
|
||||
depending on which one is more reasonable in the moment
|
||||
for example, .delete-confirm-container takes advantage of the @extend here.
|
||||
|
||||
.#{$base}-label
|
||||
padding: 12px 0px 12px 32px
|
||||
cursor: pointer
|
||||
.#{$base}-container
|
||||
@extend .checkbox-hider__container
|
||||
|
||||
.#{$base}-label
|
||||
@extend .checkbox-hider__label
|
||||
|
||||
@mixin single-button-form
|
||||
display: inline-block
|
|
@ -1,4 +1,6 @@
|
|||
@use "colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
.home-page
|
||||
padding: 40px
|
||||
|
@ -18,8 +20,8 @@
|
|||
padding: 16px
|
||||
border-radius: 4px
|
||||
font-size: 20px
|
||||
background-color: c.$bg-darker
|
||||
color: c.$fg-main
|
||||
background-color: map.get($_theme, "bg-1")
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
p
|
||||
margin: 0 32px
|
|
@ -1,3 +1,5 @@
|
|||
$_theme: () !default
|
||||
|
||||
.js-licenses-page
|
||||
max-width: 800px
|
||||
margin: 0 auto
|
|
@ -0,0 +1,32 @@
|
|||
$_theme: () !default
|
||||
|
||||
@use "sass:selector"
|
||||
|
||||
// preload second-level includes with the theme (there will be conflicts due to reconfiguration they are loaded individually)
|
||||
// this isn't _exactly_ what @forward is supposed to be used for, but it's the best option here
|
||||
@forward "video-list-item" show _ with ($_theme: $_theme)
|
||||
@forward "forms" show _ with ($_theme: $_theme)
|
||||
@forward "buttons" show _ with ($_theme: $_theme)
|
||||
|
||||
@use "base" with ($_theme: $_theme)
|
||||
@use "video-page" with ($_theme: $_theme)
|
||||
@use "search-page" with ($_theme: $_theme)
|
||||
@use "home-page" with ($_theme: $_theme)
|
||||
@use "channel-page" with ($_theme: $_theme)
|
||||
@use "subscriptions-page" with ($_theme: $_theme)
|
||||
@use "settings-page" with ($_theme: $_theme)
|
||||
@use "cant-think-page" with ($_theme: $_theme)
|
||||
@use "privacy-page" with ($_theme: $_theme)
|
||||
@use "licenses-page" with ($_theme: $_theme)
|
||||
@use "filters-page" with ($_theme: $_theme)
|
||||
@use "takedown-page" with ($_theme: $_theme)
|
||||
@use "nav" with ($_theme: $_theme)
|
||||
@use "footer" with ($_theme: $_theme)
|
||||
|
||||
@font-face
|
||||
font-family: "Bariol"
|
||||
src: url(/static/fonts/bariol.woff?statichash=1)
|
||||
|
||||
.button-container
|
||||
display: flex
|
||||
flex-wrap: wrap
|
|
@ -1,12 +1,14 @@
|
|||
@use "colors.sass" as c
|
||||
@use "buttons.sass" as *
|
||||
@use "_dimensions.sass" as dimensions
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "buttons" as *
|
||||
@use "_dimensions" as dimensions
|
||||
|
||||
.main-nav
|
||||
background-color: c.$bg-accent
|
||||
background-color: map.get($_theme, "bg-nav")
|
||||
display: flex
|
||||
padding: 8px
|
||||
box-shadow: 0px 0px 20px 5px rgba(0, 0, 0, 0.1)
|
||||
border-bottom: 1px solid map.get($_theme, "edge-grey")
|
||||
|
||||
+dimensions.thin
|
||||
display: block
|
||||
|
@ -30,10 +32,16 @@
|
|||
font-weight: bold
|
||||
|
||||
&, &:visited
|
||||
color: #fff
|
||||
color: map.get($_theme, "fg-bright")
|
||||
|
||||
&:focus, &:hover
|
||||
background-color: c.$bg-accent-x
|
||||
background-color: map.get($_theme, "bg-4")
|
||||
|
||||
&.icon-link
|
||||
color: map.get($_theme, "fg-dim")
|
||||
|
||||
&:hover, &:focus
|
||||
color: map.get($_theme, "fg-bright")
|
||||
|
||||
.search-form
|
||||
display: flex
|
||||
|
@ -44,8 +52,7 @@
|
|||
@include button-bg
|
||||
padding: 10px
|
||||
flex: 1
|
||||
margin: 1px
|
||||
border: 1px solid map.get($_theme, "bg-nav")
|
||||
|
||||
&:hover, &:focus
|
||||
border: 1px solid c.$edge-grey
|
||||
margin: 0px
|
||||
border-color: map.get($_theme, "edge-grey")
|
|
@ -1,3 +1,5 @@
|
|||
$_theme: () !default
|
||||
|
||||
.privacy-page
|
||||
max-width: 600px
|
||||
margin: 0 auto
|
|
@ -1,5 +1,7 @@
|
|||
@use "video-list-item.sass" as *
|
||||
@use "colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "video-list-item" as *
|
||||
|
||||
.search-page
|
||||
padding: 40px 20px 20px
|
|
@ -1,5 +1,7 @@
|
|||
@use "forms.sass" as forms
|
||||
@use "colors.sass" as c
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "forms" as forms
|
||||
|
||||
.settings-page
|
||||
padding: 40px 20px 20px
|
||||
|
@ -19,8 +21,9 @@
|
|||
.more-settings
|
||||
margin-top: 24px
|
||||
padding: 12px
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
border-radius: 8px
|
||||
background-color: c.$bg-accent-x
|
||||
background-color: map.get($_theme, "bg-3")
|
||||
|
||||
&__list
|
||||
margin: 0
|
||||
|
@ -34,7 +37,7 @@
|
|||
margin-top: 24px
|
||||
|
||||
.delete-confirm-container
|
||||
background: c.$bg-darker
|
||||
background: map.get($_theme, "bg-1")
|
||||
margin-bottom: -36px
|
||||
|
||||
@include forms.checkbox-hider("delete-confirm")
|
|
@ -1,6 +1,8 @@
|
|||
@use "colors.sass" as c
|
||||
@use "video-list-item.sass" as *
|
||||
@use "forms.sass" as forms
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "forms" as forms
|
||||
@use "video-list-item" as *
|
||||
|
||||
.subscriptions-page
|
||||
padding: 40px 20px 20px
|
||||
|
@ -33,7 +35,11 @@
|
|||
|
||||
.name
|
||||
font-size: 22px
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
.missing-reason
|
||||
font-size: 16px
|
||||
color: map.get($_theme, "fg-warning")
|
||||
|
||||
@include forms.checkbox-hider("watched-videos-display")
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
.takedown-page
|
||||
max-width: 700px
|
||||
margin: 0 auto
|
||||
|
||||
.new-section
|
||||
margin-top: 200px
|
||||
|
||||
.important-section
|
||||
padding: 4px 20px
|
||||
border: 1px solid map.get($_theme, "edge-grey")
|
||||
color: map.get($_theme, "fg-bright")
|
||||
background-color: map.get($_theme, "bg-1")
|
|
@ -1,5 +1,7 @@
|
|||
@use "colors.sass" as c
|
||||
@use "_dimensions.sass" as dimensions
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "_dimensions" as dimensions
|
||||
|
||||
// navigator hacks
|
||||
.thumbnail > .thumbnail__options-container
|
||||
|
@ -30,6 +32,7 @@
|
|||
&__show-more
|
||||
display: block
|
||||
height: $more-size
|
||||
color: #fff
|
||||
line-height: 16px
|
||||
font-size: 25px
|
||||
text-align: center
|
||||
|
@ -52,7 +55,7 @@
|
|||
&__options-list
|
||||
pointer-events: auto
|
||||
display: grid
|
||||
background-color: c.$bg-accent
|
||||
background-color: map.get($_theme, "bg-3")
|
||||
padding: 8px 0px
|
||||
border-radius: 8px
|
||||
box-shadow: 0 2px 6px 2px #000
|
||||
|
@ -67,7 +70,7 @@
|
|||
right: 0
|
||||
transform: translate(-6px, -1px) rotate(-45deg)
|
||||
clip-path: polygon(-5% -20%, 120% -20%, 120% 125%)
|
||||
background-color: c.$bg-accent
|
||||
background-color: map.get($_theme, "bg-3")
|
||||
box-shadow: 0px 0px 4px 0px #000
|
||||
pointer-events: none
|
||||
|
||||
|
@ -80,7 +83,7 @@
|
|||
margin-bottom: 12px
|
||||
|
||||
@at-root .video-list-item--watched#{&}
|
||||
background: c.$bg-darker
|
||||
background: map.get($_theme, "bg-dim")
|
||||
padding: 4px 4px 0px
|
||||
margin: -4px -4px 8px
|
||||
|
||||
|
@ -93,7 +96,7 @@
|
|||
.thumbnail
|
||||
position: relative
|
||||
display: flex
|
||||
background: c.$bg-darkest
|
||||
background: map.get($_theme, "bg-0")
|
||||
|
||||
&__link
|
||||
font-size: 0 // remove whitespace around the image
|
||||
|
@ -106,7 +109,7 @@
|
|||
position: absolute
|
||||
bottom: 3px
|
||||
right: 3px
|
||||
color: c.$fg-bright
|
||||
color: #fff
|
||||
font-size: 14px
|
||||
background: rgba(20, 20, 20, 0.85)
|
||||
line-height: 1
|
||||
|
@ -119,20 +122,20 @@
|
|||
line-height: 1.2
|
||||
|
||||
.title-link
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
text-decoration: none
|
||||
|
||||
.author-line
|
||||
margin-top: 4px
|
||||
font-size: 15px
|
||||
color: c.$fg-dim
|
||||
color: map.get($_theme, "fg-dim")
|
||||
|
||||
.author
|
||||
color: c.$fg-dim
|
||||
color: map.get($_theme, "fg-dim")
|
||||
text-decoration: none
|
||||
|
||||
&:hover, &:active
|
||||
color: c.$fg-bright
|
||||
color: map.get($_theme, "fg-bright")
|
||||
text-decoration: underline
|
||||
|
||||
@mixin recommendation-item
|
||||
|
@ -176,15 +179,15 @@
|
|||
|
||||
.author-line
|
||||
font-size: 15px
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
.author
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
.description
|
||||
margin-top: 16px
|
||||
font-size: 15px
|
||||
color: c.$fg-dim
|
||||
color: map.get($_theme, "fg-dim")
|
||||
|
||||
+dimensions.thin
|
||||
.description
|
||||
|
@ -195,7 +198,7 @@
|
|||
|
||||
.description b
|
||||
font-weight: normal
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
|
||||
@mixin channel-video
|
||||
@include large-item
|
|
@ -1,11 +1,11 @@
|
|||
@use "colors.sass" as c
|
||||
@use "video-list-item.sass" as *
|
||||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
@use "video-list-item" as *
|
||||
|
||||
.video-page
|
||||
display: grid
|
||||
grid-auto-flow: row
|
||||
padding: 20px
|
||||
grid-gap: 16px
|
||||
|
||||
@media screen and (min-width: 1000px)
|
||||
grid-template-columns: 1fr 400px
|
||||
|
@ -13,10 +13,25 @@
|
|||
&--recommended-below, &--recommended-hidden
|
||||
grid-template-columns: none
|
||||
|
||||
&--recommended-hidden .related-videos
|
||||
display: none
|
||||
&--recommended-side
|
||||
.related-videos
|
||||
border-left: 1px solid map.get($_theme, "edge-grey")
|
||||
padding-left: 12px
|
||||
padding-right: 20px
|
||||
background-color: map.get($_theme, "bg-4")
|
||||
padding-top: 12px
|
||||
|
||||
&--recommended-below
|
||||
.related-videos
|
||||
padding: 20px
|
||||
|
||||
&--recommended-hidden
|
||||
.related-videos
|
||||
display: none
|
||||
|
||||
.main-video-section
|
||||
padding: 20px
|
||||
|
||||
.video-container
|
||||
text-align: center
|
||||
|
||||
|
@ -27,7 +42,7 @@
|
|||
max-height: 80vh
|
||||
|
||||
.stream-notice
|
||||
background: c.$bg-darkest
|
||||
background: map.get($_theme, "bg-0")
|
||||
padding: 4px
|
||||
|
||||
.info
|
||||
|
@ -45,15 +60,15 @@
|
|||
margin: 0px 0px 4px
|
||||
font-size: 30px
|
||||
font-weight: normal
|
||||
color: c.$fg-bright
|
||||
color: map.get($_theme, "fg-bright")
|
||||
word-break: break-word
|
||||
|
||||
.author-link
|
||||
color: c.$fg-main
|
||||
color: map.get($_theme, "fg-main")
|
||||
text-decoration: none
|
||||
|
||||
&:hover, &:active
|
||||
color: c.$fg-bright
|
||||
color: map.get($_theme, "fg-bright")
|
||||
text-decoration: underline
|
||||
|
||||
.info-secondary
|
||||
|
@ -75,7 +90,7 @@
|
|||
margin: 16px 4px
|
||||
padding: 12px
|
||||
border-radius: 4px
|
||||
background-color: c.$bg-darkest
|
||||
background-color: map.get($_theme, "bg-0")
|
||||
|
||||
&__description
|
||||
margin-left: 12px
|
||||
|
@ -85,7 +100,7 @@
|
|||
|
||||
&__script-warning
|
||||
font-size: 15px
|
||||
color: c.$fg-warning
|
||||
color: map.get($_theme, "fg-warning")
|
||||
|
||||
&__buttons
|
||||
display: flex
|
||||
|
@ -97,12 +112,12 @@
|
|||
line-height: 1.4
|
||||
word-break: break-word
|
||||
margin: 16px 4px 4px 4px
|
||||
background-color: c.$bg-accent-area
|
||||
background-color: map.get($_theme, "bg-5")
|
||||
padding: 12px
|
||||
border-radius: 4px
|
||||
|
||||
--regular-background: #{c.$bg-accent-area}
|
||||
--highlight-background: #{c.$bg-darker}
|
||||
--regular-background: #{map.get($_theme, "bg-5")}
|
||||
--highlight-background: #{map.get($_theme, "bg-1")}
|
||||
|
||||
.subscribe-form
|
||||
display: inline-block
|
|
@ -1,17 +0,0 @@
|
|||
$bg-darkest: #202123
|
||||
$bg-darker: #303336
|
||||
$bg-dark: #36393f
|
||||
$bg-accent: #4f5359
|
||||
$bg-accent-x: #3f4247
|
||||
$bg-accent-area: #44474b
|
||||
|
||||
$fg-bright: #fff
|
||||
$fg-main: #ddd
|
||||
$fg-dim: #bbb
|
||||
$fg-warning: #fdca6d
|
||||
|
||||
$edge-grey: #a0a0a0
|
||||
|
||||
$link: #8ac2f9
|
||||
|
||||
$power-deep: #c62727
|
|
@ -1,14 +0,0 @@
|
|||
@use "colors.sass" as c
|
||||
|
||||
.takedown-page
|
||||
max-width: 700px
|
||||
margin: 0 auto
|
||||
|
||||
.new-section
|
||||
margin-top: 200px
|
||||
|
||||
.important-section
|
||||
padding: 4px 20px
|
||||
border: 1px solid c.$edge-grey
|
||||
color: c.$fg-bright
|
||||
background-color: c.$bg-darker
|
|
@ -0,0 +1,2 @@
|
|||
@use "themes/light" as *
|
||||
@use "includes/main" with ($_theme: $theme)
|
|
@ -0,0 +1,27 @@
|
|||
$_theme: () !default
|
||||
|
||||
@use "sass:map"
|
||||
|
||||
// remove separating edges
|
||||
.main-nav, .footer__center, .video-page--recommended-side .related-videos
|
||||
border: none
|
||||
|
||||
// no background change to recommended videos sidebar
|
||||
.video-page--recommended-side .related-videos
|
||||
background-color: map.get($_theme, "bg-2")
|
||||
|
||||
// navigation shadow
|
||||
.main-nav
|
||||
position: relative // needed for box shadow to overlap related videos section
|
||||
box-shadow: 0px 0px 20px 5px rgba(0, 0, 0, 0.1)
|
||||
|
||||
// thumbnail dropdown menu dividers
|
||||
.menu-look
|
||||
border-color: map.get($_theme, "bg-0")
|
||||
|
||||
// details areas
|
||||
details, .checkbox-hider__container, .more-settings
|
||||
border: none
|
||||
details[open] summary
|
||||
border: none
|
||||
margin-bottom: 4px
|
|
@ -0,0 +1,38 @@
|
|||
// Defined in scss file instead of sass because indented syntax does not have multiline maps
|
||||
// https://github.com/sass/sass/issues/216
|
||||
|
||||
@use "sass:map";
|
||||
|
||||
// This section is for colour shades
|
||||
$theme: (
|
||||
// darker
|
||||
"bg-0": #252628,
|
||||
"bg-1": #303336,
|
||||
// regular
|
||||
"bg-2": #36393f,
|
||||
// lighter
|
||||
"bg-3": #3f4247, // slightly
|
||||
"bg-4": #44474b, // noticably
|
||||
"bg-5": #4f5359, // brightly
|
||||
|
||||
"fg-bright": #fff,
|
||||
"fg-main": #ddd,
|
||||
"fg-dim": #bbb,
|
||||
"fg-warning": #fdca6d,
|
||||
|
||||
"edge-grey": #a0a0a0,
|
||||
"placeholder": #c4c4c4,
|
||||
|
||||
"link": #8ac2f9,
|
||||
|
||||
"power-deep": #c62727,
|
||||
"power-fg": "#fff",
|
||||
|
||||
"image-dropdown": url(/static/images/arrow-down-wide-dark.svg)
|
||||
);
|
||||
|
||||
// This section is for colour meanings
|
||||
$theme: map.merge($theme, (
|
||||
"bg-dim": map.get($theme, "bg-0"),
|
||||
"bg-nav": map.get($theme, "bg-5"),
|
||||
));
|
|
@ -0,0 +1,8 @@
|
|||
// extend regular light theme to change a couple of shades
|
||||
@use "light";
|
||||
@use "sass:map";
|
||||
|
||||
// this section is for colour meanings
|
||||
$theme: map.merge(light.$theme, (
|
||||
"edge-grey": #c0c0c0,
|
||||
));
|
|
@ -0,0 +1,38 @@
|
|||
// Defined in scss file instead of sass because indented syntax does not have multiline maps
|
||||
// https://github.com/sass/sass/issues/216
|
||||
|
||||
@use "sass:map";
|
||||
|
||||
// this section is for colour shades
|
||||
$theme: (
|
||||
// lighter
|
||||
"bg-0": #fff,
|
||||
"bg-1": #fff,
|
||||
// regular
|
||||
"bg-2": #f2f2f2,
|
||||
// darker
|
||||
"bg-3": #e8e8e8, // slightly
|
||||
"bg-4": #dadada, // noticably
|
||||
"bg-5": #d0d0d0, // brightly
|
||||
|
||||
"fg-bright": #000,
|
||||
"fg-main": #202020,
|
||||
"fg-dim": #454545,
|
||||
"fg-warning": #ce8600,
|
||||
|
||||
"edge-grey": #909090,
|
||||
"placeholder": #636363,
|
||||
|
||||
"link": #0b51d4,
|
||||
|
||||
"power-deep": #c62727,
|
||||
"power-fg": #fff,
|
||||
|
||||
"image-dropdown": url(/static/images/arrow-down-wide-light.svg)
|
||||
);
|
||||
|
||||
// this section is for colour meanings
|
||||
$theme: map.merge($theme, (
|
||||
"bg-dim": map.get($theme, "bg-4"),
|
||||
"bg-nav": map.get($theme, "bg-0")
|
||||
));
|
12
server.js
|
@ -1,9 +1,11 @@
|
|||
const {Pinski} = require("pinski")
|
||||
const {setInstance} = require("pinski/plugins")
|
||||
const constants = require("./utils/constants")
|
||||
const iconLoader = require("./utils/icon-loader").icons
|
||||
|
||||
;(async () => {
|
||||
await require("./utils/upgradedb")()
|
||||
const icons = await iconLoader
|
||||
|
||||
const server = new Pinski({
|
||||
port: 10412,
|
||||
|
@ -13,19 +15,19 @@ const constants = require("./utils/constants")
|
|||
|
||||
setInstance(server)
|
||||
server.pugDefaultLocals.constants = constants
|
||||
server.pugDefaultLocals.icons = icons
|
||||
|
||||
server.muteLogsStartingWith("/vi/")
|
||||
server.muteLogsStartingWith("/favicon")
|
||||
server.muteLogsStartingWith("/static")
|
||||
|
||||
server.addSassDir("sass", ["sass/includes"])
|
||||
server.addRoute("/static/css/main.css", "sass/main.sass", "sass")
|
||||
server.addSassDir("sass", ["sass/includes", "sass/themes", "sass/theme-modules"])
|
||||
server.addRoute("/static/css/dark.css", "sass/dark.sass", "sass")
|
||||
server.addRoute("/static/css/light.css", "sass/light.sass", "sass")
|
||||
server.addRoute("/static/css/edgeless-light.css", "sass/edgeless-light.sass", "sass")
|
||||
|
||||
server.addPugDir("pug", ["pug/includes"])
|
||||
server.addPugDir("pug/errors")
|
||||
server.addRoute("/cant-think", "pug/cant-think.pug", "pug")
|
||||
server.addRoute("/privacy", "pug/privacy.pug", "pug")
|
||||
server.addRoute("/licenses", "pug/licenses.pug", "pug")
|
||||
|
||||
server.addStaticHashTableDir("html/static/js")
|
||||
server.addStaticHashTableDir("html/static/js/elemjs")
|
||||
|
|
|
@ -9,6 +9,10 @@ let constants = {
|
|||
type: "string",
|
||||
default: "http://localhost:3000"
|
||||
},
|
||||
theme: {
|
||||
type: "integer",
|
||||
default: 0
|
||||
},
|
||||
save_history: {
|
||||
type: "boolean",
|
||||
default: false
|
||||
|
@ -46,6 +50,7 @@ let constants = {
|
|||
csrf_time: 4*60*60*1000,
|
||||
seen_token_subscriptions_eligible: 40*60*60*1000,
|
||||
subscriptions_refresh_loop_min: 5*60*1000,
|
||||
subscriptions_refesh_fake_not_found_cooldown: 10*60*1000,
|
||||
},
|
||||
|
||||
// Pattern matching.
|
||||
|
|
|
@ -54,7 +54,7 @@ class User {
|
|||
|
||||
getSubscriptions() {
|
||||
if (this.token) {
|
||||
return db.prepare("SELECT ucid FROM Subscriptions WHERE token = ? AND channel_missing = 0").pluck().all(this.token)
|
||||
return db.prepare("SELECT ucid FROM Subscriptions WHERE token = ?").pluck().all(this.token)
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class User {
|
|||
|
||||
isSubscribed(ucid) {
|
||||
if (this.token) {
|
||||
return !!db.prepare("SELECT * FROM Subscriptions WHERE token = ? AND ucid = ? AND channel_missing = 0").get([this.token, ucid])
|
||||
return !!db.prepare("SELECT * FROM Subscriptions WHERE token = ? AND ucid = ?").get([this.token, ucid])
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
const fs = require("fs").promises
|
||||
|
||||
const names = ["subscriptions", "settings"]
|
||||
const icons = names.map(name => fs.readFile(`html/static/images/${name}.svg`, "utf8"))
|
||||
|
||||
module.exports.icons = Promise.all(icons).then(resolvedIcons => {
|
||||
return new Map(names.map((name, index) => [name, resolvedIcons[index]]))
|
||||
})
|
|
@ -70,6 +70,31 @@ const deltas = [
|
|||
.run()
|
||||
db.prepare("CREATE TABLE TakedownChannels (ucid TEXT NOT NULL, org TEXT, url TEXT, PRIMARY KEY (ucid))")
|
||||
.run()
|
||||
},
|
||||
// 11: Settings +theme
|
||||
function() {
|
||||
db.prepare("ALTER TABLE Settings ADD COLUMN theme INTEGER DEFAULT 0")
|
||||
.run()
|
||||
},
|
||||
// 12: Channels +missing +missing_reason, Subscriptions -
|
||||
// Better management for missing channels
|
||||
// We totally discard the existing Subscriptions.channel_missing since it is unreliable.
|
||||
function() {
|
||||
db.prepare("ALTER TABLE Channels ADD COLUMN missing INTEGER NOT NULL DEFAULT 0")
|
||||
.run()
|
||||
db.prepare("ALTER TABLE Channels ADD COLUMN missing_reason TEXT")
|
||||
.run()
|
||||
// https://www.sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes
|
||||
db.transaction(() => {
|
||||
db.prepare("CREATE TABLE NEW_Subscriptions (token TEXT NOT NULL, ucid TEXT NOT NULL, PRIMARY KEY (token, ucid))")
|
||||
.run()
|
||||
db.prepare("INSERT INTO NEW_Subscriptions (token, ucid) SELECT token, ucid FROM Subscriptions")
|
||||
.run()
|
||||
db.prepare("DROP TABLE Subscriptions")
|
||||
.run()
|
||||
db.prepare("ALTER TABLE NEW_Subscriptions RENAME TO Subscriptions")
|
||||
.run()
|
||||
})()
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -82,7 +107,7 @@ async function createBackup(entry) {
|
|||
|
||||
/**
|
||||
* @param {number} entry
|
||||
* @param {boolean} log
|
||||
* @param {boolean} [log]
|
||||
*/
|
||||
function runDelta(entry, log) {
|
||||
process.stdout.write(`Upgrading database to version ${entry}... `)
|
||||
|
|
|
@ -1,15 +1,59 @@
|
|||
const {request} = require("./request")
|
||||
const db = require("./db")
|
||||
|
||||
async function fetchChannel(ucid, instance) {
|
||||
async function fetchChannel(path, ucid, instance) {
|
||||
function updateGoodData(channel) {
|
||||
const bestIcon = channel.authorThumbnails.slice(-1)[0]
|
||||
const iconURL = bestIcon ? bestIcon.url : null
|
||||
db.prepare("REPLACE INTO Channels (ucid, name, icon_url, missing, missing_reason) VALUES (?, ?, ?, 0, NULL)").run(channel.authorId, channel.author, iconURL)
|
||||
}
|
||||
|
||||
function updateBadData(channel) {
|
||||
if (channel.identifier === "NOT_FOUND" || channel.identifier === "ACCOUNT_TERMINATED") {
|
||||
db.prepare("UPDATE Channels SET missing = 1, missing_reason = ? WHERE ucid = ?").run(channel.error, channel.authorId)
|
||||
return {
|
||||
missing: true,
|
||||
message: channel.error
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
missing: false,
|
||||
message: channel.error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!instance) throw new Error("No instance parameter provided")
|
||||
// fetch
|
||||
const channel = await request(`${instance}/api/v1/channels/${ucid}`).then(res => res.json())
|
||||
// update database
|
||||
const bestIcon = channel.authorThumbnails.slice(-1)[0]
|
||||
const iconURL = bestIcon ? bestIcon.url : null
|
||||
db.prepare("REPLACE INTO Channels (ucid, name, icon_url) VALUES (?, ?, ?)").run([channel.authorId, channel.author, iconURL])
|
||||
// return
|
||||
|
||||
const row = db.prepare("SELECT * FROM Channels WHERE ucid = ?").get(ucid)
|
||||
|
||||
// handle the case where the channel has a known error
|
||||
if (row && row.missing_reason) {
|
||||
return {
|
||||
error: true,
|
||||
ucid,
|
||||
row,
|
||||
missing: true,
|
||||
message: row.missing_reason
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {any} */
|
||||
const channel = await request(`${instance}/api/v1/channels/${ucid}?second__path=${path}`).then(res => res.json())
|
||||
|
||||
// handle the case where the channel has a newly discovered error
|
||||
if (channel.error) {
|
||||
const missingData = updateBadData(channel)
|
||||
return {
|
||||
error: true,
|
||||
ucid,
|
||||
row,
|
||||
...missingData
|
||||
}
|
||||
}
|
||||
|
||||
// handle the case where the channel returns good data (this is the only remaining scenario)
|
||||
updateGoodData(channel)
|
||||
return channel
|
||||
}
|
||||
|
||||
|
|