Compare commits

...

47 Commits

Author SHA1 Message Date
Amir Raminfar
398db90f2a Release 3.2.1 2021-01-06 11:00:09 -08:00
dependabot-preview[bot]
d8b9019114 Merge pull request #921 from amir20/dependabot/npm_and_yarn/autoprefixer-10.2.0 2021-01-06 02:32:45 +00:00
dependabot-preview[bot]
6027012548 Bump autoprefixer from 10.1.0 to 10.2.0
Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.1.0 to 10.2.0.
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/autoprefixer/compare/10.1.0...10.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-06 02:27:13 +00:00
Amir Raminfar
4d4d8f549f Adds html5 download and changes mimetype 2021-01-05 16:59:51 -08:00
Amir Raminfar
72fabbb3fa Cleans up go.mod 2021-01-05 13:53:49 -08:00
dependabot-preview[bot]
fba244144c Merge pull request #919 from amir20/dependabot/go_modules/github.com/docker/docker-20.10.2incompatible 2021-01-05 13:27:02 +00:00
dependabot-preview[bot]
c5c04ed9b5 Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 20.10.1+incompatible to 20.10.2+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Changelog](https://github.com/moby/moby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/docker/docker/compare/v20.10.1...v20.10.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-05 13:21:39 +00:00
Amir Raminfar
7e2e75fcd2 Cleans up go code 2021-01-04 20:07:28 -08:00
Amir Raminfar
89144ff61f Release 3.2.0 2021-01-04 11:26:21 -08:00
dependabot-preview[bot]
b66e959abf Merge pull request #918 from amir20/dependabot/npm_and_yarn/caniuse-lite-1.0.30001173 2021-01-04 09:27:52 +00:00
dependabot-preview[bot]
1164909c8f Bump caniuse-lite from 1.0.30001171 to 1.0.30001173
Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001171 to 1.0.30001173.
- [Release notes](https://github.com/ben-eb/caniuse-lite/releases)
- [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001171...v1.0.30001173)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-04 09:22:51 +00:00
Amir Raminfar
30fcf42bd7 Reverts subtractions 2021-01-03 17:31:46 -08:00
Amir Raminfar
911a4843c6 Subtracts 2 minutes from begenning of container 2021-01-03 17:24:55 -08:00
Amir Raminfar
5ba3d8df2f Fixes version test 2021-01-03 14:39:22 -08:00
Amir Raminfar
c362ef24fc Updates version route 2021-01-03 14:30:58 -08:00
Amir Raminfar
ac008519bc Add new functionality to download logs (#917) 2021-01-03 14:27:17 -08:00
Amir Raminfar
b87b0d018f Fixes error handeling for streaming 2021-01-03 13:44:36 -08:00
dependabot-preview[bot]
6dbbd78801 Merge pull request #916 from amir20/dependabot/npm_and_yarn/html-webpack-plugin-4.5.1 2021-01-03 17:46:42 +00:00
dependabot-preview[bot]
ebd9db4d00 Bump html-webpack-plugin from 4.5.0 to 4.5.1
Bumps [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/jantimon/html-webpack-plugin/releases)
- [Changelog](https://github.com/jantimon/html-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/jantimon/html-webpack-plugin/compare/v4.5.0...v4.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-03 17:41:50 +00:00
Amir Raminfar
de15fcd74f Tries to user readers instead of channels (#915) 2021-01-02 19:25:52 -08:00
Amir Raminfar
246f06e1a5 Fixes formatting 2021-01-01 14:58:22 -08:00
Amir Raminfar
da2401bb89 Adds is-hidden-mobile for header 2021-01-01 14:50:47 -08:00
dependabot-preview[bot]
8d7f897e19 Merge pull request #913 from amir20/dependabot/npm_and_yarn/webpack-cli-4.3.1 2020-12-31 17:48:43 +00:00
dependabot-preview[bot]
76b506ad25 Bump webpack-cli from 4.3.0 to 4.3.1
Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 4.3.0 to 4.3.1.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@4.3.0...webpack-cli@4.3.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-31 17:43:38 +00:00
dependabot-preview[bot]
5e21179d2e Merge pull request #912 from amir20/dependabot/npm_and_yarn/sass-1.32.0 2020-12-30 00:32:10 +00:00
dependabot-preview[bot]
619f23517c Bump sass from 1.30.0 to 1.32.0
Bumps [sass](https://github.com/sass/dart-sass) from 1.30.0 to 1.32.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.30.0...1.32.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-30 00:26:08 +00:00
dependabot-preview[bot]
0a40077c9a Merge pull request #911 from amir20/dependabot/npm_and_yarn/postcss-8.2.2 2020-12-29 21:06:08 +00:00
dependabot-preview[bot]
cf0b4a5896 Bump postcss from 8.2.1 to 8.2.2
Bumps [postcss](https://github.com/postcss/postcss) from 8.2.1 to 8.2.2.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.2.1...8.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-29 21:01:01 +00:00
dependabot-preview[bot]
22c2003794 Merge pull request #910 from amir20/dependabot/npm_and_yarn/webpack-dev-server-3.11.1 2020-12-29 13:47:45 +00:00
dependabot-preview[bot]
e05425e161 Bump webpack-dev-server from 3.11.0 to 3.11.1
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 3.11.0 to 3.11.1.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/v3.11.1/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v3.11.0...v3.11.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-29 13:42:37 +00:00
dependabot-preview[bot]
65e2000876 Merge pull request #909 from amir20/dependabot/npm_and_yarn/caniuse-lite-1.0.30001171 2020-12-29 00:42:27 +00:00
dependabot-preview[bot]
138c5fd957 Bump caniuse-lite from 1.0.30001170 to 1.0.30001171
Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001170 to 1.0.30001171.
- [Release notes](https://github.com/ben-eb/caniuse-lite/releases)
- [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001170...v1.0.30001171)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-29 00:37:08 +00:00
dependabot-preview[bot]
5144cafa97 Merge pull request #908 from amir20/dependabot/npm_and_yarn/webpack-5.11.1 2020-12-28 18:44:09 +00:00
dependabot-preview[bot]
f7d4f41de4 Bump webpack from 5.11.0 to 5.11.1
Bumps [webpack](https://github.com/webpack/webpack) from 5.11.0 to 5.11.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.11.0...v5.11.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-28 18:38:34 +00:00
dependabot-preview[bot]
8ff8ce109b Merge pull request #907 from amir20/dependabot/npm_and_yarn/webpack-cli-4.3.0 2020-12-25 18:10:29 +00:00
dependabot-preview[bot]
6a0a3eb0fa Bump webpack-cli from 4.2.0 to 4.3.0
Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@4.2.0...webpack-cli@4.3.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-25 18:05:48 +00:00
dependabot[bot]
3abdee6c2f Bump node-notifier from 8.0.0 to 8.0.1 in /integration (#906)
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-12-22 07:25:21 -08:00
dependabot-preview[bot]
eeb9243118 Merge pull request #905 from amir20/dependabot/npm_and_yarn/node-notifier-8.0.1 2020-12-21 16:31:34 +00:00
dependabot-preview[bot]
b9b4cdbcd9 [Security] Bump node-notifier from 8.0.0 to 8.0.1
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1. **This update includes a security fix.**
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-21 16:25:43 +00:00
dependabot-preview[bot]
8d9abdb929 Merge pull request #904 from amir20/dependabot/npm_and_yarn/webpack-5.11.0 2020-12-21 13:19:49 +00:00
dependabot-preview[bot]
56dddc61ee Bump webpack from 5.10.3 to 5.11.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.10.3 to 5.11.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.10.3...v5.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-21 13:13:10 +00:00
dependabot-preview[bot]
5acd019994 Merge pull request #903 from amir20/dependabot/npm_and_yarn/caniuse-lite-1.0.30001170 2020-12-20 06:42:44 +00:00
dependabot-preview[bot]
ed7eab4e26 Bump caniuse-lite from 1.0.30001168 to 1.0.30001170
Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001168 to 1.0.30001170.
- [Release notes](https://github.com/ben-eb/caniuse-lite/releases)
- [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001168...v1.0.30001170)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-20 06:37:23 +00:00
dependabot-preview[bot]
1b6ee569e5 Merge pull request #902 from amir20/dependabot/npm_and_yarn/dompurify-2.2.6 2020-12-18 15:28:22 +00:00
dependabot-preview[bot]
c76296ab02 Bump dompurify from 2.2.5 to 2.2.6
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.2.5 to 2.2.6.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/commits/2.2.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-18 15:22:52 +00:00
dependabot-preview[bot]
dac35f658c Merge pull request #901 from amir20/dependabot/npm_and_yarn/dompurify-2.2.5 2020-12-18 15:05:43 +00:00
dependabot-preview[bot]
7139d5ff63 Bump dompurify from 2.2.4 to 2.2.5
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 2.2.4 to 2.2.5.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/2.2.4...2.2.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-12-18 15:00:25 +00:00
15 changed files with 410 additions and 401 deletions

View File

@@ -1,13 +1,26 @@
<template>
<scrollable-view :scrollable="scrollable" v-if="container">
<template v-slot:header v-if="showTitle">
<div class="columns is-vcentered mr-0">
<div class="columns is-vcentered mr-0 is-hidden-mobile">
<div class="column is-narrow">
<container-title :value="container.name" @close="$emit('close')"></container-title>
</div>
<div class="column is-clipped">
<container-stat :stat="container.stat" :state="container.state"></container-stat>
</div>
<div class="column is-narrow">
<a
class="button is-small is-outlined"
id="download"
:href="`${base}/api/logs/download?id=${container.id}`"
download
>
<span class="icon">
<icon name="save"></icon>
</span>
Download
</a>
</div>
<div class="column is-narrow" v-if="closable">
<button class="delete is-medium" @click="$emit('close')"></button>
</div>
@@ -26,6 +39,8 @@ import LogViewerWithSource from "./LogViewerWithSource";
import ScrollableView from "./ScrollableView";
import ContainerTitle from "./ContainerTitle";
import ContainerStat from "./ContainerStat";
import Icon from "./Icon";
import config from "../store/config";
export default {
props: {
@@ -51,12 +66,16 @@ export default {
ScrollableView,
ContainerTitle,
ContainerStat,
Icon,
},
computed: {
...mapGetters(["allContainersById"]),
container() {
return this.allContainersById[this.id];
},
base() {
return config.base;
},
},
};
</script>
@@ -73,4 +92,16 @@ button.delete {
opacity: 1;
}
}
#download.button {
.icon {
margin-right: 5px;
height: 80%;
}
&:hover {
color: var(--primary-color);
border-color: var(--primary-color);
}
}
</style>

View File

@@ -124,9 +124,7 @@ describe("<LogEventSource />", () => {
describe("render html correctly", () => {
const RealDate = Date;
beforeAll(() => {
global.Date = class extends (
RealDate
) {
global.Date = class extends RealDate {
constructor(arg) {
if (arg) {
return new RealDate(arg);

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
<template> </template>
<template></template>
<script>
import { mapActions, mapGetters, mapState } from "vuex";

View File

@@ -1,10 +1,7 @@
package docker
import (
"bufio"
"bytes"
"context"
"encoding/binary"
"encoding/json"
"fmt"
"io"
@@ -37,9 +34,9 @@ type dockerProxy interface {
type Client interface {
ListContainers() ([]Container, error)
FindContainer(string) (Container, error)
ContainerLogs(context.Context, string, int, string) (<-chan string, <-chan error)
ContainerLogs(context.Context, string, int, string) (io.ReadCloser, error)
Events(context.Context) (<-chan ContainerEvent, <-chan error)
ContainerLogsBetweenDates(context.Context, string, time.Time, time.Time) ([]string, error)
ContainerLogsBetweenDates(context.Context, string, time.Time, time.Time) (io.ReadCloser, error)
ContainerStats(context.Context, string, chan<- ContainerStat) error
}
@@ -121,34 +118,6 @@ func (d *dockerClient) ListContainers() ([]Container, error) {
return containers, nil
}
func logReader(reader io.ReadCloser, tty bool) func() (string, error) {
if tty {
scanner := bufio.NewScanner(reader)
return func() (string, error) {
if scanner.Scan() {
return scanner.Text(), nil
}
return "", io.EOF
}
}
hdr := make([]byte, 8)
var buffer bytes.Buffer
return func() (string, error) {
buffer.Reset()
_, err := reader.Read(hdr)
if err != nil {
return "", err
}
count := binary.BigEndian.Uint32(hdr[4:])
_, err = io.CopyN(&buffer, reader, int64(count))
if err != nil {
return "", err
}
return buffer.String(), nil
}
}
func (d *dockerClient) ContainerStats(ctx context.Context, id string, stats chan<- ContainerStat) error {
response, err := d.cli.ContainerStats(ctx, id, true)
@@ -192,7 +161,7 @@ func (d *dockerClient) ContainerStats(ctx context.Context, id string, stats chan
return nil
}
func (d *dockerClient) ContainerLogs(ctx context.Context, id string, tailSize int, since string) (<-chan string, <-chan error) {
func (d *dockerClient) ContainerLogs(ctx context.Context, id string, tailSize int, since string) (io.ReadCloser, error) {
log.WithField("id", id).WithField("since", since).Debug("streaming logs for container")
options := types.ContainerLogsOptions{
@@ -203,42 +172,18 @@ func (d *dockerClient) ContainerLogs(ctx context.Context, id string, tailSize in
Timestamps: true,
Since: since,
}
reader, err := d.cli.ContainerLogs(ctx, id, options)
errChannel := make(chan error, 1)
reader, err := d.cli.ContainerLogs(ctx, id, options)
if err != nil {
errChannel <- err
close(errChannel)
return nil, errChannel
return nil, err
}
messages := make(chan string)
go func() {
<-ctx.Done()
reader.Close()
}()
containerJSON, err := d.cli.ContainerInspect(ctx, id)
if err != nil {
return nil, err
}
containerJSON, _ := d.cli.ContainerInspect(ctx, id)
go func() {
defer close(messages)
defer close(errChannel)
defer reader.Close()
nextEntry := logReader(reader, containerJSON.Config.Tty)
for {
line, err := nextEntry()
if err != nil {
errChannel <- err
break
}
select {
case messages <- line:
case <-ctx.Done():
}
}
}()
return messages, errChannel
return newLogReader(reader, containerJSON.Config.Tty), nil
}
func (d *dockerClient) Events(ctx context.Context) (<-chan ContainerEvent, <-chan error) {
@@ -267,7 +212,7 @@ func (d *dockerClient) Events(ctx context.Context) (<-chan ContainerEvent, <-cha
return messages, errors
}
func (d *dockerClient) ContainerLogsBetweenDates(ctx context.Context, id string, from time.Time, to time.Time) ([]string, error) {
func (d *dockerClient) ContainerLogsBetweenDates(ctx context.Context, id string, from time.Time, to time.Time) (io.ReadCloser, error) {
options := types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
@@ -275,25 +220,17 @@ func (d *dockerClient) ContainerLogsBetweenDates(ctx context.Context, id string,
Since: strconv.FormatInt(from.Unix(), 10),
Until: strconv.FormatInt(to.Unix(), 10),
}
reader, _ := d.cli.ContainerLogs(ctx, id, options)
defer reader.Close()
containerJSON, _ := d.cli.ContainerInspect(ctx, id)
reader, err := d.cli.ContainerLogs(ctx, id, options)
nextEntry := logReader(reader, containerJSON.Config.Tty)
var messages []string
for {
line, err := nextEntry()
if err != nil {
if err == io.EOF {
break
} else {
return nil, err
}
}
messages = append(messages, line)
if err != nil {
return nil, err
}
return messages, nil
containerJSON, err := d.cli.ContainerInspect(ctx, id)
if err != nil {
return nil, err
}
return newLogReader(reader, containerJSON.Config.Tty), nil
}

View File

@@ -7,6 +7,7 @@ import (
"errors"
"io"
"io/ioutil"
"strings"
"testing"
"github.com/docker/docker/api/types"
@@ -132,13 +133,10 @@ func Test_dockerClient_ContainerLogs_happy(t *testing.T) {
proxy.On("ContainerInspect", mock.Anything, id).Return(json, nil)
client := &dockerClient{proxy, filters.NewArgs()}
messages, _ := client.ContainerLogs(context.Background(), id, 300, "since")
logReader, _ := client.ContainerLogs(context.Background(), id, 300, "since")
actual, _ := <-messages
assert.Equal(t, expected, actual, "message doesn't match expected")
_, ok := <-messages
assert.False(t, ok, "channel should have been closed")
actual, _ := ioutil.ReadAll(logReader)
assert.Equal(t, expected, string(actual), "message doesn't match expected")
proxy.AssertExpectations(t)
}
@@ -148,7 +146,7 @@ func Test_dockerClient_ContainerLogs_happy_with_tty(t *testing.T) {
proxy := new(mockedProxy)
expected := "INFO Testing logs..."
reader := ioutil.NopCloser(bytes.NewReader([]byte(expected)))
reader := ioutil.NopCloser(strings.NewReader(expected))
options := types.ContainerLogsOptions{ShowStdout: true, ShowStderr: true, Follow: true, Tail: "300", Timestamps: true}
proxy.On("ContainerLogs", mock.Anything, id, options).Return(reader, nil)
@@ -156,13 +154,11 @@ func Test_dockerClient_ContainerLogs_happy_with_tty(t *testing.T) {
proxy.On("ContainerInspect", mock.Anything, id).Return(json, nil)
client := &dockerClient{proxy, filters.NewArgs()}
messages, _ := client.ContainerLogs(context.Background(), id, 300, "")
logReader, _ := client.ContainerLogs(context.Background(), id, 300, "")
actual, _ := <-messages
assert.Equal(t, expected, actual, "message doesn't match expected")
actual, _ := ioutil.ReadAll(logReader)
assert.Equal(t, expected, string(actual), "message doesn't match expected")
_, ok := <-messages
assert.False(t, ok, "channel should have been closed")
proxy.AssertExpectations(t)
}
@@ -174,14 +170,10 @@ func Test_dockerClient_ContainerLogs_error(t *testing.T) {
client := &dockerClient{proxy, filters.NewArgs()}
messages, err := client.ContainerLogs(context.Background(), id, 300, "")
reader, err := client.ContainerLogs(context.Background(), id, 300, "")
assert.Nil(t, messages, "messages should be nil")
e, _ := <-err
assert.Error(t, e, "error should have been returned")
_, ok := <-err
assert.False(t, ok, "error channel should have been closed")
assert.Nil(t, reader, "reader should be nil")
assert.Error(t, err, "error should have been returned")
proxy.AssertExpectations(t)
}

49
docker/reader.go Normal file
View File

@@ -0,0 +1,49 @@
package docker
import (
"bytes"
"encoding/binary"
"io"
)
type logReader struct {
readerCloser io.ReadCloser
tty bool
lastHeader []byte
buffer bytes.Buffer
}
func newLogReader(reader io.ReadCloser, tty bool) io.ReadCloser {
return &logReader{
reader,
tty,
make([]byte, 8),
bytes.Buffer{},
}
}
func (r *logReader) Read(p []byte) (n int, err error) {
if r.tty {
return r.readerCloser.Read(p)
} else {
if r.buffer.Len() > 0 {
return r.buffer.Read(p)
} else {
r.buffer.Reset()
_, err := r.readerCloser.Read(r.lastHeader)
if err != nil {
return 0, err
}
count := binary.BigEndian.Uint32(r.lastHeader[4:])
_, err = io.CopyN(&r.buffer, r.readerCloser, int64(count))
if err != nil {
return 0, err
}
return r.buffer.Read(p)
}
}
}
func (r *logReader) Close() error {
return r.readerCloser.Close()
}

2
go.mod
View File

@@ -5,7 +5,7 @@ require (
github.com/beme/abide v0.0.0-20190723115211-635a09831760
github.com/containerd/containerd v1.4.3 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v20.10.1+incompatible
github.com/docker/docker v20.10.2+incompatible
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/dustin/go-humanize v1.0.0

4
go.sum
View File

@@ -55,8 +55,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.1+incompatible h1:u0HIBLwOJdemyBdTCkoBX34u3lb5KyBo0rQE3a5Yg+E=
github.com/docker/docker v20.10.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.2+incompatible h1:vFgEHPqWBTp4pTjdLwjAA4bSo3gvIGOYwuJTlEjVBCw=
github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=

View File

@@ -2754,6 +2754,13 @@ lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.4:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
make-dir@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392"
@@ -2931,9 +2938,9 @@ node-modules-regexp@^1.0.0:
integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
node-notifier@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.0.tgz#a7eee2d51da6d0f7ff5094bc7108c911240c1620"
integrity sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==
version "8.0.1"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1"
integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==
dependencies:
growly "^1.3.0"
is-wsl "^2.2.0"
@@ -3485,9 +3492,11 @@ semver@^6.0.0, semver@^6.3.0:
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.2:
version "7.3.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
set-blocking@^2.0.0:
version "2.0.0"
@@ -4019,9 +4028,9 @@ uuid@^3.3.2:
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-to-istanbul@^7.0.0:
version "7.0.0"
@@ -4189,6 +4198,11 @@ y18n@^4.0.0:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@^18.1.2:
version "18.1.3"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"

View File

@@ -1,6 +1,6 @@
{
"name": "dozzle",
"version": "3.1.2",
"version": "3.2.1",
"description": "Realtime log viewer for docker containers. ",
"scripts": {
"prestart": "yarn clean",
@@ -32,7 +32,7 @@
"buefy": "^0.9.4",
"bulma": "^0.9.1",
"date-fns": "^2.16.1",
"dompurify": "^2.2.4",
"dompurify": "^2.2.6",
"hotkeys-js": "^3.8.1",
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
@@ -49,34 +49,34 @@
"@babel/plugin-transform-runtime": "^7.12.10",
"@vue/component-compiler-utils": "^3.2.0",
"@vue/test-utils": "^1.1.2",
"autoprefixer": "^10.1.0",
"autoprefixer": "^10.2.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^26.6.3",
"babel-preset-env": "^1.7.0",
"caniuse-lite": "^1.0.30001168",
"caniuse-lite": "^1.0.30001173",
"css-loader": "^5.0.1",
"eventsourcemock": "^2.0.0",
"html-webpack-plugin": "^4.5.0",
"html-webpack-plugin": "^4.5.1",
"husky": "^5.0.6",
"jest": "^26.6.3",
"jest-serializer-vue": "^2.0.2",
"lint-staged": "^10.5.3",
"mini-css-extract-plugin": "^1.3.3",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.1",
"postcss": "^8.2.2",
"postcss-loader": "^4.1.0",
"prettier": "^2.2.1",
"release-it": "^14.2.2",
"sass": "^1.30.0",
"sass": "^1.32.0",
"sass-loader": "^10.1.0",
"vue-hot-reload-api": "^2.3.4",
"vue-jest": "^3.0.7",
"vue-loader": "^15.9.6",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.12",
"webpack": "^5.10.3",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0",
"webpack": "^5.11.1",
"webpack-cli": "^4.3.1",
"webpack-dev-server": "^3.11.1",
"webpack-pwa-manifest": "^4.3.0"
},
"lint-staged": {

View File

@@ -29,7 +29,7 @@ Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline' fonts.googleapis.com; img-src 'self'; manifest-src 'self'; font-src fonts.gstatic.com; connect-src 'self' api.github.com; require-trusted-types-for 'script'
Content-Type: text/plain; charset=utf-8
dev
dev compiled with go1.15.6
/* snapshot: Test_handler_streamEvents_error */
HTTP/1.1 200 OK
@@ -81,12 +81,15 @@ X-Content-Type-Options: nosniff
error finding container
/* snapshot: Test_handler_streamLogs_error_reading */
HTTP/1.1 200 OK
HTTP/1.1 500 Internal Server Error
Connection: close
Cache-Control: no-cache
Connection: keep-alive
Content-Type: text/event-stream
X-Accel-Buffering: no
Content-Type: text/plain; charset=utf-8
X-Accel-Buffering: no
X-Content-Type-Options: nosniff
test error
/* snapshot: Test_handler_streamLogs_happy */
HTTP/1.1 200 OK
@@ -112,9 +115,6 @@ X-Accel-Buffering: no
event: container-stopped
data: end of stream
event: container-stopped
data: end of stream
/* snapshot: Test_handler_streamLogs_happy_with_id */
HTTP/1.1 200 OK
Connection: close

View File

@@ -1,6 +1,9 @@
package web
import (
"bufio"
"compress/gzip"
"context"
"encoding/json"
"fmt"
"html/template"
@@ -8,6 +11,7 @@ import (
"net/http"
"runtime"
"strings"
"time"
"github.com/amir20/dozzle/docker"
@@ -52,6 +56,7 @@ func createRouter(h *handler) *mux.Router {
}
s := r.PathPrefix(base).Subrouter()
s.HandleFunc("/api/logs/stream", h.streamLogs)
s.HandleFunc("/api/logs/download", h.downloadLogs)
s.HandleFunc("/api/logs", h.fetchLogsBetweenDates)
s.HandleFunc("/api/events/stream", h.streamEvents)
s.HandleFunc("/version", h.version)
@@ -103,11 +108,42 @@ func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request)
to, _ := time.Parse(time.RFC3339, r.URL.Query().Get("to"))
id := r.URL.Query().Get("id")
messages, _ := h.client.ContainerLogsBetweenDates(r.Context(), id, from, to)
reader, err := h.client.ContainerLogsBetweenDates(r.Context(), id, from, to)
defer reader.Close()
for _, m := range messages {
fmt.Fprintln(w, m)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(w, reader)
}
func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
container, err := h.client.FindContainer(id)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
now := time.Now()
from := time.Unix(container.Created, 0)
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%v.log.gz", container.ID))
w.Header().Set("Content-Type", "application/gzip")
zw := gzip.NewWriter(w)
defer zw.Close()
zw.Name = fmt.Sprintf("%v.log", container.ID)
zw.Comment = "Logs generated by Dozzle"
zw.ModTime = now
reader, err := h.client.ContainerLogsBetweenDates(r.Context(), container.ID, from, now)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(zw, reader)
}
func (h *handler) streamLogs(w http.ResponseWriter, r *http.Request) {
@@ -123,45 +159,51 @@ func (h *handler) streamLogs(w http.ResponseWriter, r *http.Request) {
return
}
container, e := h.client.FindContainer(id)
if e != nil {
http.Error(w, e.Error(), http.StatusNotFound)
container, err := h.client.FindContainer(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
messages, err := h.client.ContainerLogs(r.Context(), container.ID, h.config.TailSize, r.Header.Get("Last-Event-ID"))
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
Loop:
for {
select {
case message, ok := <-messages:
if !ok {
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
break Loop
}
fmt.Fprintf(w, "data: %s\n", message)
if index := strings.IndexAny(message, " "); index != -1 {
id := message[:index]
if _, err := time.Parse(time.RFC3339Nano, id); err == nil {
fmt.Fprintf(w, "id: %s\n", id)
}
}
fmt.Fprintf(w, "\n")
reader, err := h.client.ContainerLogs(r.Context(), container.ID, h.config.TailSize, r.Header.Get("Last-Event-ID"))
if err != nil {
if err == io.EOF {
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
case e := <-err:
if e == io.EOF {
log.Debugf("container stopped: %v", container.ID)
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
} else {
log.Debugf("error while reading from log stream: %v", e)
break Loop
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return
}
defer reader.Close()
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
message := scanner.Text()
fmt.Fprintf(w, "data: %s\n", message)
if index := strings.IndexAny(message, " "); index != -1 {
id := message[:index]
if _, err := time.Parse(time.RFC3339Nano, id); err == nil {
fmt.Fprintf(w, "id: %s\n", id)
}
}
fmt.Fprintf(w, "\n")
f.Flush()
}
log.Debugf("streaming stopped: %v", container.ID)
if scanner.Err() == nil {
log.Debugf("container stopped: %v", container.ID)
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
} else if scanner.Err() != context.Canceled {
log.Errorf("unknown error while streaming %v", scanner.Err())
}
log.WithField("routines", runtime.NumGoroutine()).Debug("runtime goroutine stats")
@@ -199,14 +241,14 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
for _, c := range containers {
if c.State == "running" {
if err := h.client.ContainerStats(ctx, c.ID, stats); err != nil {
log.Errorf("Error while streaming container stats: %v", err)
log.Errorf("error while streaming container stats: %v", err)
}
}
}
}
if err := sendContainersJSON(h.client, w); err != nil {
log.Errorf("Error while encoding containers to stream: %v", err)
log.Errorf("error while encoding containers to stream: %v", err)
}
f.Flush()
@@ -257,24 +299,25 @@ func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
}
func (h *handler) version(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, h.config.Version)
fmt.Fprintf(w, "%v compiled with %v", h.config.Version, runtime.Version())
}
func sendContainersJSON(client docker.Client, w http.ResponseWriter) error {
if containers, err := client.ListContainers(); err != nil {
containers, err := client.ListContainers()
if err != nil {
return err
} else {
if _, err := fmt.Fprint(w, "event: containers-changed\ndata: "); err != nil {
return err
}
}
if err := json.NewEncoder(w).Encode(containers); err != nil {
return err
}
if _, err := fmt.Fprint(w, "event: containers-changed\ndata: "); err != nil {
return err
}
if _, err := fmt.Fprint(w, "\n\n"); err != nil {
return err
}
if err := json.NewEncoder(w).Encode(containers); err != nil {
return err
}
if _, err := fmt.Fprint(w, "\n\n"); err != nil {
return err
}
return nil

View File

@@ -4,9 +4,11 @@ import (
"context"
"errors"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"github.com/magiconair/properties/assert"
@@ -25,34 +27,17 @@ type MockedClient struct {
func (m *MockedClient) FindContainer(id string) (docker.Container, error) {
args := m.Called(id)
container, ok := args.Get(0).(docker.Container)
if !ok {
panic("containers is not of type docker.Container")
}
return container, args.Error(1)
return args.Get(0).(docker.Container), args.Error(1)
}
func (m *MockedClient) ListContainers() ([]docker.Container, error) {
args := m.Called()
containers, ok := args.Get(0).([]docker.Container)
if !ok {
panic("containers is not of type []docker.Container")
}
return containers, args.Error(1)
return args.Get(0).([]docker.Container), args.Error(1)
}
func (m *MockedClient) ContainerLogs(ctx context.Context, id string, tailSize int, since string) (<-chan string, <-chan error) {
func (m *MockedClient) ContainerLogs(ctx context.Context, id string, tailSize int, since string) (io.ReadCloser, error) {
args := m.Called(ctx, id, tailSize)
channel, ok := args.Get(0).(chan string)
if !ok {
panic("channel is not of type chan string")
}
err, ok := args.Get(1).(chan error)
if !ok {
panic("error is not of type chan error")
}
return channel, err
return args.Get(0).(io.ReadCloser), args.Error(1)
}
func (m *MockedClient) Events(ctx context.Context) (<-chan docker.ContainerEvent, <-chan error) {
@@ -82,15 +67,9 @@ func Test_handler_streamLogs_happy(t *testing.T) {
require.NoError(t, err, "NewRequest should not return an error.")
mockedClient := new(MockedClient)
messages := make(chan string)
errChannel := make(chan error)
reader := ioutil.NopCloser(strings.NewReader("INFO Testing logs..."))
mockedClient.On("FindContainer", id).Return(docker.Container{ID: id}, nil)
mockedClient.On("ContainerLogs", mock.Anything, mock.Anything, 300).Return(messages, errChannel)
go func() {
messages <- "INFO Testing logs..."
close(messages)
}()
mockedClient.On("ContainerLogs", mock.Anything, mock.Anything, 300).Return(reader, nil)
h := handler{client: mockedClient, config: &Config{TailSize: 300}}
handler := http.HandlerFunc(h.streamLogs)
@@ -109,15 +88,9 @@ func Test_handler_streamLogs_happy_with_id(t *testing.T) {
require.NoError(t, err, "NewRequest should not return an error.")
mockedClient := new(MockedClient)
messages := make(chan string)
errChannel := make(chan error)
reader := ioutil.NopCloser(strings.NewReader("2020-05-13T18:55:37.772853839Z INFO Testing logs..."))
mockedClient.On("FindContainer", id).Return(docker.Container{ID: id}, nil)
mockedClient.On("ContainerLogs", mock.Anything, mock.Anything, 300).Return(messages, errChannel)
go func() {
messages <- "2020-05-13T18:55:37.772853839Z INFO Testing logs..."
close(messages)
}()
mockedClient.On("ContainerLogs", mock.Anything, mock.Anything, 300).Return(reader, nil)
h := handler{client: mockedClient, config: &Config{TailSize: 300}}
handler := http.HandlerFunc(h.streamLogs)
@@ -136,15 +109,8 @@ func Test_handler_streamLogs_happy_container_stopped(t *testing.T) {
require.NoError(t, err, "NewRequest should not return an error.")
mockedClient := new(MockedClient)
messages := make(chan string)
errChannel := make(chan error)
mockedClient.On("FindContainer", id).Return(docker.Container{ID: id}, nil)
mockedClient.On("ContainerLogs", mock.Anything, id, 300).Return(messages, errChannel)
go func() {
errChannel <- io.EOF
close(messages)
}()
mockedClient.On("ContainerLogs", mock.Anything, id, 300).Return(ioutil.NopCloser(strings.NewReader("")), io.EOF)
h := handler{client: mockedClient, config: &Config{TailSize: 300}}
handler := http.HandlerFunc(h.streamLogs)
@@ -182,15 +148,8 @@ func Test_handler_streamLogs_error_reading(t *testing.T) {
require.NoError(t, err, "NewRequest should not return an error.")
mockedClient := new(MockedClient)
messages := make(chan string)
errChannel := make(chan error)
mockedClient.On("FindContainer", id).Return(docker.Container{ID: id}, nil)
mockedClient.On("ContainerLogs", mock.Anything, id, 300).Return(messages, errChannel)
go func() {
errChannel <- errors.New("test error")
close(messages)
}()
mockedClient.On("ContainerLogs", mock.Anything, id, 300).Return(ioutil.NopCloser(strings.NewReader("")), errors.New("test error"))
h := handler{client: mockedClient, config: &Config{TailSize: 300}}
handler := http.HandlerFunc(h.streamLogs)

315
yarn.lock
View File

@@ -294,6 +294,11 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@discoveryjs/json-ext@^0.5.0":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.1.tgz#cf87081ac9b0f3eb3b5740415b50b7966bac8fc5"
integrity sha512-Oee4NT60Lxe90m7VTYBU4UbABNaz0N4Q3G62CPB+6mGE4KuLMsTACmH8q3PH5u9pSZCuOdE9JClJ9vBqsp6DQg==
"@iarna/toml@2.2.5":
version "2.2.5"
resolved "https://registry.yarnpkg.com/@iarna/toml/-/toml-2.2.5.tgz#b32366c89b43c6f8cefbdefac778b9c828e3ba8c"
@@ -1324,17 +1329,17 @@
"@webassemblyjs/wast-parser" "1.9.1"
"@xtuc/long" "4.2.2"
"@webpack-cli/info@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.1.0.tgz#c596d5bc48418b39df00c5ed7341bf0f102dbff1"
integrity sha512-uNWSdaYHc+f3LdIZNwhdhkjjLDDl3jP2+XBqAq9H8DjrJUvlOKdP8TNruy1yEaDfgpAIgbSAN7pye4FEHg9tYQ==
"@webpack-cli/info@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.2.1.tgz#af98311f983d0b9fce7284cfcf1acaf1e9f4879c"
integrity sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==
dependencies:
envinfo "^7.7.3"
"@webpack-cli/serve@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.1.0.tgz#13ad38f89b6e53d1133bac0006a128217a6ebf92"
integrity sha512-7RfnMXCpJ/NThrhq4gYQYILB18xWyoQcBey81oIyVbmgbc6m5ZHHyFK+DyH7pLHJf0p14MxL4mTsoPAgBSTpIg==
"@webpack-cli/serve@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.2.1.tgz#7513d7a769e3f97958de799b5b49874425ae3396"
integrity sha512-Zj1z6AyS+vqV6Hfi7ngCjFGdHV5EwZNIHo6QfFTNe9PyW+zBU1zJ9BiOW1pmUEq950RC4+Dym6flyA/61/vhyw==
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
@@ -1528,11 +1533,6 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
array-back@^4.0.0, array-back@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.1.tgz#9b80312935a52062e1a233a9c7abeb5481b30e90"
integrity sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -1621,15 +1621,15 @@ atob@^2.1.2:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
autoprefixer@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.1.0.tgz#b19fd8524edef8c85c9db3bdb0c998de84e172fb"
integrity sha512-0/lBNwN+ZUnb5su18NZo5MBIjDaq6boQKZcxwy86Gip/CmXA2zZqUoFQLCNAGI5P25ZWSP2RWdhDJ8osfKEjoQ==
autoprefixer@^10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.0.tgz#73c148882ff771b48df9e76eaad88565516eda0c"
integrity sha512-5SdPoK2Q3rxVh4xC8GKdy772KbEESdl2SyJADCw5FMUrd5eNtpOTLo7oCFMEKvK86zQdvsIVTYk93E8dAfRy6g==
dependencies:
browserslist "^4.15.0"
caniuse-lite "^1.0.30001165"
browserslist "^4.16.1"
caniuse-lite "^1.0.30001173"
colorette "^1.2.1"
fraction.js "^4.0.12"
fraction.js "^4.0.13"
normalize-range "^0.1.2"
postcss-value-parser "^4.1.0"
@@ -2323,16 +2323,16 @@ browserslist@^3.2.6:
caniuse-lite "^1.0.30000844"
electron-to-chromium "^1.3.47"
browserslist@^4.14.5, browserslist@^4.15.0:
version "4.15.0"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.15.0.tgz#3d48bbca6a3f378e86102ffd017d9a03f122bdb0"
integrity sha512-IJ1iysdMkGmjjYeRlDU8PQejVwxvVO5QOfXH7ylW31GO6LwNRSmm/SgRXtNsEXqMLl2e+2H5eEJ7sfynF8TCaQ==
browserslist@^4.14.5, browserslist@^4.16.1:
version "4.16.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766"
integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==
dependencies:
caniuse-lite "^1.0.30001164"
caniuse-lite "^1.0.30001173"
colorette "^1.2.1"
electron-to-chromium "^1.3.612"
electron-to-chromium "^1.3.634"
escalade "^3.1.1"
node-releases "^1.1.67"
node-releases "^1.1.69"
bser@2.1.1:
version "2.1.1"
@@ -2455,10 +2455,10 @@ camelcase@^6.0.0, camelcase@^6.2.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001164, caniuse-lite@^1.0.30001165, caniuse-lite@^1.0.30001168:
version "1.0.30001168"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001168.tgz#6fcd098c139d003b9bd484cbb9ca26cb89907f9a"
integrity sha512-P2zmX7swIXKu+GMMR01TWa4csIKELTNnZKc+f1CjebmZJQtTAEXmpQSoKVJVVcvPGAA0TEYTOUp3VehavZSFPQ==
caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001173:
version "1.0.30001173"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001173.tgz#3c47bbe3cd6d7a9eda7f50ac016d158005569f56"
integrity sha512-R3aqmjrICdGCTAnSXtNyvWYMK3YtV5jwudbq0T7nN9k4kmE4CBuwPqyJ+KBzepSTh0huivV2gLbSMEzTTmfeYw==
capture-exit@^2.0.0:
version "2.0.0"
@@ -2710,16 +2710,6 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
command-line-usage@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.0.tgz#f28376a3da3361ff3d36cfd31c3c22c9a64c7cb6"
integrity sha512-Ew1clU4pkUeo6AFVDFxCbnN7GIZfXl48HIOQeFQnkO3oOqvpI7wdqtLRwv9iOCZ/7A+z4csVZeiDdEcj8g6Wiw==
dependencies:
array-back "^4.0.0"
chalk "^2.4.2"
table-layout "^1.0.0"
typical "^5.2.0"
commander@^2.19.0, commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@@ -2872,7 +2862,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^7.0.0:
cross-spawn@^7.0.0, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -3004,10 +2994,10 @@ debug@4.3.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0:
dependencies:
ms "2.1.2"
debug@^3.1.1, debug@^3.2.5:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
debug@^3.1.1, debug@^3.2.6:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
@@ -3057,7 +3047,7 @@ deep-equal@^1.0.1:
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
deep-extend@^0.6.0, deep-extend@~0.6.0:
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
@@ -3258,10 +3248,10 @@ domhandler@^2.3.0:
dependencies:
domelementtype "1"
dompurify@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.4.tgz#a98cd182b729bdd8715c3eb7a8bf8eafb2ff7410"
integrity sha512-jE21SelIgWrGKoXGfGPA524Zt1IJFBnktwfFMHDlEYRx5FZOdc+4eEH9mkA6PuhExrq3HVpJnY8hMYUzAMl0OA==
dompurify@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.6.tgz#54945dc5c0b45ce5ae228705777e8e59d7b2edc4"
integrity sha512-7b7ZArhhH0SP6W2R9cqK6RjaU82FZ2UPM7RO8qN1b1wyvC/NY1FNWcX1Pu00fFOAnzEORtwXe4bPaClg6pUybQ==
domutils@1.5.1:
version "1.5.1"
@@ -3327,10 +3317,10 @@ electron-to-chromium@^1.3.47:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz#e6671936f4571a874eb26e2e833aa0b2c0b776e0"
integrity sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q==
electron-to-chromium@^1.3.612:
version "1.3.619"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.619.tgz#4dc529ae802f5c9c31e7eea830144340539b62b4"
integrity sha512-WFGatwtk7Fw0QcKCZzfGD72hvbcXV8kLY8aFuj0Ip0QRnOtyLYMsc+wXbSjb2w4lk1gcAeNU1/lQ20A+tvuypQ==
electron-to-chromium@^1.3.634:
version "1.3.634"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.634.tgz#82ea400f520f739c4f6ff00c1f7524827a917d25"
integrity sha512-QPrWNYeE/A0xRvl/QP3E0nkaEvYUvH3gM04ZWYtIa6QlSpEetRlRI1xvQ7hiMIySHHEV+mwDSX8Kj4YZY6ZQAw==
emittery@^0.7.1:
version "0.7.1"
@@ -3584,6 +3574,21 @@ execa@^1.0.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
execa@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.0"
human-signals "^2.1.0"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.1"
onetime "^5.1.2"
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
exif-parser@^0.1.12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
@@ -3742,6 +3747,11 @@ fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fastest-levenshtein@^1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
fastq@^1.6.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
@@ -3749,14 +3759,7 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
dependencies:
websocket-driver ">=0.5.1"
faye-websocket@~0.11.1:
faye-websocket@^0.11.3:
version "0.11.3"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
@@ -3891,10 +3894,10 @@ forwarded@~0.1.2:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
fraction.js@^4.0.12:
version "4.0.12"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.12.tgz#0526d47c65a5fb4854df78bc77f7bec708d7b8c3"
integrity sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA==
fraction.js@^4.0.13:
version "4.0.13"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe"
integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA==
fragment-cache@^0.2.1:
version "0.2.1"
@@ -3965,6 +3968,11 @@ get-stream@^5.0.0, get-stream@^5.1.0:
dependencies:
pump "^3.0.0"
get-stream@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718"
integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -4267,17 +4275,17 @@ html-minifier-terser@^5.0.1:
relateurl "^0.2.7"
terser "^4.6.3"
html-webpack-plugin@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c"
integrity sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw==
html-webpack-plugin@^4.5.1:
version "4.5.1"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.1.tgz#40aaf1b5cb78f2f23a83333999625c20929cda65"
integrity sha512-yzK7RQZwv9xB+pcdHNTjcqbaaDZ+5L0zJHXfi89iWIZmb/FtzxhLk0635rmJihcQbs3ZUF27Xp4oWGx6EK56zg==
dependencies:
"@types/html-minifier-terser" "^5.0.0"
"@types/tapable" "^1.0.5"
"@types/webpack" "^4.41.8"
html-minifier-terser "^5.0.1"
loader-utils "^1.2.3"
lodash "^4.17.15"
lodash "^4.17.20"
pretty-error "^2.1.1"
tapable "^1.1.3"
util.promisify "1.0.0"
@@ -4382,6 +4390,11 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
husky@^5.0.6:
version "5.0.6"
resolved "https://registry.yarnpkg.com/husky/-/husky-5.0.6.tgz#27dbefe8603c6c0912fd89a3a67edfed9fac8bb9"
@@ -4480,7 +4493,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -5452,7 +5465,7 @@ json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json3@^3.3.2:
json3@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
@@ -6069,9 +6082,9 @@ node-modules-regexp@^1.0.0:
integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
node-notifier@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.0.tgz#a7eee2d51da6d0f7ff5094bc7108c911240c1620"
integrity sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==
version "8.0.1"
resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1"
integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==
dependencies:
growly "^1.3.0"
is-wsl "^2.2.0"
@@ -6080,10 +6093,10 @@ node-notifier@^8.0.0:
uuid "^8.3.0"
which "^2.0.2"
node-releases@^1.1.67:
version "1.1.67"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12"
integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg==
node-releases@^1.1.69:
version "1.1.69"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.69.tgz#3149dbde53b781610cd8b486d62d86e26c3725f6"
integrity sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==
nopt@^5.0.0:
version "5.0.0"
@@ -6151,7 +6164,7 @@ npm-run-path@^2.0.0:
dependencies:
path-key "^2.0.0"
npm-run-path@^4.0.0:
npm-run-path@^4.0.0, npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
@@ -6268,7 +6281,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
onetime@^5.1.0:
onetime@^5.1.0, onetime@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
@@ -6747,10 +6760,10 @@ postcss@^7.0.14:
source-map "^0.6.1"
supports-color "^6.1.0"
postcss@^8.1.4, postcss@^8.2.1:
version "8.2.1"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.1.tgz#eabc5557c4558059b9d9e5b15bce7ffa9089c2a8"
integrity sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA==
postcss@^8.1.4, postcss@^8.2.2:
version "8.2.2"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.2.tgz#60613b62297005084fd21024a68637798864fe26"
integrity sha512-HM1NDNWLgglJPQQMNwvLxgH2KcrKZklKLi/xXYIOaqQB57p/pDWEJNS83PVICYsn1Dg/9C26TiejNr422/ePaQ==
dependencies:
colorette "^1.2.1"
nanoid "^3.1.20"
@@ -7026,11 +7039,6 @@ rechoir@^0.7.0:
dependencies:
resolve "^1.9.0"
reduce-flatten@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27"
integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==
regenerate@^1.2.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f"
@@ -7396,10 +7404,10 @@ sass-loader@^10.1.0:
schema-utils "^3.0.0"
semver "^7.3.2"
sass@^1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.30.0.tgz#60bbbbaf76ba10117e61c6c24f00161c3d60610e"
integrity sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw==
sass@^1.32.0:
version "1.32.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.0.tgz#10101a026c13080b14e2b374d4e15ee24400a4d3"
integrity sha512-fhyqEbMIycQA4blrz/C0pYhv2o4x2y6FYYAH0CshBw3DXh5D5wyERgxw0ptdau1orc/GhNrhF7DFN2etyOCEng==
dependencies:
chokidar ">=2.0.0 <4.0.0"
@@ -7438,7 +7446,7 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
selfsigned@^1.10.7:
selfsigned@^1.10.8:
version "1.10.8"
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
@@ -7601,7 +7609,7 @@ sigmund@^1.0.1:
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"
integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=
signal-exit@^3.0.0, signal-exit@^3.0.2:
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
@@ -7664,26 +7672,26 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
sockjs-client@1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
sockjs-client@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add"
integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==
dependencies:
debug "^3.2.5"
debug "^3.2.6"
eventsource "^1.0.7"
faye-websocket "~0.11.1"
inherits "^2.0.3"
json3 "^3.3.2"
url-parse "^1.4.3"
faye-websocket "^0.11.3"
inherits "^2.0.4"
json3 "^3.3.3"
url-parse "^1.4.7"
sockjs@0.3.20:
version "0.3.20"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855"
integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==
sockjs@^0.3.21:
version "0.3.21"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==
dependencies:
faye-websocket "^0.10.0"
faye-websocket "^0.11.3"
uuid "^3.4.0"
websocket-driver "0.6.5"
websocket-driver "^0.7.4"
source-list-map@^2.0.0, source-list-map@^2.0.1:
version "2.0.1"
@@ -8003,16 +8011,6 @@ symbol-tree@^3.2.4:
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
table-layout@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.1.tgz#8411181ee951278ad0638aea2f779a9ce42894f9"
integrity sha512-dEquqYNJiGwY7iPfZ3wbXDI944iqanTSchrACLL2nOB+1r+h1Nzu2eH+DuPPvWvm5Ry7iAPeFlgEtP5bIp5U7Q==
dependencies:
array-back "^4.0.1"
deep-extend "~0.6.0"
typical "^5.2.0"
wordwrapjs "^4.0.0"
tapable@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
@@ -8257,11 +8255,6 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typical@^5.0.0, typical@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066"
integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==
union-value@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
@@ -8351,7 +8344,7 @@ url-parse-lax@^3.0.0:
dependencies:
prepend-http "^2.0.0"
url-parse@^1.4.3:
url-parse@^1.4.3, url-parse@^1.4.7:
version "1.4.7"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
@@ -8402,7 +8395,7 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
uuid@8.3.1, uuid@^8.3.0:
uuid@8.3.1:
version "8.3.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31"
integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==
@@ -8412,6 +8405,11 @@ uuid@^3.3.2, uuid@^3.4.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.0:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132"
@@ -8577,21 +8575,21 @@ webidl-conversions@^6.1.0:
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
webpack-cli@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.2.0.tgz#10a09030ad2bd4d8b0f78322fba6ea43ec56aaaa"
integrity sha512-EIl3k88vaF4fSxWSgtAQR+VwicfLMTZ9amQtqS4o+TDPW9HGaEpbFBbAZ4A3ZOT5SOnMxNOzROsSTPiE8tBJPA==
webpack-cli@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.3.1.tgz#87a7873bc9c6a4708aa657759274b691e72a04a8"
integrity sha512-/F4+9QNZM/qKzzL9/06Am8NXIkGV+/NqQ62Dx7DSqudxxpAgBqYn6V7+zp+0Y7JuWksKUbczRY3wMTd+7Uj6OA==
dependencies:
"@webpack-cli/info" "^1.1.0"
"@webpack-cli/serve" "^1.1.0"
"@discoveryjs/json-ext" "^0.5.0"
"@webpack-cli/info" "^1.2.1"
"@webpack-cli/serve" "^1.2.1"
colorette "^1.2.1"
command-line-usage "^6.1.0"
commander "^6.2.0"
enquirer "^2.3.6"
execa "^4.1.0"
execa "^5.0.0"
fastest-levenshtein "^1.0.12"
import-local "^3.0.2"
interpret "^2.2.0"
leven "^3.1.0"
rechoir "^0.7.0"
v8-compile-cache "^2.2.0"
webpack-merge "^4.2.2"
@@ -8607,10 +8605,10 @@ webpack-dev-middleware@^3.7.2:
range-parser "^1.2.1"
webpack-log "^2.0.0"
webpack-dev-server@^3.11.0:
version "3.11.0"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c"
integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==
webpack-dev-server@^3.11.1:
version "3.11.1"
resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0"
integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==
dependencies:
ansi-html "0.0.7"
bonjour "^3.5.0"
@@ -8632,11 +8630,11 @@ webpack-dev-server@^3.11.0:
p-retry "^3.0.1"
portfinder "^1.0.26"
schema-utils "^1.0.0"
selfsigned "^1.10.7"
selfsigned "^1.10.8"
semver "^6.3.0"
serve-index "^1.9.1"
sockjs "0.3.20"
sockjs-client "1.4.0"
sockjs "^0.3.21"
sockjs-client "^1.5.0"
spdy "^4.0.2"
strip-ansi "^3.0.1"
supports-color "^6.1.0"
@@ -8686,10 +8684,10 @@ webpack-sources@^2.1.1:
source-list-map "^2.0.1"
source-map "^0.6.1"
webpack@^5.10.3:
version "5.10.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.10.3.tgz#933cbd5e79d62040d988049ff0f515a6dc333006"
integrity sha512-KFPEbpNKfNU4t2CDsUZJ7KpuUbzDqGUCZqLmz4667KSUWMc9BuR3a8jpa72Emv7JUbdGwISD9OZjoI9S5BnHig==
webpack@^5.11.1:
version "5.11.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.11.1.tgz#39b2b9daeb5c6c620e03b7556ec674eaed4016b4"
integrity sha512-tNUIdAmYJv+nupRs/U/gqmADm6fgrf5xE+rSlSsf2PgsGO7j2WG7ccU6AWNlOJlHFl+HnmXlBmHIkiLf+XA9mQ==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.45"
@@ -8716,14 +8714,7 @@ webpack@^5.10.3:
watchpack "^2.0.0"
webpack-sources "^2.1.1"
websocket-driver@0.6.5:
version "0.6.5"
resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=
dependencies:
websocket-extensions ">=0.1.1"
websocket-driver@>=0.5.1:
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
version "0.7.4"
resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
@@ -8796,14 +8787,6 @@ word-wrap@~1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
wordwrapjs@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.0.tgz#9aa9394155993476e831ba8e59fb5795ebde6800"
integrity sha512-Svqw723a3R34KvsMgpjFBYCgNOSdcW3mQFK4wIfhGQhtaFVOJmdYoXgi63ne3dTlWgatVcUc7t4HtQ/+bUVIzQ==
dependencies:
reduce-flatten "^2.0.0"
typical "^5.0.0"
wrap-ansi@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"