dark theme support
This commit is contained in:
parent
8979719a1a
commit
1c524efbf7
96
build_static.php
Executable file
96
build_static.php
Executable file
@ -0,0 +1,96 @@
|
|||||||
|
#!/usr/bin/env php8.1
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function gethash(string $path): string {
|
||||||
|
return substr(sha1(file_get_contents($path)), 0, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sassc(string $src_file, string $dst_file): int {
|
||||||
|
$cmd = 'sassc -t compressed '.escapeshellarg($src_file).' '.escapeshellarg($dst_file);
|
||||||
|
exec($cmd, $output, $code);
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clean_css(string $file) {
|
||||||
|
$output = $file.'.out';
|
||||||
|
if (file_exists($output))
|
||||||
|
unlink($output);
|
||||||
|
|
||||||
|
$cmd = ROOT.'/node_modules/clean-css-cli/bin/cleancss -O2 "all:on;mergeSemantically:on;restructureRules:on" '.escapeshellarg($file).' > '.escapeshellarg($output);
|
||||||
|
system($cmd);
|
||||||
|
|
||||||
|
if (file_exists($output)) {
|
||||||
|
unlink($file);
|
||||||
|
rename($output, $file);
|
||||||
|
} else {
|
||||||
|
fwrite(STDERR, "error: could not cleancss $file\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dark_diff(string $light_file, string $dark_file): void {
|
||||||
|
$temp_output = $dark_file.'.diff';
|
||||||
|
$cmd = ROOT.'/dark-theme-diff.js '.escapeshellarg($light_file).' '.$dark_file.' > '.$temp_output;
|
||||||
|
exec($cmd, $output, $code);
|
||||||
|
if ($code != 0) {
|
||||||
|
fwrite(STDERR, "dark_diff failed with code $code\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink($dark_file);
|
||||||
|
rename($temp_output, $dark_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
require __DIR__.'/init.php';
|
||||||
|
|
||||||
|
function build_static(): void {
|
||||||
|
$css_dir = ROOT.'/htdocs/css';
|
||||||
|
$hashes = [];
|
||||||
|
|
||||||
|
if (!file_exists($css_dir))
|
||||||
|
mkdir($css_dir);
|
||||||
|
|
||||||
|
// 1. scss -> css
|
||||||
|
$themes = ['light', 'dark'];
|
||||||
|
$entries = ['common', 'admin'];
|
||||||
|
foreach ($themes as $theme) {
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$input = ROOT.'/htdocs/scss/entries/'.$entry.'/'.$theme.'.scss';
|
||||||
|
$output = $css_dir.'/'.$entry.($theme == 'dark' ? '_dark' : '').'.css';
|
||||||
|
if (sassc($input, $output) != 0) {
|
||||||
|
fwrite(STDERR, "error: could not compile entries/$entry/$theme.scss\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1.1. apply clean-css optimizations and transformations
|
||||||
|
clean_css($output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. generate dark theme diff
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
$light_file = $css_dir.'/'.$entry.'.css';
|
||||||
|
$dark_file = str_replace('.css', '_dark.css', $light_file);
|
||||||
|
dark_diff($light_file, $dark_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. calculate hashes
|
||||||
|
foreach (['css', 'js'] as $type) {
|
||||||
|
$reldir = ROOT.'/htdocs/';
|
||||||
|
$entries = glob_recursive($reldir.$type.'/*.'.$type);
|
||||||
|
if (empty($entries)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach ($entries as $file) {
|
||||||
|
$name = preg_replace('/^'.preg_quote($reldir, '/').'/', '', $file);
|
||||||
|
$hashes[$name] = gethash($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. write config-static.php
|
||||||
|
$scfg = "<?php\n\n";
|
||||||
|
$scfg .= "return ".var_export($hashes, true).";\n";
|
||||||
|
|
||||||
|
file_put_contents(ROOT.'/config-static.php', $scfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
build_static();
|
14
dark-theme-diff.js
Executable file
14
dark-theme-diff.js
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const {generateCSSPatch} = require('css-patch')
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const files = process.argv.slice(2)
|
||||||
|
if (files.length !== 2) {
|
||||||
|
console.log(`usage: ${process.argv[0]} file1 file2`)
|
||||||
|
process.exit()
|
||||||
|
}
|
||||||
|
|
||||||
|
const css1 = fs.readFileSync(files[0], 'utf-8')
|
||||||
|
const css2 = fs.readFileSync(files[1], 'utf-8')
|
||||||
|
|
||||||
|
console.log(generateCSSPatch(css1, css2))
|
@ -25,7 +25,12 @@ git reset --hard
|
|||||||
git pull origin master
|
git pull origin master
|
||||||
|
|
||||||
composer8.1 install --no-dev --optimize-autoloader --ignore-platform-reqs
|
composer8.1 install --no-dev --optimize-autoloader --ignore-platform-reqs
|
||||||
$PHP prepare_static.php
|
|
||||||
|
if [ ! -d node_modules ]; then
|
||||||
|
npm i
|
||||||
|
fi
|
||||||
|
|
||||||
|
$PHP build_static.php
|
||||||
|
|
||||||
cp "$DEV_DIR/config-local.php" .
|
cp "$DEV_DIR/config-local.php" .
|
||||||
cat config-local.php | grep -v is_dev | tee config-local.php >/dev/null
|
cat config-local.php | grep -v is_dev | tee config-local.php >/dev/null
|
||||||
|
@ -39,11 +39,14 @@ class RequestDispatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$skin = new Skin();
|
$skin = new Skin();
|
||||||
$skin->static[] = '/css/common-bundle.css';
|
$skin->static[] = '/css/common.css';
|
||||||
$skin->static[] = '/js/common.js';
|
$skin->static[] = '/js/common.js';
|
||||||
|
|
||||||
|
$lang = LangData::getInstance();
|
||||||
|
$skin->addLangKeys($lang->search('/^theme_/'));
|
||||||
|
|
||||||
/** @var RequestHandler $handler */
|
/** @var RequestHandler $handler */
|
||||||
$handler = new $handler_class($skin, LangData::getInstance(), $router_input);
|
$handler = new $handler_class($skin, $lang, $router_input);
|
||||||
$resp = $handler->beforeDispatch();
|
$resp = $handler->beforeDispatch();
|
||||||
if ($resp instanceof Response) {
|
if ($resp instanceof Response) {
|
||||||
$resp->send();
|
$resp->send();
|
||||||
|
@ -23,11 +23,16 @@ class Skin {
|
|||||||
else
|
else
|
||||||
$js = null;
|
$js = null;
|
||||||
|
|
||||||
|
$theme = ($_COOKIE['theme'] ?? 'auto');
|
||||||
|
if (!in_array($theme, ['auto', 'dark', 'light']))
|
||||||
|
$theme = 'auto';
|
||||||
|
|
||||||
$layout_ctx = new SkinContext('\\skin\\base');
|
$layout_ctx = new SkinContext('\\skin\\base');
|
||||||
$lang = $this->getLang();
|
$lang = $this->getLang();
|
||||||
$lang = !empty($lang) ? json_encode($lang, JSON_UNESCAPED_UNICODE) : '';
|
$lang = !empty($lang) ? json_encode($lang, JSON_UNESCAPED_UNICODE) : '';
|
||||||
return new Response(200, $layout_ctx->layout(
|
return new Response(200, $layout_ctx->layout(
|
||||||
static: $this->static,
|
static: $this->static,
|
||||||
|
theme: $theme,
|
||||||
title: $this->title,
|
title: $this->title,
|
||||||
opts: $this->options,
|
opts: $this->options,
|
||||||
js: $js,
|
js: $js,
|
||||||
|
@ -53,10 +53,12 @@ class SkinContext extends SkinBase {
|
|||||||
return call_user_func_array($fn, $arguments);
|
return call_user_func_array($fn, $arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __get(string $name) {
|
public function &__get(string $name) {
|
||||||
$fn = $this->ns.'\\'.$name;
|
$fn = $this->ns.'\\'.$name;
|
||||||
if (function_exists($fn))
|
if (function_exists($fn)) {
|
||||||
return [$this, $name];
|
$f = [$this, $name];
|
||||||
|
return $f;
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists($name, $this->data))
|
if (array_key_exists($name, $this->data))
|
||||||
return $this->data[$name];
|
return $this->data[$name];
|
||||||
|
@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="9.474"><path d="M0 4.737l4.737 4.737 1.105-1.106L3 5.526h12V.79h-1.579v3.158H3l2.842-2.842L4.737 0z"/></svg>
|
|
Before Width: | Height: | Size: 168 B |
@ -14,6 +14,39 @@ if (!String.prototype.endsWith) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Object.assign) {
|
||||||
|
Object.defineProperty(Object, 'assign', {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: true,
|
||||||
|
writable: true,
|
||||||
|
value: function(target, firstSource) {
|
||||||
|
'use strict';
|
||||||
|
if (target === undefined || target === null) {
|
||||||
|
throw new TypeError('Cannot convert first argument to object');
|
||||||
|
}
|
||||||
|
|
||||||
|
var to = Object(target);
|
||||||
|
for (var i = 1; i < arguments.length; i++) {
|
||||||
|
var nextSource = arguments[i];
|
||||||
|
if (nextSource === undefined || nextSource === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var keysArray = Object.keys(Object(nextSource));
|
||||||
|
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
|
||||||
|
var nextKey = keysArray[nextIndex];
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
|
||||||
|
if (desc !== undefined && desc.enumerable) {
|
||||||
|
to[nextKey] = nextSource[nextKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// AJAX
|
// AJAX
|
||||||
//
|
//
|
||||||
@ -87,7 +120,7 @@ if (!String.prototype.endsWith) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
opts = extend({}, defaultOpts, opts);
|
opts = Object.assign({}, defaultOpts, opts);
|
||||||
|
|
||||||
var xhr = createXMLHttpRequest();
|
var xhr = createXMLHttpRequest();
|
||||||
xhr.open(method, url);
|
xhr.open(method, url);
|
||||||
@ -244,11 +277,11 @@ function setCookie(name, value, days) {
|
|||||||
date.setTime(date.getTime() + (days*24*60*60*1000));
|
date.setTime(date.getTime() + (days*24*60*60*1000));
|
||||||
expires = "; expires=" + date.toUTCString();
|
expires = "; expires=" + date.toUTCString();
|
||||||
}
|
}
|
||||||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
document.cookie = name + "=" + (value || "") + expires + "; domain=" + window.appConfig.cookieHost + "; path=/";
|
||||||
}
|
}
|
||||||
|
|
||||||
function unsetCookie(name) {
|
function unsetCookie(name) {
|
||||||
document.cookie = name+'=; Max-Age=-99999999;';
|
document.cookie = name + '=; Max-Age=-99999999; domain=' + window.appConfig.cookieHost + "; path=/";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCookie(name) {
|
function getCookie(name) {
|
||||||
@ -312,6 +345,34 @@ function escape(str) {
|
|||||||
return pre.innerHTML;
|
return pre.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseUrl(uri) {
|
||||||
|
var parser = document.createElement('a');
|
||||||
|
parser.href = uri;
|
||||||
|
|
||||||
|
return {
|
||||||
|
protocol: parser.protocol, // => "http:"
|
||||||
|
host: parser.host, // => "example.com:3000"
|
||||||
|
hostname: parser.hostname, // => "example.com"
|
||||||
|
port: parser.port, // => "3000"
|
||||||
|
pathname: parser.pathname, // => "/pathname/"
|
||||||
|
hash: parser.hash, // => "#hash"
|
||||||
|
search: parser.search, // => "?search=test"
|
||||||
|
origin: parser.origin, // => "http://example.com:3000"
|
||||||
|
path: (parser.pathname || '') + (parser.search || '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function once(fn, context) {
|
||||||
|
var result;
|
||||||
|
return function() {
|
||||||
|
if (fn) {
|
||||||
|
result = fn.apply(context || this, arguments);
|
||||||
|
fn = null;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -390,3 +451,229 @@ window.__lang = {};
|
|||||||
unsetCookie('is_retina');
|
unsetCookie('is_retina');
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var StaticManager = {
|
||||||
|
loadedStyles: [],
|
||||||
|
versions: {},
|
||||||
|
|
||||||
|
setStyles: function(list, versions) {
|
||||||
|
this.loadedStyles = list;
|
||||||
|
this.versions = versions;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadStyle: function(name, theme, callback) {
|
||||||
|
var url;
|
||||||
|
if (!window.appConfig.devMode) {
|
||||||
|
var filename = name + (theme === 'dark' ? '_dark' : '') + '.css';
|
||||||
|
url = '/css/'+filename+'?'+this.versions[filename];
|
||||||
|
} else {
|
||||||
|
url = '/sass.php?name='+name+'&theme='+theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
var el = document.createElement('link');
|
||||||
|
el.onerror = callback
|
||||||
|
el.onload = callback
|
||||||
|
el.setAttribute('rel', 'stylesheet');
|
||||||
|
el.setAttribute('type', 'text/css');
|
||||||
|
el.setAttribute('id', 'style_'+name+'_dark');
|
||||||
|
el.setAttribute('href', url);
|
||||||
|
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var ThemeSwitcher = (function() {
|
||||||
|
/**
|
||||||
|
* @type {string[]}
|
||||||
|
*/
|
||||||
|
var modes = ['auto', 'dark', 'light'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
var currentModeIndex = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean|null}
|
||||||
|
*/
|
||||||
|
var systemState = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isSystemModeSupported() {
|
||||||
|
try {
|
||||||
|
// crashes on:
|
||||||
|
// Mozilla/5.0 (Windows NT 6.2; ARM; Trident/7.0; Touch; rv:11.0; WPDesktop; Lumia 630 Dual SIM) like Gecko
|
||||||
|
// Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Mobile/15E148 Safari/604.1
|
||||||
|
// Mozilla/5.0 (iPad; CPU OS 12_5_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1
|
||||||
|
//
|
||||||
|
// error examples:
|
||||||
|
// - window.matchMedia("(prefers-color-scheme: dark)").addEventListener is not a function. (In 'window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",this.onSystemSettingChange.bind(this))', 'window.matchMedia("(prefers-color-scheme: dark)").addEventListener' is undefined)
|
||||||
|
// - Object [object MediaQueryList] has no method 'addEventListener'
|
||||||
|
return !!window['matchMedia']
|
||||||
|
&& typeof window.matchMedia("(prefers-color-scheme: dark)").addEventListener === 'function';
|
||||||
|
} catch (e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function isDarkModeApplied() {
|
||||||
|
var st = StaticManager.loadedStyles;
|
||||||
|
for (var i = 0; i < st.length; i++) {
|
||||||
|
var name = st[i];
|
||||||
|
if (ge('style_'+name+'_dark'))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getSavedMode() {
|
||||||
|
var val = getCookie('theme');
|
||||||
|
if (!val)
|
||||||
|
return modes[0];
|
||||||
|
if (modes.indexOf(val) === -1) {
|
||||||
|
console.error('[ThemeSwitcher getSavedMode] invalid cookie value')
|
||||||
|
unsetCookie('theme')
|
||||||
|
return modes[0]
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} dark
|
||||||
|
*/
|
||||||
|
function changeTheme(dark) {
|
||||||
|
addClass(document.body, 'theme-changing');
|
||||||
|
|
||||||
|
var onDone = function() {
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
removeClass(document.body, 'theme-changing');
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
window.requestAnimationFrame(function() {
|
||||||
|
if (dark)
|
||||||
|
enableDark(onDone);
|
||||||
|
else
|
||||||
|
disableDark(onDone);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {function} callback
|
||||||
|
*/
|
||||||
|
function enableDark(callback) {
|
||||||
|
var names = [];
|
||||||
|
StaticManager.loadedStyles.forEach(function(name) {
|
||||||
|
var el = ge('style_'+name+'_dark');
|
||||||
|
if (el)
|
||||||
|
return;
|
||||||
|
names.push(name);
|
||||||
|
});
|
||||||
|
|
||||||
|
var left = names.length;
|
||||||
|
names.forEach(function(name) {
|
||||||
|
StaticManager.loadStyle(name, 'dark', once(function(e) {
|
||||||
|
left--;
|
||||||
|
if (left === 0)
|
||||||
|
callback();
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {function} callback
|
||||||
|
*/
|
||||||
|
function disableDark(callback) {
|
||||||
|
StaticManager.loadedStyles.forEach(function(name) {
|
||||||
|
var el = ge('style_'+name+'_dark');
|
||||||
|
if (el)
|
||||||
|
el.remove();
|
||||||
|
})
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} mode
|
||||||
|
*/
|
||||||
|
function setLabel(mode) {
|
||||||
|
var labelEl = ge('theme-switcher-label');
|
||||||
|
labelEl.innerHTML = escape(lang('theme_'+mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: function() {
|
||||||
|
var cur = getSavedMode();
|
||||||
|
currentModeIndex = modes.indexOf(cur);
|
||||||
|
|
||||||
|
var systemSupported = isSystemModeSupported();
|
||||||
|
if (!systemSupported) {
|
||||||
|
if (currentModeIndex === 0) {
|
||||||
|
modes.shift(); // remove 'auto' from the list
|
||||||
|
currentModeIndex = 1; // set to 'light'
|
||||||
|
if (isDarkModeApplied())
|
||||||
|
disableDark();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* @param {boolean} dark
|
||||||
|
*/
|
||||||
|
var onSystemChange = function(dark) {
|
||||||
|
var prevSystemState = systemState;
|
||||||
|
systemState = dark;
|
||||||
|
|
||||||
|
if (modes[currentModeIndex] !== 'auto')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (systemState !== prevSystemState)
|
||||||
|
changeTheme(systemState);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {
|
||||||
|
onSystemChange(e.matches === true)
|
||||||
|
});
|
||||||
|
|
||||||
|
onSystemChange(window.matchMedia('(prefers-color-scheme: dark)').matches === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLabel(modes[currentModeIndex]);
|
||||||
|
},
|
||||||
|
|
||||||
|
next: function(e) {
|
||||||
|
if (hasClass(document.body, 'theme-changing')) {
|
||||||
|
console.log('next: theme changing is in progress, ignoring...')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentModeIndex = (currentModeIndex + 1) % modes.length;
|
||||||
|
switch (modes[currentModeIndex]) {
|
||||||
|
case 'auto':
|
||||||
|
if (systemState !== null)
|
||||||
|
changeTheme(systemState);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'light':
|
||||||
|
if (isDarkModeApplied())
|
||||||
|
changeTheme(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'dark':
|
||||||
|
if (!isDarkModeApplied())
|
||||||
|
changeTheme(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setLabel(modes[currentModeIndex]);
|
||||||
|
setCookie('theme', modes[currentModeIndex]);
|
||||||
|
|
||||||
|
return cancelEvent(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
@ -4,7 +4,14 @@ require __DIR__.'/../init.php';
|
|||||||
global $config;
|
global $config;
|
||||||
|
|
||||||
$name = $_REQUEST['name'] ?? '';
|
$name = $_REQUEST['name'] ?? '';
|
||||||
if (!$config['is_dev'] || !$name || !file_exists($path = ROOT.'/htdocs/scss/'.$name.'.scss')) {
|
$theme = $_REQUEST['theme'] ?? '';
|
||||||
|
|
||||||
|
if ($theme != 'light' && $theme != 'dark') {
|
||||||
|
http_response_code(403);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$config['is_dev'] || !$name || !file_exists($path = ROOT.'/htdocs/scss/entries/'.$name.'/'.$theme.'.scss')) {
|
||||||
// logError(__FILE__.': access denied');
|
// logError(__FILE__.': access denied');
|
||||||
http_response_code(403);
|
http_response_code(403);
|
||||||
exit;
|
exit;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@import 'vars';
|
@import '../vars';
|
||||||
|
|
||||||
.blog-write-link-wrap {
|
.blog-write-link-wrap {
|
||||||
margin-bottom: $base-padding;
|
margin-bottom: $base-padding;
|
||||||
@ -81,7 +81,7 @@
|
|||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
.blog-upload-item-info {
|
.blog-upload-item-info {
|
||||||
color: #888;
|
color: $grey;
|
||||||
font-size: $fs - 2px;
|
font-size: $fs - 2px;
|
||||||
}
|
}
|
||||||
.blog-upload-item-note {
|
.blog-upload-item-note {
|
||||||
@ -102,7 +102,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.blog-post-date {
|
.blog-post-date {
|
||||||
color: #888;
|
color: $grey;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
font-size: $fs - 1px;
|
font-size: $fs - 1px;
|
||||||
> a {
|
> a {
|
||||||
@ -168,7 +168,7 @@
|
|||||||
background-color: $code-block-bg;
|
background-color: $code-block-bg;
|
||||||
|
|
||||||
span.term-prompt {
|
span.term-prompt {
|
||||||
color: #999;
|
color: $light-grey;
|
||||||
@include user-select(none);
|
@include user-select(none);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@
|
|||||||
border-left: 3px #e0e0e0 solid;
|
border-left: 3px #e0e0e0 solid;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
padding: 5px 0 5px 12px;
|
padding: 5px 0 5px 12px;
|
||||||
color: #888;
|
color: $grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.table-100 {
|
table.table-100 {
|
||||||
@ -266,7 +266,7 @@
|
|||||||
.blog-post-comments {
|
.blog-post-comments {
|
||||||
margin-top: $base-padding;
|
margin-top: $base-padding;
|
||||||
padding: 12px 15px;
|
padding: 12px 15px;
|
||||||
border: 1px #e0e0e0 solid;
|
border: 1px $border-color solid;
|
||||||
@include radius(3px);
|
@include radius(3px);
|
||||||
}
|
}
|
||||||
.blog-post-comments img {
|
.blog-post-comments img {
|
||||||
@ -317,7 +317,7 @@ td.blog-item-date-cell {
|
|||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
.blog-item-date {
|
.blog-item-date {
|
||||||
color: #777;
|
color: $grey;
|
||||||
//text-transform: lowercase;
|
//text-transform: lowercase;
|
||||||
}
|
}
|
||||||
td.blog-item-title-cell {
|
td.blog-item-title-cell {
|
||||||
@ -344,6 +344,8 @@ td.blog-item-title-cell {
|
|||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
a.blog-item-view-all-link {
|
a.blog-item-view-all-link {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 17px;
|
padding: 4px 17px;
|
||||||
@ -356,7 +358,7 @@ a.blog-item-view-all-link:hover {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #ededed;
|
background-color: #ededed;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
.blog-tags {
|
.blog-tags {
|
||||||
float: right;
|
float: right;
|
||||||
@ -374,7 +376,7 @@ a.blog-item-view-all-link:hover {
|
|||||||
font-size: $fs - 1px;
|
font-size: $fs - 1px;
|
||||||
}
|
}
|
||||||
.blog-tag-item > a {
|
.blog-tag-item > a {
|
||||||
color: #222;
|
color: $fg;
|
||||||
}
|
}
|
||||||
.blog-tag-item-count {
|
.blog-tag-item-count {
|
||||||
color: #aaa;
|
color: #aaa;
|
@ -1,4 +1,4 @@
|
|||||||
@import "vars";
|
@import "../vars";
|
||||||
|
|
||||||
.clearfix:after {
|
.clearfix:after {
|
||||||
content: ".";
|
content: ".";
|
||||||
@ -13,7 +13,7 @@ html, body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
//background-color: $bg;
|
background-color: $bg;
|
||||||
color: $fg;
|
color: $fg;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
@ -35,13 +35,15 @@ body.full-width .base-width {
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"], textarea {
|
input[type="text"],
|
||||||
|
input[type="password"],
|
||||||
|
textarea {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border: 1px $input-border solid;
|
border: 1px $input-border solid;
|
||||||
border-radius: 0px;
|
border-radius: 0;
|
||||||
background-color: $input-bg;
|
background-color: $input-bg;
|
||||||
color: $fg;
|
color: $fg;
|
||||||
font-family: $ff;
|
font-family: $ff;
|
||||||
@ -49,14 +51,16 @@ input[type="text"], textarea {
|
|||||||
padding: 6px;
|
padding: 6px;
|
||||||
outline: none;
|
outline: none;
|
||||||
@include radius(3px);
|
@include radius(3px);
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: $input-border-focused;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
}
|
}
|
||||||
input[type="text"]:focus,
|
|
||||||
textarea:focus {
|
|
||||||
border-color: $input-border-focused;
|
|
||||||
}
|
|
||||||
//input[type="checkbox"] {
|
//input[type="checkbox"] {
|
||||||
// margin-left: 0;
|
// margin-left: 0;
|
||||||
//}
|
//}
|
||||||
@ -110,137 +114,6 @@ p, p code {
|
|||||||
padding: $base-padding 0;
|
padding: $base-padding 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.head {
|
|
||||||
padding: 0 $side-padding;
|
|
||||||
}
|
|
||||||
.head-inner {
|
|
||||||
//padding: 13px 0;
|
|
||||||
position: relative;
|
|
||||||
border-bottom: 2px $border-color solid;
|
|
||||||
}
|
|
||||||
.head-logo {
|
|
||||||
padding: 4px 0;
|
|
||||||
font-family: $ffMono;
|
|
||||||
font-size: 15px;
|
|
||||||
display: inline-block;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
@include transition(background-color, 0.03s);
|
|
||||||
}
|
|
||||||
.head-logo {
|
|
||||||
padding: 16px 0;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.head-logo:after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: 40px;
|
|
||||||
position: absolute;
|
|
||||||
right: -40px;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
border-left: 8px #fff solid;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: linear-gradient(to left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%); /* W3C */
|
|
||||||
}
|
|
||||||
.head-logo > a {
|
|
||||||
color: $fg;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.head-logo > a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.head-logo-enter {
|
|
||||||
display: inline;
|
|
||||||
opacity: 0;
|
|
||||||
font-size: 11px;
|
|
||||||
position: relative;
|
|
||||||
background: #eee;
|
|
||||||
padding: 2px 5px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: normal;
|
|
||||||
vertical-align: middle;
|
|
||||||
top: -1px;
|
|
||||||
@include transition(opacity, 0.03s);
|
|
||||||
}
|
|
||||||
.head-logo-enter-icon {
|
|
||||||
width: 12px;
|
|
||||||
height: 7px;
|
|
||||||
display: inline-block;
|
|
||||||
background: url(/img/enter.svg) 0 0 no-repeat;
|
|
||||||
background-size: 12px 7px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
.head-logo > a:hover .head-logo-enter {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.head-logo-path {
|
|
||||||
color: $fg;
|
|
||||||
font-weight: bold;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
@include transition(color, 0.03s);
|
|
||||||
}
|
|
||||||
.head-logo > a:hover .head-logo-path:not(.alwayshover) {
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
.head-logo-path:not(.neverhover):hover {
|
|
||||||
color: #000 !important;
|
|
||||||
}
|
|
||||||
.head-logo-dolsign {
|
|
||||||
color: $head-green-color;
|
|
||||||
font-weight: normal;
|
|
||||||
&.is_root {
|
|
||||||
color: $head-red-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.head-logo-cd {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.head-logo > a:hover .head-logo-cd {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.head-logo-path-mapped {
|
|
||||||
padding: 3px 5px;
|
|
||||||
background: #f1f1f1;
|
|
||||||
pointer-events: none;
|
|
||||||
@include radius(3px);
|
|
||||||
margin: 0 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.head-items {
|
|
||||||
float: right;
|
|
||||||
color: #777; // color of separators
|
|
||||||
//padding: 8px 0;
|
|
||||||
}
|
|
||||||
a.head-item {
|
|
||||||
color: $fg;
|
|
||||||
font-size: $fs - 1px;
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
padding: 16px 0;
|
|
||||||
}
|
|
||||||
a.head-item > span {
|
|
||||||
padding: 0 12px;
|
|
||||||
border-right: 1px #d0d0d0 solid;
|
|
||||||
}
|
|
||||||
a.head-item > span > span {
|
|
||||||
padding: 2px 0;
|
|
||||||
}
|
|
||||||
a.head-item:last-child > span {
|
|
||||||
border-right: 0;
|
|
||||||
padding-right: 1px;
|
|
||||||
}
|
|
||||||
/*a.head-item:first-child > span {
|
|
||||||
padding-left: 2px;
|
|
||||||
}*/
|
|
||||||
a.head-item:hover {
|
|
||||||
//color: $link-color;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
a.head-item:hover > span > span {
|
|
||||||
border-bottom: 1px #d0d0d0 solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.contacts {
|
table.contacts {
|
||||||
border: 0;
|
border: 0;
|
||||||
@ -257,17 +130,17 @@ table.contacts td {
|
|||||||
table.contacts td.label {
|
table.contacts td.label {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
color: #777;
|
color: $dark-grey;
|
||||||
}
|
}
|
||||||
table.contacts td.value {
|
table.contacts td.value {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
}
|
}
|
||||||
table.contacts td.value span {
|
table.contacts td.value span {
|
||||||
background: #eee;
|
background: $inline-code-block-bg;
|
||||||
padding: 3px 7px 4px;
|
padding: 3px 7px 4px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
color: #333;
|
color: $fg;
|
||||||
font-family: $ffMono;
|
font-family: $ffMono;
|
||||||
font-size: $fs - 1px;
|
font-size: $fs - 1px;
|
||||||
}
|
}
|
||||||
@ -283,13 +156,14 @@ table.contacts td pre {
|
|||||||
table.contacts div.note {
|
table.contacts div.note {
|
||||||
font-size: $fs - 3px;
|
font-size: $fs - 3px;
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
color: #777;
|
color: $dark-grey;
|
||||||
> a {
|
> a {
|
||||||
color: #777;
|
color: $dark-grey;
|
||||||
border-bottom: 1px #ccc solid;
|
border-bottom: 1px $border-color solid;
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-bottom-color: #999;
|
color: $link-color;
|
||||||
|
border-bottom-color: $link-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,11 +234,11 @@ table.contacts div.note {
|
|||||||
//font-weight: bold;
|
//font-weight: bold;
|
||||||
}
|
}
|
||||||
.md-file-attach-size {
|
.md-file-attach-size {
|
||||||
color: #888;
|
color: $grey;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
.md-file-attach-note {
|
.md-file-attach-note {
|
||||||
color: #000;
|
color: $fg;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +276,7 @@ table.contacts div.note {
|
|||||||
}
|
}
|
||||||
.md-image-note {
|
.md-image-note {
|
||||||
line-height: 150%;
|
line-height: 150%;
|
||||||
color: #777;
|
color: $dark-grey;
|
||||||
padding: 2px 0 4px;
|
padding: 2px 0 4px;
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
@import 'vars';
|
@import '../vars';
|
||||||
|
|
||||||
$form-field-label-width: 120px;
|
$form-field-label-width: 120px;
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ form { display: block; margin: 0; }
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
color: #888;
|
color: $grey;
|
||||||
}
|
}
|
||||||
.form-field {
|
.form-field {
|
||||||
//margin-left: $form-field-label-width + 10px;
|
//margin-left: $form-field-label-width + 10px;
|
157
htdocs/scss/app/head.scss
Normal file
157
htdocs/scss/app/head.scss
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
.head {
|
||||||
|
padding: 0 $side-padding;
|
||||||
|
}
|
||||||
|
.head-inner {
|
||||||
|
//padding: 13px 0;
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 2px $border-color solid;
|
||||||
|
}
|
||||||
|
.head-logo {
|
||||||
|
padding: 4px 0;
|
||||||
|
font-family: $ffMono;
|
||||||
|
font-size: 15px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
body:not(.theme-changing) .head-logo {
|
||||||
|
@include transition(background-color, 0.03s);
|
||||||
|
}
|
||||||
|
.head-logo {
|
||||||
|
padding: 16px 0;
|
||||||
|
background-color: $bg;
|
||||||
|
}
|
||||||
|
.head-logo:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 40px;
|
||||||
|
position: absolute;
|
||||||
|
right: -40px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
border-left: 8px $bg solid;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: linear-gradient(to left, rgba($bg, 0) 0%, rgba($bg, 1) 100%); /* W3C */
|
||||||
|
}
|
||||||
|
.head-logo > a {
|
||||||
|
color: $fg;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.head-logo > a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.head-logo-enter {
|
||||||
|
background: $code-block-bg;
|
||||||
|
color: $hljs_fg;
|
||||||
|
display: inline;
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 11px;
|
||||||
|
position: relative;
|
||||||
|
padding: 2px 5px;
|
||||||
|
font-weight: normal;
|
||||||
|
vertical-align: middle;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
body:not(.theme-changing) .head-logo-enter {
|
||||||
|
@include transition(opacity, 0.03s);
|
||||||
|
}
|
||||||
|
.head-logo-enter-icon {
|
||||||
|
width: 12px;
|
||||||
|
height: 7px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 5px;
|
||||||
|
position: relative;
|
||||||
|
top: 1px;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
path {
|
||||||
|
fill: $hljs_fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.head-logo > a:hover .head-logo-enter {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.head-logo-path {
|
||||||
|
color: $fg;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
body:not(.theme-changing) .head-logo-path {
|
||||||
|
@include transition(color, 0.03s);
|
||||||
|
}
|
||||||
|
.head-logo > a:hover .head-logo-path:not(.alwayshover) {
|
||||||
|
color: $light_grey;
|
||||||
|
}
|
||||||
|
.head-logo-path:not(.neverhover):hover {
|
||||||
|
color: $fg !important;
|
||||||
|
}
|
||||||
|
.head-logo-dolsign {
|
||||||
|
color: $head_green_color;
|
||||||
|
font-weight: normal;
|
||||||
|
&.is_root {
|
||||||
|
color: $head_red_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.head-logo-cd {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.head-logo > a:hover .head-logo-cd {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
.head-logo-path-mapped {
|
||||||
|
padding: 3px 5px;
|
||||||
|
background: #f1f1f1;
|
||||||
|
pointer-events: none;
|
||||||
|
@include radius(3px);
|
||||||
|
margin: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.head-items {
|
||||||
|
float: right;
|
||||||
|
color: #777; // color of separators
|
||||||
|
//padding: 8px 0;
|
||||||
|
}
|
||||||
|
a.head-item {
|
||||||
|
color: $fg;
|
||||||
|
font-size: $fs - 1px;
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
padding: 16px 0;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
position: relative;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-right: 1px $head-items-separator solid;
|
||||||
|
|
||||||
|
> span {
|
||||||
|
padding: 2px 0;
|
||||||
|
|
||||||
|
> span.moon-icon {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
> svg path {
|
||||||
|
fill: $fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-theme-switcher > span {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child > span {
|
||||||
|
border-right: 0;
|
||||||
|
padding-right: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a.head-item:hover {
|
||||||
|
//color: $link-color;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a.head-item:hover > span > span {
|
||||||
|
border-bottom: 1px $head-items-separator solid;
|
||||||
|
}
|
1
htdocs/scss/app/hljs.scss
Normal file
1
htdocs/scss/app/hljs.scss
Normal file
@ -0,0 +1 @@
|
|||||||
|
@import "../hljs/github.css";
|
@ -1,4 +1,4 @@
|
|||||||
@import 'vars';
|
@import '../vars';
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
3
htdocs/scss/bundle_admin.scss
Normal file
3
htdocs/scss/bundle_admin.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.admin-page {
|
||||||
|
line-height: 155%;
|
||||||
|
}
|
10
htdocs/scss/bundle_common.scss
Normal file
10
htdocs/scss/bundle_common.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@import "./app/common";
|
||||||
|
@import "./app/head";
|
||||||
|
@import "./app/blog";
|
||||||
|
@import "./app/form";
|
||||||
|
@import "./app/pages";
|
||||||
|
@import "./hljs/github.scss";
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
@import "./app/mobile";
|
||||||
|
}
|
46
htdocs/scss/colors/dark.scss
Normal file
46
htdocs/scss/colors/dark.scss
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
$head_green_color: #0bad19;
|
||||||
|
$head_red_color: #e23636;
|
||||||
|
$link-color: #71abe5;
|
||||||
|
|
||||||
|
$grey: #798086;
|
||||||
|
$dark-grey: $grey;
|
||||||
|
$light-grey: $grey;
|
||||||
|
$fg: #eee;
|
||||||
|
$bg: #222;
|
||||||
|
|
||||||
|
$code-block-bg: #394146;
|
||||||
|
$inline-code-block-bg: #394146;
|
||||||
|
|
||||||
|
$light-bg: #464c4e;
|
||||||
|
$dark-bg: #272C2D;
|
||||||
|
$dark-fg: #999;
|
||||||
|
|
||||||
|
$input-border: #48535a;
|
||||||
|
$input-border-focused: #48535a;
|
||||||
|
$input-bg: #30373b;
|
||||||
|
$border-color: #48535a;
|
||||||
|
|
||||||
|
$error-block-bg: #f9eeee;
|
||||||
|
$error-block-fg: #d13d3d;
|
||||||
|
|
||||||
|
$success-block-bg: #eff5f0;
|
||||||
|
$success-block-fg: #2a6f34;
|
||||||
|
|
||||||
|
$head-items-separator: #5e6264;
|
||||||
|
|
||||||
|
// colors from https://github.com/Kelbster/highlightjs-material-dark-theme/blob/master/css/materialdark.css
|
||||||
|
$hljs_fg: #CDD3D8;
|
||||||
|
$hljs_bg: #2B2B2D;
|
||||||
|
$hljs_quote: #6272a4;
|
||||||
|
$hljs_string: #f1fa8c;
|
||||||
|
$hljs_literal: #bd93f9;
|
||||||
|
$hljs_title: #75A5FF;
|
||||||
|
$hljs_keyword: #C792EA;
|
||||||
|
$hljs_type: #da4939;
|
||||||
|
$hljs_tag: #abb2bf;
|
||||||
|
$hljs_regexp: #F77669;
|
||||||
|
$hljs_symbol: #C792EA;
|
||||||
|
$hljs_builtin: #C792EA;
|
||||||
|
$hljs_meta: #75A5FF;
|
||||||
|
$hljs_deletion: #e6e1dc;
|
||||||
|
$hljs_addition: #144212;
|
46
htdocs/scss/colors/light.scss
Normal file
46
htdocs/scss/colors/light.scss
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
$head_green_color: #0bad19;
|
||||||
|
$head_red_color: #ce1a1a;
|
||||||
|
$link-color: #116fd4;
|
||||||
|
|
||||||
|
$grey: #888;
|
||||||
|
$dark-grey: #777;
|
||||||
|
$light-grey: #999;
|
||||||
|
$fg: #222;
|
||||||
|
$bg: #fff;
|
||||||
|
|
||||||
|
$code-block-bg: #f3f3f3;
|
||||||
|
$inline-code-block-bg: #f1f1f1;
|
||||||
|
|
||||||
|
$light-bg: #464c4e;
|
||||||
|
$dark-bg: #272C2D;
|
||||||
|
$dark-fg: #999;
|
||||||
|
|
||||||
|
$input-border: #e0e0e0;
|
||||||
|
$input-border-focused: #e0e0e0;
|
||||||
|
$input-bg: #f7f7f7;
|
||||||
|
$border-color: #e0e0e0;
|
||||||
|
|
||||||
|
$error-block-bg: #f9eeee;
|
||||||
|
$error-block-fg: #d13d3d;
|
||||||
|
|
||||||
|
$success-block-bg: #eff5f0;
|
||||||
|
$success-block-fg: #2a6f34;
|
||||||
|
|
||||||
|
$head-items-separator: #d0d0d0;
|
||||||
|
|
||||||
|
// github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||||
|
$hljs_fg: #333;
|
||||||
|
$hljs_bg: #f8f8f8;
|
||||||
|
$hljs_quote: #998;
|
||||||
|
$hljs_string: #d14;
|
||||||
|
$hljs_literal: #008080;
|
||||||
|
$hljs_title: #900;
|
||||||
|
$hljs_keyword: $hljs_fg;
|
||||||
|
$hljs_type: #458;
|
||||||
|
$hljs_tag: #000080;
|
||||||
|
$hljs_regexp: #009926;
|
||||||
|
$hljs_symbol: #990073;
|
||||||
|
$hljs_builtin: #0086b3;
|
||||||
|
$hljs_meta: #999;
|
||||||
|
$hljs_deletion: #fdd;
|
||||||
|
$hljs_addition: #dfd;
|
@ -1,9 +0,0 @@
|
|||||||
@import "./common.scss";
|
|
||||||
@import "./blog.scss";
|
|
||||||
@import "./form.scss";
|
|
||||||
@import "./hljs/github.scss";
|
|
||||||
@import "./pages.scss";
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
@import "./mobile.scss";
|
|
||||||
}
|
|
2
htdocs/scss/entries/admin/dark.scss
Normal file
2
htdocs/scss/entries/admin/dark.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import '../../colors/dark';
|
||||||
|
@import '../../bundle_admin';
|
2
htdocs/scss/entries/admin/light.scss
Normal file
2
htdocs/scss/entries/admin/light.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import '../../colors/light';
|
||||||
|
@import '../../bundle_admin';
|
2
htdocs/scss/entries/common/dark.scss
Normal file
2
htdocs/scss/entries/common/dark.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import '../../colors/dark';
|
||||||
|
@import '../../bundle_common';
|
2
htdocs/scss/entries/common/light.scss
Normal file
2
htdocs/scss/entries/common/light.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import '../../colors/light';
|
||||||
|
@import '../../bundle_common';
|
@ -1 +0,0 @@
|
|||||||
@import "./hljs/github.css";
|
|
@ -1,27 +1,21 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
.hljs {
|
.hljs {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
color: #333;
|
color: $hljs_fg;
|
||||||
background: #f8f8f8;
|
background: $hljs_bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-comment,
|
.hljs-comment,
|
||||||
.hljs-quote {
|
.hljs-quote {
|
||||||
color: #998;
|
color: $hljs_quote;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-keyword,
|
.hljs-keyword,
|
||||||
.hljs-selector-tag,
|
.hljs-selector-tag,
|
||||||
.hljs-subst {
|
.hljs-subst {
|
||||||
color: #333;
|
color: $hljs_fg;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,18 +24,18 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
|||||||
.hljs-variable,
|
.hljs-variable,
|
||||||
.hljs-template-variable,
|
.hljs-template-variable,
|
||||||
.hljs-tag .hljs-attr {
|
.hljs-tag .hljs-attr {
|
||||||
color: #008080;
|
color: $hljs_literal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-string,
|
.hljs-string,
|
||||||
.hljs-doctag {
|
.hljs-doctag {
|
||||||
color: #d14;
|
color: $hljs_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-title,
|
.hljs-title,
|
||||||
.hljs-section,
|
.hljs-section,
|
||||||
.hljs-selector-id {
|
.hljs-selector-id {
|
||||||
color: #900;
|
color: $hljs_title;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,43 +45,43 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
|||||||
|
|
||||||
.hljs-type,
|
.hljs-type,
|
||||||
.hljs-class .hljs-title {
|
.hljs-class .hljs-title {
|
||||||
color: #458;
|
color: $hljs_type;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-tag,
|
.hljs-tag,
|
||||||
.hljs-name,
|
.hljs-name,
|
||||||
.hljs-attribute {
|
.hljs-attribute {
|
||||||
color: #000080;
|
color: $hljs_tag;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-regexp,
|
.hljs-regexp,
|
||||||
.hljs-link {
|
.hljs-link {
|
||||||
color: #009926;
|
color: $hljs_regexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-symbol,
|
.hljs-symbol,
|
||||||
.hljs-bullet {
|
.hljs-bullet {
|
||||||
color: #990073;
|
color: $hljs_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-built_in,
|
.hljs-built_in,
|
||||||
.hljs-builtin-name {
|
.hljs-builtin-name {
|
||||||
color: #0086b3;
|
color: $hljs_builtin;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-meta {
|
.hljs-meta {
|
||||||
color: #999;
|
color: $hljs_meta;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-deletion {
|
.hljs-deletion {
|
||||||
background: #fdd;
|
background: $hljs_deletion;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-addition {
|
.hljs-addition {
|
||||||
background: #dfd;
|
background: $hljs_addition;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hljs-emphasis {
|
.hljs-emphasis {
|
||||||
|
@ -4,42 +4,9 @@ $ff: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
|
|||||||
$ffMono: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;
|
$ffMono: SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;
|
||||||
|
|
||||||
$base-width: 900px;
|
$base-width: 900px;
|
||||||
//$sb-width: 120px;
|
|
||||||
$side-padding: 25px;
|
$side-padding: 25px;
|
||||||
$base-padding: 18px;
|
$base-padding: 18px;
|
||||||
|
|
||||||
$footer-height: 64px;
|
$footer-height: 64px;
|
||||||
$head-green-color: #0bad19;
|
|
||||||
$head-red-color: #ce1a1a;
|
|
||||||
$link-color: #116fd4;
|
|
||||||
|
|
||||||
$bg: #f7f7f7;
|
|
||||||
$content-bg: #fff;
|
|
||||||
$code-block-bg: #f3f3f3;
|
|
||||||
$inline-code-block-bg: #f1f1f1;
|
|
||||||
|
|
||||||
$fg: #222;
|
|
||||||
$blue1: #729fcf;
|
|
||||||
$blue2: #3465a4;
|
|
||||||
$blue3: #204a87;
|
|
||||||
$orange1: #fcaf3e;
|
|
||||||
$orange2: #f57900;
|
|
||||||
$orange3: #ce5c00;
|
|
||||||
|
|
||||||
$light-bg: #464c4e;
|
|
||||||
$dark-bg: #272C2D;
|
|
||||||
$dark-fg: #999;
|
|
||||||
|
|
||||||
$input-border: #e0e0e0;
|
|
||||||
$input-border-focused: #e0e0e0;
|
|
||||||
$input-bg: #f7f7f7;
|
|
||||||
$border-color: #e0e0e0;
|
|
||||||
|
|
||||||
$error-block-bg: #f9eeee;
|
|
||||||
$error-block-fg: #d13d3d;
|
|
||||||
|
|
||||||
$success-block-bg: #eff5f0;
|
|
||||||
$success-block-fg: #2a6f34;
|
|
||||||
|
|
||||||
@mixin radius($radius) {
|
@mixin radius($radius) {
|
||||||
-o-border-radius: $radius;
|
-o-border-radius: $radius;
|
||||||
@ -50,9 +17,9 @@ $success-block-fg: #2a6f34;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin transition($property, $duration, $easing: linear) {
|
@mixin transition($property, $duration, $easing: linear) {
|
||||||
transition: $property $duration $easing;
|
transition: $property $duration $easing;
|
||||||
-webkit-transition: $property $duration $easing;
|
-webkit-transition: $property $duration $easing;
|
||||||
-moz-transition: $property $duration $easing;
|
-moz-transition: $property $duration $easing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin linearGradient($top, $bottom){
|
@mixin linearGradient($top, $bottom){
|
||||||
|
@ -20,6 +20,11 @@ return [
|
|||||||
'delete' => 'delete',
|
'delete' => 'delete',
|
||||||
'info_saved' => 'Information saved.',
|
'info_saved' => 'Information saved.',
|
||||||
|
|
||||||
|
// theme switcher
|
||||||
|
'theme_auto' => 'auto',
|
||||||
|
'theme_dark' => 'dark',
|
||||||
|
'theme_light' => 'light',
|
||||||
|
|
||||||
// contacts
|
// contacts
|
||||||
'contacts_email' => 'email',
|
'contacts_email' => 'email',
|
||||||
'contacts_pgp' => 'OpenPGP public key',
|
'contacts_pgp' => 'OpenPGP public key',
|
||||||
|
@ -142,7 +142,7 @@ class Upload extends Model {
|
|||||||
if (is_file($dir.'/'.$f))
|
if (is_file($dir.'/'.$f))
|
||||||
unlink($dir.'/'.$f);
|
unlink($dir.'/'.$f);
|
||||||
else
|
else
|
||||||
logError('deleteAllImagePreviews: '.$dir.'/'.$f.' is not a file!');
|
logError(__METHOD__.': '.$dir.'/'.$f.' is not a file!');
|
||||||
$deleted++;
|
$deleted++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
647
package-lock.json
generated
Normal file
647
package-lock.json
generated
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
{
|
||||||
|
"name": "www",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"devDependencies": {
|
||||||
|
"clean-css": "^5.3.0",
|
||||||
|
"clean-css-cli": "^5.6.0",
|
||||||
|
"css-patch": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/anymatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/binary-extensions": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chokidar": {
|
||||||
|
"version": "3.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"anymatch": "~3.1.2",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"glob-parent": "~5.1.2",
|
||||||
|
"is-binary-path": "~2.1.0",
|
||||||
|
"is-glob": "~4.0.1",
|
||||||
|
"normalize-path": "~3.0.0",
|
||||||
|
"readdirp": "~3.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.10.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/clean-css": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"source-map": "~0.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/clean-css-cli": {
|
||||||
|
"version": "5.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-5.6.0.tgz",
|
||||||
|
"integrity": "sha512-68vorNEG808D1QzeerO9AlwQVTuaR8YSK4aqwIsjJq0wDSyPH11ApHY0O+EQrdEGUZcN+d72v+Nn/gpxjAFewQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": "^3.5.2",
|
||||||
|
"clean-css": "^5.3.0",
|
||||||
|
"commander": "7.x",
|
||||||
|
"glob": "^7.1.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cleancss": "bin/cleancss"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/commander": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/css-patch": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-patch/-/css-patch-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-wCIyPGugTmf10KO39QLD3N+qIum0ljrj/8pJdULjjuXQ6oEeYd5+quMF7jIdnEL5Ftp0wmbvO8qPvAmzrw0EaA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"diff": "^5.0.0",
|
||||||
|
"stylis": "^4.0.13"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/diff": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/glob": {
|
||||||
|
"version": "7.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^3.1.1",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/readdirp": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/stylis": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"anymatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"binary-extensions": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"braces": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fill-range": "^7.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chokidar": {
|
||||||
|
"version": "3.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"anymatch": "~3.1.2",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"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.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clean-css": {
|
||||||
|
"version": "5.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz",
|
||||||
|
"integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"source-map": "~0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clean-css-cli": {
|
||||||
|
"version": "5.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-5.6.0.tgz",
|
||||||
|
"integrity": "sha512-68vorNEG808D1QzeerO9AlwQVTuaR8YSK4aqwIsjJq0wDSyPH11ApHY0O+EQrdEGUZcN+d72v+Nn/gpxjAFewQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chokidar": "^3.5.2",
|
||||||
|
"clean-css": "^5.3.0",
|
||||||
|
"commander": "7.x",
|
||||||
|
"glob": "^7.1.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"css-patch": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-patch/-/css-patch-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-wCIyPGugTmf10KO39QLD3N+qIum0ljrj/8pJdULjjuXQ6oEeYd5+quMF7jIdnEL5Ftp0wmbvO8qPvAmzrw0EaA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"diff": "^5.0.0",
|
||||||
|
"stylis": "^4.0.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"diff": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fill-range": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fsevents": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^3.1.1",
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"readdirp": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"stylis": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
package.json
Normal file
7
package.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"devDependencies": {
|
||||||
|
"clean-css": "^5.3.0",
|
||||||
|
"clean-css-cli": "^5.6.0",
|
||||||
|
"css-patch": "^1.2.0"
|
||||||
|
}
|
||||||
|
}
|
@ -1,48 +0,0 @@
|
|||||||
#!/usr/bin/env php8.1
|
|
||||||
<?php
|
|
||||||
|
|
||||||
function gethash(string $path): string {
|
|
||||||
return substr(sha1(file_get_contents($path)), 0, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sassc(string $src_dir, string $dst_dir, string $file): int {
|
|
||||||
$cmd = 'sassc -t expanded '.escapeshellarg($src_dir.'/'.$file).' '.escapeshellarg($dst_dir.'/'.preg_replace('/\.scss$/', '.css', $file));
|
|
||||||
exec($cmd, $output, $code);
|
|
||||||
return $code;
|
|
||||||
}
|
|
||||||
|
|
||||||
require __DIR__.'/init.php';
|
|
||||||
global $config;
|
|
||||||
|
|
||||||
function build_static(): void {
|
|
||||||
$css_dir = ROOT.'/htdocs/css';
|
|
||||||
$hashes = [];
|
|
||||||
|
|
||||||
if (!file_exists($css_dir))
|
|
||||||
mkdir($css_dir);
|
|
||||||
|
|
||||||
$files = ['common-bundle.scss', 'admin.scss'];
|
|
||||||
foreach ($files as $file) {
|
|
||||||
if (sassc(ROOT.'/htdocs/scss', $css_dir, $file) != 0)
|
|
||||||
fwrite(STDERR, "error: could not compile $file\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (['css', 'js'] as $type) {
|
|
||||||
$reldir = ROOT.'/htdocs/';
|
|
||||||
$files = glob_recursive($reldir.$type.'/*.'.$type);
|
|
||||||
if (empty($files)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$name = preg_replace('/^'.preg_quote($reldir, '/').'/', '', $file);
|
|
||||||
$hashes[$name] = gethash($file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scfg = "<?php\n\n";
|
|
||||||
$scfg .= "return ".var_export($hashes, true).";\n";
|
|
||||||
|
|
||||||
file_put_contents(ROOT.'/config-static.php', $scfg);
|
|
||||||
}
|
|
||||||
|
|
||||||
build_static();
|
|
@ -2,7 +2,17 @@
|
|||||||
|
|
||||||
namespace skin\base;
|
namespace skin\base;
|
||||||
|
|
||||||
function layout($ctx, $title, $unsafe_body, $static, $meta, $js, $opts, $exec_time, $unsafe_lang) {
|
use admin;
|
||||||
|
use RequestDispatcher;
|
||||||
|
|
||||||
|
function layout($ctx, $title, $unsafe_body, $static, $meta, $js, $opts, $exec_time, $unsafe_lang, $theme) {
|
||||||
|
global $config;
|
||||||
|
$app_config = json_encode([
|
||||||
|
'domain' => $config['domain'],
|
||||||
|
'devMode' => $config['is_dev'],
|
||||||
|
'cookieHost' => $config['cookie_host'],
|
||||||
|
]);
|
||||||
|
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@ -12,16 +22,16 @@ return <<<HTML
|
|||||||
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon">
|
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon">
|
||||||
<link rel="alternate" type="application/rss+xml" href="/feed.rss">
|
<link rel="alternate" type="application/rss+xml" href="/feed.rss">
|
||||||
<title>{$title}</title>
|
<title>{$title}</title>
|
||||||
|
<script type="text/javascript">window.appConfig = {$app_config};</script>
|
||||||
{$ctx->renderMeta($meta)}
|
{$ctx->renderMeta($meta)}
|
||||||
{$ctx->renderStatic($static)}
|
{$ctx->renderStatic($static, $theme)}
|
||||||
</head>
|
</head>
|
||||||
<body{$ctx->if_true($opts['full_width'], ' class="full-width"')}>
|
<body{$ctx->if_true($opts['full_width'], ' class="full-width"')}>
|
||||||
{$ctx->renderHeader(renderLogo($ctx, $opts['logo_path_map'], $opts['logo_link_map']))}
|
{$ctx->renderHeader($theme, renderLogo($ctx, $opts['logo_path_map'], $opts['logo_link_map']))}
|
||||||
<div class="page-content base-width">
|
<div class="page-content base-width">
|
||||||
<div class="page-content-inner">{$unsafe_body}</div>
|
<div class="page-content-inner">{$unsafe_body}</div>
|
||||||
</div>
|
</div>
|
||||||
{$ctx->if_true($js != '' || !empty($lang) || $opts['dynlogo_enabled'],
|
{$ctx->renderScript($js, $unsafe_lang, $opts['dynlogo_enabled'])}
|
||||||
$ctx->renderScript, $js, $unsafe_lang, $opts['dynlogo_enabled'])}
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<!--
|
<!--
|
||||||
@ -32,11 +42,18 @@ HTML;
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderScript($ctx, $unsafe_js, $unsafe_lang, $enable_dynlogo) {
|
function renderScript($ctx, $unsafe_js, $unsafe_lang, $enable_dynlogo) {
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
$styles = json_encode($ctx->styleNames);
|
||||||
|
$versions = !$config['is_dev'] ? json_encode($config['static']) : '{}';
|
||||||
|
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
StaticManager.setStyles({$styles}, {$versions});
|
||||||
{$ctx->if_true($unsafe_js, '(function(){'.$unsafe_js.'})();')}
|
{$ctx->if_true($unsafe_js, '(function(){'.$unsafe_js.'})();')}
|
||||||
{$ctx->if_true($unsafe_lang, 'extend(__lang, '.$unsafe_lang.');')}
|
{$ctx->if_true($unsafe_lang, 'extend(__lang, '.$unsafe_lang.');')}
|
||||||
{$ctx->if_true($enable_dynlogo, 'DynamicLogo.init();')}
|
{$ctx->if_true($enable_dynlogo, 'DynamicLogo.init();')}
|
||||||
|
ThemeSwitcher.init();
|
||||||
</script>
|
</script>
|
||||||
HTML;
|
HTML;
|
||||||
}
|
}
|
||||||
@ -53,26 +70,76 @@ function renderMeta($ctx, $meta) {
|
|||||||
}, $meta));
|
}, $meta));
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderStatic($ctx, $static) {
|
function renderStatic($ctx, $static, $theme) {
|
||||||
global $config;
|
global $config;
|
||||||
$html = [];
|
$html = [];
|
||||||
|
$dark = $theme == 'dark';
|
||||||
|
$ctx->styleNames = [];
|
||||||
foreach ($static as $name) {
|
foreach ($static as $name) {
|
||||||
// list($name, $options) = $item;
|
// list($name, $options) = $item;
|
||||||
$version = $config['is_dev'] ? time() : $config['static'][substr($name, 1)] ?? 'notfound';
|
$version = $config['is_dev'] ? time() : $config['static'][substr($name, 1)] ?? 'notfound';
|
||||||
if (str_ends_with($name, '.js'))
|
if (str_ends_with($name, '.js'))
|
||||||
$html[] = jsLink($name, $version);
|
$html[] = jsLink($name, $version);
|
||||||
else if (str_ends_with($name, '.css'))
|
else if (str_ends_with($name, '.css')) {
|
||||||
$html[] = cssLink($name, $version/*, $options*/);
|
$html[] = cssLink($name, 'light', $version, $style_name);
|
||||||
|
$ctx->styleNames[] = $style_name;
|
||||||
|
|
||||||
|
if ($dark)
|
||||||
|
$html[] = cssLink($name, 'dark', $version, $style_name);
|
||||||
|
else if (!$config['is_dev'])
|
||||||
|
$html[] = cssPrefetchLink(str_replace('.css', '_dark.css', $name), $version);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return implode("\n", $html);
|
return implode("\n", $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderHeader($ctx, $unsafe_logo_html) {
|
function jsLink(string $name, $version = null): string {
|
||||||
|
if ($version !== null)
|
||||||
|
$name .= '?'.$version;
|
||||||
|
return '<script src="'.$name.'" type="text/javascript"></script>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssLink(string $name, string $theme, $version = null, &$bname = null): string {
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
$dname = dirname($name);
|
||||||
|
$bname = basename($name);
|
||||||
|
if (($pos = strrpos($bname, '.')))
|
||||||
|
$bname = substr($bname, 0, $pos);
|
||||||
|
|
||||||
|
if ($config['is_dev']) {
|
||||||
|
$href = '/sass.php?name='.urlencode($bname).'&theme='.$theme;
|
||||||
|
} else {
|
||||||
|
$href = $dname.'/'.$bname.($theme == 'dark' ? '_dark' : '').'.css'.($version !== null ? '?'.$version : '');
|
||||||
|
}
|
||||||
|
$id = 'style_'.$bname;
|
||||||
|
if ($theme == 'dark')
|
||||||
|
$id .= '_dark';
|
||||||
|
return '<link rel="stylesheet" id="'.$id.'" type="text/css" href="'.$href.'">';
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssPrefetchLink(string $name, $verison = null): string {
|
||||||
|
$url = $name;
|
||||||
|
if ($verison)
|
||||||
|
$url .= '?'.$verison;
|
||||||
|
return <<<HTML
|
||||||
|
<link rel="prefetch" href="{$url}" />
|
||||||
|
HTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderHeader($ctx, $theme, $unsafe_logo_html) {
|
||||||
return <<<HTML
|
return <<<HTML
|
||||||
<div class="head base-width">
|
<div class="head base-width">
|
||||||
<div class="head-inner clearfix">
|
<div class="head-inner clearfix">
|
||||||
<div class="head-logo">{$unsafe_logo_html}</div>
|
<div class="head-logo">{$unsafe_logo_html}</div>
|
||||||
<div class="head-items clearfix">
|
<div class="head-items clearfix">
|
||||||
|
<a class="head-item is-theme-switcher" href="javascript:void(0)" onclick="return ThemeSwitcher.next(event)">
|
||||||
|
<span>
|
||||||
|
<span>
|
||||||
|
<span class="moon-icon">{$ctx->renderMoonIcon()}</span><span id="theme-switcher-label">{$theme}</span>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
<a class="head-item" href="/"><span><span>blog</span></span></a>
|
<a class="head-item" href="/"><span><span>blog</span></span></a>
|
||||||
<a class="head-item" href="/projects/"><span><span>projects</span></span></a>
|
<a class="head-item" href="/projects/"><span><span>projects</span></span></a>
|
||||||
<a class="head-item" href="https://git.ch1p.io/?s=idle"><span><span>git</span></span></a>
|
<a class="head-item" href="https://git.ch1p.io/?s=idle"><span><span>git</span></span></a>
|
||||||
@ -87,9 +154,9 @@ HTML;
|
|||||||
|
|
||||||
// TODO rewrite this fcking crap
|
// TODO rewrite this fcking crap
|
||||||
function renderLogo($ctx, array $path_map = [], array $link_map = []): string {
|
function renderLogo($ctx, array $path_map = [], array $link_map = []): string {
|
||||||
$uri = \RequestDispatcher::path();
|
$uri = RequestDispatcher::path();
|
||||||
|
|
||||||
if (!\admin::isAdmin()) {
|
if (!admin::isAdmin()) {
|
||||||
$prompt_sign = '<span class="head-logo-dolsign">$</span>';
|
$prompt_sign = '<span class="head-logo-dolsign">$</span>';
|
||||||
} else {
|
} else {
|
||||||
$prompt_sign = '<span class="head-logo-dolsign is_root">#</span>';
|
$prompt_sign = '<span class="head-logo-dolsign is_root">#</span>';
|
||||||
@ -143,7 +210,7 @@ function renderLogo($ctx, array $path_map = [], array $link_map = []): string {
|
|||||||
$last_pos = $pos + 1;
|
$last_pos = $pos + 1;
|
||||||
$close_tags++;
|
$close_tags++;
|
||||||
}
|
}
|
||||||
$html .= str_repeat('</span>', $close_tags).' '.$prompt_sign.' <span class="head-logo-cd">cd <span id="head_cd_text">~</span> <span class="head-logo-enter"><span class="head-logo-enter-icon"></span>Enter</span></span></a>';
|
$html .= str_repeat('</span>', $close_tags).' '.$prompt_sign.' <span class="head-logo-cd">cd <span id="head_cd_text">~</span> <span class="head-logo-enter"><span class="head-logo-enter-icon">'.enterIcon().'</span>Enter</span></span></a>';
|
||||||
|
|
||||||
for ($i = count($path_parts)-1, $j = 0; $i >= 0; $i--, $j++) {
|
for ($i = count($path_parts)-1, $j = 0; $i >= 0; $i--, $j++) {
|
||||||
if (isset($path_map[$j])) {
|
if (isset($path_map[$j])) {
|
||||||
@ -169,25 +236,16 @@ function renderLogo($ctx, array $path_map = [], array $link_map = []): string {
|
|||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsLink(string $name, $version = null): string {
|
function enterIcon() {
|
||||||
if ($version !== null)
|
return <<<SVG
|
||||||
$name .= '?'.$version;
|
<svg width="12" height="7" viewBox="0 0 9.6 5.172" xmlns="http://www.w3.org/2000/svg">
|
||||||
return '<script src="'.$name.'" type="text/javascript"></script>';
|
<path d="M.4 2.586l2.779 2.8.648-.654-1.667-1.68H9.2V.253h-.926V2.12H2.16L3.827.44 3.18-.214z"/>
|
||||||
|
</svg>
|
||||||
|
SVG;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cssLink(string $name, $version = null/*, $options = null*/): string {
|
function renderMoonIcon($ctx) {
|
||||||
global $config;
|
return <<<SVG
|
||||||
if ($config['is_dev']) {
|
<svg width="18" height="18" xmlns="http://www.w3.org/2000/svg"><path d="M14.54 10.37a5.4 5.4 0 01-6.91-6.91.59.59 0 00-.74-.75 6.66 6.66 0 00-2.47 1.54 6.6 6.6 0 1010.87 6.86.59.59 0 00-.75-.74zm-1.61 2.39a5.44 5.44 0 01-7.69-7.69 5.58 5.58 0 011-.76 6.55 6.55 0 007.47 7.47 5.15 5.15 0 01-.78.98z" fill-rule="evenodd" /></svg>
|
||||||
$bname = basename($name);
|
SVG;
|
||||||
if (($pos = strrpos($bname, '.')))
|
|
||||||
$bname = substr($bname, 0, $pos);
|
|
||||||
$href = '/sass.php?name='.urlencode($bname);
|
|
||||||
} else {
|
|
||||||
$href = $name.($version !== null ? '?'.$version : '');
|
|
||||||
}
|
|
||||||
$s = '<link rel="stylesheet" type="text/css" href="'.$href.'"';
|
|
||||||
// if (!is_null($options))
|
|
||||||
// $s .= ' media="'.$options.'"';
|
|
||||||
$s .= '>';
|
|
||||||
return $s;
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user