rework error pages and setup pages

This commit is contained in:
Pig Fang 2020-02-01 12:44:39 +08:00
parent 25a31302ae
commit 100e5960e7
22 changed files with 172 additions and 379 deletions

View File

@ -112,10 +112,6 @@ class SetupController extends Controller
'site_name' => 'required',
]);
if ($request->has('generate_random')) {
$artisan->call('key:generate');
$artisan->call('salt:random');
}
$artisan->call('jwt:secret', ['--no-interaction' => true]);
$artisan->call('passport:keys', ['--no-interaction' => true]);
@ -157,8 +153,6 @@ class SetupController extends Controller
$filesystem->put(storage_path('install.lock'), '');
return view('setup.wizard.finish')->with([
'email' => $request->input('email'),
]);
return view('setup.wizard.finish');
}
}

View File

@ -32,8 +32,10 @@ class LanguagesMenuComposer
return $locale;
});
$current = 'locales.'.app()->getLocale();
$view->with([
'current' => config('locales.'.app()->getLocale().'.short_name'),
'lang_short_name' => config($current.'.short_name'),
'lang_name' => config($current.'.name'),
'langs' => $langs,
]);
}

View File

@ -37,7 +37,10 @@ class ViewServiceProvider extends ServiceProvider
]);
});
View::composer('shared.languages', Composers\LanguagesMenuComposer::class);
View::composer(
['shared.languages', 'errors.*'],
Composers\LanguagesMenuComposer::class
);
View::composer('shared.user-menu', Composers\UserMenuComposer::class);
@ -72,11 +75,9 @@ class ViewServiceProvider extends ServiceProvider
View::composer(['errors.*', 'setup.*'], function ($view) use ($webpack) {
$view->with([
'styles' => [
$webpack->url('setup.css'),
],
'scripts' => [
$webpack->url('language-chooser.js'),
$webpack->url('spectre.css'),
],
'scripts' => [],
]);
});

View File

@ -28,6 +28,7 @@
"react-hot-loader": "^4.12.18",
"rxjs": "^6.5.3",
"skinview3d": "^1.2.1",
"spectre.css": "^0.5.8",
"vue": "^2.6.11",
"vue-good-table": "^2.18.1",
"vue-recaptcha": "^1.2.0",

View File

@ -0,0 +1,5 @@
@font-face {
font-family: Minecraft;
src: url('./minecraft.woff2') format('woff2'),
url('./minecraft.woff') format('woff');
}

View File

@ -1,4 +0,0 @@
const chooser = document.querySelector<HTMLInputElement>('#language-chooser')
chooser?.addEventListener('change', () => {
window.location.href = `?lang=${chooser.value}`
})

View File

