cli: add --target flag

This commit is contained in:
Michał Wieluński 2023-11-14 21:42:02 +01:00
parent 97cbc6271d
commit b0cbd66219
No known key found for this signature in database
9 changed files with 418 additions and 28 deletions

View file

@ -3,6 +3,7 @@
- ELK now routes `sql_table` edges to the exact columns (ty @landmaj) [#1681](https://github.com/terrastruct/d2/pull/1681)
- Adds new unfilled triangle arrowhead. [#1711](https://github.com/terrastruct/d2/pull/1711)
- Grid containers can now have custom label positions. [#1715](https://github.com/terrastruct/d2/pull/1715)
- A single board from a multi-board diagram can now be rendered with `--target` flag. [#1725](https://github.com/terrastruct/d2/pull/1725)
#### Improvements 🧹

View file

@ -111,6 +111,11 @@ Bundle all assets and layers into the output svg
.It Fl -force-appendix Ar false
An appendix for tooltips and links is added to PNG exports since they are not interactive. Setting this to true adds an appendix to SVG exports as well
.Ns .
.It Fl -target
Target board to render. Pass an empty string to target root board. If target ends with '*', it will be rendered
with all of its scenarios, steps, and layers. Otherwise, only the target board will be rendered. E.g. --target=''
to render root board only or --target='layers.x.*' to render layer 'x' with all of its children
.Ns .
.It Fl d , -debug
Print debug logs
.Ns .

View file

@ -115,6 +115,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
if err != nil {
return err
}
targetFlag := ms.Opts.String("", "target", "", "*", "target board to render. Pass an empty string to target root board. If target ends with '*', it will be rendered with all of its scenarios, steps, and layers. Otherwise, only the target board will be rendered. E.g. --target='' to render root board only or --target='layers.x.*' to render layer 'x' with all of its children.")
fontRegularFlag := ms.Opts.String("D2_FONT_REGULAR", "font-regular", "", "", "path to .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used.")
fontItalicFlag := ms.Opts.String("D2_FONT_ITALIC", "font-italic", "", "", "path to .ttf file to use for the italic font. If none provided, Source Sans Pro Regular-Italic is used.")
@ -310,6 +311,9 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
if inputPath == "-" {
return xmain.UsageErrorf("-w[atch] cannot be combined with reading input from stdin")
}
if *targetFlag != "*" {
return xmain.UsageErrorf("-w[atch] cannot be combined with --target")
}
w, err := newWatcher(ctx, ms, watcherOpts{
plugins: plugins,
layout: layoutFlag,
@ -330,10 +334,30 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
return w.run()
}
var boardPath []string
var noChildren bool
switch *targetFlag {
case "*":
case "":
noChildren = true
default:
target := *targetFlag
if strings.HasSuffix(target, ".*") {
target = target[:len(target)-2]
} else {
noChildren = true
}
key, err := d2parser.ParseKey(target)
if err != nil {
return xmain.UsageErrorf("invalid target: %s", *targetFlag)
}
boardPath = key.IDA()
}
ctx, cancel := timelib.WithTimeout(ctx, time.Minute*2)
defer cancel()
_, written, err := compile(ctx, ms, plugins, nil, layoutFlag, renderOpts, fontFamily, *animateIntervalFlag, inputPath, outputPath, "", *bundleFlag, *forceAppendixFlag, pw.Page)
_, written, err := compile(ctx, ms, plugins, nil, layoutFlag, renderOpts, fontFamily, *animateIntervalFlag, inputPath, outputPath, boardPath, noChildren, *bundleFlag, *forceAppendixFlag, pw.Page)
if err != nil {
if written {
return fmt.Errorf("failed to fully compile (partial render written) %s: %w", ms.HumanPath(inputPath), err)
@ -368,7 +392,7 @@ func LayoutResolver(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plu
}
}
func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs fs.FS, layout *string, renderOpts d2svg.RenderOpts, fontFamily *d2fonts.FontFamily, animateInterval int64, inputPath, outputPath, boardPath string, bundle, forceAppendix bool, page playwright.Page) (_ []byte, written bool, _ error) {
func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs fs.FS, layout *string, renderOpts d2svg.RenderOpts, fontFamily *d2fonts.FontFamily, animateInterval int64, inputPath, outputPath string, boardPath []string, noChildren, bundle, forceAppendix bool, page playwright.Page) (_ []byte, written bool, _ error) {
start := time.Now()
input, err := ms.ReadPath(inputPath)
if err != nil {
@ -400,6 +424,16 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs
}
cancel()
diagram = diagram.GetBoard(boardPath)
if diagram == nil {
return nil, false, fmt.Errorf(`render target "%s" not found`, strings.Join(boardPath, "."))
}
if noChildren {
diagram.Layers = nil
diagram.Scenarios = nil
diagram.Steps = nil
}
plugin, _ := d2plugin.FindPlugin(ctx, plugins, *opts.Layout)
if animateInterval > 0 {
@ -503,12 +537,13 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, fs
}
}
board := diagram.GetBoard(boardPath)
if board == nil {
return nil, false, fmt.Errorf(`Diagram with path "%s" not found. Did you mean to specify a board like "layers.%s"?`, boardPath, boardPath)
var boards [][]byte
var err error
if noChildren {
boards, err = renderSingle(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, diagram)
} else {
boards, err = render(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, diagram)
}
boards, err := render(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, board)
if err != nil {
return nil, false, err
}
@ -725,6 +760,19 @@ func render(ctx context.Context, ms *xmain.State, compileDur time.Duration, plug
return boards, nil
}
func renderSingle(ctx context.Context, ms *xmain.State, compileDur time.Duration, plugin d2plugin.Plugin, opts d2svg.RenderOpts, inputPath, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([][]byte, error) {
start := time.Now()
out, err := _render(ctx, ms, plugin, opts, outputPath, bundle, forceAppendix, page, ruler, diagram)
if err != nil {
return [][]byte{}, err
}
dur := compileDur + time.Since(start)
if opts.MasterID == "" {
ms.Log.Success.Printf("successfully compiled %s to %s in %s", ms.HumanPath(inputPath), ms.HumanPath(outputPath), dur)
}
return [][]byte{out}, nil
}
func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([]byte, error) {
toPNG := getExportExtension(outputPath) == PNG
var scale *float64

View file

@ -426,7 +426,11 @@ func (w *watcher) compileLoop(ctx context.Context) error {
fs := trackedFS{}
w.boardpathMu.Lock()
svg, _, err := compile(ctx, w.ms, w.plugins, &fs, w.layout, w.renderOpts, w.fontFamily, w.animateInterval, w.inputPath, w.outputPath, w.boardPath, w.bundle, w.forceAppendix, w.pw.Page)
var boardPath []string
if w.boardPath != "" {
boardPath = strings.Split(w.boardPath, string(os.PathSeparator))
}
svg, _, err := compile(ctx, w.ms, w.plugins, &fs, w.layout, w.renderOpts, w.fontFamily, w.animateInterval, w.inputPath, w.outputPath, boardPath, false, w.bundle, w.forceAppendix, w.pw.Page)
w.boardpathMu.Unlock()
errs := ""
if err != nil {

View file

@ -6,7 +6,6 @@ import (
"hash/fnv"
"math"
"net/url"
"os"
"strings"
"oss.terrastruct.com/util-go/go2"
@ -73,19 +72,7 @@ type Diagram struct {
Steps []*Diagram `json:"steps,omitempty"`
}
// boardPath comes in the form of "x/layers/z/scenarios/a"
// or "layers/z/scenarios/a"
// or "x/z/a"
func (d *Diagram) GetBoard(boardPath string) *Diagram {
path := strings.Split(boardPath, string(os.PathSeparator))
if len(path) == 0 || len(boardPath) == 0 {
return d
}
return d.getBoard(path)
}
func (d *Diagram) getBoard(boardPath []string) *Diagram {
func (d *Diagram) GetBoard(boardPath []string) *Diagram {
if len(boardPath) == 0 {
return d
}
@ -103,7 +90,7 @@ func (d *Diagram) getBoard(boardPath []string) *Diagram {
}
for _, b := range d.Layers {
if b.Name == boardPath[1] {
return b.getBoard(boardPath[2:])
return b.GetBoard(boardPath[2:])
}
}
case "scenarios":
@ -112,7 +99,7 @@ func (d *Diagram) getBoard(boardPath []string) *Diagram {
}
for _, b := range d.Scenarios {
if b.Name == boardPath[1] {
return b.getBoard(boardPath[2:])
return b.GetBoard(boardPath[2:])
}
}
case "steps":
@ -121,24 +108,24 @@ func (d *Diagram) getBoard(boardPath []string) *Diagram {
}
for _, b := range d.Steps {
if b.Name == boardPath[1] {
return b.getBoard(boardPath[2:])
return b.GetBoard(boardPath[2:])
}
}
}
for _, b := range d.Layers {
if b.Name == head {
return b.getBoard(boardPath[1:])
return b.GetBoard(boardPath[1:])
}
}
for _, b := range d.Scenarios {
if b.Name == head {
return b.getBoard(boardPath[1:])
return b.GetBoard(boardPath[1:])
}
}
for _, b := range d.Steps {
if b.Name == head {
return b.getBoard(boardPath[1:])
return b.GetBoard(boardPath[1:])
}
}
return nil

View file

@ -239,6 +239,66 @@ You provided: .png`)
testdataIgnoreDiff(t, ".png", png)
},
},
{
name: "target-root",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "target-root.d2", `title: {
label: Main Plan
}
scenarios: {
b: {
title.label: Backup Plan
}
}`)
err := runTestMain(t, ctx, dir, env, "--target", "", "target-root.d2", "target-root.svg")
assert.Success(t, err)
svg := readFile(t, dir, "target-root.svg")
assert.Testdata(t, ".svg", svg)
},
},
{
name: "target-b",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "target-b.d2", `title: {
label: Main Plan
}
scenarios: {
b: {
title.label: Backup Plan
}
}`)
err := runTestMain(t, ctx, dir, env, "--target", "b", "target-b.d2", "target-b.svg")
assert.Success(t, err)
svg := readFile(t, dir, "target-b.svg")
assert.Testdata(t, ".svg", svg)
},
},
{
name: "target-nested-with-special-chars",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "target-nested-with-special-chars.d2", `layers: {
a: {
layers: {
"x / y . z": {
mad
}
}
}
}`)
err := runTestMain(t, ctx, dir, env, "--target", `layers.a.layers."x / y . z"`, "target-nested-with-special-chars.d2", "target-nested-with-special-chars.svg")
assert.Success(t, err)
svg := readFile(t, dir, "target-nested-with-special-chars.svg")
assert.Testdata(t, ".svg", svg)
},
},
{
name: "target-invalid",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {
writeFile(t, dir, "target-invalid.d2", `x -> y`)
err := runTestMain(t, ctx, dir, env, "--target", "b", "target-invalid.d2", "target-invalid.svg")
assert.ErrorString(t, err, `failed to wait xmain test: e2etests-cli/d2: failed to compile target-invalid.d2: render target "b" not found`)
},
},
{
name: "multiboard/life",
run: func(t *testing.T, ctx context.Context, dir string, env *xos.Env) {

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.1-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 334 268"><svg id="d2-svg" class="d2-2079990668" width="334" height="268" viewBox="-101 -101 334 268"><rect x="-101.000000" y="-101.000000" width="334.000000" height="268.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-2079990668 .text-bold {
font-family: "d2-2079990668-font-bold";
}
@font-face {
font-family: d2-2079990668-font-bold;
src: url("data:application/font-woff;base64,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");
}]]></style><style type="text/css"><![CDATA[.shape {
shape-rendering: geometricPrecision;
stroke-linejoin: round;
}
.connection {
stroke-linecap: round;
stroke-linejoin: round;
}
.blend {
mix-blend-mode: multiply;
opacity: 0.5;
}
.d2-2079990668 .fill-N1{fill:#0A0F25;}
.d2-2079990668 .fill-N2{fill:#676C7E;}
.d2-2079990668 .fill-N3{fill:#9499AB;}
.d2-2079990668 .fill-N4{fill:#CFD2DD;}
.d2-2079990668 .fill-N5{fill:#DEE1EB;}
.d2-2079990668 .fill-N6{fill:#EEF1F8;}
.d2-2079990668 .fill-N7{fill:#FFFFFF;}
.d2-2079990668 .fill-B1{fill:#0D32B2;}
.d2-2079990668 .fill-B2{fill:#0D32B2;}
.d2-2079990668 .fill-B3{fill:#E3E9FD;}
.d2-2079990668 .fill-B4{fill:#E3E9FD;}
.d2-2079990668 .fill-B5{fill:#EDF0FD;}
.d2-2079990668 .fill-B6{fill:#F7F8FE;}
.d2-2079990668 .fill-AA2{fill:#4A6FF3;}
.d2-2079990668 .fill-AA4{fill:#EDF0FD;}
.d2-2079990668 .fill-AA5{fill:#F7F8FE;}
.d2-2079990668 .fill-AB4{fill:#EDF0FD;}
.d2-2079990668 .fill-AB5{fill:#F7F8FE;}
.d2-2079990668 .stroke-N1{stroke:#0A0F25;}
.d2-2079990668 .stroke-N2{stroke:#676C7E;}
.d2-2079990668 .stroke-N3{stroke:#9499AB;}
.d2-2079990668 .stroke-N4{stroke:#CFD2DD;}
.d2-2079990668 .stroke-N5{stroke:#DEE1EB;}
.d2-2079990668 .stroke-N6{stroke:#EEF1F8;}
.d2-2079990668 .stroke-N7{stroke:#FFFFFF;}
.d2-2079990668 .stroke-B1{stroke:#0D32B2;}
.d2-2079990668 .stroke-B2{stroke:#0D32B2;}
.d2-2079990668 .stroke-B3{stroke:#E3E9FD;}
.d2-2079990668 .stroke-B4{stroke:#E3E9FD;}
.d2-2079990668 .stroke-B5{stroke:#EDF0FD;}
.d2-2079990668 .stroke-B6{stroke:#F7F8FE;}
.d2-2079990668 .stroke-AA2{stroke:#4A6FF3;}
.d2-2079990668 .stroke-AA4{stroke:#EDF0FD;}
.d2-2079990668 .stroke-AA5{stroke:#F7F8FE;}
.d2-2079990668 .stroke-AB4{stroke:#EDF0FD;}
.d2-2079990668 .stroke-AB5{stroke:#F7F8FE;}
.d2-2079990668 .background-color-N1{background-color:#0A0F25;}
.d2-2079990668 .background-color-N2{background-color:#676C7E;}
.d2-2079990668 .background-color-N3{background-color:#9499AB;}
.d2-2079990668 .background-color-N4{background-color:#CFD2DD;}
.d2-2079990668 .background-color-N5{background-color:#DEE1EB;}
.d2-2079990668 .background-color-N6{background-color:#EEF1F8;}
.d2-2079990668 .background-color-N7{background-color:#FFFFFF;}
.d2-2079990668 .background-color-B1{background-color:#0D32B2;}
.d2-2079990668 .background-color-B2{background-color:#0D32B2;}
.d2-2079990668 .background-color-B3{background-color:#E3E9FD;}
.d2-2079990668 .background-color-B4{background-color:#E3E9FD;}
.d2-2079990668 .background-color-B5{background-color:#EDF0FD;}
.d2-2079990668 .background-color-B6{background-color:#F7F8FE;}
.d2-2079990668 .background-color-AA2{background-color:#4A6FF3;}
.d2-2079990668 .background-color-AA4{background-color:#EDF0FD;}
.d2-2079990668 .background-color-AA5{background-color:#F7F8FE;}
.d2-2079990668 .background-color-AB4{background-color:#EDF0FD;}
.d2-2079990668 .background-color-AB5{background-color:#F7F8FE;}
.d2-2079990668 .color-N1{color:#0A0F25;}
.d2-2079990668 .color-N2{color:#676C7E;}
.d2-2079990668 .color-N3{color:#9499AB;}
.d2-2079990668 .color-N4{color:#CFD2DD;}
.d2-2079990668 .color-N5{color:#DEE1EB;}
.d2-2079990668 .color-N6{color:#EEF1F8;}
.d2-2079990668 .color-N7{color:#FFFFFF;}
.d2-2079990668 .color-B1{color:#0D32B2;}
.d2-2079990668 .color-B2{color:#0D32B2;}
.d2-2079990668 .color-B3{color:#E3E9FD;}
.d2-2079990668 .color-B4{color:#E3E9FD;}
.d2-2079990668 .color-B5{color:#EDF0FD;}
.d2-2079990668 .color-B6{color:#F7F8FE;}
.d2-2079990668 .color-AA2{color:#4A6FF3;}
.d2-2079990668 .color-AA4{color:#EDF0FD;}
.d2-2079990668 .color-AA5{color:#F7F8FE;}
.d2-2079990668 .color-AB4{color:#EDF0FD;}
.d2-2079990668 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]></style><g id="title"><g class="shape" ><rect x="0.000000" y="0.000000" width="132.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="66.000000" y="38.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">Backup Plan</text></g><mask id="d2-2079990668" maskUnits="userSpaceOnUse" x="-101" y="-101" width="334" height="268">
<rect x="-101" y="-101" width="334" height="268" fill="white"></rect>
<rect x="22.500000" y="22.500000" width="87" height="21" fill="rgba(0,0,0,0.75)"></rect>
</mask></svg></svg>

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.1-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 278 268"><svg id="d2-svg" class="d2-774159559" width="278" height="268" viewBox="-101 -101 278 268"><rect x="-101.000000" y="-101.000000" width="278.000000" height="268.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-774159559 .text-bold {
font-family: "d2-774159559-font-bold";
}
@font-face {
font-family: d2-774159559-font-bold;
src: url("data:application/font-woff;base64,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");
}]]></style><style type="text/css"><![CDATA[.shape {
shape-rendering: geometricPrecision;
stroke-linejoin: round;
}
.connection {
stroke-linecap: round;
stroke-linejoin: round;
}
.blend {
mix-blend-mode: multiply;
opacity: 0.5;
}
.d2-774159559 .fill-N1{fill:#0A0F25;}
.d2-774159559 .fill-N2{fill:#676C7E;}
.d2-774159559 .fill-N3{fill:#9499AB;}
.d2-774159559 .fill-N4{fill:#CFD2DD;}
.d2-774159559 .fill-N5{fill:#DEE1EB;}
.d2-774159559 .fill-N6{fill:#EEF1F8;}
.d2-774159559 .fill-N7{fill:#FFFFFF;}
.d2-774159559 .fill-B1{fill:#0D32B2;}
.d2-774159559 .fill-B2{fill:#0D32B2;}
.d2-774159559 .fill-B3{fill:#E3E9FD;}
.d2-774159559 .fill-B4{fill:#E3E9FD;}
.d2-774159559 .fill-B5{fill:#EDF0FD;}
.d2-774159559 .fill-B6{fill:#F7F8FE;}
.d2-774159559 .fill-AA2{fill:#4A6FF3;}
.d2-774159559 .fill-AA4{fill:#EDF0FD;}
.d2-774159559 .fill-AA5{fill:#F7F8FE;}
.d2-774159559 .fill-AB4{fill:#EDF0FD;}
.d2-774159559 .fill-AB5{fill:#F7F8FE;}
.d2-774159559 .stroke-N1{stroke:#0A0F25;}
.d2-774159559 .stroke-N2{stroke:#676C7E;}
.d2-774159559 .stroke-N3{stroke:#9499AB;}
.d2-774159559 .stroke-N4{stroke:#CFD2DD;}
.d2-774159559 .stroke-N5{stroke:#DEE1EB;}
.d2-774159559 .stroke-N6{stroke:#EEF1F8;}
.d2-774159559 .stroke-N7{stroke:#FFFFFF;}
.d2-774159559 .stroke-B1{stroke:#0D32B2;}
.d2-774159559 .stroke-B2{stroke:#0D32B2;}
.d2-774159559 .stroke-B3{stroke:#E3E9FD;}
.d2-774159559 .stroke-B4{stroke:#E3E9FD;}
.d2-774159559 .stroke-B5{stroke:#EDF0FD;}
.d2-774159559 .stroke-B6{stroke:#F7F8FE;}
.d2-774159559 .stroke-AA2{stroke:#4A6FF3;}
.d2-774159559 .stroke-AA4{stroke:#EDF0FD;}
.d2-774159559 .stroke-AA5{stroke:#F7F8FE;}
.d2-774159559 .stroke-AB4{stroke:#EDF0FD;}
.d2-774159559 .stroke-AB5{stroke:#F7F8FE;}
.d2-774159559 .background-color-N1{background-color:#0A0F25;}
.d2-774159559 .background-color-N2{background-color:#676C7E;}
.d2-774159559 .background-color-N3{background-color:#9499AB;}
.d2-774159559 .background-color-N4{background-color:#CFD2DD;}
.d2-774159559 .background-color-N5{background-color:#DEE1EB;}
.d2-774159559 .background-color-N6{background-color:#EEF1F8;}
.d2-774159559 .background-color-N7{background-color:#FFFFFF;}
.d2-774159559 .background-color-B1{background-color:#0D32B2;}
.d2-774159559 .background-color-B2{background-color:#0D32B2;}
.d2-774159559 .background-color-B3{background-color:#E3E9FD;}
.d2-774159559 .background-color-B4{background-color:#E3E9FD;}
.d2-774159559 .background-color-B5{background-color:#EDF0FD;}
.d2-774159559 .background-color-B6{background-color:#F7F8FE;}
.d2-774159559 .background-color-AA2{background-color:#4A6FF3;}
.d2-774159559 .background-color-AA4{background-color:#EDF0FD;}
.d2-774159559 .background-color-AA5{background-color:#F7F8FE;}
.d2-774159559 .background-color-AB4{background-color:#EDF0FD;}
.d2-774159559 .background-color-AB5{background-color:#F7F8FE;}
.d2-774159559 .color-N1{color:#0A0F25;}
.d2-774159559 .color-N2{color:#676C7E;}
.d2-774159559 .color-N3{color:#9499AB;}
.d2-774159559 .color-N4{color:#CFD2DD;}
.d2-774159559 .color-N5{color:#DEE1EB;}
.d2-774159559 .color-N6{color:#EEF1F8;}
.d2-774159559 .color-N7{color:#FFFFFF;}
.d2-774159559 .color-B1{color:#0D32B2;}
.d2-774159559 .color-B2{color:#0D32B2;}
.d2-774159559 .color-B3{color:#E3E9FD;}
.d2-774159559 .color-B4{color:#E3E9FD;}
.d2-774159559 .color-B5{color:#EDF0FD;}
.d2-774159559 .color-B6{color:#F7F8FE;}
.d2-774159559 .color-AA2{color:#4A6FF3;}
.d2-774159559 .color-AA4{color:#EDF0FD;}
.d2-774159559 .color-AA5{color:#F7F8FE;}
.d2-774159559 .color-AB4{color:#EDF0FD;}
.d2-774159559 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]></style><g id="mad"><g class="shape" ><rect x="0.000000" y="0.000000" width="76.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="38.000000" y="38.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">mad</text></g><mask id="d2-774159559" maskUnits="userSpaceOnUse" x="-101" y="-101" width="278" height="268">
<rect x="-101" y="-101" width="278" height="268" fill="white"></rect>
<rect x="22.500000" y="22.500000" width="31" height="21" fill="rgba(0,0,0,0.75)"></rect>
</mask></svg></svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" d2Version="v0.6.1-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 315 268"><svg id="d2-svg" class="d2-1300846817" width="315" height="268" viewBox="-101 -101 315 268"><rect x="-101.000000" y="-101.000000" width="315.000000" height="268.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-1300846817 .text-bold {
font-family: "d2-1300846817-font-bold";
}
@font-face {
font-family: d2-1300846817-font-bold;
src: url("data:application/font-woff;base64,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");
}]]></style><style type="text/css"><![CDATA[.shape {
shape-rendering: geometricPrecision;
stroke-linejoin: round;
}
.connection {
stroke-linecap: round;
stroke-linejoin: round;
}
.blend {
mix-blend-mode: multiply;
opacity: 0.5;
}
.d2-1300846817 .fill-N1{fill:#0A0F25;}
.d2-1300846817 .fill-N2{fill:#676C7E;}
.d2-1300846817 .fill-N3{fill:#9499AB;}
.d2-1300846817 .fill-N4{fill:#CFD2DD;}
.d2-1300846817 .fill-N5{fill:#DEE1EB;}
.d2-1300846817 .fill-N6{fill:#EEF1F8;}
.d2-1300846817 .fill-N7{fill:#FFFFFF;}
.d2-1300846817 .fill-B1{fill:#0D32B2;}
.d2-1300846817 .fill-B2{fill:#0D32B2;}
.d2-1300846817 .fill-B3{fill:#E3E9FD;}
.d2-1300846817 .fill-B4{fill:#E3E9FD;}
.d2-1300846817 .fill-B5{fill:#EDF0FD;}
.d2-1300846817 .fill-B6{fill:#F7F8FE;}
.d2-1300846817 .fill-AA2{fill:#4A6FF3;}
.d2-1300846817 .fill-AA4{fill:#EDF0FD;}
.d2-1300846817 .fill-AA5{fill:#F7F8FE;}
.d2-1300846817 .fill-AB4{fill:#EDF0FD;}
.d2-1300846817 .fill-AB5{fill:#F7F8FE;}
.d2-1300846817 .stroke-N1{stroke:#0A0F25;}
.d2-1300846817 .stroke-N2{stroke:#676C7E;}
.d2-1300846817 .stroke-N3{stroke:#9499AB;}
.d2-1300846817 .stroke-N4{stroke:#CFD2DD;}
.d2-1300846817 .stroke-N5{stroke:#DEE1EB;}
.d2-1300846817 .stroke-N6{stroke:#EEF1F8;}
.d2-1300846817 .stroke-N7{stroke:#FFFFFF;}
.d2-1300846817 .stroke-B1{stroke:#0D32B2;}
.d2-1300846817 .stroke-B2{stroke:#0D32B2;}
.d2-1300846817 .stroke-B3{stroke:#E3E9FD;}
.d2-1300846817 .stroke-B4{stroke:#E3E9FD;}
.d2-1300846817 .stroke-B5{stroke:#EDF0FD;}
.d2-1300846817 .stroke-B6{stroke:#F7F8FE;}
.d2-1300846817 .stroke-AA2{stroke:#4A6FF3;}
.d2-1300846817 .stroke-AA4{stroke:#EDF0FD;}
.d2-1300846817 .stroke-AA5{stroke:#F7F8FE;}
.d2-1300846817 .stroke-AB4{stroke:#EDF0FD;}
.d2-1300846817 .stroke-AB5{stroke:#F7F8FE;}
.d2-1300846817 .background-color-N1{background-color:#0A0F25;}
.d2-1300846817 .background-color-N2{background-color:#676C7E;}
.d2-1300846817 .background-color-N3{background-color:#9499AB;}
.d2-1300846817 .background-color-N4{background-color:#CFD2DD;}
.d2-1300846817 .background-color-N5{background-color:#DEE1EB;}
.d2-1300846817 .background-color-N6{background-color:#EEF1F8;}
.d2-1300846817 .background-color-N7{background-color:#FFFFFF;}
.d2-1300846817 .background-color-B1{background-color:#0D32B2;}
.d2-1300846817 .background-color-B2{background-color:#0D32B2;}
.d2-1300846817 .background-color-B3{background-color:#E3E9FD;}
.d2-1300846817 .background-color-B4{background-color:#E3E9FD;}
.d2-1300846817 .background-color-B5{background-color:#EDF0FD;}
.d2-1300846817 .background-color-B6{background-color:#F7F8FE;}
.d2-1300846817 .background-color-AA2{background-color:#4A6FF3;}
.d2-1300846817 .background-color-AA4{background-color:#EDF0FD;}
.d2-1300846817 .background-color-AA5{background-color:#F7F8FE;}
.d2-1300846817 .background-color-AB4{background-color:#EDF0FD;}
.d2-1300846817 .background-color-AB5{background-color:#F7F8FE;}
.d2-1300846817 .color-N1{color:#0A0F25;}
.d2-1300846817 .color-N2{color:#676C7E;}
.d2-1300846817 .color-N3{color:#9499AB;}
.d2-1300846817 .color-N4{color:#CFD2DD;}
.d2-1300846817 .color-N5{color:#DEE1EB;}
.d2-1300846817 .color-N6{color:#EEF1F8;}
.d2-1300846817 .color-N7{color:#FFFFFF;}
.d2-1300846817 .color-B1{color:#0D32B2;}
.d2-1300846817 .color-B2{color:#0D32B2;}
.d2-1300846817 .color-B3{color:#E3E9FD;}
.d2-1300846817 .color-B4{color:#E3E9FD;}
.d2-1300846817 .color-B5{color:#EDF0FD;}
.d2-1300846817 .color-B6{color:#F7F8FE;}
.d2-1300846817 .color-AA2{color:#4A6FF3;}
.d2-1300846817 .color-AA4{color:#EDF0FD;}
.d2-1300846817 .color-AA5{color:#F7F8FE;}
.d2-1300846817 .color-AB4{color:#EDF0FD;}
.d2-1300846817 .color-AB5{color:#F7F8FE;}.appendix text.text{fill:#0A0F25}.md{--color-fg-default:#0A0F25;--color-fg-muted:#676C7E;--color-fg-subtle:#9499AB;--color-canvas-default:#FFFFFF;--color-canvas-subtle:#EEF1F8;--color-border-default:#0D32B2;--color-border-muted:#0D32B2;--color-neutral-muted:#EEF1F8;--color-accent-fg:#0D32B2;--color-accent-emphasis:#0D32B2;--color-attention-subtle:#676C7E;--color-danger-fg:red;}.sketch-overlay-B1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B2{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-B3{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-B6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-AA4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AA5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB4{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-AB5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N1{fill:url(#streaks-darker);mix-blend-mode:lighten}.sketch-overlay-N2{fill:url(#streaks-dark);mix-blend-mode:overlay}.sketch-overlay-N3{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N4{fill:url(#streaks-normal);mix-blend-mode:color-burn}.sketch-overlay-N5{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N6{fill:url(#streaks-bright);mix-blend-mode:darken}.sketch-overlay-N7{fill:url(#streaks-bright);mix-blend-mode:darken}.light-code{display: block}.dark-code{display: none}]]></style><g id="title"><g class="shape" ><rect x="0.000000" y="0.000000" width="113.000000" height="66.000000" class=" stroke-B1 fill-B6" style="stroke-width:2;" /></g><text x="56.500000" y="38.500000" class="text-bold fill-N1" style="text-anchor:middle;font-size:16px">Main Plan</text></g><mask id="d2-1300846817" maskUnits="userSpaceOnUse" x="-101" y="-101" width="315" height="268">
<rect x="-101" y="-101" width="315" height="268" fill="white"></rect>
<rect x="22.500000" y="22.500000" width="68" height="21" fill="rgba(0,0,0,0.75)"></rect>
</mask></svg></svg>

After

Width:  |  Height:  |  Size: 9.1 KiB