diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..14353d9 --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,33 @@ +name: CI +on: + push: + branches: [ main, dev ] + pull_request: + branches: [ main, dev ] + +jobs: + tests: + runs-on: ubuntu-latest + container: catthehacker/ubuntu:act-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install tytanic + uses: taiki-e/cache-cargo-install-action@v2 + with: + tool: tytanic@0.2.2 + + - name: Run test suite + run: tt run + + - name: Archive artifacts + uses: actions/upload-artifact@v4 + if: always() + with: + name: artifacts + path: | + tests/**/diff/*.png + tests/**/out/*.png + tests/**/ref/*.png + retention-days: 5 \ No newline at end of file diff --git a/justfile b/justfile index de19b92..8d296ab 100644 --- a/justfile +++ b/justfile @@ -9,4 +9,10 @@ manual: gallery: for f in "{{gallery_dir}}"/*.typ; do typst c --root . "$f" "${f%typ}pdf"; done - for f in "{{gallery_dir}}"/readme/*.typ; do typst c --root . "$f" "${f%typ}png"; done \ No newline at end of file + for f in "{{gallery_dir}}"/readme/*.typ; do typst c --root . "$f" "${f%typ}png"; done + +test *filter: + tt run {{filter}} + +update-test *filter: + tt update {{filter}} \ No newline at end of file diff --git a/tests/empty/.gitignore b/tests/empty/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/empty/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/empty/ref/1.png b/tests/empty/ref/1.png new file mode 100644 index 0000000..7971661 Binary files /dev/null and b/tests/empty/ref/1.png differ diff --git a/tests/empty/test.typ b/tests/empty/test.typ new file mode 100644 index 0000000..80e1d7a --- /dev/null +++ b/tests/empty/test.typ @@ -0,0 +1,6 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({}) + +#diagram(()) diff --git a/tests/group/.gitignore b/tests/group/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/group/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/group/ref/1.png b/tests/group/ref/1.png new file mode 100644 index 0000000..4c6b690 Binary files /dev/null and b/tests/group/ref/1.png differ diff --git a/tests/group/ref/2.png b/tests/group/ref/2.png new file mode 100644 index 0000000..6628385 Binary files /dev/null and b/tests/group/ref/2.png differ diff --git a/tests/group/ref/3.png b/tests/group/ref/3.png new file mode 100644 index 0000000..3c8b5bb Binary files /dev/null and b/tests/group/ref/3.png differ diff --git a/tests/group/test.typ b/tests/group/test.typ new file mode 100644 index 0000000..213df95 --- /dev/null +++ b/tests/group/test.typ @@ -0,0 +1,51 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _seq("Alice", "Bob", comment: "Authentication Request") + + _alt( + "successful case", { + _seq("Bob", "Alice", comment: "Authentication Accepted") + }, + "some kind of failure", { + _seq("Bob", "Alice", comment: "Authentication Failure") + + _grp("My own label", desc: "My own label2", { + _seq("Alice", "Log", comment: "Log attack start") + _loop("1000 times", { + _seq("Alice", "Bob", comment: "DNS Attack") + }) + _seq("Alice", "Log", comment: "Log attack end") + }) + }, + "Another type of failure", { + _seq("Bob", "Alice", comment: "Please repeat") + } + ) +}) + +#pagebreak() + +#diagram({ + _par("a", display-name: box(width: 1.5em, height: .5em), show-bottom: false) + _par("b", display-name: box(width: 1.5em, height: .5em), show-bottom: false) + _col("a", "b", width: 2cm) + _loop("a<1", min: 1, { + _seq("a", "b", end-tip: ">>") + _seq("b", "a", end-tip: ">>") + }) + _seq("a", "b", end-tip: ">>") +}) + +#pagebreak() + +#diagram({ + _par("A") + _par("B") + _col("A", "B", width: 3cm) + _seq("A", "B", enable-dst: true) + _alt([desc], { + _ret() + }) +}) \ No newline at end of file diff --git a/tests/note/color/.gitignore b/tests/note/color/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/note/color/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/note/color/ref/1.png b/tests/note/color/ref/1.png new file mode 100644 index 0000000..b9d0ed4 Binary files /dev/null and b/tests/note/color/ref/1.png differ diff --git a/tests/note/color/test.typ b/tests/note/color/test.typ new file mode 100644 index 0000000..bf051c5 --- /dev/null +++ b/tests/note/color/test.typ @@ -0,0 +1,13 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + + _note("left", [This is displayed\ left of Alice.], pos: "a", color: rgb("#00FFFF")) + _note("right", [This is displayed right of Alice.], pos: "a") + _note("over", [This is displayed over Alice.], pos: "a") + _note("over", [This is displayed\ over Bob and Alice.], pos: ("a", "b"), color: rgb("#FFAAAA")) + _note("over", [This is yet another\ example of\ a long note.], pos: ("a", "b")) +}) \ No newline at end of file diff --git a/tests/note/position/.gitignore b/tests/note/position/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/note/position/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/note/position/ref/1.png b/tests/note/position/ref/1.png new file mode 100644 index 0000000..4ac364d Binary files /dev/null and b/tests/note/position/ref/1.png differ diff --git a/tests/note/position/ref/2.png b/tests/note/position/ref/2.png new file mode 100644 index 0000000..fb6618c Binary files /dev/null and b/tests/note/position/ref/2.png differ diff --git a/tests/note/position/ref/3.png b/tests/note/position/ref/3.png new file mode 100644 index 0000000..06d4a60 Binary files /dev/null and b/tests/note/position/ref/3.png differ diff --git a/tests/note/position/test.typ b/tests/note/position/test.typ new file mode 100644 index 0000000..4fef1cd --- /dev/null +++ b/tests/note/position/test.typ @@ -0,0 +1,49 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + + _seq("a", "b", comment: [hello]) + _note("left", [this is a first note]) + + _seq("b", "a", comment: [ok]) + _note("right", [this is another note]) + + _seq("b", "b", comment: [I am thinking]) + _note("left", [a note\ can also be defined\ on several lines]) +}) + +#pagebreak() + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + + _note("over", [initial state of Alice], pos: "a") + _note("over", [initial state of Bob], pos: "b") + _seq("b", "a", comment: [hello]) +}) + +#pagebreak() + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + _par("c", display-name: "Charlie") + _par("d", display-name: "Donald") + _par("e", display-name: "Eddie") + + _note("across", [This note float above all participants]) + + _note("over", [initial state of Alice], pos: "a") + _note("over", [initial state of Bob the builder], pos: "b", aligned: true) + + _note("over", [Note 1], pos: "a") + _note("over", [Note 2], pos: "b", aligned: true) + _note("over", [Note 3], pos: "c", aligned: true) + + _seq("a", "d") + _note("over", [this is an extremely long note], pos: ("d", "e")) +}) \ No newline at end of file diff --git a/tests/note/shape/.gitignore b/tests/note/shape/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/note/shape/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/note/shape/ref/1.png b/tests/note/shape/ref/1.png new file mode 100644 index 0000000..e9bff45 Binary files /dev/null and b/tests/note/shape/ref/1.png differ diff --git a/tests/note/shape/test.typ b/tests/note/shape/test.typ new file mode 100644 index 0000000..c14131d --- /dev/null +++ b/tests/note/shape/test.typ @@ -0,0 +1,14 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _par("caller") + _par("server") + + _seq("caller", "server", comment: [conReq]) + _note("over", [idle], pos: "caller", shape: "hex") + _seq("server", "caller", comment: [conConf]) + _note("over", ["r" as rectangle\ "h" as hexagon], pos: "server", shape: "rect") + _note("over", [this is\ on several\ lines], pos: "server", shape: "rect") + _note("over", [this is\ on several\ lines], pos: "caller", shape: "hex") +}) \ No newline at end of file diff --git a/tests/note/styled-body/.gitignore b/tests/note/styled-body/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/note/styled-body/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/note/styled-body/ref/1.png b/tests/note/styled-body/ref/1.png new file mode 100644 index 0000000..49b7d78 Binary files /dev/null and b/tests/note/styled-body/ref/1.png differ diff --git a/tests/note/styled-body/test.typ b/tests/note/styled-body/test.typ new file mode 100644 index 0000000..419a36c --- /dev/null +++ b/tests/note/styled-body/test.typ @@ -0,0 +1,33 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _par("a", display-name: [Alice]) + _par("b", display-name: [The *Famous* Bob]) + + _seq("a", "b", comment: [hello #strike([there])]) + + _gap() + _seq("b", "a", comment: [ok]) + _note("left", [ + This is *bold*\ + This is _italics_\ + This is `monospaced`\ + This is #strike([stroked])\ + This is #underline([underlined])\ + This is #underline([waved])\ + ]) + + _seq("a", "b", comment: [A _well formatted_ message]) + _note("right", [ + This is #box(text([displayed], size: 18pt), fill: rgb("#5F9EA0"))\ + #underline([left of]) Alice. + ], pos: "a") + _note("left", [ + #underline([This], stroke: red) is #text([displayed], fill: rgb("#118888"))\ + *#text([left of], fill: rgb("#800080")) #strike([Alice], stroke: red) Bob.* + ], pos: "b") + _note("over", [ + #underline([This is hosted], stroke: rgb("#FF33FF")) by #box(baseline: 50%, image("/gallery/gitea.png", width: 1cm, height: 1cm, fit: "contain")) + ], pos: ("a", "b")) +}) \ No newline at end of file diff --git a/tests/participant/shapes/.gitignore b/tests/participant/shapes/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/participant/shapes/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/participant/shapes/ref/1.png b/tests/participant/shapes/ref/1.png new file mode 100644 index 0000000..67e3f67 Binary files /dev/null and b/tests/participant/shapes/ref/1.png differ diff --git a/tests/participant/shapes/test.typ b/tests/participant/shapes/test.typ new file mode 100644 index 0000000..c130cdf --- /dev/null +++ b/tests/participant/shapes/test.typ @@ -0,0 +1,21 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + + +#let TYPST = image("/gallery/typst.png", width: 1.5cm, height: 1.5cm, fit: "contain") +#let FERRIS = image("/gallery/ferris.png", width: 1.5cm, height: 1.5cm, fit: "contain") +#let ME = image("/gallery/me.jpg", width: 1.5cm, height: 1.5cm, fit: "contain") + +#diagram({ + _par("Foo", display-name: "Participant", shape: "participant") + _par("Foo1", display-name: "Actor", shape: "actor") + _par("Foo2", display-name: "Boundary", shape: "boundary") + _par("Foo3", display-name: "Control", shape: "control") + _par("Foo4", display-name: "Entity", shape: "entity") + _par("Foo5", display-name: "Database", shape: "database") + _par("Foo6", display-name: "Collections", shape: "collections") + _par("Foo7", display-name: "Queue", shape: "queue") + _par("Foo8", display-name: "Typst", shape: "custom", custom-image: TYPST) + _par("Foo9", display-name: "Ferris", shape: "custom", custom-image: FERRIS) + _par("Foo10", display-name: "Baryhobal", shape: "custom", custom-image: ME) +}) \ No newline at end of file diff --git a/tests/sequence/comment-align/.gitignore b/tests/sequence/comment-align/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/sequence/comment-align/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/sequence/comment-align/ref/1.png b/tests/sequence/comment-align/ref/1.png new file mode 100644 index 0000000..c3a1f6c Binary files /dev/null and b/tests/sequence/comment-align/ref/1.png differ diff --git a/tests/sequence/comment-align/ref/2.png b/tests/sequence/comment-align/ref/2.png new file mode 100644 index 0000000..9823f8b Binary files /dev/null and b/tests/sequence/comment-align/ref/2.png differ diff --git a/tests/sequence/comment-align/test.typ b/tests/sequence/comment-align/test.typ new file mode 100644 index 0000000..f69d949 --- /dev/null +++ b/tests/sequence/comment-align/test.typ @@ -0,0 +1,57 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _par("alice", display-name: "Alice") + _par("bob", display-name: "Bob") + _seq("alice", "bob", comment: "This is a very long comment") + + // Left to right + _seq("alice", "bob", comment: "Start aligned", comment-align: "start") + _seq("alice", "bob", comment: "End aligned", comment-align: "end") + _seq("alice", "bob", comment: "Left aligned", comment-align: "left") + _seq("alice", "bob", comment: "Right aligned", comment-align: "right") + _seq("alice", "bob", comment: "Centered", comment-align: "center") + _gap() + + // Right to left + _seq("bob", "alice", comment: "Start aligned", comment-align: "start") + _seq("bob", "alice", comment: "End aligned", comment-align: "end") + _seq("bob", "alice", comment: "Left aligned", comment-align: "left") + _seq("bob", "alice", comment: "Right aligned", comment-align: "right") + _seq("bob", "alice", comment: "Centered", comment-align: "center") + _gap() + + // Slant left to right + _seq("alice", "bob", comment: "Start aligned", comment-align: "start", slant: 10) + _seq("alice", "bob", comment: "End aligned", comment-align: "end", slant: 10) + _seq("alice", "bob", comment: "Left aligned", comment-align: "left", slant: 10) + _seq("alice", "bob", comment: "Right aligned", comment-align: "right", slant: 10) + _seq("alice", "bob", comment: "Centered", comment-align: "center", slant: 10) + _gap() + + // Slant right to left + _seq("bob", "alice", comment: "Start aligned", comment-align: "start", slant: 10) + _seq("bob", "alice", comment: "End aligned", comment-align: "end", slant: 10) + _seq("bob", "alice", comment: "Left aligned", comment-align: "left", slant: 10) + _seq("bob", "alice", comment: "Right aligned", comment-align: "right", slant: 10) + _seq("bob", "alice", comment: "Centered", comment-align: "center", slant: 10) +}) + +#pagebreak() + +#diagram({ + _par("alice", display-name: "Alice") + + _seq("alice", "alice", comment: "Start aligned", comment-align: "start") + _seq("alice", "alice", comment: "End aligned", comment-align: "end") + _seq("alice", "alice", comment: "Left aligned", comment-align: "left") + _seq("alice", "alice", comment: "Right aligned", comment-align: "right") + _seq("alice", "alice", comment: "Centered", comment-align: "center") + + _seq("alice", "alice", comment: "Start aligned", comment-align: "start", flip: true) + _seq("alice", "alice", comment: "End aligned", comment-align: "end", flip: true) + _seq("alice", "alice", comment: "Left aligned", comment-align: "left", flip: true) + _seq("alice", "alice", comment: "Right aligned", comment-align: "right", flip: true) + _seq("alice", "alice", comment: "Centered", comment-align: "center", flip: true) +}) \ No newline at end of file diff --git a/tests/sequence/special-par/.gitignore b/tests/sequence/special-par/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/sequence/special-par/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/sequence/special-par/ref/1.png b/tests/sequence/special-par/ref/1.png new file mode 100644 index 0000000..aa44644 Binary files /dev/null and b/tests/sequence/special-par/ref/1.png differ diff --git a/tests/sequence/special-par/test.typ b/tests/sequence/special-par/test.typ new file mode 100644 index 0000000..2710cb3 --- /dev/null +++ b/tests/sequence/special-par/test.typ @@ -0,0 +1,12 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _seq("?", "Alice", comment: [?->\ *short* to actor1]) + _seq("[", "Alice", comment: [\[->\ *from start* to actor1]) + _seq("[", "Bob", comment: [\[->\ *from start* to actor2]) + _seq("?", "Bob", comment: [?->\ *short* to actor2]) + _seq("Alice", "]", comment: [->\]\ from actor1 *to end*]) + _seq("Alice", "?", comment: [->?\ *short* from actor1]) + _seq("Alice", "Bob", comment: [->\ from actor1 to actor2]) +}) diff --git a/tests/sequence/tips/.gitignore b/tests/sequence/tips/.gitignore new file mode 100644 index 0000000..40223be --- /dev/null +++ b/tests/sequence/tips/.gitignore @@ -0,0 +1,4 @@ +# generated by tytanic, do not edit + +diff/** +out/** diff --git a/tests/sequence/tips/ref/1.png b/tests/sequence/tips/ref/1.png new file mode 100644 index 0000000..c3753c5 Binary files /dev/null and b/tests/sequence/tips/ref/1.png differ diff --git a/tests/sequence/tips/ref/2.png b/tests/sequence/tips/ref/2.png new file mode 100644 index 0000000..7bba0e4 Binary files /dev/null and b/tests/sequence/tips/ref/2.png differ diff --git a/tests/sequence/tips/ref/3.png b/tests/sequence/tips/ref/3.png new file mode 100644 index 0000000..85bc2c2 Binary files /dev/null and b/tests/sequence/tips/ref/3.png differ diff --git a/tests/sequence/tips/test.typ b/tests/sequence/tips/test.typ new file mode 100644 index 0000000..e3d60bd --- /dev/null +++ b/tests/sequence/tips/test.typ @@ -0,0 +1,84 @@ +#set page(width: auto, height: auto) +#import "/src/lib.typ": * + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + + _seq("a", "b", end-tip: ">", comment: `->`) + _seq("a", "b", end-tip: ">>", comment: `->>`) + _seq("a", "b", end-tip: "\\", comment: `-\`) + _seq("a", "b", end-tip: "\\\\", comment: `-\\`) + _seq("a", "b", end-tip: "/", comment: `-/`) + _seq("a", "b", end-tip: "//", comment: `-//`) + _seq("a", "b", end-tip: "x", comment: `->x`) + _seq("a", "b", start-tip: "x", comment: `x->`) + _seq("a", "b", start-tip: "o", comment: `o->`) + _seq("a", "b", end-tip: ("o", ">"), comment: `->o`) + _seq("a", "b", start-tip: "o", end-tip: ("o", ">"), comment: `o->o`) + _seq("a", "b", start-tip: ">", end-tip: ">", comment: `<->`) + _seq("a", "b", start-tip: ("o", ">"), end-tip: ("o", ">"), comment: `o<->o`) + _seq("a", "b", start-tip: "x", end-tip: "x", comment: `x<->x`) + _seq("a", "b", end-tip: ("o", ">>"), comment: `->>o`) + _seq("a", "b", end-tip: ("o", "\\"), comment: `-\o`) + _seq("a", "b", end-tip: ("o", "\\\\"), comment: `-\\o`) + _seq("a", "b", end-tip: ("o", "/"), comment: `-/o`) + _seq("a", "b", end-tip: ("o", "//"), comment: `-//o`) + _seq("a", "b", start-tip: "x", end-tip: ("o", ">"), comment: `x->o`) +}) + +#pagebreak() + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + + _seq("b", "a", end-tip: ">", comment: `->`) + _seq("b", "a", end-tip: ">>", comment: `->>`) + _seq("b", "a", end-tip: "\\", comment: `-\`) + _seq("b", "a", end-tip: "\\\\", comment: `-\\`) + _seq("b", "a", end-tip: "/", comment: `-/`) + _seq("b", "a", end-tip: "//", comment: `-//`) + _seq("b", "a", end-tip: "x", comment: `->x`) + _seq("b", "a", start-tip: "x", comment: `x->`) + _seq("b", "a", start-tip: "o", comment: `o->`) + _seq("b", "a", end-tip: ("o", ">"), comment: `->o`) + _seq("b", "a", start-tip: "o", end-tip: ("o", ">"), comment: `o->o`) + _seq("b", "a", start-tip: ">", end-tip: ">", comment: `<->`) + _seq("b", "a", start-tip: ("o", ">"), end-tip: ("o", ">"), comment: `o<->o`) + _seq("b", "a", start-tip: "x", end-tip: "x", comment: `x<->x`) + _seq("b", "a", end-tip: ("o", ">>"), comment: `->>o`) + _seq("b", "a", end-tip: ("o", "\\"), comment: `-\o`) + _seq("b", "a", end-tip: ("o", "\\\\"), comment: `-\\o`) + _seq("b", "a", end-tip: ("o", "/"), comment: `-/o`) + _seq("b", "a", end-tip: ("o", "//"), comment: `-//o`) + _seq("b", "a", start-tip: "x", end-tip: ("o", ">"), comment: `x->o`) +}) + +#pagebreak() + +#diagram({ + _par("a", display-name: "Alice") + _par("b", display-name: "Bob") + + _seq("a", "a", end-tip: ">", comment: `->`) + _seq("a", "a", end-tip: ">>", comment: `->>`) + _seq("a", "a", end-tip: "\\", comment: `-\`) + _seq("a", "a", end-tip: "\\\\", comment: `-\\`) + _seq("a", "a", end-tip: "/", comment: `-/`) + _seq("a", "a", end-tip: "//", comment: `-//`) + _seq("a", "a", end-tip: "x", comment: `->x`) + _seq("a", "a", start-tip: "x", comment: `x->`) + _seq("a", "a", start-tip: "o", comment: `o->`) + _seq("a", "a", end-tip: ("o", ">"), comment: `->o`) + _seq("a", "a", start-tip: "o", end-tip: ("o", ">"), comment: `o->o`) + _seq("a", "a", start-tip: ">", end-tip: ">", comment: `<->`) + _seq("a", "a", start-tip: ("o", ">"), end-tip: ("o", ">"), comment: `o<->o`) + _seq("a", "a", start-tip: "x", end-tip: "x", comment: `x<->x`) + _seq("a", "a", end-tip: ("o", ">>"), comment: `->>o`) + _seq("a", "a", end-tip: ("o", "\\"), comment: `-\o`) + _seq("a", "a", end-tip: ("o", "\\\\"), comment: `-\\o`) + _seq("a", "a", end-tip: ("o", "/"), comment: `-/o`) + _seq("a", "a", end-tip: ("o", "//"), comment: `-//o`) + _seq("a", "a", start-tip: "x", end-tip: ("o", ">"), comment: `x->o`) +})