@ -1,224 +0,0 @@
@import 'common.styl'
html
background #f1f1f1
margin 0 20px
font-weight 400
body
background #FFF none repeat scroll 0% 0%
color #444
font-family Ubuntu, 'Microsoft Yahei', 'Microsoft Jhenghei', sans-serif
margin 140px auto 25px
padding 20px 20px 10px
max-width 700px
box-shadow 0px 1px 3px rgba(0, 0, 0, 0.13)
h1, h2
border-bottom 1px solid #DEDEDE
clear both
color #666
font-size 24px
font-weight 400
padding 0px 0px 7px
p
padding-bottom 2px
font-size 14px
line-height 1.5
#logo
margin 6px 0 14px
border-bottom none
text-align center
a
font-family Minecraft, sans-serif
transition color 0.2s ease-in-out
font-weight 400
font-size 50px
color #666
height 84px
line-height 1.3em
margin -130px auto 25px
padding 0
outline 0
text-decoration none
overflow hidden
display block
a:hover
color #42a5f5
/* Mobile phone */
@media (max-width: 48em)
#logo a
font-size 40px
@media (max-width: 35.5em)
#logo a
font-size 30px
#language-chooser
float right
margin-top 4px
height 24px
.step
margin 20px 0 15px
text-align left
padding 0
input
font-family Ubuntu, 'Microsoft Yahei', 'Microsoft Jhenghei', sans-serif
.alert
font-size 16px
padding 15px
margin-top 15px
margin-bottom 20px
border 1px solid transparent
border-radius 4px
ul
margin 0px
.alert-warning
color #8a6d3b
background-color #fcf8e3
border-color #faebcc
.form-table td, .form-table th
padding 10px 20px 10px 0
vertical-align top
font-size 14px
td > input
font-family Ubuntu, 'Microsoft Yahei', 'Microsoft Jhenghei', sans-serif
.form-table
border-collapse collapse
margin-top 1em
width 100%
.form-table td
margin-bottom 9px
.form-table th
text-align left
width 140px
.form-table p
margin 4px 0 0
font-size 11px
.form-table input
line-height 20px
font-size 15px
padding 3px 5px
border 1px solid #ddd
-webkit-box-shadow inset 0 1px 2px rgba(0, 0, 0, 0.07)
box-shadow inset 0 1px 2px rgba(0, 0, 0, 0.07)
.form-table input[type=email], .form-table input[type=password], .form-table input[type=text], .form-table input[type=url]
width 206px
.container .button, .container .button-primary, .container .button-secondary
display inline-block
text-decoration none
font-size 13px
line-height 26px
height 28px
margin 0
padding 0 10px 1px
cursor pointer
border-width 1px
border-style solid
-webkit-appearance none
-webkit-border-radius 3px
border-radius 3px
white-space nowrap
-webkit-box-sizing border-box
-moz-box-sizing border-box
box-sizing border-box
.container button::-moz-focus-inner, .container input[type=reset]::-moz-focus-inner, .container input[type=button]::-moz-focus-inner, .container input[type=submit]::-moz-focus-inner
border-width 0
border-style none
padding 0
.container .button-group.button-large .button, .container .button.button-large
height 30px
line-height 28px
padding 0 12px 2px
.container .button:active, .container .button:focus
outline 0
.container .button.hidden
display none
.container input[type=reset], .container input[type=reset]:active, .container input[type=reset]:focus, .container input[type=reset]:hover
background 0 0
border none
-webkit-box-shadow none
box-shadow none
padding 0 2px 1px
width auto
.container .button, .container .button-secondary
color #555
border-color #ccc
background #f7f7f7
-webkit-box-shadow 0 1px 0 #ccc
box-shadow 0 1px 0 #ccc
vertical-align top
.container p .button
vertical-align baseline
.container .button-secondary:focus, .container .button-secondary:hover, .container .button.focus, .container .button.hover, .container .button:focus, .container .button:hover
background #fafafa
border-color #999
color #23282d
.container .button-link:focus, .container .button-secondary:focus, .container .button.focus, .container .button:focus
border-color #5b9dd9
-webkit-box-shadow 0 0 3px rgba(0, 115, 170, 0.8)
box-shadow 0 0 3px rgba(0, 115, 170, 0.8)
.container .button-secondary:active, .container .button.active, .container .button.active:hover, .container .button:active
background #eee
border-color #999
-webkit-box-shadow inset 0 2px 5px -3px rgba(0, 0, 0, 0.5)
box-shadow inset 0 2px 5px -3px rgba(0, 0, 0, 0.5)
-webkit-transform translateY(1px)
-ms-transform translateY(1px)
transform translateY(1px)
.container .button.active:focus
border-color #5b9dd9
-webkit-box-shadow inset 0 2px 5px -3px rgba(0, 0, 0, 0.5), 0 0 3px rgba(0, 115, 170, 0.8)
box-shadow inset 0 2px 5px -3px rgba(0, 0, 0, 0.5), 0 0 3px rgba(0, 115, 170, 0.8)
.container .button-disabled, .container .button-secondary.disabled, .container .button-secondary:disabled, .container .button-secondary[disabled], .container .button.disabled, .container .button:disabled, .container .button[disabled]
color #a0a5aa !important
border-color #ddd !important
background #f7f7f7 !important
-webkit-box-shadow none !important
box-shadow none !important
text-shadow 0 1px 0 #fff !important
cursor default
-webkit-transform none !important
-ms-transform none !important
transform none !important
.faq
display inline-block
text-decoration none
background-color #0069d9
color #fff
padding 5px 15px
margin 20px 0 6px 0
border-radius 3px

