├── starboard ├── web │ ├── .gitignore │ ├── static │ │ ├── fs.go │ │ ├── fonts │ │ │ └── Inter.var.woff2 │ │ ├── images │ │ │ └── favicon-32x32.png │ │ └── css │ │ │ ├── styles.css │ │ │ └── raster2.css │ └── templates │ │ ├── fs.go │ │ ├── header.html.tmpl │ │ ├── footer.html.tmpl │ │ ├── icons.html.tmpl │ │ ├── index.html.tmpl │ │ ├── browse.html.tmpl │ │ └── editor.html.tmpl ├── scripts │ ├── README.md │ └── download_runtime │ │ └── main.go ├── internal │ ├── nbserver │ │ ├── README.md │ │ ├── errors.go │ │ ├── breadcrumb.go │ │ ├── fs.go │ │ ├── handler.go │ │ ├── notebook.go │ │ └── browse.go │ ├── npm │ │ ├── extract.go │ │ ├── download.go │ │ └── types.go │ └── fs │ │ └── stripprefix │ │ └── stripprefix.go ├── .gitignore ├── .goreleaser.yml ├── main.go ├── README.md ├── go.mod ├── cmd │ ├── serve.go │ └── root.go ├── assets │ └── notebooks │ │ └── procedural-art.nb └── go.sum ├── .github ├── FUNDING.yml └── workflows │ ├── release.yml │ └── starboard-cli.yml ├── .gitignore ├── README.md └── LICENSE /starboard/web/.gitignore: -------------------------------------------------------------------------------- 1 | static/vendor/* 2 | -------------------------------------------------------------------------------- /starboard/scripts/README.md: -------------------------------------------------------------------------------- 1 | # scripts 2 | 3 | Tools and utilities. -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: gzuidhof 4 | -------------------------------------------------------------------------------- /starboard/web/static/fs.go: -------------------------------------------------------------------------------- 1 | package static 2 | 3 | import ( 4 | "embed" 5 | ) 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /starboard/web/templates/fs.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | import ( 4 | "embed" 5 | ) 6 | 7 | //go:embed * 8 | var FS embed.FS 9 | -------------------------------------------------------------------------------- /starboard/web/static/fonts/Inter.var.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzuidhof/starboard-cli/HEAD/starboard/web/static/fonts/Inter.var.woff2 -------------------------------------------------------------------------------- /starboard/internal/nbserver/README.md: -------------------------------------------------------------------------------- 1 | # nbserver 2 | 3 | The nbserver package contains the functionality for the `starboard serve` command. 4 | -------------------------------------------------------------------------------- /starboard/web/static/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gzuidhof/starboard-cli/HEAD/starboard/web/static/images/favicon-32x32.png -------------------------------------------------------------------------------- /starboard/.gitignore: -------------------------------------------------------------------------------- 1 | # Generated asset files 2 | vfsdata.go 3 | 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, built with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # 17 | .DS_store 18 | dist/ -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | -------------------------------------------------------------------------------- /starboard/web/templates/header.html.tmpl: -------------------------------------------------------------------------------- 1 | {{define "header"}} 2 | 3 |

Starboard
Serve

4 |

5 | Serve is used to display and edit local Starboard Notebook files. 6 |

7 |
8 | {{end}} -------------------------------------------------------------------------------- /starboard/web/templates/footer.html.tmpl: -------------------------------------------------------------------------------- 1 | {{define "footer"}} 2 | 13 | {{end}} 14 | -------------------------------------------------------------------------------- /starboard/web/templates/icons.html.tmpl: -------------------------------------------------------------------------------- 1 | {{define "icon-folder"}} {{/* From tabler-icons, edited manually, MIT Licensed */}} 2 | 3 | 4 | 5 | 6 | {{end}} 7 | -------------------------------------------------------------------------------- /starboard/web/static/css/styles.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | @font-face { 3 | font-family: "Inter var"; 4 | font-weight: 200 900; 5 | font-display: swap; 6 | src: local("Inter var"), url("/static/fonts/Inter.var.woff2?v=3.15") format("woff2"); 7 | } 8 | 9 | :root { 10 | --fontSize: 16px; 11 | --serveBrandColor: #3a59b7; 12 | } 13 | 14 | .breadcrumb-delimiter { 15 | margin: 0 0.4rem; 16 | } 17 | 18 | .full-page-width { 19 | width: 100vw; 20 | transform: translateX(calc( -2 * var(--lineHeight))); 21 | } -------------------------------------------------------------------------------- /starboard/.goreleaser.yml: -------------------------------------------------------------------------------- 1 | before: 2 | hooks: 3 | - go generate 4 | builds: 5 | - binary: starboard 6 | goos: 7 | - windows 8 | - darwin 9 | - linux 10 | goarch: 11 | - amd64 12 | - arm64 13 | ldflags: 14 | - -s -w -X github.com/gzuidhof/starboard-cli/starboard/cmd.version={{.Version}} -X github.com/gzuidhof/starboard-cli/starboard/cmd.commit={{.Commit}} -X github.com/gzuidhof/starboard-cli/starboard/cmd.date={{.CommitDate}} -X github.com/gzuidhof/starboard-cli/starboard/cmd.target={{.Env.GOOS}} -------------------------------------------------------------------------------- /starboard/web/templates/index.html.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{if .title}}{{.title}}{{else}}Starboard Serve{{end}} 6 | 7 | 8 | 9 | 10 | 11 | {{ .head }} 12 | 13 | 14 | {{ .body }} 15 | 16 | 17 | -------------------------------------------------------------------------------- /starboard/main.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package main 6 | 7 | //go:generate go run scripts/download_runtime/main.go starboard-notebook 0.10.1 web/static/vendor/ 8 | //go:generate go run scripts/download_runtime/main.go starboard-wrap 0.2.5 web/static/vendor/ 9 | 10 | import ( 11 | "github.com/gzuidhof/starboard-cli/starboard/cmd" 12 | ) 13 | 14 | func main() { 15 | cmd.Execute() 16 | } 17 | -------------------------------------------------------------------------------- /starboard/README.md: -------------------------------------------------------------------------------- 1 | # starboard (cli) 2 | 3 | To download a new runtime, specify its version and the target folder in the `go:generate` in main.go. 4 | 5 | ## Development 6 | To run the serve command with the latest static assets and templates without having to `go generate`, use: 7 | 8 | ``` 9 | go run main.go serve --static_folder web/static --templates_folder web/templates 10 | ``` 11 | 12 | Consider it live-reload as long as you are only changing template files :). 13 | 14 | ## Releases 15 | 16 | Releases are minted on CI, you can create one locally by running 17 | ``` 18 | goreleaser --snapshot --skip-publish --rm-dist 19 | ``` 20 | -------------------------------------------------------------------------------- /starboard/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gzuidhof/starboard-cli/starboard 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/gofiber/adaptor/v2 v2.1.2 7 | github.com/gofiber/fiber/v2 v2.7.1 8 | github.com/klauspost/compress v1.11.13 // indirect 9 | github.com/mitchellh/go-homedir v1.1.0 10 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 11 | github.com/spf13/afero v1.6.0 12 | github.com/spf13/cobra v1.1.1 13 | github.com/spf13/viper v1.7.1 14 | github.com/valyala/fasthttp v1.23.0 // indirect 15 | github.com/valyala/tcplisten v1.0.0 // indirect 16 | golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect 17 | ) 18 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | pull_request: 5 | push: 6 | 7 | jobs: 8 | goreleaser: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - 12 | name: Checkout 13 | uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | - 17 | name: Set up Go 18 | uses: actions/setup-go@v2 19 | with: 20 | go-version: 1.16 21 | - 22 | name: Run GoReleaser 23 | uses: goreleaser/goreleaser-action@v2 24 | with: 25 | workdir: starboard 26 | version: latest 27 | args: release --rm-dist 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | -------------------------------------------------------------------------------- /starboard/internal/nbserver/errors.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package nbserver 6 | 7 | import ( 8 | "net/http" 9 | "os" 10 | ) 11 | 12 | // Adapted from Go http sourcecode 13 | func toHTTPError(err error) (msg string, httpStatus int) { 14 | 15 | if os.IsNotExist(err) { 16 | return "404 page not found", http.StatusNotFound 17 | } 18 | 19 | if os.IsPermission(err) { 20 | return "403 Forbidden", http.StatusForbidden 21 | } 22 | 23 | // Default: 24 | return "500 Internal Server Error", http.StatusInternalServerError 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/starboard-cli.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | 11 | build: 12 | name: Build 13 | runs-on: ubuntu-latest 14 | steps: 15 | 16 | - name: Set up Go 1.15 17 | uses: actions/setup-go@v2 18 | with: 19 | go-version: ^1.15 20 | 21 | - name: Check out code 22 | uses: actions/checkout@v2 23 | 24 | - name: Get dependencies 25 | working-directory: starboard 26 | run: | 27 | go get -v -t -d ./... 28 | 29 | - name: Build 30 | working-directory: starboard 31 | run: | 32 | go generate 33 | go build -v . 34 | 35 | - name: Test 36 | working-directory: starboard 37 | run: go test -v . 38 | -------------------------------------------------------------------------------- /starboard/web/templates/browse.html.tmpl: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | {{template "header"}} 5 | 6 | 7 |
8 | {{template "icon-folder"}} / 9 | {{range .breadCrumbs}} 10 | {{.Name}} {{if .IsFolder}}/{{end}} 13 | {{end}} 14 |
15 | 16 | 17 | {{if not (eq .path "/")}} 18 | .. 19 | {{end}} 20 | {{range .entries}} 21 | 22 | {{.Name}} 23 | 24 | {{end}} 25 | 26 |
27 |
28 |
29 | {{template "footer"}} 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | starboard-cli 2 | --- 3 | 4 | The `starboard` command line tool is used for interacting with [Starboard Notebooks](https://github.com/gzuidhof/starboard-notebook) locally. It starts a local webserver so you can view and edit notebook files on your computer. 5 | 6 | ## Installation 7 | Pre-built binaries can be found on the [**Github releases page**](https://github.com/gzuidhof/starboard-cli/releases/). 8 | 9 | Alternatively, you can build it yourself by cloning this repository and running: 10 | 11 | ```bash 12 | cd starboard 13 | go generate 14 | go install 15 | ``` 16 | 17 | ## Usage 18 | ```bash 19 | # Serve files in current folder 20 | starboard serve . 21 | 22 | ## Serve files under a certain path 23 | starboard serve ./assets 24 | ``` 25 | 26 | ## Screenshots 27 | 28 | ### `starboard serve` directory listing 29 | ![Starboard Serve Screenshot](https://i.imgur.com/6k8VDz8.png) 30 | 31 | ### `starboard serve` notebook view/editor 32 | ![Starboard Server Notebook View Screenshot](https://i.imgur.com/gy2Iuyl.png) 33 | 34 | ## License 35 | This is free software; you can redistribute it and/or modify it under the terms of the [Mozilla Public License Version 2.0](./LICENSE). 36 | -------------------------------------------------------------------------------- /starboard/internal/nbserver/breadcrumb.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package nbserver 6 | 7 | import ( 8 | "strings" 9 | ) 10 | 11 | type BreadCrumb struct { 12 | Name string 13 | /** 14 | * Path without leading "/" 15 | */ 16 | Path string 17 | IsFolder bool 18 | IsNotebook bool 19 | } 20 | 21 | func makeBreadCrumbs(path string, lastIsFolder bool) []BreadCrumb { 22 | path = strings.Trim(path, "/") 23 | if path == "" { 24 | return []BreadCrumb{} 25 | } 26 | parts := strings.Split(path, "/") 27 | 28 | bc := make([]BreadCrumb, len(parts)) 29 | 30 | for i := 0; i < len(parts); i++ { 31 | bc[i] = BreadCrumb{ 32 | Name: parts[i], 33 | IsFolder: i < len(parts)-1 || lastIsFolder, 34 | Path: strings.Join(parts[:i+1], "/"), 35 | } 36 | 37 | if i == len(parts)-1 && !lastIsFolder { 38 | bc[i].IsNotebook = isProbablyNotebookFilename(parts[i]) 39 | bc[i].Path = strings.Replace(bc[i].Path, defaultBrowseEndpoint, defaultNotebookEndpoint, 1) 40 | } 41 | } 42 | 43 | return bc 44 | } 45 | -------------------------------------------------------------------------------- /starboard/internal/nbserver/fs.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package nbserver 6 | 7 | import ( 8 | "strings" 9 | 10 | "github.com/gzuidhof/starboard-cli/starboard/web/static" 11 | "github.com/gzuidhof/starboard-cli/starboard/web/templates" 12 | "github.com/spf13/afero" 13 | "github.com/spf13/viper" 14 | ) 15 | 16 | const dev = true 17 | 18 | type serveFS struct { 19 | static afero.Fs 20 | templates afero.Fs 21 | } 22 | 23 | func getFileSystems() serveFS { 24 | var staticFS afero.Fs 25 | var templatesFS afero.Fs 26 | 27 | if viper.GetString("static_folder") != "" { 28 | staticFS = afero.NewReadOnlyFs(afero.NewBasePathFs(afero.NewOsFs(), viper.GetString("static_folder"))) 29 | } else { 30 | staticFS = afero.FromIOFS{static.FS} 31 | } 32 | 33 | if viper.GetString("templates_folder") != "" { 34 | templatesFS = afero.NewReadOnlyFs(afero.NewBasePathFs(afero.NewOsFs(), viper.GetString("templates_folder"))) 35 | } else { 36 | templatesFS = afero.FromIOFS{templates.FS} 37 | } 38 | 39 | return serveFS{ 40 | static: staticFS, 41 | templates: templatesFS, 42 | } 43 | } 44 | 45 | func isProbablyNotebookFilename(name string) bool { 46 | return strings.HasSuffix(name, ".nb") || strings.HasSuffix(name, ".sb") || strings.HasSuffix(name, ".sbnb") 47 | } 48 | -------------------------------------------------------------------------------- /starboard/cmd/serve.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package cmd 6 | 7 | import ( 8 | "log" 9 | 10 | "github.com/gzuidhof/starboard-cli/starboard/internal/nbserver" 11 | "github.com/spf13/cobra" 12 | "github.com/spf13/viper" 13 | ) 14 | 15 | // serveCmd represents the serve command 16 | var serveCmd = &cobra.Command{ 17 | Use: "serve", 18 | Short: "Serves the notebook files in your current folder", 19 | Long: `Serve serves the notebook files in the current folder.`, 20 | Run: func(cmd *cobra.Command, args []string) { 21 | if len(args) < 1 { 22 | log.Fatal("The serve path argument is required") 23 | } 24 | 25 | nbserver.Start(args[0]) 26 | }, 27 | } 28 | 29 | func init() { 30 | rootCmd.AddCommand(serveCmd) 31 | 32 | // Here you will define your flags and configuration settings. 33 | 34 | // Cobra supports Persistent Flags which will work for this command 35 | // and all subcommands, e.g.: 36 | // serveCmd.PersistentFlags().String("foo", "", "A help for foo") 37 | 38 | // Cobra supports local flags which will only run when this command 39 | // is called directly, e.g.: 40 | serveCmd.Flags().StringP("port", "p", "8585", "Port to serve files on") 41 | serveCmd.Flags().String("port_secondary", "9959", "Port used as secondary origin (for additional sandboxing)") 42 | 43 | serveCmd.Flags().String("static_folder", "", "Override where static assets are served from, it uses the embedded assets if not set") 44 | serveCmd.Flags().String("templates_folder", "", "Override where templates are loaded from, it uses the embedded assets if not set") 45 | 46 | viper.BindPFlag("port", serveCmd.Flags().Lookup("port")) 47 | viper.BindPFlag("port_secondary", serveCmd.Flags().Lookup("port_secondary")) 48 | 49 | viper.BindPFlag("static_folder", serveCmd.Flags().Lookup("static_folder")) 50 | viper.BindPFlag("templates_folder", serveCmd.Flags().Lookup("templates_folder")) 51 | } 52 | -------------------------------------------------------------------------------- /starboard/internal/npm/extract.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package npm 6 | 7 | import ( 8 | "archive/tar" 9 | "compress/gzip" 10 | "fmt" 11 | "io" 12 | "os" 13 | "path" 14 | "path/filepath" 15 | "strings" 16 | ) 17 | 18 | func createWithNestedDirectories(p string) (*os.File, error) { 19 | if err := os.MkdirAll(filepath.Dir(p), 0770); err != nil { 20 | return nil, err 21 | } 22 | return os.Create(p) 23 | } 24 | 25 | // Adapted from https://stackoverflow.com/questions/57639648/how-to-decompress-tar-gz-file-in-go 26 | func extractTarGz(gzipStream io.Reader, intoFolder string, stripPrefix string) error { 27 | uncompressedStream, err := gzip.NewReader(gzipStream) 28 | if err != nil { 29 | return fmt.Errorf("ExtractTarGz: NewReader failed") 30 | } 31 | 32 | tarReader := tar.NewReader(uncompressedStream) 33 | for true { 34 | header, err := tarReader.Next() 35 | 36 | if err == io.EOF { 37 | break 38 | } 39 | 40 | if err != nil { 41 | return fmt.Errorf("ExtractTarGz: Next() failed: %s", err.Error()) 42 | } 43 | 44 | switch header.Typeflag { 45 | case tar.TypeDir: 46 | // We create every file with directories leading up to it, so no need to do anything here. 47 | // if err := os.Mkdir(path.Join(intoFolder, strings.TrimPrefix(header.Name, stripPrefix)), 0755); err != nil { 48 | // return fmt.Errorf("ExtractTarGz: Mkdir() failed: %s", err.Error()) 49 | // } 50 | case tar.TypeReg: 51 | outFile, err := createWithNestedDirectories(path.Join(intoFolder, strings.TrimPrefix(header.Name, stripPrefix))) 52 | if err != nil { 53 | return fmt.Errorf("ExtractTarGz: createWithNestedDirectories() failed: %s", err.Error()) 54 | } 55 | if _, err := io.Copy(outFile, tarReader); err != nil { 56 | return fmt.Errorf("ExtractTarGz: Copy() failed: %s", err.Error()) 57 | } 58 | outFile.Close() 59 | 60 | default: 61 | return fmt.Errorf( 62 | "ExtractTarGz: unknown type: %v in %s", 63 | header.Typeflag, 64 | header.Name) 65 | } 66 | } 67 | 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /starboard/internal/npm/download.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package npm 6 | 7 | import ( 8 | "encoding/json" 9 | "fmt" 10 | "io/ioutil" 11 | "log" 12 | "net/http" 13 | "path" 14 | ) 15 | 16 | const defaultNPMRegistryEndpoint = "https://registry.npmjs.org/" 17 | 18 | func downloadAndUnpackTarball(tarballURL string, intoFolder string) error { 19 | log.Printf("Downloading tarball from %s", tarballURL) 20 | resp, err := http.Get(tarballURL) 21 | if err != nil { 22 | return fmt.Errorf("failed to fetch tarball from %s: %v", tarballURL, err) 23 | } 24 | defer resp.Body.Close() 25 | 26 | return extractTarGz(resp.Body, intoFolder, "package/") 27 | } 28 | 29 | func GetRegistryEntry(packageName string) (NPMRegistryEntry, error) { 30 | url := defaultNPMRegistryEndpoint + packageName 31 | resp, err := http.Get(url) 32 | if err != nil { 33 | return NPMRegistryEntry{}, fmt.Errorf("failed to fetch %s: %v", url, err) 34 | } 35 | defer resp.Body.Close() 36 | body, err := ioutil.ReadAll(resp.Body) 37 | 38 | var sb NPMRegistryEntry 39 | 40 | err = json.Unmarshal(body, &sb) 41 | if err != nil { 42 | return NPMRegistryEntry{}, fmt.Errorf("failed to unmarshal NPM response: %v", err) 43 | } 44 | return sb, nil 45 | } 46 | 47 | /** 48 | * DownloadPackageIntoFolder downloads given NPM package into the outfolder, it puts it in a subfolder 49 | * called @, this function returns that folder name. 50 | */ 51 | func DownloadPackageIntoFolder(packageName string, version string, outFolder string) (string, error) { 52 | 53 | sb, err := GetRegistryEntry(packageName) 54 | if err != nil { 55 | return "", fmt.Errorf("failed to get registry entry: %v", err) 56 | } 57 | 58 | versionToGet := version 59 | if version == "latest" { 60 | versionToGet = sb.DistTags.Latest 61 | } 62 | 63 | packageID := packageName + "@" + versionToGet 64 | 65 | outFolder = path.Join(outFolder, packageID) 66 | 67 | tarballURL := sb.Versions[versionToGet].Dist.Tarball 68 | err = downloadAndUnpackTarball(tarballURL, outFolder) 69 | if err != nil { 70 | return "", fmt.Errorf("failed to download and handle tarball: %v", err) 71 | } 72 | 73 | return packageID, nil 74 | } 75 | -------------------------------------------------------------------------------- /starboard/scripts/download_runtime/main.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package main 6 | 7 | import ( 8 | "log" 9 | "os" 10 | "path" 11 | 12 | "github.com/gzuidhof/starboard-cli/starboard/internal/npm" 13 | ) 14 | 15 | const defaultRuntimePackageName = "starboard-notebook" 16 | const defaultIframeResizerPackageName = "iframe-resizer" 17 | 18 | // Deletes the src and test folder in the output, saves some KB in executable size. 19 | func deleteUselessFiles(fromFolder string, toRemove []string) { 20 | for _, folder := range toRemove { 21 | err := os.RemoveAll(path.Join(fromFolder, folder)) 22 | if err != nil { 23 | log.Fatalf("Failed to delete: %v", err) 24 | } 25 | } 26 | } 27 | 28 | func dirExists(dirpath string) bool { 29 | info, err := os.Stat(dirpath) 30 | if os.IsNotExist(err) { 31 | return false 32 | } 33 | return info.IsDir() 34 | } 35 | 36 | func main() { 37 | if len(os.Args) < 4 { 38 | log.Print("Not enough arguments, supply 3 arguments: the package name, version and output folder") 39 | os.Exit(1) 40 | } 41 | packageName := os.Args[1] 42 | version := os.Args[2] 43 | outFolder := os.Args[3] 44 | 45 | if version != "latest" && dirExists(path.Join(outFolder, packageName+"@"+version)) { 46 | log.Printf("Skipping NPM fetch of %s as version %v already seems to be vendored already", packageName, version) 47 | os.Exit(0) 48 | } 49 | 50 | // id has the form @ 51 | id, err := npm.DownloadPackageIntoFolder(packageName, version, outFolder) 52 | packageFolder := path.Join(outFolder, id) 53 | 54 | if packageName == defaultRuntimePackageName { 55 | deleteUselessFiles(packageFolder, []string{"dist/src", "dist/test"}) 56 | } else if packageName == defaultIframeResizerPackageName { 57 | // Possible improvement: create a "keep-these-files" function.. we really only need one file 58 | deleteUselessFiles(packageFolder, []string{ 59 | ".github", 60 | "CHANGELOG.md", // Some large markdown files we really don't have to statically bundle 61 | "CONTRIBUTING.md", 62 | "README.md", 63 | "js/iframeResizer.js", // We use the minified version instead 64 | "js/iframeResizer.contentWindow.js", 65 | "js/iframeResizer.contentWindow.map", 66 | "js/iframeResizer.contentWindow.min.js", 67 | "js/index.js", 68 | }) 69 | } 70 | 71 | if err != nil { 72 | log.Fatalf("Failed to fetch %s: %v", packageName, err) 73 | } 74 | log.Printf("Downloaded %s into %s", id, outFolder) 75 | } 76 | -------------------------------------------------------------------------------- /starboard/cmd/root.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package cmd 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | 11 | "github.com/spf13/cobra" 12 | 13 | homedir "github.com/mitchellh/go-homedir" 14 | "github.com/spf13/viper" 15 | ) 16 | 17 | var cfgFile string 18 | 19 | // Version (injected by goreleaser) 20 | var version = "" 21 | var date = "date unknown" 22 | var commit = "" 23 | var target = "" 24 | 25 | // rootCmd represents the base command when called without any subcommands 26 | var rootCmd = &cobra.Command{ 27 | Use: "starboard", 28 | Short: "The Starboard CLI is a tool for working with notebook files locally.", 29 | Long: `Starboard CLI is a tool for viewing, editing, and doing other operations on notebook files locally. 30 | 31 | The most common usecase is to serve notebook files on localhost.`, 32 | // Uncomment the following line if your bare application 33 | // has an action associated with it: 34 | // Run: func(cmd *cobra.Command, args []string) { }, 35 | } 36 | 37 | // Execute adds all child commands to the root command and sets flags appropriately. 38 | // This is called by main.main(). It only needs to happen once to the rootCmd. 39 | func Execute() { 40 | if err := rootCmd.Execute(); err != nil { 41 | fmt.Println(err) 42 | os.Exit(1) 43 | } 44 | } 45 | 46 | func init() { 47 | cobra.OnInitialize(initConfig) 48 | 49 | // Here you will define your flags and configuration settings. 50 | // Cobra supports persistent flags, which, if defined here, 51 | // will be global for your application. 52 | 53 | rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.starboard.yaml)") 54 | 55 | rootCmd.Version = version + " " + target + " (" + date + ") " + commit 56 | 57 | // Cobra also supports local flags, which will only run 58 | // when this action is called directly. 59 | // rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") 60 | } 61 | 62 | // initConfig reads in config file and ENV variables if set. 63 | func initConfig() { 64 | if cfgFile != "" { 65 | // Use config file from the flag. 66 | viper.SetConfigFile(cfgFile) 67 | } else { 68 | // Find home directory. 69 | home, err := homedir.Dir() 70 | if err != nil { 71 | fmt.Println(err) 72 | os.Exit(1) 73 | } 74 | 75 | // Search config in home directory with name ".starboard" (without extension). 76 | viper.AddConfigPath(home) 77 | viper.SetConfigName(".starboard") 78 | } 79 | 80 | viper.AutomaticEnv() // read in environment variables that match 81 | 82 | // If a config file is found, read it in. 83 | if err := viper.ReadInConfig(); err == nil { 84 | fmt.Println("Using config file:", viper.ConfigFileUsed()) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /starboard/assets/notebooks/procedural-art.nb: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # Procedural art using P5.js from Javascript and Python. 3 | 4 | This notebook shows how you can use [p5.js](https://p5js.org/) (a library for generative art) in a notebook environment. After that we'll call p5.js from Python - note that everything here runs in the browser! 5 | 6 | Let's go! 7 | # %%--- [esm] 8 | # properties: 9 | # run_on_load: true 10 | # ---%% 11 | import "https://cdn.jsdelivr.net/npm/p5@1.1.9/lib/p5.min.js" 12 | new p5(); 13 | 14 | console.log("P5 library initialized") 15 | # %%--- [js] 16 | # properties: 17 | # run_on_load: true 18 | # ---%% 19 | var n = 12; 20 | var speed = 2; 21 | 22 | function draw() { 23 | background('#eee'); 24 | translate(400 / 2, 400 / 2); 25 | for (let i = 0; i < n; i++) { 26 | push(); 27 | rotate(frameCount * speed / 1000 * (i + 1)); 28 | fill(i * 5, i * 100, i * 150); 29 | const s = 200 - i * 10; 30 | rect(0, 0, s, s); 31 | pop(); 32 | } 33 | } 34 | # %%--- [js] 35 | # properties: 36 | # run_on_load: true 37 | # ---%% 38 | function setup () { 39 | const cnv = createCanvas(400, 400); 40 | rectMode(CENTER); 41 | return cnv.canvas 42 | } 43 | 44 | var output = setup(); 45 | output; // The last line gets shown below - in this case it's the canvas 46 | # %% [markdown] 47 | Actually we can make it interactive! 48 | 49 | > Click on the Play ▶️ button on the left of the cell below to run it. 50 | # %% [javascript] 51 | html` 52 |
53 | Change Speed 54 | {speed = e.target.value/10; e.target.nextElementSibling.value = speed}} type="range" min="1" max="100" value=${speed * 10} class="slider"> 55 | ${speed} 56 |
` 57 | # %% [markdown] 58 | We can override the draw function in Python! This allows you to use p5.js from Python, entirely in the browser 🤯. 59 | 60 | > It may take some seconds to load (it downloads and initializes a Python Pyodide runtime in your browser) 61 | # %% [python] 62 | from js import window as w 63 | 64 | # Set the speed back to a reasonable value.. Note the slider above still works! 65 | w.speed = 3 66 | n = 28 67 | 68 | def draw(): 69 | w.background('#edf'); 70 | w.translate(400 / 2, 400 / 2); 71 | for i in range(n): 72 | w.push(); 73 | w.rotate(w.frameCount * w.speed / 1000 * (i + 1)); 74 | w.fill(i * 30, i * 20, i * 120); 75 | s = 180 - i * 6; 76 | w.triangle(0, 0, 0, s, s, s*0.5); 77 | w.pop(); 78 | 79 | w.draw = draw 80 | w.output 81 | # %% [markdown] 82 | And that's it :) 83 | 84 | By using a notebook system like Starboard we can iterate quickly on the visualizations, and make it interactive using HTML. 85 | 86 | Combining JS and Python can be really powerful, and you can share your work just by sharing a link. You can embed a notebook like this onto your website/blog and it remains fully functional! Try the `Share or Embed` button above. -------------------------------------------------------------------------------- /starboard/internal/npm/types.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package npm 6 | 7 | import "time" 8 | 9 | type NPMRegistryEntry struct { 10 | ID string `json:"_id"` 11 | Rev string `json:"_rev"` 12 | Name string `json:"name"` 13 | DistTags struct { 14 | Latest string `json:"latest"` 15 | } `json:"dist-tags"` 16 | Versions map[string]struct { 17 | Name string `json:"name"` 18 | Version string `json:"version"` 19 | Description string `json:"description"` 20 | Author struct { 21 | Name string `json:"name"` 22 | Email string `json:"email"` 23 | } `json:"author"` 24 | Funding struct { 25 | Type string `json:"type"` 26 | URL string `json:"url"` 27 | } `json:"funding"` 28 | License string `json:"license"` 29 | Repository struct { 30 | Type string `json:"type"` 31 | URL string `json:"url"` 32 | } `json:"repository"` 33 | Keywords []string `json:"keywords"` 34 | Scripts map[string]string `json:"scripts"` 35 | Main string `json:"main"` 36 | DevDependencies map[string]string `json:"devDependencies"` 37 | Dependencies map[string]string `json:"dependencies"` 38 | GitHead string `json:"gitHead"` 39 | ID string `json:"_id"` 40 | NodeVersion string `json:"_nodeVersion"` 41 | NpmVersion string `json:"_npmVersion"` 42 | Dist struct { 43 | Integrity string `json:"integrity"` 44 | Shasum string `json:"shasum"` 45 | Tarball string `json:"tarball"` 46 | FileCount int `json:"fileCount"` 47 | UnpackedSize int `json:"unpackedSize"` 48 | NpmSignature string `json:"npm-signature"` 49 | } `json:"dist"` 50 | Maintainers []struct { 51 | Name string `json:"name"` 52 | Email string `json:"email"` 53 | } `json:"maintainers"` 54 | NpmUser struct { 55 | Name string `json:"name"` 56 | Email string `json:"email"` 57 | } `json:"_npmUser"` 58 | Directories struct { 59 | } `json:"directories"` 60 | NpmOperationalInternal struct { 61 | Host string `json:"host"` 62 | Tmp string `json:"tmp"` 63 | } `json:"_npmOperationalInternal"` 64 | HasShrinkwrap bool `json:"_hasShrinkwrap"` 65 | } `json:"versions"` 66 | Time map[string]time.Time `json:"time"` 67 | Maintainers []struct { 68 | Name string `json:"name"` 69 | Email string `json:"email"` 70 | } `json:"maintainers"` 71 | Description string `json:"description"` 72 | Keywords []string `json:"keywords"` 73 | Repository struct { 74 | Type string `json:"type"` 75 | URL string `json:"url"` 76 | } `json:"repository"` 77 | Author struct { 78 | Name string `json:"name"` 79 | Email string `json:"email"` 80 | } `json:"author"` 81 | License string `json:"license"` 82 | Readme string `json:"readme"` 83 | ReadmeFilename string `json:"readmeFilename"` 84 | } 85 | -------------------------------------------------------------------------------- /starboard/internal/nbserver/handler.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package nbserver 6 | 7 | import ( 8 | "html/template" 9 | "log" 10 | "net/http" 11 | "path/filepath" 12 | 13 | "github.com/gzuidhof/starboard-cli/starboard/internal/fs/stripprefix" 14 | "github.com/shurcooL/httpfs/html/vfstemplate" 15 | "github.com/spf13/afero" 16 | "github.com/spf13/viper" 17 | 18 | "github.com/gofiber/adaptor/v2" 19 | "github.com/gofiber/fiber/v2" 20 | "github.com/gofiber/fiber/v2/middleware/filesystem" 21 | "github.com/gofiber/fiber/v2/middleware/logger" 22 | "github.com/gofiber/fiber/v2/middleware/recover" 23 | ) 24 | 25 | var indexTemplate *template.Template 26 | var browseTemplate *template.Template 27 | var editorTemplate *template.Template 28 | 29 | func loadTemplates(fs *afero.HttpFs) { 30 | 31 | t, err := vfstemplate.ParseGlob(fs, nil, "*.tmpl") 32 | if err != nil { 33 | log.Fatalf("Failed to parse templates in vfs: %v", err) 34 | } 35 | indexTemplate = t.Lookup("index.html.tmpl") 36 | browseTemplate = t.Lookup("browse.html.tmpl") 37 | editorTemplate = t.Lookup("editor.html.tmpl") 38 | } 39 | 40 | func CreateServer(serveFolderAbs string, serveFS serveFS, portPrimary string, portSecondary string) { 41 | app := fiber.New(fiber.Config{CaseSensitive: true, DisableStartupMessage: true}) 42 | 43 | app.Use(recover.New()) 44 | app.Use(logger.New()) 45 | 46 | app.Use("/static/*", filesystem.New(filesystem.Config{ 47 | Root: afero.NewHttpFs(stripprefix.New("/static/", serveFS.static)), 48 | })) 49 | 50 | writeFileSystem := afero.NewBasePathFs(afero.NewOsFs(), serveFolderAbs).(*afero.BasePathFs) 51 | app.Get(defaultBrowseEndpoint+"*", adaptor.HTTPHandler(&browseHandler{ 52 | root: http.Dir(serveFolderAbs), 53 | })) 54 | 55 | app.All(defaultNotebookEndpoint+"*", adaptor.HTTPHandler(¬ebookHandler{ 56 | root: http.Dir(serveFolderAbs), 57 | iframeHost: "http://localhost:" + portSecondary, 58 | writeFS: writeFileSystem, 59 | serveFolder: serveFolderAbs, 60 | })) 61 | 62 | app.Get("/", func(c *fiber.Ctx) error { 63 | if isProbablyNotebookFilename(serveFolderAbs) { 64 | c.Redirect("/nb/") 65 | } else { 66 | c.Redirect("/browse/") 67 | } 68 | 69 | return nil 70 | }) 71 | 72 | done := make(chan bool) 73 | go func() { 74 | log.Fatal(app.Listen(":" + portPrimary)) 75 | }() 76 | go func() { 77 | log.Fatal(app.Listen(":" + portSecondary)) 78 | }() 79 | log.Printf("Listening on :%v (and :%s for sandboxing)\nhttp://localhost:%v", portPrimary, portSecondary, portPrimary) 80 | 81 | <-done 82 | } 83 | 84 | func Start(servePath string) { 85 | port := viper.GetString("port") 86 | portSecondary := viper.GetString("port_secondary") 87 | serveFolder := servePath 88 | serveFolderAbs, err := filepath.Abs(serveFolder) 89 | if err != nil { 90 | log.Fatalf("Invalid serve folder, could not get absolute path: %v", err) 91 | } 92 | 93 | serveFS := getFileSystems() 94 | loadTemplates(afero.NewHttpFs(serveFS.templates)) 95 | 96 | CreateServer(serveFolderAbs, serveFS, port, portSecondary) 97 | } 98 | -------------------------------------------------------------------------------- /starboard/internal/nbserver/notebook.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package nbserver 6 | 7 | import ( 8 | "bytes" 9 | "html/template" 10 | "io/ioutil" 11 | "log" 12 | "net/http" 13 | "path" 14 | "strings" 15 | 16 | "github.com/spf13/afero" 17 | ) 18 | 19 | var defaultNotebookEndpoint = "/nb/" 20 | 21 | type notebookHandler struct { 22 | iframeHost string 23 | root http.FileSystem 24 | writeFS *afero.BasePathFs 25 | serveFolder string 26 | } 27 | 28 | func (h *notebookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 29 | // loadTemplates(fs.templates) // TODO: Only do this in dev mode 30 | if r.Method == http.MethodGet { 31 | upath := strings.TrimPrefix(r.URL.Path, defaultNotebookEndpoint) 32 | r.URL.Path = upath 33 | 34 | // if !strings.HasPrefix(upath, "/") { 35 | // upath = "/" + upath 36 | // r.URL.Path = upath 37 | // } 38 | 39 | upath = path.Clean(upath) 40 | h.serveNotebook(w, r, h.root, upath) 41 | } else if r.Method == http.MethodPut { 42 | upath := strings.TrimPrefix(r.URL.Path, defaultNotebookEndpoint) 43 | upath = path.Clean(upath) 44 | 45 | content, err := ioutil.ReadAll(r.Body) 46 | if err != nil { 47 | http.Error(w, "Could not read body, bad request.", http.StatusBadRequest) 48 | return 49 | } 50 | 51 | log.Printf("Writing to %s (%v bytes)", upath, len(content)) 52 | err = afero.WriteFile(h.writeFS, upath, content, 0644) 53 | if err != nil { 54 | log.Printf("Failed to save notebook to disk: %v", err) 55 | http.Error(w, "Could not save notebook", http.StatusInternalServerError) 56 | return 57 | } 58 | } 59 | } 60 | 61 | // name is '/'-separated, not filepath.Separator. 62 | func (h *notebookHandler) serveNotebook(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name string) { 63 | f, err := fs.Open(name) 64 | 65 | if err != nil { 66 | msg, code := toHTTPError(err) 67 | http.Error(w, msg, code) 68 | return 69 | } 70 | 71 | defer f.Close() 72 | d, err := f.Stat() 73 | 74 | if err != nil { 75 | msg, code := toHTTPError(err) 76 | http.Error(w, msg, code) 77 | return 78 | } 79 | 80 | if d.IsDir() { 81 | url := r.URL.Path 82 | // redirect if the directory name doesn't end in a slash 83 | if url == "" || url[len(url)-1] != '/' { 84 | localRedirect(w, r, path.Base(url)+"/") 85 | return 86 | } 87 | 88 | localRedirect(w, r, path.Join(defaultBrowseEndpoint, url)) 89 | return 90 | } 91 | 92 | fileContent, err := ioutil.ReadAll(f) 93 | 94 | if err != nil { 95 | log.Print("Failed to read file") 96 | msg, code := toHTTPError(err) 97 | http.Error(w, msg, code) 98 | return 99 | } 100 | 101 | crumbs := makeBreadCrumbs(r.URL.Path, false) 102 | 103 | var b bytes.Buffer 104 | err = editorTemplate.Execute(&b, map[string]interface{}{ 105 | "browseEndpoint": defaultBrowseEndpoint, 106 | "notebookEndpoint": defaultNotebookEndpoint, 107 | "path": r.URL.Path, 108 | "breadCrumbs": crumbs, 109 | "iframeHost": h.iframeHost, 110 | "notebookContent": string(fileContent), 111 | }) 112 | 113 | if err != nil { 114 | http.Error(w, err.Error(), http.StatusInternalServerError) 115 | return 116 | } 117 | 118 | w.Header().Set("Content-Type", "text/html; charset=utf-8") 119 | 120 | err = indexTemplate.Execute(w, map[string]interface{}{ 121 | "body": template.HTML(b.String()), 122 | }) 123 | if err != nil { 124 | http.Error(w, err.Error(), http.StatusInternalServerError) 125 | return 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /starboard/web/templates/editor.html.tmpl: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 | {{template "icon-folder"}} / 7 | {{range .breadCrumbs}} 8 | {{.Name}} {{if .IsFolder}}/{{end}} 11 | {{end}} 12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 | Current notebook content 20 |

21 |     
22 |
23 | 24 | {{template "footer"}} 25 | 26 | -------------------------------------------------------------------------------- /starboard/internal/fs/stripprefix/stripprefix.go: -------------------------------------------------------------------------------- 1 | // from https://github.com/icexin/eggos, MIT licensed 2 | 3 | // stripprefix strip the leading prefix of file name on access fs methods 4 | // if file name is not an abs path, stripprefix do nothing 5 | package stripprefix 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "strings" 11 | "time" 12 | 13 | "github.com/spf13/afero" 14 | ) 15 | 16 | type fs struct { 17 | prefix string 18 | backend afero.Fs 19 | } 20 | 21 | func New(prefix string, backend afero.Fs) afero.Fs { 22 | return &fs{ 23 | prefix: prefix, 24 | backend: backend, 25 | } 26 | } 27 | 28 | func (f *fs) Chown(name string, uid int, gid int) error { 29 | return fmt.Errorf("Chown not implemented in stripprefix fs") 30 | } 31 | 32 | func (f *fs) strip(name string) (string, error) { 33 | // if !filepath.IsAbs(name) { 34 | // return name, nil 35 | // } 36 | p := strings.TrimPrefix(name, f.prefix) 37 | if len(p) == len(name) { 38 | return "", os.ErrNotExist 39 | } 40 | if p == "" { 41 | return ".", nil 42 | } 43 | return p, nil 44 | } 45 | 46 | // Create creates a file in the filesystem, returning the file and an 47 | // error, if any happens. 48 | func (f *fs) Create(name string) (afero.File, error) { 49 | p, err := f.strip(name) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return f.backend.Create(p) 54 | } 55 | 56 | // Mkdir creates a directory in the filesystem, return an error if any 57 | // happens. 58 | func (f *fs) Mkdir(name string, perm os.FileMode) error { 59 | p, err := f.strip(name) 60 | if err != nil { 61 | return err 62 | } 63 | return f.backend.Mkdir(p, perm) 64 | } 65 | 66 | // MkdirAll creates a directory path and all parents that does not exist 67 | // yet. 68 | func (f *fs) MkdirAll(path string, perm os.FileMode) error { 69 | p, err := f.strip(path) 70 | if err != nil { 71 | return err 72 | } 73 | return f.backend.MkdirAll(p, perm) 74 | } 75 | 76 | // Open opens a file, returning it or an error, if any happens. 77 | func (f *fs) Open(name string) (afero.File, error) { 78 | p, err := f.strip(name) 79 | if err != nil { 80 | return nil, err 81 | } 82 | return f.backend.Open(p) 83 | } 84 | 85 | // OpenFile opens a file using the given flags and the given mode. 86 | func (f *fs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) { 87 | p, err := f.strip(name) 88 | if err != nil { 89 | return nil, err 90 | } 91 | return f.backend.OpenFile(p, flag, perm) 92 | } 93 | 94 | // Remove removes a file identified by name, returning an error, if any 95 | // happens. 96 | func (f *fs) Remove(name string) error { 97 | p, err := f.strip(name) 98 | if err != nil { 99 | return err 100 | } 101 | return f.backend.Remove(p) 102 | } 103 | 104 | // RemoveAll removes a directory path and any children it contains. It 105 | // does not fail if the path does not exist (return nil). 106 | func (f *fs) RemoveAll(path string) error { 107 | p, err := f.strip(path) 108 | if err != nil { 109 | return err 110 | } 111 | return f.backend.RemoveAll(p) 112 | } 113 | 114 | // Rename renames a file. 115 | func (f *fs) Rename(oldname string, newname string) error { 116 | p1, err := f.strip(oldname) 117 | if err != nil { 118 | return err 119 | } 120 | p2, err := f.strip(newname) 121 | if err != nil { 122 | return err 123 | } 124 | return f.backend.Rename(p1, p2) 125 | } 126 | 127 | // Stat returns a FileInfo describing the named file, or an error, if any 128 | // happens. 129 | func (f *fs) Stat(name string) (os.FileInfo, error) { 130 | p, err := f.strip(name) 131 | if err != nil { 132 | return nil, err 133 | } 134 | return f.backend.Stat(p) 135 | } 136 | 137 | // The name of this FileSystem 138 | func (f *fs) Name() string { 139 | return "stripprefix" 140 | } 141 | 142 | //Chmod changes the mode of the named file to mode. 143 | func (f *fs) Chmod(name string, mode os.FileMode) error { 144 | p, err := f.strip(name) 145 | if err != nil { 146 | return err 147 | } 148 | return f.backend.Chmod(p, mode) 149 | } 150 | 151 | //Chtimes changes the access and modification times of the named file 152 | func (f *fs) Chtimes(name string, atime time.Time, mtime time.Time) error { 153 | p, err := f.strip(name) 154 | if err != nil { 155 | return err 156 | } 157 | return f.backend.Chtimes(p, atime, mtime) 158 | } 159 | -------------------------------------------------------------------------------- /starboard/internal/nbserver/browse.go: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | package nbserver 6 | 7 | import ( 8 | "bytes" 9 | "html/template" 10 | "log" 11 | "net/http" 12 | "net/url" 13 | "path" 14 | "sort" 15 | "strings" 16 | ) 17 | 18 | var defaultBrowseEndpoint = "/browse/" 19 | 20 | // Used for escaping HTML content 21 | var htmlReplacer = strings.NewReplacer( 22 | "&", "&", 23 | "<", "<", 24 | ">", ">", 25 | `"`, """, 26 | "'", "'", 27 | ) 28 | 29 | // The implementation of the browse handler is based on https://golang.org/src/net/http/fs.go?s=20871:20911#L710 30 | 31 | type browseHandler struct { 32 | root http.FileSystem 33 | } 34 | 35 | type BrowseEntry struct { 36 | Name string 37 | URL string 38 | IsNotebook bool 39 | LastModified string 40 | } 41 | 42 | func (f *browseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 43 | // loadTemplates(fs.templates) // TODO: Only do this in dev mode 44 | upath := strings.TrimPrefix(r.URL.Path, defaultBrowseEndpoint) 45 | 46 | if !strings.HasPrefix(upath, "/") { 47 | upath = "/" + upath 48 | r.URL.Path = upath 49 | } 50 | 51 | upath = path.Clean(upath) 52 | serveFile(w, r, f.root, upath, true) 53 | } 54 | 55 | // localRedirect gives a Moved Permanently response. 56 | // It does not convert relative paths to absolute paths like Redirect does. 57 | func localRedirect(w http.ResponseWriter, r *http.Request, newPath string) { 58 | if q := r.URL.RawQuery; q != "" { 59 | newPath += "?" + q 60 | } 61 | 62 | w.Header().Set("Location", newPath) 63 | w.WriteHeader(http.StatusMovedPermanently) 64 | } 65 | 66 | // name is '/'-separated, not filepath.Separator. 67 | func serveFile(w http.ResponseWriter, r *http.Request, fs http.FileSystem, name string, redirect bool) { 68 | f, err := fs.Open(name) 69 | 70 | if err != nil { 71 | msg, code := toHTTPError(err) 72 | http.Error(w, msg, code) 73 | return 74 | } 75 | 76 | defer f.Close() 77 | d, err := f.Stat() 78 | 79 | if err != nil { 80 | msg, code := toHTTPError(err) 81 | http.Error(w, msg, code) 82 | return 83 | } 84 | 85 | if redirect { 86 | // redirect to canonical path: / at end of directory url 87 | // r.URL.Path always begins with / 88 | url := r.URL.Path 89 | 90 | if d.IsDir() { 91 | if url[len(url)-1] != '/' { 92 | localRedirect(w, r, path.Base(url)+"/") 93 | return 94 | } 95 | } else { 96 | if url[len(url)-1] == '/' { 97 | localRedirect(w, r, "../"+path.Base(url)) 98 | return 99 | } 100 | } 101 | } 102 | 103 | if d.IsDir() { 104 | url := r.URL.Path 105 | 106 | // redirect if the directory name doesn't end in a slash 107 | if url == "" || url[len(url)-1] != '/' { 108 | localRedirect(w, r, path.Base(url)+"/") 109 | return 110 | } 111 | 112 | // if checkIfModifiedSince(r, d.ModTime()) == condFalse { 113 | // writeNotModified(w) 114 | // return 115 | // } 116 | // setLastModified(w, d.ModTime()) 117 | 118 | dirList(w, r, f) 119 | return 120 | } 121 | 122 | // Note(gzuidhof): I replaced serveContent with ServeContent 123 | // serveContent will check modification time 124 | // sizeFunc := func() (int64, error) { return d.Size(), nil } 125 | http.ServeContent(w, r, d.Name(), d.ModTime(), f) 126 | } 127 | 128 | func dirList(w http.ResponseWriter, r *http.Request, f http.File) { 129 | dirs, err := f.Readdir(-1) 130 | 131 | if err != nil { 132 | log.Printf("Error reading directory: %s", err) 133 | http.Error(w, "Error reading directory", http.StatusInternalServerError) 134 | return 135 | } 136 | 137 | sort.Slice(dirs, func(i, j int) bool { 138 | // Folders go above 139 | if dirs[i].IsDir() && !dirs[j].IsDir() { 140 | return true 141 | } else if !dirs[i].IsDir() && dirs[j].IsDir() { 142 | return false 143 | } 144 | 145 | return dirs[i].Name() < dirs[j].Name() 146 | 147 | }) 148 | 149 | entries := make([]BrowseEntry, len(dirs)) 150 | for i, d := range dirs { 151 | name := d.Name() 152 | if d.IsDir() { 153 | name += "/" 154 | } 155 | isNotebook := isProbablyNotebookFilename(name) 156 | URL := url.URL{Path: name} 157 | if isNotebook { 158 | URL = url.URL{Path: path.Join(defaultNotebookEndpoint, r.URL.Path, name)} 159 | } 160 | 161 | entries[i] = BrowseEntry{ 162 | Name: htmlReplacer.Replace(name), 163 | URL: URL.String(), 164 | IsNotebook: isNotebook, 165 | LastModified: d.ModTime().String(), 166 | } 167 | } 168 | crumbs := makeBreadCrumbs(r.URL.Path, true) 169 | 170 | var b bytes.Buffer 171 | err = browseTemplate.Execute(&b, map[string]interface{}{ 172 | "browseEndpoint": defaultBrowseEndpoint, 173 | "notebookEndpoint": defaultNotebookEndpoint, 174 | "path": r.URL.Path, 175 | "breadCrumbs": crumbs, 176 | "entries": entries, 177 | }) 178 | if err != nil { 179 | http.Error(w, err.Error(), http.StatusInternalServerError) 180 | return 181 | } 182 | 183 | w.Header().Set("Content-Type", "text/html; charset=utf-8") 184 | 185 | err = indexTemplate.Execute(w, map[string]interface{}{ 186 | "body": template.HTML(b.String()), 187 | }) 188 | if err != nil { 189 | http.Error(w, err.Error(), http.StatusInternalServerError) 190 | return 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /starboard/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= 8 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 9 | cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= 10 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 11 | cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= 12 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 13 | cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= 14 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 15 | cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= 16 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 17 | cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= 18 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 19 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= 20 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 21 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 22 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 23 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= 24 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 25 | github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= 26 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= 27 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= 28 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 29 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= 30 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 31 | github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= 32 | github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc= 33 | github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= 34 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= 35 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 36 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= 37 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 38 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= 39 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 40 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 41 | github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= 42 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 43 | github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= 44 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 45 | github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c h1:+0HFd5KSZ/mm3JmhmrDukiId5iR6w4+BdFtfSy4yWIc= 46 | github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= 47 | github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= 48 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= 49 | github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= 50 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 51 | github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= 52 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 53 | github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= 54 | github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= 55 | github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= 56 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 57 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= 58 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= 59 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= 60 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= 61 | github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= 62 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 63 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 64 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 65 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 66 | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= 67 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= 68 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= 69 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= 70 | github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= 71 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 72 | github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= 73 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 74 | github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= 75 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 76 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= 77 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 78 | github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= 79 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 80 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 81 | github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= 82 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 83 | github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 84 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 85 | github.com/gofiber/adaptor/v2 v2.1.2 h1:/oCKz+EWkV+yjQWLu8k1PM+K1mhNXGG1B9R2DNcTP7s= 86 | github.com/gofiber/adaptor/v2 v2.1.2/go.mod h1:Ra0B7NC2qFOhQR+AiGWU0W1cUa05afGlmoob9fM0mgo= 87 | github.com/gofiber/fiber/v2 v2.7.1 h1:CpzGXD+7VhmptQ6McU5qYyRFxZdQkP2Y32ySIid+BXQ= 88 | github.com/gofiber/fiber/v2 v2.7.1/go.mod h1:f8BRRIMjMdRyt2qmJ/0Sea3j3rwwfufPrh9WNBRiVZ0= 89 | github.com/gofiber/utils v0.1.2 h1:1SH2YEz4RlNS0tJlMJ0bGwO0JkqPqvq6TbHK9tXZKtk= 90 | github.com/gofiber/utils v0.1.2/go.mod h1:pacRFtghAE3UoknMOUiXh2Io/nLWSUHtQCi/3QASsOc= 91 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 92 | github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= 93 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 94 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 95 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 96 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= 97 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 98 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 99 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 100 | github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= 101 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 102 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 103 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 104 | github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= 105 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 106 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 107 | github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= 108 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 109 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 110 | github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= 111 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 112 | github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= 113 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 114 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 115 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ= 116 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 117 | github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= 118 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 119 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 120 | github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= 121 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 122 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= 123 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 124 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 125 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 126 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= 127 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= 128 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= 129 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 130 | github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= 131 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= 132 | github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= 133 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 134 | github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= 135 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 136 | github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= 137 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 138 | github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= 139 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 140 | github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= 141 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 142 | github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= 143 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 144 | github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= 145 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 146 | github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= 147 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 148 | github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= 149 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 150 | github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= 151 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 152 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 153 | github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= 154 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 155 | github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= 156 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 157 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 158 | github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= 159 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 160 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 161 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 162 | github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= 163 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 164 | github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= 165 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 166 | github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= 167 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 168 | github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= 169 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 170 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= 171 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 172 | github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= 173 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= 174 | github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= 175 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 176 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= 177 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 178 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 179 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 180 | github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= 181 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 182 | github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0= 183 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= 184 | github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= 185 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 186 | github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= 187 | github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= 188 | github.com/klauspost/compress v1.11.13 h1:eSvu8Tmq6j2psUJqJrLcWH6K3w5Dwc+qipbaA6eVEN4= 189 | github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= 190 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= 191 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 192 | github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= 193 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 194 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= 195 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 196 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 197 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 198 | github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= 199 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 200 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 201 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 202 | github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= 203 | github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= 204 | github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= 205 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 206 | github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= 207 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 208 | github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= 209 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 210 | github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= 211 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 212 | github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= 213 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 214 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 215 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 216 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 217 | github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= 218 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 219 | github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= 220 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 221 | github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= 222 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 223 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 224 | github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= 225 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 226 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 227 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 228 | github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= 229 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 230 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= 231 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 232 | github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= 233 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= 234 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= 235 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 236 | github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= 237 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= 238 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 239 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 240 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 241 | github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= 242 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 243 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 244 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 245 | github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= 246 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 247 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 248 | github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= 249 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= 250 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 251 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= 252 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 253 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= 254 | github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= 255 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 256 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 257 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= 258 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 259 | github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= 260 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 261 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= 262 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 263 | github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= 264 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 265 | github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= 266 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 267 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= 268 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 269 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= 270 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 271 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk= 272 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= 273 | github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= 274 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 275 | github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= 276 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 277 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= 278 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 279 | github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= 280 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 281 | github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= 282 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= 283 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= 284 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= 285 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= 286 | github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= 287 | github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= 288 | github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= 289 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 290 | github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= 291 | github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= 292 | github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= 293 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= 294 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= 295 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 296 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 297 | github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= 298 | github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= 299 | github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= 300 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 301 | github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= 302 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 303 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 304 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 305 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 306 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 307 | github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= 308 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 309 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= 310 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= 311 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 312 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 313 | github.com/valyala/fasthttp v1.18.0/go.mod h1:jjraHZVbKOXftJfsOYoAjaeygpj5hr8ermTRJNroD7A= 314 | github.com/valyala/fasthttp v1.22.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= 315 | github.com/valyala/fasthttp v1.23.0 h1:0ufwSD9BhWa6f8HWdmdq4FHQ23peRo3Ng/Qs8m5NcFs= 316 | github.com/valyala/fasthttp v1.23.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= 317 | github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= 318 | github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= 319 | github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= 320 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= 321 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= 322 | go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= 323 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= 324 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 325 | go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= 326 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 327 | go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= 328 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 329 | go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= 330 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= 331 | go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= 332 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= 333 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 334 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 335 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 336 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 337 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 338 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 339 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 340 | golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= 341 | golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 342 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 343 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 344 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 345 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 346 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= 347 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 348 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 349 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= 350 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 351 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 352 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 353 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 354 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 355 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 356 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 357 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= 358 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 359 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 360 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= 361 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 362 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 363 | golang.org/x/mod v0.1.0 h1:sfUMP1Gu8qASkorDVjnMuvgJzwFbTZSeXFiGBYAVdl4= 364 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 365 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 366 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 367 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 368 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 369 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 370 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 371 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 372 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 373 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 374 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 375 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 376 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 377 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 378 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 379 | golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 380 | golang.org/x/net v0.0.0-20210226101413-39120d07d75e h1:jIQURUJ9mlLvYwTBtRHm9h58rYhSonLvRvgAnP8Nr7I= 381 | golang.org/x/net v0.0.0-20210226101413-39120d07d75e/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 382 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 383 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 384 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= 385 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 386 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 387 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 388 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 389 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 390 | golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= 391 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 392 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 393 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 394 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 395 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 396 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 397 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 398 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 399 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 400 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 401 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 402 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 403 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 404 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 405 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 406 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 407 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 408 | golang.org/x/sys v0.0.0-20201210223839-7e3030f88018/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 409 | golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 410 | golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0= 411 | golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 412 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 413 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= 414 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 415 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 416 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 417 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 418 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 419 | golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= 420 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 421 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 422 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= 423 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 424 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 425 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 426 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 427 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 428 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 429 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 430 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 431 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 432 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 433 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 434 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 435 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 436 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 437 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 438 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 439 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 440 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc h1:NCy3Ohtk6Iny5V/reW2Ktypo4zIpWBdRJ1uFMjBxdg8= 441 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 442 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= 443 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 444 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 445 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 446 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 447 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 448 | google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= 449 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 450 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 451 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 452 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 453 | google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= 454 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 455 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 456 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 457 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 458 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 459 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 460 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 461 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 462 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 463 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= 464 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 465 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 466 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 467 | google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= 468 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 469 | gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= 470 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 471 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 472 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 473 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 474 | gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= 475 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 476 | gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= 477 | gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 478 | gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= 479 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 480 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 481 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 482 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 483 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 484 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 485 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 486 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 487 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 488 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 489 | honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= 490 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 491 | rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= 492 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 493 | -------------------------------------------------------------------------------- /starboard/web/static/css/raster2.css: -------------------------------------------------------------------------------- 1 | /* Raster v20 (release package) (rsms.me/raster) - @gzuidhof: removed font imports from rsms.me*/ 2 | 3 | :root { 4 | --fontSize: 12px; 5 | --sansFont: "Inter"; 6 | --monoFont: "iaw-mono"; 7 | --lineHeight: calc(var(--fontSize)*1.5); 8 | --baseline: calc(var(--lineHeight)/2); 9 | --blockSpacingTop: 0px; 10 | --blockSpacingBottom: var(--lineHeight); 11 | --hrThickness: 2px; 12 | --h1-size: 2.8rem; 13 | --h2-size: 2.2rem; 14 | --h3-size: 1.4rem; 15 | --h4-size: 1.1rem; 16 | --columnGap: calc(var(--lineHeight)*2); 17 | --rowGap: var(--lineHeight); 18 | --displayScale: 1; 19 | --pixel: 1px; 20 | --foreground-color-rgb: 0, 0, 0; 21 | --foreground-color-a: 1; 22 | --foreground-color: rgba(var(--foreground-color-rgb), var(--foreground-color-a)); 23 | --background-color: #fff 24 | } 25 | 26 | @supports (font-variation-settings:normal) { 27 | :root { 28 | --sansFont: "Inter var"; 29 | --monoFont: "iaw-mono-var" 30 | } 31 | } 32 | 33 | @media only screen and (-webkit-min-device-pixel-ratio:1.5), 34 | only screen and (min-device-pixel-ratio:1.5), 35 | only screen and (min-resolution:1.5dppx) { 36 | :root { 37 | --displayScale: 2; 38 | --pixel: 0.5px 39 | } 40 | } 41 | 42 | @media only screen and (-webkit-min-device-pixel-ratio:2.5), 43 | only screen and (min-device-pixel-ratio:2.5), 44 | only screen and (min-resolution:2.5dppx) { 45 | :root { 46 | --displayScale: 3; 47 | --pixel: 0.34px 48 | } 49 | } 50 | 51 | @media only screen and (-webkit-min-device-pixel-ratio:3.5), 52 | only screen and (min-device-pixel-ratio:3.5), 53 | only screen and (min-resolution:3.5dppx) { 54 | :root { 55 | --displayScale: 4; 56 | --pixel: 0.25px 57 | } 58 | } 59 | 60 | * { 61 | font: inherit; 62 | line-height: inherit 63 | } 64 | 65 | a, 66 | abbr, 67 | acronym, 68 | address, 69 | applet, 70 | article, 71 | aside, 72 | audio, 73 | b, 74 | big, 75 | blockquote, 76 | body, 77 | canvas, 78 | caption, 79 | center, 80 | cite, 81 | code, 82 | dd, 83 | del, 84 | details, 85 | dfn, 86 | div, 87 | dl, 88 | dt, 89 | em, 90 | embed, 91 | fieldset, 92 | figcaption, 93 | figure, 94 | footer, 95 | form, 96 | grid, 97 | h1, 98 | h2, 99 | h3, 100 | h4, 101 | h5, 102 | h6, 103 | header, 104 | hgroup, 105 | hr, 106 | html, 107 | i, 108 | iframe, 109 | img, 110 | ins, 111 | kbd, 112 | label, 113 | legend, 114 | li, 115 | main, 116 | mark, 117 | menu, 118 | nav, 119 | noscript, 120 | object, 121 | ol, 122 | output, 123 | p, 124 | pre, 125 | q, 126 | s, 127 | samp, 128 | section, 129 | small, 130 | span, 131 | strike, 132 | strong, 133 | sub, 134 | summary, 135 | sup, 136 | table, 137 | tbody, 138 | td, 139 | tfoot, 140 | th, 141 | thead, 142 | time, 143 | tr, 144 | tt, 145 | u, 146 | ul, 147 | var, 148 | video { 149 | margin: 0; 150 | padding: 0; 151 | border: 0; 152 | vertical-align: baseline 153 | } 154 | 155 | blockquote, 156 | q { 157 | quotes: none 158 | } 159 | 160 | blockquote:after, 161 | blockquote:before, 162 | q:after, 163 | q:before { 164 | content: ""; 165 | content: none 166 | } 167 | 168 | a, 169 | a:active, 170 | a:visited { 171 | color: inherit 172 | } 173 | 174 | r-grid { 175 | display: grid; 176 | --grid-tc: repeat(4, 1fr); 177 | grid-template-columns: var(--grid-tc); 178 | --grid-cs: 1; 179 | --grid-ce: -1 180 | } 181 | 182 | r-grid>r-cell { 183 | display: block; 184 | -moz-appearance: none; 185 | appearance: none; 186 | -webkit-appearance: none 187 | } 188 | 189 | r-grid[columns="1"] { 190 | --grid-tc: repeat(1, 1fr) 191 | } 192 | 193 | r-grid[columns="2"] { 194 | --grid-tc: repeat(2, 1fr) 195 | } 196 | 197 | r-grid[columns="3"] { 198 | --grid-tc: repeat(3, 1fr) 199 | } 200 | 201 | r-grid[columns="4"] { 202 | --grid-tc: repeat(4, 1fr) 203 | } 204 | 205 | r-grid[columns="5"] { 206 | --grid-tc: repeat(5, 1fr) 207 | } 208 | 209 | r-grid[columns="6"] { 210 | --grid-tc: repeat(6, 1fr) 211 | } 212 | 213 | r-grid[columns="7"] { 214 | --grid-tc: repeat(7, 1fr) 215 | } 216 | 217 | r-grid[columns="8"] { 218 | --grid-tc: repeat(8, 1fr) 219 | } 220 | 221 | r-grid[columns="9"] { 222 | --grid-tc: repeat(9, 1fr) 223 | } 224 | 225 | r-grid[columns="10"] { 226 | --grid-tc: repeat(10, 1fr) 227 | } 228 | 229 | r-grid[columns="11"] { 230 | --grid-tc: repeat(11, 1fr) 231 | } 232 | 233 | r-grid[columns="12"] { 234 | --grid-tc: repeat(12, 1fr) 235 | } 236 | 237 | r-grid[columns="13"] { 238 | --grid-tc: repeat(13, 1fr) 239 | } 240 | 241 | r-grid[columns="14"] { 242 | --grid-tc: repeat(14, 1fr) 243 | } 244 | 245 | r-grid[columns="15"] { 246 | --grid-tc: repeat(15, 1fr) 247 | } 248 | 249 | r-grid[columns="16"] { 250 | --grid-tc: repeat(16, 1fr) 251 | } 252 | 253 | r-grid[columns="17"] { 254 | --grid-tc: repeat(17, 1fr) 255 | } 256 | 257 | r-grid[columns="18"] { 258 | --grid-tc: repeat(18, 1fr) 259 | } 260 | 261 | r-grid[columns="19"] { 262 | --grid-tc: repeat(19, 1fr) 263 | } 264 | 265 | r-grid[columns="20"] { 266 | --grid-tc: repeat(20, 1fr) 267 | } 268 | 269 | r-grid[columns="21"] { 270 | --grid-tc: repeat(21, 1fr) 271 | } 272 | 273 | r-grid[columns="22"] { 274 | --grid-tc: repeat(22, 1fr) 275 | } 276 | 277 | r-grid[columns="23"] { 278 | --grid-tc: repeat(23, 1fr) 279 | } 280 | 281 | r-grid[columns="24"] { 282 | --grid-tc: repeat(24, 1fr) 283 | } 284 | 285 | r-grid[columns="25"] { 286 | --grid-tc: repeat(25, 1fr) 287 | } 288 | 289 | r-grid[columns="26"] { 290 | --grid-tc: repeat(26, 1fr) 291 | } 292 | 293 | r-grid[columns="27"] { 294 | --grid-tc: repeat(27, 1fr) 295 | } 296 | 297 | r-grid[columns="28"] { 298 | --grid-tc: repeat(28, 1fr) 299 | } 300 | 301 | r-grid[columns="29"] { 302 | --grid-tc: repeat(29, 1fr) 303 | } 304 | 305 | r-grid[columns="30"] { 306 | --grid-tc: repeat(30, 1fr) 307 | } 308 | 309 | r-grid>r-cell[span^="1"] { 310 | --grid-cs: 1 311 | } 312 | 313 | r-grid>r-cell[span^="2"] { 314 | --grid-cs: 2 315 | } 316 | 317 | r-grid>r-cell[span^="3"] { 318 | --grid-cs: 3 319 | } 320 | 321 | r-grid>r-cell[span^="4"] { 322 | --grid-cs: 4 323 | } 324 | 325 | r-grid>r-cell[span^="5"] { 326 | --grid-cs: 5 327 | } 328 | 329 | r-grid>r-cell[span^="6"] { 330 | --grid-cs: 6 331 | } 332 | 333 | r-grid>r-cell[span^="7"] { 334 | --grid-cs: 7 335 | } 336 | 337 | r-grid>r-cell[span^="8"] { 338 | --grid-cs: 8 339 | } 340 | 341 | r-grid>r-cell[span^="9"] { 342 | --grid-cs: 9 343 | } 344 | 345 | r-grid>r-cell[span^="10"] { 346 | --grid-cs: 10 347 | } 348 | 349 | r-grid>r-cell[span^="11"] { 350 | --grid-cs: 11 351 | } 352 | 353 | r-grid>r-cell[span^="12"] { 354 | --grid-cs: 12 355 | } 356 | 357 | r-grid>r-cell[span^="13"] { 358 | --grid-cs: 13 359 | } 360 | 361 | r-grid>r-cell[span^="14"] { 362 | --grid-cs: 14 363 | } 364 | 365 | r-grid>r-cell[span^="15"] { 366 | --grid-cs: 15 367 | } 368 | 369 | r-grid>r-cell[span^="16"] { 370 | --grid-cs: 16 371 | } 372 | 373 | r-grid>r-cell[span^="17"] { 374 | --grid-cs: 17 375 | } 376 | 377 | r-grid>r-cell[span^="18"] { 378 | --grid-cs: 18 379 | } 380 | 381 | r-grid>r-cell[span^="19"] { 382 | --grid-cs: 19 383 | } 384 | 385 | r-grid>r-cell[span^="20"] { 386 | --grid-cs: 20 387 | } 388 | 389 | r-grid>r-cell[span^="21"] { 390 | --grid-cs: 21 391 | } 392 | 393 | r-grid>r-cell[span^="22"] { 394 | --grid-cs: 22 395 | } 396 | 397 | r-grid>r-cell[span^="23"] { 398 | --grid-cs: 23 399 | } 400 | 401 | r-grid>r-cell[span^="24"] { 402 | --grid-cs: 24 403 | } 404 | 405 | r-grid>r-cell[span^="25"] { 406 | --grid-cs: 25 407 | } 408 | 409 | r-grid>r-cell[span^="26"] { 410 | --grid-cs: 26 411 | } 412 | 413 | r-grid>r-cell[span^="27"] { 414 | --grid-cs: 27 415 | } 416 | 417 | r-grid>r-cell[span^="28"] { 418 | --grid-cs: 28 419 | } 420 | 421 | r-grid>r-cell[span^="29"] { 422 | --grid-cs: 29 423 | } 424 | 425 | r-grid>r-cell[span^="30"] { 426 | --grid-cs: 30 427 | } 428 | 429 | r-grid>r-cell[span$="+1"], 430 | r-grid>r-cell[span="1"] { 431 | --grid-ce: 1 432 | } 433 | 434 | r-grid>r-cell[span$="+2"], 435 | r-grid>r-cell[span$="-1"], 436 | r-grid>r-cell[span="2"] { 437 | --grid-ce: 2 438 | } 439 | 440 | r-grid>r-cell[span$="+3"], 441 | r-grid>r-cell[span$="-2"], 442 | r-grid>r-cell[span="3"] { 443 | --grid-ce: 3 444 | } 445 | 446 | r-grid>r-cell[span$="+4"], 447 | r-grid>r-cell[span$="-3"], 448 | r-grid>r-cell[span="4"] { 449 | --grid-ce: 4 450 | } 451 | 452 | r-grid>r-cell[span$="+5"], 453 | r-grid>r-cell[span$="-4"], 454 | r-grid>r-cell[span="5"] { 455 | --grid-ce: 5 456 | } 457 | 458 | r-grid>r-cell[span$="+6"], 459 | r-grid>r-cell[span$="-5"], 460 | r-grid>r-cell[span="6"] { 461 | --grid-ce: 6 462 | } 463 | 464 | r-grid>r-cell[span$="+7"], 465 | r-grid>r-cell[span$="-6"], 466 | r-grid>r-cell[span="7"] { 467 | --grid-ce: 7 468 | } 469 | 470 | r-grid>r-cell[span$="+8"], 471 | r-grid>r-cell[span$="-7"], 472 | r-grid>r-cell[span="8"] { 473 | --grid-ce: 8 474 | } 475 | 476 | r-grid>r-cell[span$="+9"], 477 | r-grid>r-cell[span$="-8"], 478 | r-grid>r-cell[span="9"] { 479 | --grid-ce: 9 480 | } 481 | 482 | r-grid>r-cell[span$="+10"], 483 | r-grid>r-cell[span$="-9"], 484 | r-grid>r-cell[span="10"] { 485 | --grid-ce: 10 486 | } 487 | 488 | r-grid>r-cell[span$="+11"], 489 | r-grid>r-cell[span$="-10"], 490 | r-grid>r-cell[span="11"] { 491 | --grid-ce: 11 492 | } 493 | 494 | r-grid>r-cell[span$="+12"], 495 | r-grid>r-cell[span$="-11"], 496 | r-grid>r-cell[span="12"] { 497 | --grid-ce: 12 498 | } 499 | 500 | r-grid>r-cell[span$="+13"], 501 | r-grid>r-cell[span$="-12"], 502 | r-grid>r-cell[span="13"] { 503 | --grid-ce: 13 504 | } 505 | 506 | r-grid>r-cell[span$="+14"], 507 | r-grid>r-cell[span$="-13"], 508 | r-grid>r-cell[span="14"] { 509 | --grid-ce: 14 510 | } 511 | 512 | r-grid>r-cell[span$="+15"], 513 | r-grid>r-cell[span$="-14"], 514 | r-grid>r-cell[span="15"] { 515 | --grid-ce: 15 516 | } 517 | 518 | r-grid>r-cell[span$="+16"], 519 | r-grid>r-cell[span$="-15"], 520 | r-grid>r-cell[span="16"] { 521 | --grid-ce: 16 522 | } 523 | 524 | r-grid>r-cell[span$="+17"], 525 | r-grid>r-cell[span$="-16"], 526 | r-grid>r-cell[span="17"] { 527 | --grid-ce: 17 528 | } 529 | 530 | r-grid>r-cell[span$="+18"], 531 | r-grid>r-cell[span$="-17"], 532 | r-grid>r-cell[span="18"] { 533 | --grid-ce: 18 534 | } 535 | 536 | r-grid>r-cell[span$="+19"], 537 | r-grid>r-cell[span$="-18"], 538 | r-grid>r-cell[span="19"] { 539 | --grid-ce: 19 540 | } 541 | 542 | r-grid>r-cell[span$="+20"], 543 | r-grid>r-cell[span$="-19"], 544 | r-grid>r-cell[span="20"] { 545 | --grid-ce: 20 546 | } 547 | 548 | r-grid>r-cell[span$="+21"], 549 | r-grid>r-cell[span$="-20"], 550 | r-grid>r-cell[span="21"] { 551 | --grid-ce: 21 552 | } 553 | 554 | r-grid>r-cell[span$="+22"], 555 | r-grid>r-cell[span$="-21"], 556 | r-grid>r-cell[span="22"] { 557 | --grid-ce: 22 558 | } 559 | 560 | r-grid>r-cell[span$="+23"], 561 | r-grid>r-cell[span$="-22"], 562 | r-grid>r-cell[span="23"] { 563 | --grid-ce: 23 564 | } 565 | 566 | r-grid>r-cell[span$="+24"], 567 | r-grid>r-cell[span$="-23"], 568 | r-grid>r-cell[span="24"] { 569 | --grid-ce: 24 570 | } 571 | 572 | r-grid>r-cell[span$="+25"], 573 | r-grid>r-cell[span$="-24"], 574 | r-grid>r-cell[span="25"] { 575 | --grid-ce: 25 576 | } 577 | 578 | r-grid>r-cell[span$="+26"], 579 | r-grid>r-cell[span$="-25"], 580 | r-grid>r-cell[span="26"] { 581 | --grid-ce: 26 582 | } 583 | 584 | r-grid>r-cell[span$="+27"], 585 | r-grid>r-cell[span$="-26"], 586 | r-grid>r-cell[span="27"] { 587 | --grid-ce: 27 588 | } 589 | 590 | r-grid>r-cell[span$="+28"], 591 | r-grid>r-cell[span$="-27"], 592 | r-grid>r-cell[span="28"] { 593 | --grid-ce: 28 594 | } 595 | 596 | r-grid>r-cell[span$="+29"], 597 | r-grid>r-cell[span$="-28"], 598 | r-grid>r-cell[span="29"] { 599 | --grid-ce: 29 600 | } 601 | 602 | r-grid>r-cell[span$="+30"], 603 | r-grid>r-cell[span$="-29"], 604 | r-grid>r-cell[span="30"] { 605 | --grid-ce: 30 606 | } 607 | 608 | r-grid>r-cell[span$="-30"] { 609 | --grid-ce: 31 610 | } 611 | 612 | r-grid>r-cell[span] { 613 | grid-column-end: span var(--grid-ce) 614 | } 615 | 616 | r-grid>r-cell[span*="+"], 617 | r-grid>r-cell[span*="-"], 618 | r-grid>r-cell[span*=".."] { 619 | grid-column-start: var(--grid-cs) 620 | } 621 | 622 | r-grid>r-cell[span*="-"], 623 | r-grid>r-cell[span*=".."] { 624 | grid-column-end: var(--grid-ce) 625 | } 626 | 627 | r-grid>r-cell[span=row] { 628 | grid-column: 1/-1 629 | } 630 | 631 | @media only screen and (max-width:720px) { 632 | r-grid[columns-s="1"] { 633 | --grid-tc: repeat(1, 1fr) 634 | } 635 | r-grid[columns-s="2"] { 636 | --grid-tc: repeat(2, 1fr) 637 | } 638 | r-grid[columns-s="3"] { 639 | --grid-tc: repeat(3, 1fr) 640 | } 641 | r-grid[columns-s="4"] { 642 | --grid-tc: repeat(4, 1fr) 643 | } 644 | r-grid[columns-s="5"] { 645 | --grid-tc: repeat(5, 1fr) 646 | } 647 | r-grid[columns-s="6"] { 648 | --grid-tc: repeat(6, 1fr) 649 | } 650 | r-grid[columns-s="7"] { 651 | --grid-tc: repeat(7, 1fr) 652 | } 653 | r-grid[columns-s="8"] { 654 | --grid-tc: repeat(8, 1fr) 655 | } 656 | r-grid[columns-s="9"] { 657 | --grid-tc: repeat(9, 1fr) 658 | } 659 | r-grid[columns-s="10"] { 660 | --grid-tc: repeat(10, 1fr) 661 | } 662 | r-grid[columns-s="11"] { 663 | --grid-tc: repeat(11, 1fr) 664 | } 665 | r-grid[columns-s="12"] { 666 | --grid-tc: repeat(12, 1fr) 667 | } 668 | r-grid[columns-s="13"] { 669 | --grid-tc: repeat(13, 1fr) 670 | } 671 | r-grid[columns-s="14"] { 672 | --grid-tc: repeat(14, 1fr) 673 | } 674 | r-grid[columns-s="15"] { 675 | --grid-tc: repeat(15, 1fr) 676 | } 677 | r-grid[columns-s="16"] { 678 | --grid-tc: repeat(16, 1fr) 679 | } 680 | r-grid[columns-s="17"] { 681 | --grid-tc: repeat(17, 1fr) 682 | } 683 | r-grid[columns-s="18"] { 684 | --grid-tc: repeat(18, 1fr) 685 | } 686 | r-grid[columns-s="19"] { 687 | --grid-tc: repeat(19, 1fr) 688 | } 689 | r-grid[columns-s="20"] { 690 | --grid-tc: repeat(20, 1fr) 691 | } 692 | r-grid[columns-s="21"] { 693 | --grid-tc: repeat(21, 1fr) 694 | } 695 | r-grid[columns-s="22"] { 696 | --grid-tc: repeat(22, 1fr) 697 | } 698 | r-grid[columns-s="23"] { 699 | --grid-tc: repeat(23, 1fr) 700 | } 701 | r-grid[columns-s="24"] { 702 | --grid-tc: repeat(24, 1fr) 703 | } 704 | r-grid[columns-s="25"] { 705 | --grid-tc: repeat(25, 1fr) 706 | } 707 | r-grid[columns-s="26"] { 708 | --grid-tc: repeat(26, 1fr) 709 | } 710 | r-grid[columns-s="27"] { 711 | --grid-tc: repeat(27, 1fr) 712 | } 713 | r-grid[columns-s="28"] { 714 | --grid-tc: repeat(28, 1fr) 715 | } 716 | r-grid[columns-s="29"] { 717 | --grid-tc: repeat(29, 1fr) 718 | } 719 | r-grid[columns-s="30"] { 720 | --grid-tc: repeat(30, 1fr) 721 | } 722 | r-grid>r-cell[span-s^="1"] { 723 | --grid-cs: 1 724 | } 725 | r-grid>r-cell[span-s^="2"] { 726 | --grid-cs: 2 727 | } 728 | r-grid>r-cell[span-s^="3"] { 729 | --grid-cs: 3 730 | } 731 | r-grid>r-cell[span-s^="4"] { 732 | --grid-cs: 4 733 | } 734 | r-grid>r-cell[span-s^="5"] { 735 | --grid-cs: 5 736 | } 737 | r-grid>r-cell[span-s^="6"] { 738 | --grid-cs: 6 739 | } 740 | r-grid>r-cell[span-s^="7"] { 741 | --grid-cs: 7 742 | } 743 | r-grid>r-cell[span-s^="8"] { 744 | --grid-cs: 8 745 | } 746 | r-grid>r-cell[span-s^="9"] { 747 | --grid-cs: 9 748 | } 749 | r-grid>r-cell[span-s^="10"] { 750 | --grid-cs: 10 751 | } 752 | r-grid>r-cell[span-s^="11"] { 753 | --grid-cs: 11 754 | } 755 | r-grid>r-cell[span-s^="12"] { 756 | --grid-cs: 12 757 | } 758 | r-grid>r-cell[span-s^="13"] { 759 | --grid-cs: 13 760 | } 761 | r-grid>r-cell[span-s^="14"] { 762 | --grid-cs: 14 763 | } 764 | r-grid>r-cell[span-s^="15"] { 765 | --grid-cs: 15 766 | } 767 | r-grid>r-cell[span-s^="16"] { 768 | --grid-cs: 16 769 | } 770 | r-grid>r-cell[span-s^="17"] { 771 | --grid-cs: 17 772 | } 773 | r-grid>r-cell[span-s^="18"] { 774 | --grid-cs: 18 775 | } 776 | r-grid>r-cell[span-s^="19"] { 777 | --grid-cs: 19 778 | } 779 | r-grid>r-cell[span-s^="20"] { 780 | --grid-cs: 20 781 | } 782 | r-grid>r-cell[span-s^="21"] { 783 | --grid-cs: 21 784 | } 785 | r-grid>r-cell[span-s^="22"] { 786 | --grid-cs: 22 787 | } 788 | r-grid>r-cell[span-s^="23"] { 789 | --grid-cs: 23 790 | } 791 | r-grid>r-cell[span-s^="24"] { 792 | --grid-cs: 24 793 | } 794 | r-grid>r-cell[span-s^="25"] { 795 | --grid-cs: 25 796 | } 797 | r-grid>r-cell[span-s^="26"] { 798 | --grid-cs: 26 799 | } 800 | r-grid>r-cell[span-s^="27"] { 801 | --grid-cs: 27 802 | } 803 | r-grid>r-cell[span-s^="28"] { 804 | --grid-cs: 28 805 | } 806 | r-grid>r-cell[span-s^="29"] { 807 | --grid-cs: 29 808 | } 809 | r-grid>r-cell[span-s^="30"] { 810 | --grid-cs: 30 811 | } 812 | r-grid>r-cell[span-s$="+1"], 813 | r-grid>r-cell[span-s="1"] { 814 | --grid-ce: 1 815 | } 816 | r-grid>r-cell[span-s$="+2"], 817 | r-grid>r-cell[span-s$="-1"], 818 | r-grid>r-cell[span-s="2"] { 819 | --grid-ce: 2 820 | } 821 | r-grid>r-cell[span-s$="+3"], 822 | r-grid>r-cell[span-s$="-2"], 823 | r-grid>r-cell[span-s="3"] { 824 | --grid-ce: 3 825 | } 826 | r-grid>r-cell[span-s$="+4"], 827 | r-grid>r-cell[span-s$="-3"], 828 | r-grid>r-cell[span-s="4"] { 829 | --grid-ce: 4 830 | } 831 | r-grid>r-cell[span-s$="+5"], 832 | r-grid>r-cell[span-s$="-4"], 833 | r-grid>r-cell[span-s="5"] { 834 | --grid-ce: 5 835 | } 836 | r-grid>r-cell[span-s$="+6"], 837 | r-grid>r-cell[span-s$="-5"], 838 | r-grid>r-cell[span-s="6"] { 839 | --grid-ce: 6 840 | } 841 | r-grid>r-cell[span-s$="+7"], 842 | r-grid>r-cell[span-s$="-6"], 843 | r-grid>r-cell[span-s="7"] { 844 | --grid-ce: 7 845 | } 846 | r-grid>r-cell[span-s$="+8"], 847 | r-grid>r-cell[span-s$="-7"], 848 | r-grid>r-cell[span-s="8"] { 849 | --grid-ce: 8 850 | } 851 | r-grid>r-cell[span-s$="+9"], 852 | r-grid>r-cell[span-s$="-8"], 853 | r-grid>r-cell[span-s="9"] { 854 | --grid-ce: 9 855 | } 856 | r-grid>r-cell[span-s$="+10"], 857 | r-grid>r-cell[span-s$="-9"], 858 | r-grid>r-cell[span-s="10"] { 859 | --grid-ce: 10 860 | } 861 | r-grid>r-cell[span-s$="+11"], 862 | r-grid>r-cell[span-s$="-10"], 863 | r-grid>r-cell[span-s="11"] { 864 | --grid-ce: 11 865 | } 866 | r-grid>r-cell[span-s$="+12"], 867 | r-grid>r-cell[span-s$="-11"], 868 | r-grid>r-cell[span-s="12"] { 869 | --grid-ce: 12 870 | } 871 | r-grid>r-cell[span-s$="+13"], 872 | r-grid>r-cell[span-s$="-12"], 873 | r-grid>r-cell[span-s="13"] { 874 | --grid-ce: 13 875 | } 876 | r-grid>r-cell[span-s$="+14"], 877 | r-grid>r-cell[span-s$="-13"], 878 | r-grid>r-cell[span-s="14"] { 879 | --grid-ce: 14 880 | } 881 | r-grid>r-cell[span-s$="+15"], 882 | r-grid>r-cell[span-s$="-14"], 883 | r-grid>r-cell[span-s="15"] { 884 | --grid-ce: 15 885 | } 886 | r-grid>r-cell[span-s$="+16"], 887 | r-grid>r-cell[span-s$="-15"], 888 | r-grid>r-cell[span-s="16"] { 889 | --grid-ce: 16 890 | } 891 | r-grid>r-cell[span-s$="+17"], 892 | r-grid>r-cell[span-s$="-16"], 893 | r-grid>r-cell[span-s="17"] { 894 | --grid-ce: 17 895 | } 896 | r-grid>r-cell[span-s$="+18"], 897 | r-grid>r-cell[span-s$="-17"], 898 | r-grid>r-cell[span-s="18"] { 899 | --grid-ce: 18 900 | } 901 | r-grid>r-cell[span-s$="+19"], 902 | r-grid>r-cell[span-s$="-18"], 903 | r-grid>r-cell[span-s="19"] { 904 | --grid-ce: 19 905 | } 906 | r-grid>r-cell[span-s$="+20"], 907 | r-grid>r-cell[span-s$="-19"], 908 | r-grid>r-cell[span-s="20"] { 909 | --grid-ce: 20 910 | } 911 | r-grid>r-cell[span-s$="+21"], 912 | r-grid>r-cell[span-s$="-20"], 913 | r-grid>r-cell[span-s="21"] { 914 | --grid-ce: 21 915 | } 916 | r-grid>r-cell[span-s$="+22"], 917 | r-grid>r-cell[span-s$="-21"], 918 | r-grid>r-cell[span-s="22"] { 919 | --grid-ce: 22 920 | } 921 | r-grid>r-cell[span-s$="+23"], 922 | r-grid>r-cell[span-s$="-22"], 923 | r-grid>r-cell[span-s="23"] { 924 | --grid-ce: 23 925 | } 926 | r-grid>r-cell[span-s$="+24"], 927 | r-grid>r-cell[span-s$="-23"], 928 | r-grid>r-cell[span-s="24"] { 929 | --grid-ce: 24 930 | } 931 | r-grid>r-cell[span-s$="+25"], 932 | r-grid>r-cell[span-s$="-24"], 933 | r-grid>r-cell[span-s="25"] { 934 | --grid-ce: 25 935 | } 936 | r-grid>r-cell[span-s$="+26"], 937 | r-grid>r-cell[span-s$="-25"], 938 | r-grid>r-cell[span-s="26"] { 939 | --grid-ce: 26 940 | } 941 | r-grid>r-cell[span-s$="+27"], 942 | r-grid>r-cell[span-s$="-26"], 943 | r-grid>r-cell[span-s="27"] { 944 | --grid-ce: 27 945 | } 946 | r-grid>r-cell[span-s$="+28"], 947 | r-grid>r-cell[span-s$="-27"], 948 | r-grid>r-cell[span-s="28"] { 949 | --grid-ce: 28 950 | } 951 | r-grid>r-cell[span-s$="+29"], 952 | r-grid>r-cell[span-s$="-28"], 953 | r-grid>r-cell[span-s="29"] { 954 | --grid-ce: 29 955 | } 956 | r-grid>r-cell[span-s$="+30"], 957 | r-grid>r-cell[span-s$="-29"], 958 | r-grid>r-cell[span-s="30"] { 959 | --grid-ce: 30 960 | } 961 | r-grid>r-cell[span-s$="-30"] { 962 | --grid-ce: 31 963 | } 964 | r-grid>r-cell[span-s] { 965 | grid-column-end: span var(--grid-ce) 966 | } 967 | r-grid>r-cell[span-s*="+"], 968 | r-grid>r-cell[span-s*="-"], 969 | r-grid>r-cell[span-s*=".."] { 970 | grid-column-start: var(--grid-cs) 971 | } 972 | r-grid>r-cell[span-s*="-"], 973 | r-grid>r-cell[span-s*=".."] { 974 | grid-column-end: var(--grid-ce) 975 | } 976 | r-grid>r-cell[span-s=row] { 977 | grid-column: 1/-1 978 | } 979 | } 980 | 981 | @media only screen and (min-width:1599px) { 982 | r-grid[columns-l="1"] { 983 | --grid-tc: repeat(1, 1fr) 984 | } 985 | r-grid[columns-l="2"] { 986 | --grid-tc: repeat(2, 1fr) 987 | } 988 | r-grid[columns-l="3"] { 989 | --grid-tc: repeat(3, 1fr) 990 | } 991 | r-grid[columns-l="4"] { 992 | --grid-tc: repeat(4, 1fr) 993 | } 994 | r-grid[columns-l="5"] { 995 | --grid-tc: repeat(5, 1fr) 996 | } 997 | r-grid[columns-l="6"] { 998 | --grid-tc: repeat(6, 1fr) 999 | } 1000 | r-grid[columns-l="7"] { 1001 | --grid-tc: repeat(7, 1fr) 1002 | } 1003 | r-grid[columns-l="8"] { 1004 | --grid-tc: repeat(8, 1fr) 1005 | } 1006 | r-grid[columns-l="9"] { 1007 | --grid-tc: repeat(9, 1fr) 1008 | } 1009 | r-grid[columns-l="10"] { 1010 | --grid-tc: repeat(10, 1fr) 1011 | } 1012 | r-grid[columns-l="11"] { 1013 | --grid-tc: repeat(11, 1fr) 1014 | } 1015 | r-grid[columns-l="12"] { 1016 | --grid-tc: repeat(12, 1fr) 1017 | } 1018 | r-grid[columns-l="13"] { 1019 | --grid-tc: repeat(13, 1fr) 1020 | } 1021 | r-grid[columns-l="14"] { 1022 | --grid-tc: repeat(14, 1fr) 1023 | } 1024 | r-grid[columns-l="15"] { 1025 | --grid-tc: repeat(15, 1fr) 1026 | } 1027 | r-grid[columns-l="16"] { 1028 | --grid-tc: repeat(16, 1fr) 1029 | } 1030 | r-grid[columns-l="17"] { 1031 | --grid-tc: repeat(17, 1fr) 1032 | } 1033 | r-grid[columns-l="18"] { 1034 | --grid-tc: repeat(18, 1fr) 1035 | } 1036 | r-grid[columns-l="19"] { 1037 | --grid-tc: repeat(19, 1fr) 1038 | } 1039 | r-grid[columns-l="20"] { 1040 | --grid-tc: repeat(20, 1fr) 1041 | } 1042 | r-grid[columns-l="21"] { 1043 | --grid-tc: repeat(21, 1fr) 1044 | } 1045 | r-grid[columns-l="22"] { 1046 | --grid-tc: repeat(22, 1fr) 1047 | } 1048 | r-grid[columns-l="23"] { 1049 | --grid-tc: repeat(23, 1fr) 1050 | } 1051 | r-grid[columns-l="24"] { 1052 | --grid-tc: repeat(24, 1fr) 1053 | } 1054 | r-grid[columns-l="25"] { 1055 | --grid-tc: repeat(25, 1fr) 1056 | } 1057 | r-grid[columns-l="26"] { 1058 | --grid-tc: repeat(26, 1fr) 1059 | } 1060 | r-grid[columns-l="27"] { 1061 | --grid-tc: repeat(27, 1fr) 1062 | } 1063 | r-grid[columns-l="28"] { 1064 | --grid-tc: repeat(28, 1fr) 1065 | } 1066 | r-grid[columns-l="29"] { 1067 | --grid-tc: repeat(29, 1fr) 1068 | } 1069 | r-grid[columns-l="30"] { 1070 | --grid-tc: repeat(30, 1fr) 1071 | } 1072 | r-grid>r-cell[span-l^="1"] { 1073 | --grid-cs: 1 1074 | } 1075 | r-grid>r-cell[span-l^="2"] { 1076 | --grid-cs: 2 1077 | } 1078 | r-grid>r-cell[span-l^="3"] { 1079 | --grid-cs: 3 1080 | } 1081 | r-grid>r-cell[span-l^="4"] { 1082 | --grid-cs: 4 1083 | } 1084 | r-grid>r-cell[span-l^="5"] { 1085 | --grid-cs: 5 1086 | } 1087 | r-grid>r-cell[span-l^="6"] { 1088 | --grid-cs: 6 1089 | } 1090 | r-grid>r-cell[span-l^="7"] { 1091 | --grid-cs: 7 1092 | } 1093 | r-grid>r-cell[span-l^="8"] { 1094 | --grid-cs: 8 1095 | } 1096 | r-grid>r-cell[span-l^="9"] { 1097 | --grid-cs: 9 1098 | } 1099 | r-grid>r-cell[span-l^="10"] { 1100 | --grid-cs: 10 1101 | } 1102 | r-grid>r-cell[span-l^="11"] { 1103 | --grid-cs: 11 1104 | } 1105 | r-grid>r-cell[span-l^="12"] { 1106 | --grid-cs: 12 1107 | } 1108 | r-grid>r-cell[span-l^="13"] { 1109 | --grid-cs: 13 1110 | } 1111 | r-grid>r-cell[span-l^="14"] { 1112 | --grid-cs: 14 1113 | } 1114 | r-grid>r-cell[span-l^="15"] { 1115 | --grid-cs: 15 1116 | } 1117 | r-grid>r-cell[span-l^="16"] { 1118 | --grid-cs: 16 1119 | } 1120 | r-grid>r-cell[span-l^="17"] { 1121 | --grid-cs: 17 1122 | } 1123 | r-grid>r-cell[span-l^="18"] { 1124 | --grid-cs: 18 1125 | } 1126 | r-grid>r-cell[span-l^="19"] { 1127 | --grid-cs: 19 1128 | } 1129 | r-grid>r-cell[span-l^="20"] { 1130 | --grid-cs: 20 1131 | } 1132 | r-grid>r-cell[span-l^="21"] { 1133 | --grid-cs: 21 1134 | } 1135 | r-grid>r-cell[span-l^="22"] { 1136 | --grid-cs: 22 1137 | } 1138 | r-grid>r-cell[span-l^="23"] { 1139 | --grid-cs: 23 1140 | } 1141 | r-grid>r-cell[span-l^="24"] { 1142 | --grid-cs: 24 1143 | } 1144 | r-grid>r-cell[span-l^="25"] { 1145 | --grid-cs: 25 1146 | } 1147 | r-grid>r-cell[span-l^="26"] { 1148 | --grid-cs: 26 1149 | } 1150 | r-grid>r-cell[span-l^="27"] { 1151 | --grid-cs: 27 1152 | } 1153 | r-grid>r-cell[span-l^="28"] { 1154 | --grid-cs: 28 1155 | } 1156 | r-grid>r-cell[span-l^="29"] { 1157 | --grid-cs: 29 1158 | } 1159 | r-grid>r-cell[span-l^="30"] { 1160 | --grid-cs: 30 1161 | } 1162 | r-grid>r-cell[span-l$="+1"], 1163 | r-grid>r-cell[span-l="1"] { 1164 | --grid-ce: 1 1165 | } 1166 | r-grid>r-cell[span-l$="+2"], 1167 | r-grid>r-cell[span-l$="-1"], 1168 | r-grid>r-cell[span-l="2"] { 1169 | --grid-ce: 2 1170 | } 1171 | r-grid>r-cell[span-l$="+3"], 1172 | r-grid>r-cell[span-l$="-2"], 1173 | r-grid>r-cell[span-l="3"] { 1174 | --grid-ce: 3 1175 | } 1176 | r-grid>r-cell[span-l$="+4"], 1177 | r-grid>r-cell[span-l$="-3"], 1178 | r-grid>r-cell[span-l="4"] { 1179 | --grid-ce: 4 1180 | } 1181 | r-grid>r-cell[span-l$="+5"], 1182 | r-grid>r-cell[span-l$="-4"], 1183 | r-grid>r-cell[span-l="5"] { 1184 | --grid-ce: 5 1185 | } 1186 | r-grid>r-cell[span-l$="+6"], 1187 | r-grid>r-cell[span-l$="-5"], 1188 | r-grid>r-cell[span-l="6"] { 1189 | --grid-ce: 6 1190 | } 1191 | r-grid>r-cell[span-l$="+7"], 1192 | r-grid>r-cell[span-l$="-6"], 1193 | r-grid>r-cell[span-l="7"] { 1194 | --grid-ce: 7 1195 | } 1196 | r-grid>r-cell[span-l$="+8"], 1197 | r-grid>r-cell[span-l$="-7"], 1198 | r-grid>r-cell[span-l="8"] { 1199 | --grid-ce: 8 1200 | } 1201 | r-grid>r-cell[span-l$="+9"], 1202 | r-grid>r-cell[span-l$="-8"], 1203 | r-grid>r-cell[span-l="9"] { 1204 | --grid-ce: 9 1205 | } 1206 | r-grid>r-cell[span-l$="+10"], 1207 | r-grid>r-cell[span-l$="-9"], 1208 | r-grid>r-cell[span-l="10"] { 1209 | --grid-ce: 10 1210 | } 1211 | r-grid>r-cell[span-l$="+11"], 1212 | r-grid>r-cell[span-l$="-10"], 1213 | r-grid>r-cell[span-l="11"] { 1214 | --grid-ce: 11 1215 | } 1216 | r-grid>r-cell[span-l$="+12"], 1217 | r-grid>r-cell[span-l$="-11"], 1218 | r-grid>r-cell[span-l="12"] { 1219 | --grid-ce: 12 1220 | } 1221 | r-grid>r-cell[span-l$="+13"], 1222 | r-grid>r-cell[span-l$="-12"], 1223 | r-grid>r-cell[span-l="13"] { 1224 | --grid-ce: 13 1225 | } 1226 | r-grid>r-cell[span-l$="+14"], 1227 | r-grid>r-cell[span-l$="-13"], 1228 | r-grid>r-cell[span-l="14"] { 1229 | --grid-ce: 14 1230 | } 1231 | r-grid>r-cell[span-l$="+15"], 1232 | r-grid>r-cell[span-l$="-14"], 1233 | r-grid>r-cell[span-l="15"] { 1234 | --grid-ce: 15 1235 | } 1236 | r-grid>r-cell[span-l$="+16"], 1237 | r-grid>r-cell[span-l$="-15"], 1238 | r-grid>r-cell[span-l="16"] { 1239 | --grid-ce: 16 1240 | } 1241 | r-grid>r-cell[span-l$="+17"], 1242 | r-grid>r-cell[span-l$="-16"], 1243 | r-grid>r-cell[span-l="17"] { 1244 | --grid-ce: 17 1245 | } 1246 | r-grid>r-cell[span-l$="+18"], 1247 | r-grid>r-cell[span-l$="-17"], 1248 | r-grid>r-cell[span-l="18"] { 1249 | --grid-ce: 18 1250 | } 1251 | r-grid>r-cell[span-l$="+19"], 1252 | r-grid>r-cell[span-l$="-18"], 1253 | r-grid>r-cell[span-l="19"] { 1254 | --grid-ce: 19 1255 | } 1256 | r-grid>r-cell[span-l$="+20"], 1257 | r-grid>r-cell[span-l$="-19"], 1258 | r-grid>r-cell[span-l="20"] { 1259 | --grid-ce: 20 1260 | } 1261 | r-grid>r-cell[span-l$="+21"], 1262 | r-grid>r-cell[span-l$="-20"], 1263 | r-grid>r-cell[span-l="21"] { 1264 | --grid-ce: 21 1265 | } 1266 | r-grid>r-cell[span-l$="+22"], 1267 | r-grid>r-cell[span-l$="-21"], 1268 | r-grid>r-cell[span-l="22"] { 1269 | --grid-ce: 22 1270 | } 1271 | r-grid>r-cell[span-l$="+23"], 1272 | r-grid>r-cell[span-l$="-22"], 1273 | r-grid>r-cell[span-l="23"] { 1274 | --grid-ce: 23 1275 | } 1276 | r-grid>r-cell[span-l$="+24"], 1277 | r-grid>r-cell[span-l$="-23"], 1278 | r-grid>r-cell[span-l="24"] { 1279 | --grid-ce: 24 1280 | } 1281 | r-grid>r-cell[span-l$="+25"], 1282 | r-grid>r-cell[span-l$="-24"], 1283 | r-grid>r-cell[span-l="25"] { 1284 | --grid-ce: 25 1285 | } 1286 | r-grid>r-cell[span-l$="+26"], 1287 | r-grid>r-cell[span-l$="-25"], 1288 | r-grid>r-cell[span-l="26"] { 1289 | --grid-ce: 26 1290 | } 1291 | r-grid>r-cell[span-l$="+27"], 1292 | r-grid>r-cell[span-l$="-26"], 1293 | r-grid>r-cell[span-l="27"] { 1294 | --grid-ce: 27 1295 | } 1296 | r-grid>r-cell[span-l$="+28"], 1297 | r-grid>r-cell[span-l$="-27"], 1298 | r-grid>r-cell[span-l="28"] { 1299 | --grid-ce: 28 1300 | } 1301 | r-grid>r-cell[span-l$="+29"], 1302 | r-grid>r-cell[span-l$="-28"], 1303 | r-grid>r-cell[span-l="29"] { 1304 | --grid-ce: 29 1305 | } 1306 | r-grid>r-cell[span-l$="+30"], 1307 | r-grid>r-cell[span-l$="-29"], 1308 | r-grid>r-cell[span-l="30"] { 1309 | --grid-ce: 30 1310 | } 1311 | r-grid>r-cell[span-l$="-30"] { 1312 | --grid-ce: 31 1313 | } 1314 | r-grid>r-cell[span-l] { 1315 | grid-column-end: span var(--grid-ce) 1316 | } 1317 | r-grid>r-cell[span-l*="+"], 1318 | r-grid>r-cell[span-l*="-"], 1319 | r-grid>r-cell[span-l*=".."] { 1320 | grid-column-start: var(--grid-cs) 1321 | } 1322 | r-grid>r-cell[span-l*="-"], 1323 | r-grid>r-cell[span-l*=".."] { 1324 | grid-column-end: var(--grid-ce) 1325 | } 1326 | r-grid>r-cell[span-l=row] { 1327 | grid-column: 1/-1 1328 | } 1329 | } 1330 | 1331 | r-grid.debug>* { 1332 | --color: rgba(248, 110, 91, 0.3); 1333 | background-image: -webkit-gradient(linear, left top, left bottom, from(var(--color)), to(var(--color))); 1334 | background-image: linear-gradient(180deg, var(--color) 0, var(--color)) 1335 | } 1336 | 1337 | r-grid.debug>:nth-child(6n+2) { 1338 | --color: rgba(103, 126, 208, 0.3) 1339 | } 1340 | 1341 | r-grid.debug>:nth-child(6n+3) { 1342 | --color: rgba(224, 174, 72, 0.3) 1343 | } 1344 | 1345 | r-grid.debug>:nth-child(6n+4) { 1346 | --color: rgba(77, 214, 115, 0.3) 1347 | } 1348 | 1349 | r-grid.debug>:nth-child(6n+5) { 1350 | --color: rgba(217, 103, 219, 0.3) 1351 | } 1352 | 1353 | r-grid.debug>:nth-child(6n+6) { 1354 | --color: rgba(94, 204, 211, 0.3) 1355 | } 1356 | 1357 | r-grid.debug>:nth-child(6n+7) { 1358 | --color: rgba(248, 110, 91, 0.3) 1359 | } 1360 | 1361 | html { 1362 | font-family: var(--sansFont), -system-ui, system-ui, sans-serif; 1363 | font-size: var(--fontSize); 1364 | line-height: var(--lineHeight); 1365 | background: var(--background-color); 1366 | color: var(--foreground-color); 1367 | letter-spacing: -.01em; 1368 | -webkit-text-size-adjust: 100%; 1369 | -moz-text-size-adjust: 100%; 1370 | -ms-text-size-adjust: 100%; 1371 | text-size-adjust: 100%; 1372 | font-variant-ligatures: contextual common-ligatures; 1373 | font-feature-settings: "kern" 1, "liga" 1, "calt" 1, "cv10" 1 1374 | } 1375 | 1376 | body { 1377 | -webkit-overflow-scrolling: touch; 1378 | scroll-behavior: smooth; 1379 | overflow-x: hidden; 1380 | padding: calc(var(--lineHeight)*2); 1381 | padding-bottom: calc(var(--lineHeight)*3) 1382 | } 1383 | 1384 | @media only screen and (max-width:720px) { 1385 | body { 1386 | padding: var(--lineHeight); 1387 | padding-bottom: calc(var(--lineHeight)*2) 1388 | } 1389 | } 1390 | 1391 | [flow-cols-l], 1392 | [flow-cols-s], 1393 | [flow-cols] { 1394 | -webkit-column-gap: var(--columnGap); 1395 | -moz-column-gap: var(--columnGap); 1396 | column-gap: var(--columnGap); 1397 | -webkit-column-fill: balance; 1398 | -moz-column-fill: balance; 1399 | column-fill: balance 1400 | } 1401 | 1402 | [flow-cols="1"] { 1403 | -webkit-column-count: 1; 1404 | -moz-column-count: 1; 1405 | column-count: 1 1406 | } 1407 | 1408 | [flow-cols="2"] { 1409 | -webkit-column-count: 2; 1410 | -moz-column-count: 2; 1411 | column-count: 2 1412 | } 1413 | 1414 | [flow-cols="3"] { 1415 | -webkit-column-count: 3; 1416 | -moz-column-count: 3; 1417 | column-count: 3 1418 | } 1419 | 1420 | [flow-cols="4"] { 1421 | -webkit-column-count: 4; 1422 | -moz-column-count: 4; 1423 | column-count: 4 1424 | } 1425 | 1426 | [flow-cols="5"] { 1427 | -webkit-column-count: 5; 1428 | -moz-column-count: 5; 1429 | column-count: 5 1430 | } 1431 | 1432 | [flow-cols="6"] { 1433 | -webkit-column-count: 6; 1434 | -moz-column-count: 6; 1435 | column-count: 6 1436 | } 1437 | 1438 | [flow-cols="7"] { 1439 | -webkit-column-count: 7; 1440 | -moz-column-count: 7; 1441 | column-count: 7 1442 | } 1443 | 1444 | [flow-cols="8"] { 1445 | -webkit-column-count: 8; 1446 | -moz-column-count: 8; 1447 | column-count: 8 1448 | } 1449 | 1450 | @media only screen and (max-width:720px) { 1451 | [flow-cols-s="1"] { 1452 | -webkit-column-count: 1; 1453 | -moz-column-count: 1; 1454 | column-count: 1 1455 | } 1456 | [flow-cols-s="2"] { 1457 | -webkit-column-count: 2; 1458 | -moz-column-count: 2; 1459 | column-count: 2 1460 | } 1461 | [flow-cols-s="3"] { 1462 | -webkit-column-count: 3; 1463 | -moz-column-count: 3; 1464 | column-count: 3 1465 | } 1466 | [flow-cols-s="4"] { 1467 | -webkit-column-count: 4; 1468 | -moz-column-count: 4; 1469 | column-count: 4 1470 | } 1471 | [flow-cols-s="5"] { 1472 | -webkit-column-count: 5; 1473 | -moz-column-count: 5; 1474 | column-count: 5 1475 | } 1476 | [flow-cols-s="6"] { 1477 | -webkit-column-count: 6; 1478 | -moz-column-count: 6; 1479 | column-count: 6 1480 | } 1481 | [flow-cols-s="7"] { 1482 | -webkit-column-count: 7; 1483 | -moz-column-count: 7; 1484 | column-count: 7 1485 | } 1486 | [flow-cols-s="8"] { 1487 | -webkit-column-count: 8; 1488 | -moz-column-count: 8; 1489 | column-count: 8 1490 | } 1491 | } 1492 | 1493 | @media only screen and (min-width:1599px) { 1494 | [flow-cols-l="1"] { 1495 | -webkit-column-count: 1; 1496 | -moz-column-count: 1; 1497 | column-count: 1 1498 | } 1499 | [flow-cols-l="2"] { 1500 | -webkit-column-count: 2; 1501 | -moz-column-count: 2; 1502 | column-count: 2 1503 | } 1504 | [flow-cols-l="3"] { 1505 | -webkit-column-count: 3; 1506 | -moz-column-count: 3; 1507 | column-count: 3 1508 | } 1509 | [flow-cols-l="4"] { 1510 | -webkit-column-count: 4; 1511 | -moz-column-count: 4; 1512 | column-count: 4 1513 | } 1514 | [flow-cols-l="5"] { 1515 | -webkit-column-count: 5; 1516 | -moz-column-count: 5; 1517 | column-count: 5 1518 | } 1519 | [flow-cols-l="6"] { 1520 | -webkit-column-count: 6; 1521 | -moz-column-count: 6; 1522 | column-count: 6 1523 | } 1524 | [flow-cols-l="7"] { 1525 | -webkit-column-count: 7; 1526 | -moz-column-count: 7; 1527 | column-count: 7 1528 | } 1529 | [flow-cols-l="8"] { 1530 | -webkit-column-count: 8; 1531 | -moz-column-count: 8; 1532 | column-count: 8 1533 | } 1534 | } 1535 | 1536 | address, 1537 | article, 1538 | aside, 1539 | blockquote, 1540 | dd, 1541 | dl, 1542 | dt, 1543 | fieldset, 1544 | figure, 1545 | form, 1546 | h1, 1547 | h2, 1548 | h3, 1549 | h4, 1550 | h5, 1551 | h6, 1552 | li, 1553 | nav, 1554 | ol, 1555 | p, 1556 | pre, 1557 | r-grid, 1558 | table, 1559 | tfoot, 1560 | ul, 1561 | video { 1562 | margin-top: var(--blockSpacingTop); 1563 | margin-bottom: var(--blockSpacingBottom) 1564 | } 1565 | 1566 | :first-child { 1567 | margin-top: unset 1568 | } 1569 | 1570 | :last-child { 1571 | margin-bottom: unset 1572 | } 1573 | 1574 | hr:first-child { 1575 | margin-top: calc(var(--hrThickness)/-2); 1576 | margin-bottom: calc(var(--lineHeight) - var(--hrThickness)/2) 1577 | } 1578 | 1579 | hr:last-child { 1580 | margin-bottom: calc(var(--hrThickness)/-2) 1581 | } 1582 | 1583 | hr, 1584 | hr:last-child, 1585 | hr:only-child { 1586 | margin-top: calc(var(--lineHeight) - var(--hrThickness)/2) 1587 | } 1588 | 1589 | hr, 1590 | hr:only-child { 1591 | border: none; 1592 | background: var(--foreground-color); 1593 | height: var(--hrThickness); 1594 | margin-bottom: calc(var(--lineHeight) - var(--hrThickness)/2) 1595 | } 1596 | 1597 | *+hr:last-child { 1598 | margin-top: calc(var(--hrThickness)/-2) 1599 | } 1600 | 1601 | hr:not(:first-child) { 1602 | margin-top: var(--lineHeight); 1603 | margin-bottom: calc(var(--lineHeight) - var(--hrThickness)) 1604 | } 1605 | 1606 | r-grid>hr { 1607 | grid-column: 1/-1 1608 | } 1609 | 1610 | r-grid>hr, 1611 | r-grid>hr:not(:first-child):not(:last-child) { 1612 | margin-top: calc(var(--lineHeight) - var(--hrThickness)); 1613 | margin-bottom: 0 1614 | } 1615 | 1616 | .bold, 1617 | b, 1618 | strong { 1619 | font-weight: 600 1620 | } 1621 | 1622 | .italic, 1623 | em, 1624 | i { 1625 | font-style: italic 1626 | } 1627 | 1628 | .code, 1629 | .monospace, 1630 | code, 1631 | pre, 1632 | tt { 1633 | font-family: var(--monoFont), Inconsolata, Menlo, monospace; 1634 | font-weight: 430; 1635 | word-wrap: break-word; 1636 | white-space: pre-wrap 1637 | } 1638 | 1639 | b .code, 1640 | b .monospace, 1641 | b code, 1642 | b pre, 1643 | b tt { 1644 | font-weight: 600 1645 | } 1646 | 1647 | .code b, 1648 | .monospace b, 1649 | code b, 1650 | pre b, 1651 | tt b { 1652 | font-weight: 600; 1653 | font-weight: 580 1654 | } 1655 | 1656 | pre { 1657 | overflow-x: auto; 1658 | display: block 1659 | } 1660 | 1661 | pre, 1662 | pre code, 1663 | pre tt { 1664 | white-space: pre; 1665 | word-wrap: normal 1666 | } 1667 | 1668 | h { 1669 | display: block; 1670 | -moz-appearance: none; 1671 | appearance: none; 1672 | -webkit-appearance: none 1673 | } 1674 | 1675 | .h1, 1676 | h, 1677 | h1 { 1678 | font-weight: 720; 1679 | letter-spacing: -.05em; 1680 | font-size: var(--h1-size); 1681 | line-height: calc(var(--lineHeight)*2); 1682 | margin-left: calc(var(--h1-size)/-22); 1683 | margin-top: calc(var(--lineHeight)*2); 1684 | margin-bottom: var(--lineHeight); 1685 | word-break: break-word 1686 | } 1687 | 1688 | h1.single-line { 1689 | margin-top: var(--lineHeight); 1690 | padding-top: calc(var(--lineHeight)*0.5) 1691 | } 1692 | 1693 | h1.single-line, 1694 | h1.single-line:first-child { 1695 | padding-bottom: calc(var(--lineHeight)*0.5) 1696 | } 1697 | 1698 | h1.single-line:first-child { 1699 | margin-top: 0 1700 | } 1701 | 1702 | .h2, 1703 | h2 { 1704 | font-weight: 700; 1705 | letter-spacing: -.03em; 1706 | font-size: var(--h2-size); 1707 | line-height: calc(var(--lineHeight)*2); 1708 | margin-left: calc(var(--h2-size)/-26); 1709 | margin-bottom: var(--lineHeight) 1710 | } 1711 | 1712 | *+h2, 1713 | h2.single-line { 1714 | margin-top: var(--lineHeight); 1715 | padding-top: calc(var(--lineHeight)*0.5); 1716 | padding-bottom: calc(var(--lineHeight)*0.5); 1717 | margin-bottom: 0 1718 | } 1719 | 1720 | h2.single-line:first-child { 1721 | margin-top: unset 1722 | } 1723 | 1724 | .h3, 1725 | .h4, 1726 | h3, 1727 | h4 { 1728 | font-weight: 700; 1729 | letter-spacing: -.02em; 1730 | font-size: var(--h3-size); 1731 | padding-top: calc(var(--baseline)*0.75); 1732 | padding-bottom: calc(var(--baseline)*0.25); 1733 | margin-bottom: var(--baseline) 1734 | } 1735 | 1736 | .h4, 1737 | h4 { 1738 | font-weight: 700; 1739 | letter-spacing: -.012em; 1740 | font-size: var(--h4-size) 1741 | } 1742 | 1743 | h3.single-line, 1744 | h4.single-line { 1745 | padding-bottom: calc(var(--baseline)*1.25); 1746 | margin-bottom: 0 1747 | } 1748 | 1749 | h3+h1, 1750 | h3+h1.single-line, 1751 | h4+h1, 1752 | h4+h1.single-line { 1753 | margin-top: calc(var(--baseline)*3) 1754 | } 1755 | 1756 | h3.single-line+h1, 1757 | h3.single-line+h1.single-line, 1758 | h3.single-line+h2, 1759 | h3.single-line+h2.single-line, 1760 | h4.single-line+h1, 1761 | h4.single-line+h1.single-line, 1762 | h4.single-line+h2, 1763 | h4.single-line+h2.single-line { 1764 | margin-top: var(--lineHeight) 1765 | } 1766 | 1767 | h3+h2, 1768 | h3+h2.single-line, 1769 | h4+h2, 1770 | h4+h2.single-line { 1771 | margin-top: var(--baseline) 1772 | } 1773 | 1774 | .h5, 1775 | .h6, 1776 | h5, 1777 | h6 { 1778 | font-weight: 670; 1779 | letter-spacing: -.015em 1780 | } 1781 | 1782 | .h5, 1783 | .h6, 1784 | h5, 1785 | h6, 1786 | r-grid>r-cell.h1, 1787 | r-grid>r-cell.h2, 1788 | r-grid>r-cell.h3, 1789 | r-grid>r-cell.h4, 1790 | r-grid>r-cell.h5, 1791 | r-grid>r-cell.h6 { 1792 | margin-bottom: 0 1793 | } 1794 | 1795 | .h1.large, 1796 | h1.large { 1797 | --h1-size: 4rem; 1798 | line-height: calc(var(--lineHeight)*3); 1799 | font-weight: 730 1800 | } 1801 | 1802 | .h1.xlarge, 1803 | h1.xlarge { 1804 | --h1-size: 5.5rem; 1805 | line-height: calc(var(--lineHeight)*4); 1806 | font-weight: 740 1807 | } 1808 | 1809 | .h1.xxlarge, 1810 | h1.xxlarge { 1811 | --h1-size: 7.5rem; 1812 | line-height: calc(var(--lineHeight)*5); 1813 | font-weight: 750 1814 | } 1815 | 1816 | .h1.xxxlarge, 1817 | h1.xxxlarge { 1818 | --h1-size: 10.5rem; 1819 | line-height: calc(var(--lineHeight)*7); 1820 | font-weight: 760 1821 | } 1822 | 1823 | .small { 1824 | font-size: .85rem; 1825 | line-height: var(--lineHeight) 1826 | } 1827 | 1828 | .xsmall { 1829 | font-size: .8em; 1830 | line-height: calc(var(--lineHeight)*0.75); 1831 | padding-top: calc(var(--lineHeight)*0.25) 1832 | } 1833 | 1834 | .xxsmall { 1835 | font-size: .65em; 1836 | line-height: calc(var(--lineHeight)*0.7); 1837 | padding-top: calc(var(--lineHeight)*0.3) 1838 | } 1839 | 1840 | .xxxsmall { 1841 | font-size: .5em; 1842 | line-height: calc(var(--lineHeight)*0.5); 1843 | padding-bottom: calc(var(--lineHeight)*0.25) 1844 | } 1845 | 1846 | a { 1847 | text-decoration: underline; 1848 | -webkit-text-decoration: underline rgba(0, 0, 0, .3); 1849 | text-decoration: underline rgba(0, 0, 0, .3); 1850 | white-space: nowrap 1851 | } 1852 | 1853 | a:hover { 1854 | color: var(--blue) 1855 | } 1856 | 1857 | .h1>a, 1858 | .h2>a, 1859 | .h3>a, 1860 | .h4>a, 1861 | .h5>a, 1862 | .h6>a, 1863 | h1>a, 1864 | h2>a, 1865 | h3>a, 1866 | h4>a, 1867 | h5>a, 1868 | h6>a { 1869 | text-decoration: none 1870 | } 1871 | 1872 | .h1>a:hover, 1873 | .h2>a:hover, 1874 | .h3>a:hover, 1875 | .h4>a:hover, 1876 | .h5>a:hover, 1877 | .h6>a:hover, 1878 | h1>a:hover, 1879 | h2>a:hover, 1880 | h3>a:hover, 1881 | h4>a:hover, 1882 | h5>a:hover, 1883 | h6>a:hover { 1884 | text-decoration: underline; 1885 | -webkit-text-decoration: underline rgba(0, 0, 0, .3); 1886 | text-decoration: underline rgba(0, 0, 0, .3); 1887 | color: inherit 1888 | } 1889 | 1890 | img, 1891 | img:first-child, 1892 | img:last-child { 1893 | display: block; 1894 | margin-top: var(--baseline); 1895 | margin-bottom: var(--baseline) 1896 | } 1897 | 1898 | img:only-child { 1899 | margin: 0 1900 | } 1901 | 1902 | *+img { 1903 | margin-top: calc(var(--baseline)*-1) 1904 | } 1905 | 1906 | img.cover, 1907 | img.fill { 1908 | -o-object-fit: cover; 1909 | object-fit: cover 1910 | } 1911 | 1912 | r-grid>r-cell>img, 1913 | r-grid>r-cell>p>img { 1914 | -o-object-fit: contain; 1915 | object-fit: contain; 1916 | max-width: 100% 1917 | } 1918 | 1919 | r-grid { 1920 | grid-column-gap: var(--columnGap); 1921 | grid-row-gap: var(--rowGap) 1922 | } 1923 | 1924 | r-grid.compact { 1925 | grid-row-gap: 0 1926 | } 1927 | 1928 | li { 1929 | margin-left: .2em; 1930 | margin-bottom: var(--baseline) 1931 | } 1932 | 1933 | li>p+ol, 1934 | li>p+ul { 1935 | margin-top: calc(var(--baseline)*-1) 1936 | } 1937 | 1938 | li.task-list-item { 1939 | list-style-type: none 1940 | } 1941 | 1942 | li.task-list-item>input[type=checkbox] { 1943 | list-style: none; 1944 | margin-right: .5em; 1945 | margin-left: -1.4em; 1946 | background: none; 1947 | -webkit-appearance: none; 1948 | -moz-appearance: none; 1949 | appearance: none; 1950 | width: 1.5em; 1951 | height: var(--baseline); 1952 | display: inline-block; 1953 | position: relative; 1954 | border: none; 1955 | opacity: 1; 1956 | --outlineSvgUrl: url('data:image/svg+xml;utf8,'); 1957 | --checkSvgUrl: url('data:image/svg+xml;utf8,') 1958 | } 1959 | 1960 | li.task-list-item>input[type=checkbox]:after, 1961 | li.task-list-item>input[type=checkbox]:before { 1962 | display: block; 1963 | position: absolute; 1964 | content: "X"; 1965 | color: transparent; 1966 | left: 0; 1967 | top: -.25em; 1968 | bottom: -.25em; 1969 | width: 1.1em; 1970 | background-size: contain; 1971 | background-repeat: no-repeat; 1972 | background-position: 50%; 1973 | --webkit-touch-callout: none 1974 | } 1975 | 1976 | li.task-list-item>input[type=checkbox]:after { 1977 | background-image: var(--outlineSvgUrl) 1978 | } 1979 | 1980 | li.task-list-item>input[type=checkbox][checked]:before { 1981 | background-image: var(--checkSvgUrl) 1982 | } 1983 | 1984 | @supports ((-webkit-mask-image:linear-gradient(rgba(0, 0, 0, 1.0), red)) or (mask-image:linear-gradient(rgba(0, 0, 0, 1.0), red))) { 1985 | li.task-list-item>input[type=checkbox]:after, 1986 | li.task-list-item>input[type=checkbox]:before { 1987 | -webkit-mask-size: contain; 1988 | mask-size: contain; 1989 | -webkit-mask-repeat: no-repeat; 1990 | mask-repeat: no-repeat; 1991 | -webkit-mask-position: center center; 1992 | mask-position: center center 1993 | } 1994 | li.task-list-item>input[type=checkbox]:after { 1995 | background: var(--foreground-color); 1996 | -webkit-mask-image: var(--outlineSvgUrl); 1997 | mask-image: var(--outlineSvgUrl) 1998 | } 1999 | li.task-list-item>input[type=checkbox][checked]:before { 2000 | background: var(--foreground-color); 2001 | -webkit-mask-image: var(--checkSvgUrl); 2002 | mask-image: var(--checkSvgUrl) 2003 | } 2004 | } 2005 | 2006 | .compact>li>p+ol, 2007 | .compact>li>p+ul { 2008 | margin-top: calc(var(--blockSpacingBottom)*-1) 2009 | } 2010 | 2011 | ol, 2012 | ul { 2013 | list-style-position: outside; 2014 | --list-indentation: 2em 2015 | } 2016 | 2017 | ol.compact>li, 2018 | ul.compact>li { 2019 | margin-bottom: 0 2020 | } 2021 | 2022 | ul { 2023 | padding-left: 1.3em 2024 | } 2025 | 2026 | ol[start] { 2027 | -webkit-padding-start: var(--list-indentation); 2028 | padding-inline-start: var(--list-indentation) 2029 | } 2030 | 2031 | ol:not([start]) { 2032 | list-style: none; 2033 | counter-reset: ol-counter; 2034 | padding-left: var(--list-indentation) 2035 | } 2036 | 2037 | ol:not([start])>li { 2038 | counter-increment: ol-counter; 2039 | position: relative 2040 | } 2041 | 2042 | ol:not([start])>li:before { 2043 | content: counter(ol-counter) ". "; 2044 | font-weight: 500; 2045 | font-variant-numeric: tabular-nums; 2046 | position: absolute; 2047 | --space: 0.5em; 2048 | --width: calc(var(--list-indentation) - var(--space)); 2049 | left: calc(-1*(var(--width) + var(--space))); 2050 | width: var(--width); 2051 | height: var(--lineHeight); 2052 | text-align: left 2053 | } 2054 | 2055 | table { 2056 | --border-width: 1px; 2057 | --border-opacity: 0.15; 2058 | --border-color: rgba(var(--foreground-color-rgb), calc(var(--foreground-color-a)*var(--border-opacity))); 2059 | overflow: auto; 2060 | border-spacing: 0; 2061 | border-collapse: collapse; 2062 | border-top: var(--border-width) solid var(--border-color); 2063 | border-right: var(--border-width) solid var(--border-color); 2064 | position: relative; 2065 | margin-top: calc(var(--lineHeight)*1 + var(--border-width)*-1); 2066 | margin-bottom: calc(var(--lineHeight)*1.5) 2067 | } 2068 | 2069 | table:first-child { 2070 | margin-top: calc(var(--lineHeight)*0.5 + var(--border-width)*-1); 2071 | margin-bottom: calc(var(--lineHeight)*0.5) 2072 | } 2073 | 2074 | table * { 2075 | box-sizing: border-box 2076 | } 2077 | 2078 | table td, 2079 | table th { 2080 | position: relative; 2081 | padding: var(--baseline) 1em; 2082 | background-image: linear-gradient(90deg, var(--border-color), var(--border-color) 1px, transparent 0, transparent calc(var(--baseline)/2)); 2083 | background-repeat: no-repeat; 2084 | background-size: 100% 100%; 2085 | background-position: 0 -1px 2086 | } 2087 | 2088 | table td:after, 2089 | table th:after { 2090 | position: absolute; 2091 | left: 0; 2092 | bottom: 0; 2093 | right: 0; 2094 | height: var(--border-width); 2095 | background: var(--border-color); 2096 | content: "A"; 2097 | color: transparent; 2098 | pointer-events: none 2099 | } 2100 | 2101 | table th { 2102 | text-align: left; 2103 | font-weight: 600 2104 | } 2105 | 2106 | table th[align=center] { 2107 | text-align: center 2108 | } 2109 | 2110 | table th[align=right] { 2111 | text-align: right 2112 | } 2113 | 2114 | p+table { 2115 | margin-top: calc(var(--lineHeight)*1.5 + var(--border-width)*-1) 2116 | } 2117 | 2118 | @media only screen and (max-width:720px) { 2119 | .only-large-window { 2120 | display: none 2121 | } 2122 | } 2123 | 2124 | @media only screen and (min-width:601px) { 2125 | .only-small-window { 2126 | display: none 2127 | } 2128 | } 2129 | 2130 | :root { 2131 | --base-grid-color1: rgba(20, 230, 245, 0.3); 2132 | --base-grid-color2: hsla(0, 0%, 47.1%, 0.05) 2133 | } 2134 | 2135 | .show-base-grid { 2136 | background-image: repeating-linear-gradient(0deg, var(--base-grid-color2), var(--base-grid-color2) 1px, transparent 0, transparent calc(var(--baseline)/2), var(--base-grid-color1) calc(var(--baseline)/2), var(--base-grid-color1) calc(var(--baseline)/2 + 1px), transparent calc(var(--baseline)/2 + 1px), transparent var(--baseline)); 2137 | background-repeat: repeat-y; 2138 | background-size: 100% var(--baseline); 2139 | background-position: 0 .5px 2140 | } 2141 | 2142 | .single-line { 2143 | white-space: nowrap; 2144 | overflow: hidden; 2145 | text-overflow: ellipsis 2146 | } 2147 | 2148 | .block { 2149 | display: block 2150 | } 2151 | 2152 | .inline { 2153 | display: inline-block 2154 | } 2155 | 2156 | .flex-h { 2157 | -webkit-box-orient: horizontal; 2158 | flex-direction: row 2159 | } 2160 | 2161 | .flex-h, 2162 | .flex-v { 2163 | display: -webkit-box; 2164 | display: flex; 2165 | -webkit-box-direction: normal 2166 | } 2167 | 2168 | .flex-v { 2169 | -webkit-box-orient: vertical; 2170 | flex-direction: column 2171 | } 2172 | 2173 | .left { 2174 | text-align: left 2175 | } 2176 | 2177 | .right { 2178 | text-align: right 2179 | } 2180 | 2181 | .center { 2182 | text-align: center 2183 | } 2184 | 2185 | .flex-v.center { 2186 | align-self: center 2187 | } 2188 | 2189 | .flex-h .bottom { 2190 | align-self: flex-end 2191 | } 2192 | 2193 | img.top { 2194 | -o-object-position: center top; 2195 | object-position: center top; 2196 | align-self: center 2197 | } 2198 | 2199 | img.center { 2200 | -o-object-position: center center; 2201 | object-position: center center; 2202 | align-self: center 2203 | } 2204 | 2205 | img.bottom { 2206 | -o-object-position: center bottom; 2207 | object-position: center bottom; 2208 | align-self: center 2209 | } 2210 | 2211 | img.left.top { 2212 | -o-object-position: left top; 2213 | object-position: left top; 2214 | align-self: flex-start 2215 | } 2216 | 2217 | img.left.center { 2218 | -o-object-position: left center; 2219 | object-position: left center; 2220 | align-self: flex-start 2221 | } 2222 | 2223 | img.left.bottom { 2224 | -o-object-position: left bottom; 2225 | object-position: left bottom; 2226 | align-self: flex-start 2227 | } 2228 | 2229 | img.right.top { 2230 | -o-object-position: right top; 2231 | object-position: right top; 2232 | align-self: flex-end 2233 | } 2234 | 2235 | img.right.center { 2236 | -o-object-position: right center; 2237 | object-position: right center; 2238 | align-self: flex-end 2239 | } 2240 | 2241 | img.right.bottom { 2242 | -o-object-position: right bottom; 2243 | object-position: right bottom; 2244 | align-self: flex-end 2245 | } 2246 | 2247 | .padding0 { 2248 | padding: 0 2249 | } 2250 | 2251 | .padding1 { 2252 | padding: calc(var(--lineHeight)*1) 2253 | } 2254 | 2255 | .padding2 { 2256 | padding: calc(var(--lineHeight)*2) 2257 | } 2258 | 2259 | .padding3 { 2260 | padding: calc(var(--lineHeight)*3) 2261 | } 2262 | 2263 | .padding4 { 2264 | padding: calc(var(--lineHeight)*4) 2265 | } 2266 | 2267 | .padding5 { 2268 | padding: calc(var(--lineHeight)*5); 2269 | padding: calc(var(--lineHeight)*6); 2270 | padding: calc(var(--lineHeight)*7); 2271 | padding: calc(var(--lineHeight)*8) 2272 | } 2273 | 2274 | .margin0 { 2275 | margin: 0 2276 | } 2277 | 2278 | .margin1 { 2279 | margin: calc(var(--lineHeight)*1) 2280 | } 2281 | 2282 | .margin2 { 2283 | margin: calc(var(--lineHeight)*2) 2284 | } 2285 | 2286 | .margin3 { 2287 | margin: calc(var(--lineHeight)*3) 2288 | } 2289 | 2290 | .margin4 { 2291 | margin: calc(var(--lineHeight)*4) 2292 | } 2293 | 2294 | .margin5 { 2295 | margin: calc(var(--lineHeight)*5); 2296 | margin: calc(var(--lineHeight)*6); 2297 | margin: calc(var(--lineHeight)*7); 2298 | margin: calc(var(--lineHeight)*8) 2299 | } 2300 | 2301 | .w-1 { 2302 | width: calc(var(--lineHeight)*1) 2303 | } 2304 | 2305 | .w-2 { 2306 | width: calc(var(--lineHeight)*2) 2307 | } 2308 | 2309 | .w-3 { 2310 | width: calc(var(--lineHeight)*3) 2311 | } 2312 | 2313 | .w-4 { 2314 | width: calc(var(--lineHeight)*4) 2315 | } 2316 | 2317 | .w-5 { 2318 | width: calc(var(--lineHeight)*5) 2319 | } 2320 | 2321 | .w-6 { 2322 | width: calc(var(--lineHeight)*6) 2323 | } 2324 | 2325 | .w-7 { 2326 | width: calc(var(--lineHeight)*7) 2327 | } 2328 | 2329 | .w-8 { 2330 | width: calc(var(--lineHeight)*8) 2331 | } 2332 | 2333 | .w-9 { 2334 | width: calc(var(--lineHeight)*9) 2335 | } 2336 | 2337 | .w-10 { 2338 | width: calc(var(--lineHeight)*10) 2339 | } 2340 | 2341 | .w-11 { 2342 | width: calc(var(--lineHeight)*11) 2343 | } 2344 | 2345 | .w-12 { 2346 | width: calc(var(--lineHeight)*12) 2347 | } 2348 | 2349 | .w-13 { 2350 | width: calc(var(--lineHeight)*13) 2351 | } 2352 | 2353 | .w-14 { 2354 | width: calc(var(--lineHeight)*14) 2355 | } 2356 | 2357 | .w-15 { 2358 | width: calc(var(--lineHeight)*15) 2359 | } 2360 | 2361 | .w-16 { 2362 | width: calc(var(--lineHeight)*16) 2363 | } 2364 | 2365 | .w-17 { 2366 | width: calc(var(--lineHeight)*17) 2367 | } 2368 | 2369 | .w-18 { 2370 | width: calc(var(--lineHeight)*18) 2371 | } 2372 | 2373 | .w-19 { 2374 | width: calc(var(--lineHeight)*19) 2375 | } 2376 | 2377 | .w-20 { 2378 | width: calc(var(--lineHeight)*20) 2379 | } 2380 | 2381 | .w-21 { 2382 | width: calc(var(--lineHeight)*21) 2383 | } 2384 | 2385 | .w-22 { 2386 | width: calc(var(--lineHeight)*22) 2387 | } 2388 | 2389 | .w-23 { 2390 | width: calc(var(--lineHeight)*23) 2391 | } 2392 | 2393 | .w-24 { 2394 | width: calc(var(--lineHeight)*24) 2395 | } 2396 | 2397 | .w-25 { 2398 | width: calc(var(--lineHeight)*25) 2399 | } 2400 | 2401 | .w-26 { 2402 | width: calc(var(--lineHeight)*26) 2403 | } 2404 | 2405 | .w-27 { 2406 | width: calc(var(--lineHeight)*27) 2407 | } 2408 | 2409 | .w-28 { 2410 | width: calc(var(--lineHeight)*28) 2411 | } 2412 | 2413 | .w-29 { 2414 | width: calc(var(--lineHeight)*29) 2415 | } 2416 | 2417 | .w-30 { 2418 | width: calc(var(--lineHeight)*30) 2419 | } 2420 | 2421 | .w-31 { 2422 | width: calc(var(--lineHeight)*31) 2423 | } 2424 | 2425 | .w-32 { 2426 | width: calc(var(--lineHeight)*32) 2427 | } 2428 | 2429 | .w-33 { 2430 | width: calc(var(--lineHeight)*33) 2431 | } 2432 | 2433 | .w-34 { 2434 | width: calc(var(--lineHeight)*34) 2435 | } 2436 | 2437 | .w-35 { 2438 | width: calc(var(--lineHeight)*35) 2439 | } 2440 | 2441 | .w-36 { 2442 | width: calc(var(--lineHeight)*36) 2443 | } 2444 | 2445 | .w-37 { 2446 | width: calc(var(--lineHeight)*37) 2447 | } 2448 | 2449 | .w-38 { 2450 | width: calc(var(--lineHeight)*38) 2451 | } 2452 | 2453 | .w-39 { 2454 | width: calc(var(--lineHeight)*39) 2455 | } 2456 | 2457 | .w-40 { 2458 | width: calc(var(--lineHeight)*40) 2459 | } 2460 | 2461 | .w-full { 2462 | width: 100% 2463 | } 2464 | 2465 | .h-1 { 2466 | height: calc(var(--lineHeight)*1) 2467 | } 2468 | 2469 | .h-2 { 2470 | height: calc(var(--lineHeight)*2) 2471 | } 2472 | 2473 | .h-3 { 2474 | height: calc(var(--lineHeight)*3) 2475 | } 2476 | 2477 | .h-4 { 2478 | height: calc(var(--lineHeight)*4) 2479 | } 2480 | 2481 | .h-5 { 2482 | height: calc(var(--lineHeight)*5) 2483 | } 2484 | 2485 | .h-6 { 2486 | height: calc(var(--lineHeight)*6) 2487 | } 2488 | 2489 | .h-7 { 2490 | height: calc(var(--lineHeight)*7) 2491 | } 2492 | 2493 | .h-8 { 2494 | height: calc(var(--lineHeight)*8) 2495 | } 2496 | 2497 | .h-9 { 2498 | height: calc(var(--lineHeight)*9) 2499 | } 2500 | 2501 | .h-10 { 2502 | height: calc(var(--lineHeight)*10) 2503 | } 2504 | 2505 | .h-11 { 2506 | height: calc(var(--lineHeight)*11) 2507 | } 2508 | 2509 | .h-12 { 2510 | height: calc(var(--lineHeight)*12) 2511 | } 2512 | 2513 | .h-13 { 2514 | height: calc(var(--lineHeight)*13) 2515 | } 2516 | 2517 | .h-14 { 2518 | height: calc(var(--lineHeight)*14) 2519 | } 2520 | 2521 | .h-15 { 2522 | height: calc(var(--lineHeight)*15) 2523 | } 2524 | 2525 | .h-16 { 2526 | height: calc(var(--lineHeight)*16) 2527 | } 2528 | 2529 | .h-17 { 2530 | height: calc(var(--lineHeight)*17) 2531 | } 2532 | 2533 | .h-18 { 2534 | height: calc(var(--lineHeight)*18) 2535 | } 2536 | 2537 | .h-19 { 2538 | height: calc(var(--lineHeight)*19) 2539 | } 2540 | 2541 | .h-20 { 2542 | height: calc(var(--lineHeight)*20) 2543 | } 2544 | 2545 | .h-21 { 2546 | height: calc(var(--lineHeight)*21) 2547 | } 2548 | 2549 | .h-22 { 2550 | height: calc(var(--lineHeight)*22) 2551 | } 2552 | 2553 | .h-23 { 2554 | height: calc(var(--lineHeight)*23) 2555 | } 2556 | 2557 | .h-24 { 2558 | height: calc(var(--lineHeight)*24) 2559 | } 2560 | 2561 | .h-25 { 2562 | height: calc(var(--lineHeight)*25) 2563 | } 2564 | 2565 | .h-26 { 2566 | height: calc(var(--lineHeight)*26) 2567 | } 2568 | 2569 | .h-27 { 2570 | height: calc(var(--lineHeight)*27) 2571 | } 2572 | 2573 | .h-28 { 2574 | height: calc(var(--lineHeight)*28) 2575 | } 2576 | 2577 | .h-29 { 2578 | height: calc(var(--lineHeight)*29) 2579 | } 2580 | 2581 | .h-30 { 2582 | height: calc(var(--lineHeight)*30) 2583 | } 2584 | 2585 | .h-31 { 2586 | height: calc(var(--lineHeight)*31) 2587 | } 2588 | 2589 | .h-32 { 2590 | height: calc(var(--lineHeight)*32) 2591 | } 2592 | 2593 | .h-33 { 2594 | height: calc(var(--lineHeight)*33) 2595 | } 2596 | 2597 | .h-34 { 2598 | height: calc(var(--lineHeight)*34) 2599 | } 2600 | 2601 | .h-35 { 2602 | height: calc(var(--lineHeight)*35) 2603 | } 2604 | 2605 | .h-36 { 2606 | height: calc(var(--lineHeight)*36) 2607 | } 2608 | 2609 | .h-37 { 2610 | height: calc(var(--lineHeight)*37) 2611 | } 2612 | 2613 | .h-38 { 2614 | height: calc(var(--lineHeight)*38) 2615 | } 2616 | 2617 | .h-39 { 2618 | height: calc(var(--lineHeight)*39) 2619 | } 2620 | 2621 | .h-40 { 2622 | height: calc(var(--lineHeight)*40) 2623 | } 2624 | 2625 | .opacity0 { 2626 | opacity: 0 2627 | } 2628 | 2629 | .opacity1 { 2630 | opacity: .1 2631 | } 2632 | 2633 | .opacity2 { 2634 | opacity: .2 2635 | } 2636 | 2637 | .opacity3 { 2638 | opacity: .3 2639 | } 2640 | 2641 | .opacity4 { 2642 | opacity: .4 2643 | } 2644 | 2645 | .opacity5 { 2646 | opacity: .5 2647 | } 2648 | 2649 | .opacity6 { 2650 | opacity: .6 2651 | } 2652 | 2653 | .opacity7 { 2654 | opacity: .7 2655 | } 2656 | 2657 | .opacity8 { 2658 | opacity: .8 2659 | } 2660 | 2661 | .opacity9 { 2662 | opacity: .9 2663 | } 2664 | 2665 | .opacity10 { 2666 | opacity: 1 2667 | } 2668 | 2669 | :root { 2670 | --red: #ee2711; 2671 | --blue: #1871e9; 2672 | --green: #12c05b; 2673 | --yellow: #f9bf0f 2674 | } 2675 | 2676 | .red { 2677 | color: var(--red) 2678 | } 2679 | 2680 | .bg-red { 2681 | background-color: var(--red) 2682 | } 2683 | 2684 | .blue { 2685 | color: var(--blue) 2686 | } 2687 | 2688 | .bg-blue { 2689 | background-color: var(--blue) 2690 | } 2691 | 2692 | .green { 2693 | color: var(--green) 2694 | } 2695 | 2696 | .bg-green { 2697 | background-color: var(--green) 2698 | } 2699 | 2700 | .yellow { 2701 | color: var(--yellow) 2702 | } 2703 | 2704 | .bg-yellow { 2705 | background-color: var(--yellow) 2706 | } --------------------------------------------------------------------------------