View File

@ -0,0 +1,15 @@
body {
height: 97vh;
}
.hero {
align-items: center;
}
h1 {
font-family: Minecraft;
}
a:hover {
text-decoration: none;
}

View File

@ -11,18 +11,20 @@
{% endfor %}
</head>
<body class="container">
<p id="logo">
<a href="{{ url('/') }}" tabindex="-1">{{ site_name }}</a>
</p>
<h1>
{% block subtitle %}{{ block('title') }}{% endblock %}
{{ include('errors.languages') }}
</h1>
{% block message %}{% endblock %}
{% if auth_user().admin %}
<a class="faq" href="https://blessing.netlify.com/faq.html" target="_blank">FAQ</a>
{% endif %}
<body class="bg-gray">
{{ include('errors.languages') }}
<div class="hero d-flex">
<div class="hero-body text-center">
<h1><a class="text-primary" href="{{ url('/') }}">{{ site_name }}</a></h1>
<div class="divider"></div>
<h3 style="margin-top: 15vh;">{% block subtitle %}{{ block('title') }}{% endblock %}</h3>
{% block message %}{% endblock %}
<div class="divider"></div>
{% if auth_user().admin %}
<a class="btn btn-link" href="https://blessing.netlify.com/faq.html" target="_blank">FAQ</a>
{% endif %}
</div>
</div>
{% for script in scripts %}
<script src="{{ script }}"></script>
{% endfor %}

View File

@ -1,10 +1,7 @@
<select id="language-chooser">
{% for code, locale in config('locales') %}
{% if locale.alias is empty %}
<option
value="{{ code }}"
{{ code == app.getLocale() ? 'selected="selected"' }}
>{{ locale.name }}</option>
{% endif %}
<div class="text-right m-2 p-2">
{% for lang in langs %}
<a href="{{ lang.url }}"
class="mx-2 p-1 label {{ lang.name == lang_name ? 'label-primary' : 'label-secondary' }}"
>{{ lang.name }}</a>
{% endfor %}
</select>
</div>

View File

@ -13,17 +13,21 @@
{% endfor %}
</head>
<body class="container">
<p id="logo">
<a href="https://github.com/bs-community/blessing-skin-server" tabindex="-1">
Blessing Skin Server
</a>
</p>
<h1>
{% block subtitle %}{{ block('title') }}{% endblock %}
{{ include('errors.languages') }}
</h1>
{% block content %}{% endblock %}
<body class="bg-secondary">
{{ include('errors.languages') }}
<div class="hero d-flex">
<div class="hero-body">
<h1 class="text-center">
<a class="text-primary" href="https://github.com/bs-community/blessing-skin-server">
Blessing Skin Server
</a>
</h1>
<div class="divider"></div>
<h3>{% block subtitle %}{{ block('title') }}{% endblock %}</h3>
<div class="divider"></div>
{% block content %}{% endblock %}
</div>
</div>
{% for script in scripts %}
<script src="{{ script }}"></script>
{% endfor %}

View File

@ -4,8 +4,8 @@
{% block content %}
<p>{{ trans('setup.locked.text') }}</p>
<p class="step">
<a href="{{ url('/') }}" class="button button-large">
<p>
<a href="{{ url('/') }}" class="btn btn-primary">
{{ trans('setup.locked.button') }}
</a>
</p>

View File

@ -8,8 +8,8 @@
<p>
{{ trans('setup.updates.success.text', {version: config('app.version')}) }}
</p>
<p class="step">
<a href="{{ url('/') }}" class="button button-large">
<p>
<a href="{{ url('/') }}" class="btn btn-primary">
{{ trans('setup.updates.welcome.button') }}
</a>
</p>

View File

@ -8,8 +8,8 @@
<p>
{{ trans('setup.updates.welcome.text', {version: config('app.version')})|nl2br }}
</p>
<p class="step">
<a href="{{ url('/setup/exec-update') }}" class="button button-large">
<p>
<a href="{{ url('/setup/exec-update') }}" class="btn btn-primary">
{{ trans('setup.updates.welcome.button') }}
</a>
</p>

View File

@ -11,26 +11,33 @@
novalidate="novalidate"
>
{{ csrf_field() }}
<table class="form-table">
<tr class="form-field form-required">
<th scope="row">
<label for="type">{{ trans('setup.wizard.database.type') }}</label>
<table>
<tr>
<th>
<label for="type" class="form-label">{{ trans('setup.wizard.database.type') }}</label>
</th>
<td>
<input name="type" type="radio" value="mysql" id="type-mysql" checked>
<label for="type-mysql">MySQL / MariaDB</label>
<input name="type" type="radio" value="pgsql" id="type-pgsql">
<label for="type-pgsql">PostgreSQL</label>
<input name="type" type="radio" value="sqlite" id="type-sqlite">
<label for="type-sqlite">SQLite</label>
<td class="form-group">
<label class="form-radio d-inline-block">
<input name="type" type="radio" value="mysql" id="type-mysql" checked>
<i class="form-icon"></i> MySQL / MariaDB
</label>
<label class="form-radio d-inline-block">
<input name="type" type="radio" value="pgsql" id="type-pgsql">
<i class="form-icon"></i> PostgreSQL
</label>
<label class="form-radio d-inline-block">
<input name="type" type="radio" value="sqlite" id="type-sqlite">
<i class="form-icon"></i> SQLite
</label>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="host">{{ trans('setup.wizard.database.host') }}</label>
<tr>
<th>
<label class="form-label" for="host">{{ trans('setup.wizard.database.host') }}</label>
</th>
<td>
<input
class="form-input"
name="host"
type="text"
id="host"
@ -39,12 +46,13 @@
>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="port">{{ trans('setup.wizard.database.port') }}</label>
<tr>
<th>
<label class="form-label" for="port">{{ trans('setup.wizard.database.port') }}</label>
</th>
<td>
<input
class="form-input"
name="port"
type="text"
id="port"
@ -53,12 +61,13 @@
>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="username">{{ trans('setup.wizard.database.username') }}</label>
<tr>
<th>
<label class="form-label" for="username">{{ trans('setup.wizard.database.username') }}</label>
</th>
<td>
<input
class="form-input"
name="username"
type="text"
id="username"
@ -67,54 +76,62 @@
>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="password">{{ trans('setup.wizard.database.password') }}</label>
<tr>
<th>
<label class="form-label" for="password">{{ trans('setup.wizard.database.password') }}</label>
</th>
<td>
<input
class="form-input"
type="password"
name="password"
id="password"
class="regular-text"
value="{{ password }}"
>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="db">{{ trans('setup.wizard.database.db') }}</label>
<tr>
<th>
<label class="form-label" for="db">{{ trans('setup.wizard.database.db') }}</label>
</th>
<td>
<input
class="form-input"
name="db"
type="text"
id="db"
size="25"
value="{{ database }}"
>
<p>{{ trans('setup.wizard.database.db-notice') }}</p>
</td>
</tr>
<tr>
<th scope="row">
<label for="prefix">{{ trans('setup.wizard.database.prefix') }}</label>
<th></th>
<td><p><small>{{ trans('setup.wizard.database.db-notice') }}</small></p></td>
</tr>
<tr>
<th>
<label class="form-label" for="prefix">{{ trans('setup.wizard.database.prefix') }}</label>
</th>
<td>
<input
class="form-input"
name="prefix"
type="text"
id="prefix"
size="25"
value="{{ prefix }}"
>
<p>{{ trans('setup.wizard.database.prefix-notice') }}</p>
</td>
</tr>
<tr>
<th></th>
<td><p><small>{{ trans('setup.wizard.database.prefix-notice') }}</small></p></td>
</tr>
</table>
{% if errors.any %}
<div class="alert alert-warning" role="alert">
<div class="toast toast-error" role="alert">
<ul>
{% for error in errors.all %}
<li>{{ error }}</li>
@ -128,7 +145,7 @@
type="submit"
name="submit"
id="submit"
class="button button-large"
class="btn btn-primary"
value="{{ trans('setup.wizard.welcome.button') }}"
>
</p>

View File

@ -4,14 +4,8 @@
{% block content %}
<p>{{ trans('setup.wizard.finish.text') }}</p>
<table class="form-table install-success">
<tr>
<th>{{ trans('auth.email') }}</th>
<td>{{ email }}</td>
</tr>
</table>
<p class="step">
<a href="{{ url('/') }}" class="button button-large">
<p>
<a href="{{ url('/') }}" class="btn btn-primary">
{{ trans('general.index') }}
</a>
</p>

View File

@ -11,86 +11,79 @@
novalidate="novalidate"
>
{{ csrf_field() }}
<table class="form-table">
<tr>
<th scope="row">
<label for="email">{{ trans('setup.wizard.info.admin-email') }}</label>
<table>
<tr class="form-group">
<th>
<label class="form-label" for="email">{{ trans('setup.wizard.info.admin-email') }}</label>
</th>
<td>
<input name="email" type="email" id="email" size="25">
<p>{{ trans('setup.wizard.info.admin-notice') }}</p>
<input class="form-input" name="email" type="email" id="email" size="25">
</td>
</tr>
<tr>
<th scope="row">
<label for="email">{{ trans('setup.wizard.info.nickname') }}</label>
<th></th>
<td><p><small>{{ trans('setup.wizard.info.admin-notice') }}</small></p></td>
</tr>
<tr class="form-group">
<th>
<label class="form-label" for="email">{{ trans('setup.wizard.info.nickname') }}</label>
</th>
<td>
<input name="nickname" type="text" id="nickname" size="25">
<input class="form-input my-2" name="nickname" type="text" id="nickname" size="25">
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="password">{{ trans('setup.wizard.info.password') }}</label>
<tr class="form-group">
<th>
<label class="form-label" for="password">{{ trans('setup.wizard.info.password') }}</label>
</th>
<td>
<input type="password" name="password" id="password" class="regular-text">
<p>{{ trans('setup.wizard.info.pwd-notice') }}</p>
<input class="form-input" type="password" name="password" id="password" class="regular-text">
</td>
</tr>
<tr class="form-field form-required">
<th scope="row">
<label for="password_confirmation">
<tr>
<th></th>
<td><p><small>{{ trans('setup.wizard.info.pwd-notice') }}</small></p></td>
</tr>
<tr class="form-group">
<th>
<label class="form-label" for="password_confirmation">
{{ trans('setup.wizard.info.confirm-pwd') }}
</label>
</th>
<td>
<input
class="form-input my-2"
type="password"
name="password_confirmation"
id="password_confirmation"
>
</td>
</tr>
<tr>
<th scope="row">
<label for="site_name">
<tr class="form-group">
<th>
<label class="form-label" for="site_name">
{{ trans('setup.wizard.info.site-name') }}
</label>
</th>
<td>
<input
class="form-input"
name="site_name"
type="text"
id="site_name"
size="25"
value="{{ config('options.site_name') }}"
>
<p>{{ trans('setup.wizard.info.site-name-notice') }}</p>
</td>
</tr>
<tr>
<th scope="row">
<label for="generate_random">{{ trans('setup.wizard.info.secure') }}</label>
</th>
<td>
<label for="generate_random">
<input
name="generate_random"
type="checkbox"
id="generate_random"
size="25"
value="on"
checked
>
{{ trans('setup.wizard.info.secure-notice') }}
</label>
</td>
<th></th>
<td><p><small>{{ trans('setup.wizard.info.site-name-notice') }}</small></p></td>
</tr>
</table>
{% if errors.any %}
<div class="alert alert-warning" role="alert">
<div class="toast toast-error" role="alert">
<ul>
{% for error in errors.all %}
<li>{{ error }}</li>
@ -104,7 +97,7 @@
type="submit"
name="submit"
id="submit"
class="button button-large"
class="btn btn-primary"
value="{{ trans('setup.wizard.info.button') }}"
>
</p>

View File

@ -5,7 +5,7 @@
{% block content %}
<p>{{ trans('setup.wizard.welcome.text', {version: config('app.version')}) }}</p>
<p class="step">
<a href="{{ url('setup/database') }}" class="button button-large">
<a href="{{ url('setup/database') }}" class="btn btn-primary">
{{ trans('setup.wizard.welcome.button') }}
</a>
</p>

View File

@ -1,7 +1,7 @@
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
<i class="fas fa-language" aria-hidden="true"></i>
<span class="d-none d-sm-inline">{{ current }}</span>
<span class="d-none d-sm-inline">{{ lang_short_name }}</span>
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
{% for lang in langs %}

View File

@ -128,8 +128,6 @@ class SetupControllerTest extends TestCase
])->assertDontSee(trans('setup.wizard.finish.title'));
$this->spy(Artisan::class, function ($spy) {
$spy->shouldReceive('call')->with('key:generate')->once();
$spy->shouldReceive('call')->with('salt:random')->once();
$spy->shouldReceive('call')
->with('jwt:secret', ['--no-interaction' => true])
->once();
@ -152,9 +150,7 @@ class SetupControllerTest extends TestCase
'password' => '12345678',
'password_confirmation' => '12345678',
'site_name' => 'bs',
'generate_random' => true,
])->assertSee(trans('setup.wizard.finish.title'))
->assertSee('a@b.c');
])->assertSee(trans('setup.wizard.finish.title'));
$superAdmin = \App\Models\User::find(1);
$this->assertEquals('a@b.c', $superAdmin->email);
$this->assertTrue($superAdmin->verifyPassword('12345678'));

View File

@ -12,7 +12,6 @@ const config = {
mode: devMode ? 'development' : 'production',
entry: {
app: ['react-hot-loader/patch', './resources/assets/src/index.tsx'],
'language-chooser': './resources/assets/src/scripts/language-chooser.ts',
style: [
'bootstrap/dist/css/bootstrap.min.css',
'admin-lte/dist/css/alt/adminlte.core.min.css',
@ -22,7 +21,11 @@ const config = {
'@fortawesome/fontawesome-free/css/all.min.css',
'./resources/assets/src/styles/common.styl',
],
setup: './resources/assets/src/styles/setup.styl',
spectre: [
'spectre.css/dist/spectre.min.css',
'./resources/assets/src/fonts/minecraft.css',
'./resources/assets/src/styles/spectre.css',
],
},
output: {
path: `${__dirname}/public/app`,
@ -72,14 +75,14 @@ const config = {
],
},
{
test: /(node_modules.*)\.css$/,
test: /\.css$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
],
},
{
test: /(common|home|setup)\.styl$/,
test: /(common|home)\.styl$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 2 } },

View File

@ -6265,7 +6265,7 @@ jqvmap-novulnerability@^1.5.1:
resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^3.13.1:
js-yaml@^3.13.1, js-yaml@^3.9.0:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
@ -6273,14 +6273,6 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.9.0:
version "3.13.1"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -9317,6 +9309,11 @@ spdy@^4.0.1:
select-hose "^2.0.0"
spdy-transport "^3.0.0"
spectre.css@^0.5.8:
version "0.5.8"
resolved "https://registry.yarnpkg.com/spectre.css/-/spectre.css-0.5.8.tgz#e543e58a52dd83409286a065b0fb1e9e1c16e077"
integrity sha512-3N4WocWY+Dl6b3e5v3nsZYyp+VSDcBfGDzyyHw/H78ie9BoAhHkxmrhLxo9y8RadxYzVrPjfPdlev3hXEUzR2w==
split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0"
resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"