diff --git a/doc/RFC_XR_Fragments.md b/doc/RFC_XR_Fragments.md index 4b3375e..1b8fd59 100644 --- a/doc/RFC_XR_Fragments.md +++ b/doc/RFC_XR_Fragments.md @@ -115,6 +115,7 @@ XR Fragments allows us to better use implicit metadata inside 3D scene(files), b 1. [XR Fragment URL Grammar](#xr-fragment-url-grammar) 1. [Spatial Referencing 3D](#spatial-referencing-3d) 1. [Level0: Files](#level0-files) + 1. [timelines](#timelines) 1. [via href metadata](#via-href-metadata) 1. [via chained extension](#via-chained-extension) 1. [via subdocuments/xattr](#via-subdocuments-xattr) @@ -304,6 +305,16 @@ A 3D scene-file can be considered XR Fragment-compatible when it contains There are **optional** auto-loaded [side-car files]() to enable hasslefree [XR Movies](#XR%20Movies).
they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a `.glb` e.g.). +## Timelines + +when a loaded file contains a timeline (animations/subtitles e.g.), then: + +> All timelines must play (looped) by default (to enable [[XR Movies]]) + +Unless an object has multiple animations (actions e.g.), then just play the first or with name `default`. + + + ## via href metadata ``` diff --git a/doc/RFC_XR_Macros.html b/doc/RFC_XR_Macros.html deleted file mode 100644 index 8e48cf8..0000000 --- a/doc/RFC_XR_Macros.html +++ /dev/null @@ -1,465 +0,0 @@ - - - - XR Macros - - - - - - - - - - -
-

XR Macros

-
- -
-stream:    IETF
-area:      Internet
-status:    informational
-author:    Leon van Kammen
-date:      2023-04-12T00:00:00Z
-workgroup: Internet Engineering Task Force
-value:     draft-XRMACROS-leonvankammen-00
-
- - - -

Abstract

- -

This draft offers a specification for embedding macros in existing 3D scenes/assets, to offer simple interactions and configure the renderer further.
-Together with URI Fragments, it allows for rich immersive experiences without the need of a complicated sandboxed scripting languages.

- -
-

Almost every idea in this document is demonstrated at https://xrfragment.org, as this spec was created during the XR Fragments spec.

-
-
-

Introduction

- -

How can we add more features to existing text & 3D scenes, without introducing new dataformats?
-Historically, there’s many attempts to create the ultimate markuplanguage or 3D fileformat.
-Their lowest common denominator is: (co)authoring using plain text.
-Therefore, XR Macros allows us to enrich/connect existing dataformats, by offering a polyglot notation based on existing notations:

- -
    -
  1. getting/setting common used 3D properties using querystring- or JSON-notation
  2. -
  3. targeting 3D properties using the lightweight query notation present in XR Fragments
  4. -
- -
-

NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible

-
- -

Core principle

- -
    -
  1. XR Macros use querystrings, but are HTML-agnostic (though pseudo-XR Fragment browsers can be implemented on top of HTML/Javascript).
  2. -
  3. An XR Macro is 3D metadata which starts with ‘!’ (!clickme: fog=0,10 e.g.)
  4. -
  5. Metadata-values can contain the | symbol to 🎲 roundrobin variable values (!toggleme: fog=0,10|fog=0,1000 e.g.)
  6. -
  7. XR Macros acts as simple eventhandlers for URI Fragments: they are automatically published on the (XR Fragments) hashbus, to act as events (so more serious scripting languages can react to them as well).
  8. -
  9. XR Macros can assign object metadata (!setlocal: foo=1 writes foo:1 metadata to the object containing the !setlocal metadata)
  10. -
  11. XR Macros can assign global metadata (!setfoo: #foo=1 writes foo:1 metadata to the root scene-node)
  12. -
- -
-

These very simple principles allow for rich interactions and dynamic querying

-
- -

Conventions and Definitions

- -

See appendix below in case certain terms are not clear.

- -

List of XR Macros

- -

(XR) Macros can be embedded in 3D assets/scenes.
-Macros enrich existing spatial content with a lowcode, limited logic-layer, by recursive (economic) use of the querystring syntax (which search engines and XR Fragments already uses.
-This is done by allowing string/integer variables, and the | symbol to roundrobin variable values.
-Macros also act as events, so more serious scripting languages can react to them as well.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
keytypeexample (JSON)functionexisting compatibility
@bgstring"@bg":"#cube"bg: binds fog near/far based to cube x/y/z (anim) valuescustom property in 3D fileformats
@fogstring"@fog":"#cube"fog: binds fog near/far based to cube x/y (anim) valuescustom property in 3D fileformats
@scrollstring"@scroll":"#cube"texturescrolling: binds texture x/y/rot based to cube x/y/z (anim) valuescustom property in 3D fileformats
@emissivestring"@emissive":"#cube"day/night/mood: binds material’s emissive value to cube x/y/z (anim) valuescustom property in 3D fileformats
- -

Usecase: click object

- - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
!clickmebg=1,1,1&foo=2object clicked
- -

Usecase: conditional click object

- - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
#foo=1scene
!clickmeq=foo>2&bg=1,1,1object clicked and foo > 2
- -
-

when a user clicks an object with the custom properties above, it should set the backgroundcolor to 1,1,1 when foo is greater than 2 (see previous example)

-
- -

Usecase: click object (roundrobin)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
!cyclemeday|noon|nightobject clicked
daybg=1,1,1roundrobin
noonbg=0.5,0.5,0.5roundrobin
nightbg=0,0,0&foo=2roundrobin
- -
-

when a user clicks an object with the custom properties above, it should trigger either day noon or night in roundrobin fashion.

-
- -

Usecase: click object or URI fragment, and scene load trigger

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
#randomscene loaded
#randomrandomURL contains #random
!randomday|noon|night#random, # or click
daybg=1,1,1roundrobin
noonbg=0.5,0.5,0.5roundrobin
nightbg=0,0,0&foo=2roundrobin
- -

Usecase: present context menu with options

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
!random!day!noon
!daybg=1,1,1clicked in contextmenu
!noonbg=0.5,0.5,0.5clicked in contextmenu
!nightbg=0,0,0&foo=2clicked in contextmenu
- -
-

When interacting with an object with more than one !-macro, the XR Browser should offer a contextmenu to execute a macro.

-
- -

In a similar way, when any !-macro is present on the sceneroot, the XR Browser should offer a context-menu to execute those macro’s.

- -

Event Bubble-flow

- -

click object with (!clickme:AR or !clickme: !reset e.g.)

- -
  β—»
-  β”‚  
-  └── does current object contain this property-key (`AR` or `!reset` e.g.)?
-         └── no: is there any (root)object containing property `AR`
-           └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit)
-           └── no: trigger URL: #AR 
-
- -

click object with (!clickme:#AR|#VR e.g.)

- -
  β—»
-  β”‚  
-  └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click)
-      └── is there any object with property-key (`#AR` e.g.)?
-         └── no: just update the URL to `#AR`
-           └── yes: apply its value to the scene, and update the URL to `#AR`
-
-click object with (`!clickme`:`!foo|!bar|!flop` e.g.)
-
- -

β—» - β”‚
- └── apply the roundrobin (rotate the options, value !foo becomes !bar upon next click) - └── is there any object with property-key (!foo e.g.)? - └── no: do nothing - └── yes: apply its value to the scene -“`

- -
-

Note that only macro’s can trigger roundrobin values or contextmenu’s, as well as roundrobin values never ending up in the toplevel URL.

-
- -

Security Considerations

- -

IANA Considerations

- -

This document has no IANA actions.

- -

Acknowledgments

- - - -

Appendix: Definitions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
definitionexplanation
scenea (local/remote) 3D scene or 3D file (index.gltf e.g.)
3D objectan object inside a scene characterized by vertex-, face- and customproperty data.
XR fragmentsURI Fragment with spatial hints like #pos=0,0,0&t=1,100 e.g.
queryan URI Fragment-operator which queries object(s) from a scene like #q=cube
FPSframes per second in spatial experiences (games,VR,AR e.g.), should be as high as possible
β—»ascii representation of an 3D object/mesh
(un)obtrusiveobtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words
-
- - - - diff --git a/doc/RFC_XR_Macros.md b/doc/RFC_XR_Macros.md deleted file mode 100644 index c0ef009..0000000 --- a/doc/RFC_XR_Macros.md +++ /dev/null @@ -1,251 +0,0 @@ -%%% -Title = "XR Macros" -area = "Internet" -workgroup = "Internet Engineering Task Force" - -[seriesInfo] -name = "XR-Macros" -value = "draft-XRMACROS-leonvankammen-00" -stream = "IETF" -status = "informational" - -date = 2023-04-12T00:00:00Z - -[[author]] -initials="L.R." -surname="van Kammen" -fullname="L.R. van Kammen" - -%%% - - - - - -.# Abstract - -This draft offers a specification for embedding macros in existing 3D scenes/assets, to offer simple interactions and configure the renderer further.
-Together with URI Fragments, it allows for rich immersive experiences without the need of a complicated sandboxed scripting languages. - -> Almost every idea in this document is demonstrated at [https://xrfragment.org](https://xrfragment.org), as this spec was created during the [XR Fragments](https://xrfragment.org) spec. - -{mainmatter} - -# Introduction - -How can we add more features to existing text & 3D scenes, without introducing new dataformats?
-Historically, there's many attempts to create the ultimate markuplanguage or 3D fileformat.
-Their lowest common denominator is: (co)authoring using plain text.
-Therefore, XR Macros allows us to enrich/connect existing dataformats, by offering a polyglot notation based on existing notations:
- -1. getting/setting common used 3D properties using querystring- or JSON-notation -1. targeting 3D properties using the lightweight query notation present in [XR Fragments](https://xrfragment.org) - -> NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible - -# Core principle - -1. XR Macros use querystrings, but are HTML-agnostic (though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript). -1. An XR Macro is 3D metadata which starts with '!' (`!clickme: fog=0,10` e.g.) -1. Metadata-values can contain the `|` symbol to 🎲 roundrobin variable values (`!toggleme: fog=0,10|fog=0,1000` e.g.) -1. XR Macros acts as simple eventhandlers for URI Fragments: they are automatically published on the ([XR Fragments](https://xrfragment.org)) hashbus, to act as events (so more serious scripting languages can react to them as well). -1. XR Macros can assign object metadata (`!setlocal: foo=1` writes `foo:1` metadata to the object containing the `!setlocal` metadata) -1. XR Macros can assign global metadata (`!setfoo: #foo=1` writes `foo:1` metadata to the root scene-node) - -> These very simple principles allow for rich interactions and dynamic querying - -# Conventions and Definitions - -See appendix below in case certain terms are not clear. - -# List of XR Macros - -(XR) Macros can be embedded in 3D assets/scenes.
-Macros enrich existing spatial content with a lowcode, limited logic-layer, by recursive (economic) use of the querystring syntax (which search engines and [XR Fragments](https://xrfragment.org) already uses.
-This is done by allowing string/integer variables, and the `|` symbol to roundrobin variable values.
-Macros also act as events, so more serious scripting languages can react to them as well.
- -| key | type | example (JSON) | function | existing compatibility | -|--------------|----------|------------------------|---------------------|----------------------------------------| -| `@bg` | string | `"@bg":"#cube"` | bg: binds fog near/far based to cube x/y/z (anim) values | custom property in 3D fileformats | -| `@fog` | string | `"@fog":"#cube"` | fog: binds fog near/far based to cube x/y (anim) values | custom property in 3D fileformats | -| `@scroll` | string | `"@scroll":"#cube"` | texturescrolling: binds texture x/y/rot based to cube x/y/z (anim) values | custom property in 3D fileformats | -| `@emissive` | string | `"@emissive":"#cube"` | day/night/mood: binds material's emissive value to cube x/y/z (anim) values | custom property in 3D fileformats | - -## Usecase: click object - -| custom property | value | trigger when | -|-----------------|--------------------------|------------------------| -| !clickme | bg=1,1,1&foo=2 | object clicked | - -## Usecase: conditional click object - -| custom property | value | trigger when | -|-----------------|--------------------------|-----------------------------| -| # | foo=1 | scene | -| !clickme | q=foo>2&bg=1,1,1 | object clicked and foo > 2 | - -> when a user clicks an object with the custom properties above, it should set the backgroundcolor to `1,1,1` when `foo` is greater than `2` (see previous example) - -## Usecase: click object (roundrobin) - -| custom property | value | trigger when | -|-----------------|--------------------------|------------------------| -| !cycleme | day|noon|night | object clicked | -| day | bg=1,1,1 | roundrobin | -| noon | bg=0.5,0.5,0.5 | roundrobin | -| night | bg=0,0,0&foo=2 | roundrobin | - -> when a user clicks an object with the custom properties above, it should trigger either `day` `noon` or `night` in roundrobin fashion. - -## Usecase: click object or URI fragment, and scene load trigger - -| custom property | value | trigger when | -|-----------------|--------------------------|------------------------| -| # | random | scene loaded | -| #random | random | URL contains #random | -| !random | day|noon|night | #random, # or click | -| day | bg=1,1,1 | roundrobin | -| noon | bg=0.5,0.5,0.5 | roundrobin | -| night | bg=0,0,0&foo=2 | roundrobin | - -## Usecase: present context menu with options - -| custom property | value | trigger when | -|-----------------|--------------------------|------------------------| -| !random | !day|!noon|!night | clicked in contextmenu | -| !day | bg=1,1,1 | clicked in contextmenu | -| !noon | bg=0.5,0.5,0.5 | clicked in contextmenu | -| !night | bg=0,0,0&foo=2 | clicked in contextmenu | - -> When interacting with an object with more than one `!`-macro, the XR Browser should offer a contextmenu to execute a macro. - -In a similar way, when **any** `!`-macro is present on the sceneroot, the XR Browser should offer a context-menu to execute those macro's. - -## Event Bubble-flow - -click object with (`!clickme`:`AR` or `!clickme`: `!reset` e.g.) -``` - β—» - β”‚ - └── does current object contain this property-key (`AR` or `!reset` e.g.)? - └── no: is there any (root)object containing property `AR` - └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit) - └── no: trigger URL: #AR -``` - -click object with (`!clickme`:`#AR|#VR` e.g.) -``` - β—» - β”‚ - └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click) - └── is there any object with property-key (`#AR` e.g.)? - └── no: just update the URL to `#AR` - └── yes: apply its value to the scene, and update the URL to `#AR` - -click object with (`!clickme`:`!foo|!bar|!flop` e.g.) -``` - β—» - β”‚ - └── apply the roundrobin (rotate the options, value `!foo` becomes `!bar` upon next click) - └── is there any object with property-key (`!foo` e.g.)? - └── no: do nothing - └── yes: apply its value to the scene -``` - -> Note that only macro's can trigger roundrobin values or contextmenu's, as well as roundrobin values never ending up in the toplevel URL. - -# Security Considerations - - -# IANA Considerations - -This document has no IANA actions. - -# Acknowledgments - -* [NLNET](https://nlnet.nl) -* [Future of Text](https://futureoftext.org) -* [visual-meta.info](https://visual-meta.info) - -# Appendix: Definitions - -|definition | explanation | -|----------------------|-------------------------------------------------------------------------------------------------------------------------------| -|scene | a (local/remote) 3D scene or 3D file (index.gltf e.g.) | -|3D object | an object inside a scene characterized by vertex-, face- and customproperty data. | -|XR fragments | URI Fragment with spatial hints like `#pos=0,0,0&t=1,100` e.g. | -|query | an URI Fragment-operator which queries object(s) from a scene like `#q=cube` | -|FPS | frames per second in spatial experiences (games,VR,AR e.g.), should be as high as possible | -|`β—»` | ascii representation of an 3D object/mesh | -|(un)obtrusive | obtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words | - diff --git a/doc/RFC_XR_Macros.txt b/doc/RFC_XR_Macros.txt deleted file mode 100644 index e92a95f..0000000 --- a/doc/RFC_XR_Macros.txt +++ /dev/null @@ -1,392 +0,0 @@ - - - - -Internet Engineering Task Force L.R. van Kammen -Internet-Draft 24 September 2025 -Intended status: Informational - - - - XR Macros - draft-XRMACROS-leonvankammen-00 - -Abstract - - This draft offers a specification for embedding macros in existing 3D - scenes/assets, to offer simple interactions and configure the - renderer further. - Together with URI Fragments, it allows for rich immersive experiences - without the need of a complicated sandboxed scripting languages. - - Almost every idea in this document is demonstrated at - https://xrfragment.org (https://xrfragment.org), as this spec was - created during the XR Fragments (https://xrfragment.org) spec. - -Status of This Memo - - This Internet-Draft is submitted in full conformance with the - provisions of BCP 78 and BCP 79. - - Internet-Drafts are working documents of the Internet Engineering - Task Force (IETF). Note that other groups may also distribute - working documents as Internet-Drafts. The list of current Internet- - Drafts is at https://datatracker.ietf.org/drafts/current/. - - Internet-Drafts are draft documents valid for a maximum of six months - and may be updated, replaced, or obsoleted by other documents at any - time. It is inappropriate to use Internet-Drafts as reference - material or to cite them other than as "work in progress." - - This Internet-Draft will expire on 28 March 2026. - -Copyright Notice - - Copyright (c) 2025 IETF Trust and the persons identified as the - document authors. All rights reserved. - - This document is subject to BCP 78 and the IETF Trust's Legal - Provisions Relating to IETF Documents (https://trustee.ietf.org/ - license-info) in effect on the date of publication of this document. - Please review these documents carefully, as they describe your rights - and restrictions with respect to this document. Code Components - - - -van Kammen Expires 28 March 2026 [Page 1] - -Internet-Draft XR Macros September 2025 - - - extracted from this document must include Revised BSD License text as - described in Section 4.e of the Trust Legal Provisions and are - provided without warranty as described in the Revised BSD License. - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 - 2. Core principle . . . . . . . . . . . . . . . . . . . . . . . 2 - 3. Conventions and Definitions . . . . . . . . . . . . . . . . . 3 - 4. List of XR Macros . . . . . . . . . . . . . . . . . . . . . . 3 - 4.1. Usecase: click object . . . . . . . . . . . . . . . . . . 4 - 4.2. Usecase: conditional click object . . . . . . . . . . . . 4 - 4.3. Usecase: click object (roundrobin) . . . . . . . . . . . 5 - 4.4. Usecase: click object or URI fragment, and scene load - trigger . . . . . . . . . . . . . . . . . . . . . . . . . 5 - 4.5. Usecase: present context menu with options . . . . . . . 6 - 4.6. Event Bubble-flow . . . . . . . . . . . . . . . . . . . . 6 - 5. Security Considerations . . . . . . . . . . . . . . . . . . . 7 - 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7 - 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 7 - 8. Appendix: Definitions . . . . . . . . . . . . . . . . . . . . 7 - -1. Introduction - - How can we add more features to existing text & 3D scenes, without - introducing new dataformats? - Historically, there's many attempts to create the ultimate - markuplanguage or 3D fileformat. - Their lowest common denominator is: (co)authoring using plain text. - Therefore, XR Macros allows us to enrich/connect existing - dataformats, by offering a polyglot notation based on existing - notations: - - 1. getting/setting common used 3D properties using querystring- or - JSON-notation - 2. targeting 3D properties using the lightweight query notation - present in XR Fragments (https://xrfragment.org) - - | NOTE: The chapters in this document are ordered from highlevel to - | lowlevel (technical) as much as possible - -2. Core principle - - 1. XR Macros use querystrings, but are HTML-agnostic (though pseudo- - XR Fragment browsers *can* be implemented on top of HTML/ - Javascript). - 2. An XR Macro is 3D metadata which starts with '!' (!clickme: - fog=0,10 e.g.) - - - -van Kammen Expires 28 March 2026 [Page 2] - -Internet-Draft XR Macros September 2025 - - - 3. Metadata-values can contain the | symbol to 🎲 roundrobin variable - values (!toggleme: fog=0,10|fog=0,1000 e.g.) - 4. XR Macros acts as simple eventhandlers for URI Fragments: they - are automatically published on the (XR Fragments - (https://xrfragment.org)) hashbus, to act as events (so more - serious scripting languages can react to them as well). - 5. XR Macros can assign object metadata (!setlocal: foo=1 writes - foo:1 metadata to the object containing the !setlocal metadata) - 6. XR Macros can assign global metadata (!setfoo: #foo=1 writes - foo:1 metadata to the root scene-node) - - | These very simple principles allow for rich interactions and - | dynamic querying - -3. Conventions and Definitions - - See appendix below in case certain terms are not clear. - -4. List of XR Macros - - (XR) Macros can be embedded in 3D assets/scenes. - Macros enrich existing spatial content with a lowcode, limited logic- - layer, by recursive (economic) use of the querystring syntax (which - search engines and XR Fragments (https://xrfragment.org) already - uses. - This is done by allowing string/integer variables, and the | symbol - to roundrobin variable values. - Macros also act as events, so more serious scripting languages can - react to them as well. - - - - - - - - - - - - - - - - - - - - - - -van Kammen Expires 28 March 2026 [Page 3] - -Internet-Draft XR Macros September 2025 - - - +=========+======+===================+=================+=============+ - |key |type |example (JSON) |function |existing | - | | | | |compatibility| - +=========+======+===================+=================+=============+ - |@bg |string|"@bg":"#cube" |bg: binds fog |custom | - | | | |near/far based to|property in | - | | | |cube x/y/z (anim)|3D | - | | | |values |fileformats | - +---------+------+-------------------+-----------------+-------------+ - |@fog |string|"@fog":"#cube" |fog: binds fog |custom | - | | | |near/far based to|property in | - | | | |cube x/y (anim) |3D | - | | | |values |fileformats | - +---------+------+-------------------+-----------------+-------------+ - |@scroll |string|"@scroll":"#cube" |texturescrolling:|custom | - | | | |binds texture |property in | - | | | |x/y/rot based to |3D | - | | | |cube x/y/z (anim)|fileformats | - | | | |values | | - +---------+------+-------------------+-----------------+-------------+ - |@emissive|string|"@emissive":"#cube"|day/night/mood: |custom | - | | | |binds material's |property in | - | | | |emissive value to|3D | - | | | |cube x/y/z (anim)|fileformats | - | | | |values | | - +---------+------+-------------------+-----------------+-------------+ - - Table 1 - -4.1. Usecase: click object - - +=================+================+================+ - | custom property | value | trigger when | - +=================+================+================+ - | !clickme | bg=1,1,1&foo=2 | object clicked | - +-----------------+----------------+----------------+ - - Table 2 - -4.2. Usecase: conditional click object - - +=================+==================+============================+ - | custom property | value | trigger when | - +=================+==================+============================+ - | # | foo=1 | scene | - +-----------------+------------------+----------------------------+ - | !clickme | q=foo>2&bg=1,1,1 | object clicked and foo > 2 | - +-----------------+------------------+----------------------------+ - - - -van Kammen Expires 28 March 2026 [Page 4] - -Internet-Draft XR Macros September 2025 - - - Table 3 - - | when a user clicks an object with the custom properties above, it - | should set the backgroundcolor to 1,1,1 when foo is greater than 2 - | (see previous example) - -4.3. Usecase: click object (roundrobin) - - +=================+================+================+ - | custom property | value | trigger when | - +=================+================+================+ - | !cycleme | day|noon|night | object clicked | - +-----------------+----------------+----------------+ - | day | bg=1,1,1 | roundrobin | - +-----------------+----------------+----------------+ - | noon | bg=0.5,0.5,0.5 | roundrobin | - +-----------------+----------------+----------------+ - | night | bg=0,0,0&foo=2 | roundrobin | - +-----------------+----------------+----------------+ - - Table 4 - - | when a user clicks an object with the custom properties above, it - | should trigger either day noon or night in roundrobin fashion. - -4.4. Usecase: click object or URI fragment, and scene load trigger - - +=================+================+======================+ - | custom property | value | trigger when | - +=================+================+======================+ - | # | random | scene loaded | - +-----------------+----------------+----------------------+ - | #random | random | URL contains #random | - +-----------------+----------------+----------------------+ - | !random | day|noon|night | #random, # or click | - +-----------------+----------------+----------------------+ - | day | bg=1,1,1 | roundrobin | - +-----------------+----------------+----------------------+ - | noon | bg=0.5,0.5,0.5 | roundrobin | - +-----------------+----------------+----------------------+ - | night | bg=0,0,0&foo=2 | roundrobin | - +-----------------+----------------+----------------------+ - - Table 5 - - - - - - - -van Kammen Expires 28 March 2026 [Page 5] - -Internet-Draft XR Macros September 2025 - - -4.5. Usecase: present context menu with options - - +=================+================+========================+ - | custom property | value | trigger when | - +=================+================+========================+ - | !random | !day | !noon | - +-----------------+----------------+------------------------+ - | !day | bg=1,1,1 | clicked in contextmenu | - +-----------------+----------------+------------------------+ - | !noon | bg=0.5,0.5,0.5 | clicked in contextmenu | - +-----------------+----------------+------------------------+ - | !night | bg=0,0,0&foo=2 | clicked in contextmenu | - +-----------------+----------------+------------------------+ - - Table 6 - - | When interacting with an object with more than one !-macro, the XR - | Browser should offer a contextmenu to execute a macro. - - In a similar way, when *any* !-macro is present on the sceneroot, the - XR Browser should offer a context-menu to execute those macro's. - -4.6. Event Bubble-flow - - click object with (!clickme:AR or !clickme: !reset e.g.) - - β—» - β”‚ - └── does current object contain this property-key (`AR` or `!reset` e.g.)? - └── no: is there any (root)object containing property `AR` - └── yes: evaluate its (roundrobin) XR macro-value(s) (and exit) - └── no: trigger URL: #AR - - click object with (!clickme:#AR|#VR e.g.) - - β—» - β”‚ - └── apply the roundrobin (rotate the options, value `#AR` becomes `#VR` upon next click) - └── is there any object with property-key (`#AR` e.g.)? - └── no: just update the URL to `#AR` - └── yes: apply its value to the scene, and update the URL to `#AR` - -click object with (`!clickme`:`!foo|!bar|!flop` e.g.) - - β—» β”‚ - └── apply the roundrobin (rotate the options, value !foo becomes !bar - upon next click) └── is there any object with property-key (!foo - e.g.)? └── no: do nothing └── yes: apply its value to the scene ``` - - - -van Kammen Expires 28 March 2026 [Page 6] - -Internet-Draft XR Macros September 2025 - - - | Note that only macro's can trigger roundrobin values or - | contextmenu's, as well as roundrobin values never ending up in the - | toplevel URL. - -5. Security Considerations - -6. IANA Considerations - - This document has no IANA actions. - -7. Acknowledgments - - * NLNET (https://nlnet.nl) - * Future of Text (https://futureoftext.org) - * visual-meta.info (https://visual-meta.info) - -8. Appendix: Definitions - - +===============+===================================================+ - | definition | explanation | - +===============+===================================================+ - | scene | a (local/remote) 3D scene or 3D file | - | | (index.gltf e.g.) | - +---------------+---------------------------------------------------+ - | 3D object | an object inside a scene characterized by | - | | vertex-, face- and customproperty data. | - +---------------+---------------------------------------------------+ - | XR fragments | URI Fragment with spatial hints like | - | | #pos=0,0,0&t=1,100 e.g. | - +---------------+---------------------------------------------------+ - | query | an URI Fragment-operator which queries | - | | object(s) from a scene like #q=cube | - +---------------+---------------------------------------------------+ - | FPS | frames per second in spatial experiences | - | | (games,VR,AR e.g.), should be as high as | - | | possible | - +---------------+---------------------------------------------------+ - | β—» | ascii representation of an 3D object/mesh | - +---------------+---------------------------------------------------+ - | (un)obtrusive | obtrusive: wrapping human text/thought in | - | | XML/HTML/JSON obfuscates human text into | - | | a salad of machine-symbols and words | - +---------------+---------------------------------------------------+ - - Table 7 - - - - - - -van Kammen Expires 28 March 2026 [Page 7] diff --git a/doc/RFC_XR_Macros.xml b/doc/RFC_XR_Macros.xml deleted file mode 100644 index 0150e79..0000000 --- a/doc/RFC_XR_Macros.xml +++ /dev/null @@ -1,381 +0,0 @@ - - - - - -XR Macros -
-
-Internet -Internet Engineering Task Force - - -This draft offers a specification for embedding macros in existing 3D scenes/assets, to offer simple interactions and configure the renderer further.
- -Together with URI Fragments, it allows for rich immersive experiences without the need of a complicated sandboxed scripting languages.
-Almost every idea in this document is demonstrated at https://xrfragment.org, as this spec was created during the XR Fragments spec. -
- -
- - - -
Introduction -How can we add more features to existing text & 3D scenes, without introducing new dataformats?
- -Historically, there's many attempts to create the ultimate markuplanguage or 3D fileformat.
- -Their lowest common denominator is: (co)authoring using plain text.
- -Therefore, XR Macros allows us to enrich/connect existing dataformats, by offering a polyglot notation based on existing notations:
-
- -
    -
  1. getting/setting common used 3D properties using querystring- or JSON-notation
  2. -
  3. targeting 3D properties using the lightweight query notation present in XR Fragments
  4. -
-
NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible -
- -
Core principle - -
    -
  1. XR Macros use querystrings, but are HTML-agnostic (though pseudo-XR Fragment browsers can be implemented on top of HTML/Javascript).
  2. -
  3. An XR Macro is 3D metadata which starts with '!' (!clickme: fog=0,10 e.g.)
  4. -
  5. Metadata-values can contain the | symbol to 🎲 roundrobin variable values (!toggleme: fog=0,10|fog=0,1000 e.g.)
  6. -
  7. XR Macros acts as simple eventhandlers for URI Fragments: they are automatically published on the (XR Fragments) hashbus, to act as events (so more serious scripting languages can react to them as well).
  8. -
  9. XR Macros can assign object metadata (!setlocal: foo=1 writes foo:1 metadata to the object containing the !setlocal metadata)
  10. -
  11. XR Macros can assign global metadata (!setfoo: #foo=1 writes foo:1 metadata to the root scene-node)
  12. -
-
These very simple principles allow for rich interactions and dynamic querying -
- -
Conventions and Definitions -See appendix below in case certain terms are not clear. -
- -
List of XR Macros -(XR) Macros can be embedded in 3D assets/scenes.
- -Macros enrich existing spatial content with a lowcode, limited logic-layer, by recursive (economic) use of the querystring syntax (which search engines and XR Fragments already uses.
- -This is done by allowing string/integer variables, and the | symbol to roundrobin variable values.
- -Macros also act as events, so more serious scripting languages can react to them as well.
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
keytypeexample (JSON)functionexisting compatibility
@bgstring"@bg":"#cube"bg: binds fog near/far based to cube x/y/z (anim) valuescustom property in 3D fileformats
@fogstring"@fog":"#cube"fog: binds fog near/far based to cube x/y (anim) valuescustom property in 3D fileformats
@scrollstring"@scroll":"#cube"texturescrolling: binds texture x/y/rot based to cube x/y/z (anim) valuescustom property in 3D fileformats
@emissivestring"@emissive":"#cube"day/night/mood: binds material's emissive value to cube x/y/z (anim) valuescustom property in 3D fileformats
-
Usecase: click object - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
!clickmebg=1,1,1&foo=2object clicked
- -
Usecase: conditional click object - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
#foo=1scene
!clickmeq=foo>2&bg=1,1,1object clicked and foo > 2
when a user clicks an object with the custom properties above, it should set the backgroundcolor to 1,1,1 when foo is greater than 2 (see previous example) -
- -
Usecase: click object (roundrobin) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
!cyclemeday|noon|nightobject clicked
daybg=1,1,1roundrobin
noonbg=0.5,0.5,0.5roundrobin
nightbg=0,0,0&foo=2roundrobin
when a user clicks an object with the custom properties above, it should trigger either day noon or night in roundrobin fashion. -
- -
Usecase: click object or URI fragment, and scene load trigger - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
#randomscene loaded
#randomrandomURL contains #random
!randomday|noon|night#random, # or click
daybg=1,1,1roundrobin
noonbg=0.5,0.5,0.5roundrobin
nightbg=0,0,0&foo=2roundrobin
- -
Usecase: present context menu with options - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
custom propertyvaluetrigger when
!random!day!noon
!daybg=1,1,1clicked in contextmenu
!noonbg=0.5,0.5,0.5clicked in contextmenu
!nightbg=0,0,0&foo=2clicked in contextmenu
When interacting with an object with more than one !-macro, the XR Browser should offer a contextmenu to execute a macro. -
In a similar way, when any !-macro is present on the sceneroot, the XR Browser should offer a context-menu to execute those macro's. -
- -
Event Bubble-flow -click object with (!clickme:AR or !clickme: !reset e.g.) - - - -click object with (!clickme:#AR|#VR e.g.) - - - -β—» - β”‚
- └── apply the roundrobin (rotate the options, value !foo becomes !bar upon next click) - └── is there any object with property-key (!foo e.g.)? - └── no: do nothing - └── yes: apply its value to the scene -```
-
Note that only macro's can trigger roundrobin values or contextmenu's, as well as roundrobin values never ending up in the toplevel URL. -
-
- -
Security Considerations -
- -
IANA Considerations -This document has no IANA actions. -
- -
Acknowledgments - -
    -
  • NLNET
  • -
  • Future of Text
  • -
  • visual-meta.info
  • -
-
- -
Appendix: Definitions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
definitionexplanation
scenea (local/remote) 3D scene or 3D file (index.gltf e.g.)
3D objectan object inside a scene characterized by vertex-, face- and customproperty data.
XR fragmentsURI Fragment with spatial hints like #pos=0,0,0&t=1,100 e.g.
queryan URI Fragment-operator which queries object(s) from a scene like #q=cube
FPSframes per second in spatial experiences (games,VR,AR e.g.), should be as high as possible
β—»ascii representation of an 3D object/mesh
(un)obtrusiveobtrusive: wrapping human text/thought in XML/HTML/JSON obfuscates human text into a salad of machine-symbols and words
- -
- -
diff --git a/index.html b/index.html index c4bd689..bc99dbc 100644 --- a/index.html +++ b/index.html @@ -1034,6 +1034,8 @@ button.sidebar-toggle{
  • THREE template #online
  • +
  • timelines
  • +
  • Trimsheet textures
  • trimsheet.svg
  • @@ -1192,8 +1194,8 @@ button.sidebar-toggle{ {"created":"20230425164931250","title":"$:/state/folded/AFRAME template","text":"show","modified":"20230425164935940"}, {"created":"20230425164931250","title":"$:/state/folded/GLSL shader template","text":"show","modified":"20230425164939576"}, {"created":"20230424142403302","text":"checked","title":"$:/state/import/select-all","modified":"20230424142404392"}, -{"created":"20230423163640468","title":"$:/state/notebook-sidebar","text":"yes","modified":"20251021145527019"}, -{"created":"20230423163641722","title":"$:/state/notebook-sidebar-section","text":"Home","modified":"20251021152611410"}, +{"created":"20230423163640468","title":"$:/state/notebook-sidebar","text":"yes","modified":"20251023085408518"}, +{"created":"20230423163641722","title":"$:/state/notebook-sidebar-section","text":"Home","modified":"20251023085514506"}, {"created":"20230427102758222","title":"$:/state/plugin-info--1887569658-$:/plugins/ihm/tidgraph--50210113","text":"documentation","modified":"20230427102759911"}, {"created":"20230427092525294","title":"$:/state/plugin-info--391242618-$:/plugins/tiddlywiki/browser-storage","text":"yes","modified":"20230427092525375"}, {"created":"20230427093219686","title":"$:/state/plugin-info--391242618-$:/plugins/tiddlywiki/browser-storage--605768392","text":"settings","modified":"20230427094141558"}, @@ -1201,7 +1203,7 @@ button.sidebar-toggle{ {"created":"20240627123502664","title":"$:/state/plugin-info-1605320774-$:/themes/nico/notebook--1711715474","text":"contents","modified":"20240627123505187"}, {"created":"20230424093627704","title":"$:/state/plugin-info-833095967-Draft of '$:/core'---1604322978","text":"readme","modified":"20230424093629208"}, {"created":"20230423163649566","title":"$:/state/showeditpreview","text":"yes","modified":"20251008095541606"}, -{"created":"20230504174435745","title":"$:/state/sidebar","text":"β€œno”","modified":"20251021145522040"}, +{"created":"20230504174435745","title":"$:/state/sidebar","text":"β€œno”","modified":"20251023085402526"}, {"created":"20230423163453188","title":"$:/state/tab--1963855381","text":"$:/core/ui/ControlPanel/Palette","modified":"20240718192009185"}, {"created":"20230427092954391","title":"$:/state/tab--2112689675","text":"$:/core/ui/ControlPanel/Advanced","modified":"20250211170652750"}, {"created":"20230424093058379","title":"$:/state/tab--697582678","text":"$:/core/ui/ControlPanel/Settings/TiddlyWiki","modified":"20230427093030201"}, @@ -1222,15 +1224,15 @@ button.sidebar-toggle{ {"created":"20250902140446967","title":"$:/state/toc/level3-🎞 Media Fragments-1869724228","text":"close","modified":"20250902140447802"}, {"created":"20241007085320030","title":"$:/state/toc/Reference-πŸ“œ level 1 spec--403145756","text":"open","modified":"20241007085320030"}, {"created":"20241007085406064","title":"$:/state/toc/Reference-πŸ“œ level 1 spec: URL--403145756","text":"open","modified":"20241007085406064"}, -{"created":"20250924095259064","title":"$:/state/toc/Reference-πŸ“œ level0: File--403145756","text":"open","modified":"20251003091341628"}, -{"created":"20241007085601222","title":"$:/state/toc/Reference-πŸ“œ level1: URL--403145756","text":"open","modified":"20251003091534623"}, +{"created":"20250924095259064","title":"$:/state/toc/Reference-πŸ“œ level0: File--403145756","text":"close","modified":"20251023085457827"}, +{"created":"20241007085601222","title":"$:/state/toc/Reference-πŸ“œ level1: URL--403145756","text":"open","modified":"20251023085502716"}, {"created":"20250922160153227","title":"$:/state/toc/Reference-πŸ“œ level2: explicit hyperlinks--403145756","text":"close","modified":"20250928162002123"}, {"created":"20250902140915727","title":"$:/state/toc/Reference-πŸ“œ level2: explicit links--403145756","text":"open","modified":"20250903120156897"}, {"created":"20250902134831617","title":"$:/state/toc/Reference-πŸ“œ level2: implicit links--403145756","text":"open","modified":"20250902135736423"}, {"created":"20241014092040790","title":"$:/state/toc/Reference-πŸ“œ level2: metadata extras--403145756","text":"open","modified":"20250902134759706"}, {"created":"20250902135414386","title":"$:/state/toc/Reference-πŸ“œ level3: 3D timeline--403145756","text":"close","modified":"20250903113119875"}, {"created":"20250906100418403","title":"$:/state/toc/Reference-πŸ“œ level3: Media Fragments--403145756","text":"close","modified":"20250928162003452"}, -{"created":"20250926185350838","title":"$:/state/toc/Reference-πŸ“œ level4: operators--403145756","text":"open","modified":"20251006094321276"}, +{"created":"20250926185350838","title":"$:/state/toc/Reference-πŸ“œ level4: operators--403145756","text":"close","modified":"20251023085500443"}, {"created":"20250910100328163","title":"$:/state/toc/Reference-πŸ“œ level4: prefix operators--403145756","text":"open","modified":"20250920082018835"}, {"created":"20250910093903362","title":"$:/state/toc/Reference-πŸ“œ level4: scheme + operators--403145756","text":"open","modified":"20250910093903362"}, {"created":"20250910091727554","title":"$:/state/toc/Reference-πŸ“œ level4: URI scheme operators--403145756","text":"open","modified":"20250910091727554"}, @@ -1268,7 +1270,7 @@ button.sidebar-toggle{ {"created":"20230622104329622","title":"$:/state/toc/Reference/js/AFRAME-THREE.js--403145756","text":"open","modified":"20230622104329622"}, {"created":"20230622111759784","title":"$:/state/toc/Reference/The parser-THREE.js--403145756","text":"open","modified":"20230622111759784"}, {"title":"$:/status/RequireReloadDueToPluginChange","text":"no"}, -{"created":"20251021145530700","title":"$:/StoryList","text":"","list":"[[XR Fragments]]","modified":"20251021152612402"}, +{"created":"20251023085422386","title":"$:/StoryList","text":"","list":"[[XR Fragments]]","modified":"20251023085515234"}, {"created":"20230423163445948","title":"$:/theme","text":"$:/themes/nico/notebook","modified":"20240718191943667"}, {"created":"20240627122947980","text":"{\n \"tiddlers\": {\n \"$:/themes/nico/notebook/LICENSE\": {\n \"title\": \"$:/themes/nico/notebook/LICENSE\",\n \"created\": \"20200419141443144\",\n \"modified\": \"20210118213330307\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\nMIT License Copyright (c) 2020 [[Nicolas Petton|https://nicolas.petton.fr]] nicolas@petton.fr\\n\\nPermission is hereby granted, free of charge, to any person obtaining a copy\\nof this software and associated documentation files (the \\\"Software\\\"), to deal\\nin the Software without restriction, including without limitation the rights\\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\\ncopies of the Software, and to permit persons to whom the Software is furnished\\nto do so, subject to the following conditions:\\n\\nThe above copyright notice and this permission notice (including the next\\nparagraph) shall be included in all copies or substantial portions of the\\nSoftware.\\n\\nTHE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\\nOR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF\\nOR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\n\"\n },\n \"$:/themes/nico/notebook/themetweaks\": {\n \"title\": \"$:/themes/nico/notebook/themetweaks\",\n \"created\": \"20201217172915960\",\n \"modified\": \"20210123211851680\",\n \"tags\": \"$:/tags/ControlPanel/Appearance\",\n \"caption\": \"{{$:/language/ThemeTweaks/ThemeTweaks}}\",\n \"text\": \"\\\\define lingo-base() $:/language/ThemeTweaks/\\n\\nYou can tweak certain aspects of the ''Notebook'' theme.\\n\\n! \u003C\u003Clingo Options>>\\n\\n|\u003C$link to=\\\"$:/themes/nico/notebook/options/stickytitles\\\">\u003C\u003Clingo Options/StickyTitles>>\u003C/$link>\u003Cbr>//\u003C\u003Clingo Options/StickyTitles/Hint>>// |\u003C$select tiddler=\\\"$:/themes/nico/notebook/options/stickytitles\\\">\u003Coption value=\\\"no\\\">{{$:/language/No}}\u003C/option>\u003Coption value=\\\"yes\\\">{{$:/language/Yes}}\u003C/option>\u003C/$select> |\\n|\u003C$link to=\\\"$:/themes/tiddlywiki/vanilla/options/codewrapping\\\">\u003C\u003Clingo Options/CodeWrapping>>\u003C/$link> |\u003C$select tiddler=\\\"$:/themes/tiddlywiki/vanilla/options/codewrapping\\\">\u003Coption value=\\\"pre\\\">{{$:/language/No}}\u003C/option>\u003Coption value=\\\"pre-wrap\\\">{{$:/language/Yes}}\u003C/option>\u003C/$select> |\\n|\u003C$link to=\\\"$:/themes/nico/notebook/options/reveal-tiddler-controls-on-hover\\\">Reveal tiddler controls on mouseover\u003C/$link> |\u003C$select tiddler=\\\"$:/themes/nico/notebook/options/reveal-tiddler-controls-on-hover\\\">\u003Coption value=\\\"no\\\">{{$:/language/No}}\u003C/option>\u003Coption value=\\\"yes\\\">{{$:/language/Yes}}\u003C/option>\u003C/$select> |\\n\\n! \u003C\u003Clingo Settings>>\\n\\n|\u003C$link to=\\\"$:/themes/nico/notebook/settings/fontfamily\\\">\u003C\u003Clingo Settings/FontFamily>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/settings/fontfamily\\\" default=\\\"\\\" tag=\\\"input\\\"/> | |\\n|\u003C$link to=\\\"$:/themes/nico/notebook/settings/codefontfamily\\\">\u003C\u003Clingo Settings/CodeFontFamily>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/settings/codefontfamily\\\" default=\\\"\\\" tag=\\\"input\\\"/> | |\\n|\u003C$link to=\\\"$:/themes/nico/notebook/settings/editorfontfamily\\\">\u003C\u003Clingo Settings/EditorFontFamily>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/settings/editorfontfamily\\\" default=\\\"\\\" tag=\\\"input\\\"/> | |\\n\\n! \u003C\u003Clingo Metrics>>\\n\\n|\u003C$link to=\\\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\\\">\u003C\u003Clingo Metrics/FontSize>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/tiddlywiki/vanilla/metrics/fontsize\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n|\u003C$link to=\\\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\\\">\u003C\u003Clingo Metrics/LineHeight>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/tiddlywiki/vanilla/metrics/lineheight\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n|\u003C$link to=\\\"$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize\\\">\u003C\u003Clingo Metrics/BodyFontSize>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/metrics/bodyfontsize\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n|\u003C$link to=\\\"$:/themes/tiddlywiki/vanilla/metrics/bodylineheight\\\">\u003C\u003Clingo Metrics/BodyLineHeight>>\u003C/$link> |\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/metrics/bodylineheight\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n|\u003C$link to=\\\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\\\">\u003C\u003Clingo Metrics/SidebarBreakpoint>>\u003C/$link>\u003Cbr>//\u003C\u003Clingo Metrics/SidebarBreakpoint/Hint>>// |^\u003C$edit-text tiddler=\\\"$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n|\u003C$link to=\\\"$:/themes/nico/notebook/metrics/sidebar-width\\\">\u003C\u003Clingo Metrics/SidebarWidth>>\u003C/$link>\u003Cbr>//\u003C\u003Clingo Metrics/SidebarWidth/Hint>>// |^\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/metrics/sidebar-width\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n|\u003C$link to=\\\"$:/themes/nico/notebook/metrics/story-width\\\">\u003C\u003Clingo Metrics/StoryWidth>>\u003C/$link>\u003Cbr>//\u003C\u003Clingo Metrics/StoryWidth/Hint>>// |^\u003C$edit-text tiddler=\\\"$:/themes/nico/notebook/metrics/story-width\\\" default=\\\"\\\" tag=\\\"input\\\"/> |\\n\\n\"\n },\n \"$:/themes/nico/notebook/base\": {\n \"title\": \"$:/themes/nico/notebook/base\",\n \"created\": \"20200419141443144\",\n \"modified\": \"20210120224227503\",\n \"tags\": \"$:/tags/Stylesheet\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline\\n\\n\\\\define if-sidebar(text)\\n \u003C$reveal state=\\\"$:/state/notebook-sidebar\\\" type=\\\"match\\\" text=\\\"yes\\\">\\n $text$\\n \u003C/$reveal>\\n\\\\end\\n\\n\\\\define if-reveal-tiddler-controls-on-hover(text)\\n \u003C$reveal state=\\\"$:/themes/nico/notebook/options/reveal-tiddler-controls-on-hover\\\" type=\\\"match\\\" text=\\\"yes\\\">\\n $text$\\n \u003C/$reveal>\\n\\\\end\\n \\n/* Top and bottom bars */\\n\\n/* Hide the top-right bar */\\n.tc-topbar.tc-topbar-right {\\n display: none;\\n}\\n\\ndiv.tc-sidebar-header {\\n padding: 0;\\n min-height: 0;\\n}\\n\\n.tc-story-river {\\n padding: 6px 0 !important;\\n width: 100% !important;\\n max-width: {{$:/themes/nico/notebook/metrics/story-width}} !important;\\n margin: 0 auto !important;\\n margin-top: 34px !important;\\n}\\n\\ndiv.tc-tiddler-frame {\\n width: 100%;\\n margin: 20px 0;\\n background: \u003C\u003Ccolour tiddler-background>>;\\n box-shadow: 0 5px 20px rgba(0,0,0, 0.12);\\n border-radius: 6px;\\n padding: 42px 60px 60px 60px;\\n}\\n\\nh1.tc-site-title {\\n margin-top: 14px;\\n font-size: 1.5em !important;\\n}\\n\\n.nc-bar {\\n padding: 10px;\\n height: {{$:/themes/nico/notebook/metrics/topbar-height}};\\n background: \u003C\u003Ccolour page-background>>;\\n display: flex;\\n justify-content: space-between;\\n}\\n\\n.nc-topbar-wrapper {\\n position: fixed;\\n top: 0;\\n left: 0;\\n right: 0;\\n /* The z-index needs to be above the z-index used in tiddlers in zoomin view */\\n z-index: 501;\\n}\\n\\n.nc-bar.nc-topbar {\\n top: 0;\\n background: \u003C\u003Ccolour page-background>>ee;\\n max-width: calc({{$:/themes/nico/notebook/metrics/story-width}} + 40px);\\n padding: 10px 20px;\\n margin: 0 auto;\\n}\\n\\n.nc-bar.nc-bottombar {\\n position: fixed;\\n bottom: 0;\\n left: 0;\\n right: 0;\\n /* The z-index needs to be above the z-index used in tiddlers in zoomin view */\\n z-index: 501;\\n}\\n\\n.nc-bar .left svg {\\n fill: \u003C\u003Ccolour sidebar-controls-foreground>>;\\n}\\n\\n.nc-bar input[type=\\\"search\\\"] {\\n width: 200px;\\n padding: .6em 1em;\\n margin-top: -.2em;\\n background: \u003C\u003Ccolour sidebar-button-foreground>>44;\\n color: \u003C\u003Ccolour foreground>>cc;\\n transition: all ease-in .2s;\\n border: 1px solid transparent;\\n outline: 0;\\n}\\n\\n.nc-bar input[type=\\\"search\\\"]:focus {\\n width: 300px;\\n background: \u003C\u003Ccolour tiddler-background>>;\\n color: \u003C\u003Ccolour foreground>>;\\n border: 1px solid \u003C\u003Ccolour primary>>;\\n box-shadow: 0 0 .2rem 0 \u003C\u003Ccolour primary>>;\\n}\\n\\ninput[type=\\\"search\\\"]::-webkit-search-cancel-button {\\n -webkit-appearance: auto;\\n}\\n\\n.nc-bar .tc-block-dropdown.tc-search-drop-down {\\n margin-left: 0;\\n width: 400px;\\n border: 0;\\n box-shadow: 0 0 6px 0 rgba(0,0,0,.2);\\n border-radius: 6px;\\n padding: 20px 0;\\n}\\n\\n.nc-bar p {\\n margin: 0;\\n}\\n\\n.nc-bar .tc-page-controls {\\n margin-top: 0;\\n}\\n\\n.nc-bar .tc-page-controls button {\\n margin-right: .8em;\\n}\\n\\n.nc-bar .tc-page-controls button .tc-btn-text {\\n font-size: 14px;\\n}\\n\\n.nc-bar .tc-block-dropdown {\\n max-height: 70vh;\\n overflow: auto;\\n}\\n\\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .nc-topbar {\\n display: none;\\n }\\n\\n .tc-story-river {\\n padding: 0 !important;\\n margin-top: 0 !important;\\n margin-bottom: 60px !important;\\n }\\n\\n div.tc-tiddler-frame {\\n margin: 0;\\n box-shadow: none;\\n border-radius: 0;\\n border-top: 0;\\n }\\n}\\n\\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .nc-bottombar {\\n display: none;\\n }\\n}\\n\\n@media(max-width: 1100px) {\\n .nc-bar input[type=\\\"search\\\"] {\\n width: 200px;\\n }\\n}\\n\\n/* Sidebar */\\n\\n@keyframes sidebar-appear {\\n 0% {\\n left: -{{$:/themes/nico/notebook/metrics/sidebar-width}};\\n }\\n 100% {\\n left: 0;\\n }\\n}\\n\\n\u003C\u003Cif-sidebar \\\"\\\"\\\"\\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .nc-sidebar {\\n animation: sidebar-appear .14s;\\n padding-top: 10px;\\n }\\n}\\n\\\"\\\"\\\">>\\n\\n.nc-sidebar {\\n background: \u003C\u003Ccolour tiddler-background>>;\\n border-right: 1px solid \u003C\u003Ccolour tiddler-border>>;\\n width: {{$:/themes/nico/notebook/metrics/sidebar-width}};\\n overflow-y: auto;\\n overflow-x: hidden;\\n z-index: 100;\\n}\\n\\n.nc-sidebar .segment {\\n border-bottom: 1px solid rgba(0,0,0,.1);\\n}\\n\\n.nc-sidebar ol {\\n margin: 0;\\n padding: 0;\\n list-style: none;\\n line-height: 1.8em;\\n}\\n\\n.nc-sidebar ol ol {\\n padding-left: 18px;\\n}\\n\\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .mobile-only {\\n display: none;\\n }\\n}\\n\\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .desktop-only {\\n display: none;\\n }\\n}\\n\\n.nc-sidebar h1.tc-site-title {\\n margin: 0;\\n}\\n\\n.nc-sidebar p {\\n margin: 6px 0;\\n}\\n\\n.nc-sidebar .tc-site-subtitle {\\n color: \u003C\u003Ccolour site-title-foreground>>;\\n}\\n\\n.nc-sidebar .section .label {\\n padding: 2px 0;\\n color: \u003C\u003Ccolour site-title-foreground>>;\\n fill: \u003C\u003Ccolour site-title-foreground>>;\\n font-weight: bold;\\n line-height: 1.6em;\\n display: block;\\n width: 100%;\\n text-align: left;\\n padding: 8px 15px;\\n border-radius: 0;\\n}\\n\\n.nc-sidebar .section:not(.open) .label:hover {\\n background: rgba(0,0,0,.06);\\n}\\n\\n.nc-sidebar .section.open .label {\\n color: \u003C\u003Ccolour tiddler-background>>;\\n fill: \u003C\u003Ccolour tiddler-background>>;\\n background: \u003C\u003Ccolour primary>>;\\n border-bottom: 1px solid rgba(0,0,0,.1);\\n}\\n\\n.nc-sidebar .section .label .caret {\\n display: inline-block;\\n width: 15px;\\n float: right;\\n}\\n\\n.nc-sidebar .content {\\n padding: 6px 15px;\\n font-size: 1em;\\n}\\n\\n.nc-sidebar .tc-tiddlylink {\\n color: \u003C\u003Ccolour primary>>;\\n}\\n\\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .nc-sidebar {\\n position: fixed;\\n left: 0;\\n top: 0;\\n bottom: 0;\\n }\\n}\\n\\n\u003C\u003Cif-sidebar \\\"\\\"\\\"\\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n @keyframes sidebar-slide {\\n 0% {\\n left: -100vw;\\n }\\n 100% {\\n left: 0;\\n }\\n }\\n .nc-sidebar {\\n overflow: auto;\\n position: fixed;\\n width: 100%;\\n left: 0;\\n top: 0;\\n bottom: 48px;\\n z-index: 3000;\\n animation: sidebar-slide ease-in .2s;\\n animation-fill-mode: forwards;\\n }\\n}\\n\\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .tc-page-container {\\n margin-left: {{$:/themes/nico/notebook/metrics/sidebar-width}} !important;\\n }\\n\\n .nc-topbar-wrapper {\\n left: {{$:/themes/nico/notebook/metrics/sidebar-width}};\\n }\\n}\\n\\\"\\\"\\\">>\\n\\n/* Animate the hamburger button */\\n\\n@keyframes menu-bars-1 {\\n 0% {}\\n 100% {\\n transform: rotate(-45deg) translateY(-10px) translateX(-6px);\\n fill: \u003C\u003Ccolour foreground>>;\\n }\\n}\\n\\n@keyframes menu-bars-2 {\\n 0% {}\\n 100% { opacity: 0; }\\n}\\n\\n@keyframes menu-bars-3 {\\n 0% {}\\n 100% {\\n transform: rotate(45deg) translateY(6px) translateX(2px);\\n fill: \u003C\u003Ccolour foreground>>;\\n }\\n}\\n\\n.sidebar-toggle {\\n /* position: fixed; */\\n /* top: 6px; */\\n /* left: 6px; */\\n /* z-index: 600; */\\n /* padding: 4px; */\\n /* border-radius: 8px; */\\n margin-right: 10px;\\n transition: all ease-in-out .2s;\\n fill: \u003C\u003Ccolour sidebar-controls-foreground>>;\\n}\\n\\n.sidebar-toggle:hover,\\n.sidebar-toggle.open {\\n fill: \u003C\u003Ccolour sidebar-controls-foreground-hover>>;\\n}\\n\\n/* @media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) { */\\n/* .sidebar-toggle { */\\n/* top: auto; */\\n/* bottom: 10px; */\\n/* left: 10px; */\\n/* } */\\n/* } */\\n\\n.sidebar-toggle .bars .bar {\\n transform: rotate(0) translateY(0) translateX(0);\\n opacity: 1;\\n transform-origin: 20px 10px;\\n transition: transform 0.4s ease-in-out, opacity 0.2s ease-in-out, fill .4s ease-in-out;\\n}\\n\\n.sidebar-toggle .bars .bar:nth-of-type(3) {\\n transform-origin: 20px 20px;\\n}\\n\\n.sidebar-toggle.open .bars .bar:nth-of-type(1) {\\n animation: menu-bars-1 .6s;\\n animation-fill-mode: forwards;\\n}\\n.sidebar-toggle.open .bars .bar:nth-of-type(2) {\\n animation: menu-bars-2 .6s;\\n animation-fill-mode: forwards;\\n}\\n.sidebar-toggle.open .bars .bar:nth-of-type(3) {\\n animation: menu-bars-3 .6s;\\n animation-fill-mode: forwards;\\n}\\n\\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n div.tc-tiddler-frame {\\n padding: 14px;\\n }\\n}\\n\\n/* Inputs */\\n\\ninput, textarea {\\n transition: border .14s ease-in-out;\\n background: \u003C\u003Ccolour tiddler-editor-background>>;\\n border: 1px solid \u003C\u003Ccolour tiddler-editor-border>>;\\n padding: .5em;\\n border-radius: 4px;\\n}\\n\\ninput:focus, textarea:focus {\\n box-shadow: 0 0 0.2rem 0 \u003C\u003Ccolour primary>>;\\n outline: 0;\\n border-color: \u003C\u003Ccolour primary>>;\\n}\\n\\nbutton {\\n border-radius: 1.5em;\\n border: 1px solid #ccc;\\n background: \u003C\u003Ccolour tiddler-background>>;\\n padding: .3em 1em;\\n cursor: pointer;\\n transition: box-shadow ease-in .1s;\\n color: \u003C\u003Ccolor foreground>>;\\n}\\n\\nbutton:focus, button:active {\\n outline: 0 none;\\n}\\n\\nbutton.tc-btn-invisible {\\n border-radius: 0;\\n}\\n\\n.tc-editor-toolbar button,\\n.tc-editor-toolbar button.tc-btn-invisible {\\n border-radius: 3px;\\n background: \u003C\u003Ccolour tiddler-editor-background>>;\\n color: \u003C\u003Ccolour foreground>>;\\n fill: \u003C\u003Ccolour foreground>>;\\n border: 1px solid \u003C\u003Ccolour tiddler-editor-border>>;\\n}\\n\\n.tc-editor-toolbar button:hover,\\n.tc-editor-toolbar button:active {\\n border-color: \u003C\u003Ccolour primary>>;\\n background: \u003C\u003Ccolour primary>>;\\n color: \u003C\u003Ccolour background>>;\\n fill: \u003C\u003Ccolour background>>;\\n}\\n\\n.tc-tiddler-frame input.tc-edit-texteditor,\\n.tc-tiddler-frame textarea.tc-edit-texteditor,\\n.tc-tiddler-frame iframe.tc-edit-texteditor {\\n transition: border .14s ease-in-out;\\n border: 1px solid \u003C\u003Ccolour tiddler-editor-border>>;\\n background: \u003C\u003Ccolour tiddler-editor-background>>;\\n padding: 4px;\\n border-radius: 4px;\\n}\\n\\n.tc-tiddler-frame input.tc-edit-texteditor:focus,\\n.tc-tiddler-frame textarea.tc-edit-texteditor:focus,\\n.tc-tiddler-frame iframe.tc-edit-texteditor:focus {\\n box-shadow: 0 0 0.2rem 0 \u003C\u003Ccolour primary>>;\\n outline: 0;\\n border-color: \u003C\u003Ccolour primary>>;\\n}\\n\\n.tc-tiddler-controls .tc-btn-text {\\n font-size: 16px;\\n}\\n\\n\u003C\u003Cif-reveal-tiddler-controls-on-hover \\\"\\\"\\\"\\n@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .tc-tiddler-frame .tc-tiddler-controls svg {\\n opacity: 0;\\n transition: all .2s ease-in;\\n }\\n\\n .tc-tiddler-controls svg.tc-image-close-button,\\n .tc-tiddler-controls .py-toggle-todo-button svg,\\n .tc-tiddler-controls svg.tc-image-done-button,\\n .tc-tiddler-frame .tc-tiddler-controls:hover svg {\\n opacity: 1;\\n }\\n\\n .tc-tiddler-controls .py-toggle-todo-button .done svg {\\n fill: #2da562;\\n }\\n}\\n\\\"\\\"\\\">>\\n\\nbutton.tc-tag-label, span.tc-tag-label {\\n padding: 0.3em 1em !important;\\n}\\n\\n/* Fonts */\\n\\nhtml, body {\\n font-family: {{$:/themes/nico/notebook/settings/fontfamily}};\\n}\\n\\n.tc-tiddler-frame input.tc-edit-texteditor,\\n.tc-tiddler-frame textarea.tc-edit-texteditor,\\n.tc-tiddler-frame iframe.tc-edit-texteditor {\\n font-family: {{$:/themes/nico/notebook/settings/editorfontfamily}};\\n}\\n\\npre, code {\\n font-family: {{$:/themes/nico/notebook/settings/codefontfamily}};\\n}\\n\\n.tc-titlebar, .tc-site-title {\\n font-size: 28px !important;\\n line-height: 34px !important;\\n font-weight: 600 !important;\\n letter-spacing: -0.5px !important;\\n}\\n\\nh1, h2, h3, h4, h5, h6 {\\n font-weight: 600;\\n}\\n\\n.tc-tiddler-body h1,\\n.tc-tiddler-body h2,\\n.tc-tiddler-preview-preview h1,\\n.tc-tiddler-preview-preview h2 {\\n font-weight: bold;\\n}\\n\\ndiv.tc-tiddler-frame .tc-tiddler-body {\\n font-size: {{$:/themes/nico/notebook/metrics/bodyfontsize}};\\n line-height: {{$:/themes/nico/notebook/metrics/bodylineheight}};\\n}\\n\\n/* Tabs */\\n\\ndiv.tc-tab-buttons {\\n margin-bottom: -4px;\\n}\\n\\ndiv.tc-tab-buttons button {\\n font-weight: bold;\\n font-size: 1.2em;\\n line-height: 1em;\\n padding: .6em .8em .4em .8em;\\n border: 0;\\n border-radius: 0;\\n background: transparent;\\n cursor: pointer;\\n transition: background ease-in .2s;\\n}\\n\\ndiv.tc-tab-buttons button:hover {\\n background: rgba(0,0,0,.03);\\n}\\n\\ndiv.tc-tab-buttons button.tc-tab-selected {\\n border: 0;\\n background: transparent;\\n border-bottom: 4px solid \u003C\u003Ccolour primary>>;\\n}\\n\\n/* Dropdowns */\\n\\n@keyframes pop {\\n 0% {\\n transform: scale(0.8);\\n opacity: 0;\\n }\\n\\n 80% {\\n transform: scale(1.03);\\n opacity: 1;\\n }\\n\\n 100% {\\n transform: scale(1);\\n opacity: 1;\\n }\\n}\\n\\n.tc-drop-down {\\n box-shadow: 0 0 10px rgba(0,0,0,.2);\\n border-radius: 6px;\\n padding: 10px 0 !important;\\n animation: pop .15s ease-in forwards;\\n}\\n\\n.tc-drop-down a, .tc-drop-down button {\\n padding: 3px 15px !important;\\n}\\n\\n.tc-search-results {\\n line-height: 2em;\\n}\\n\\n.tc-search-results em {\\n font-weight: bold;\\n font-style: normal;\\n}\\n\\n/* Draft list */\\n\\n.tc-drafts-list {\\n font-size: .9em;\\n left: auto;\\n right: 0;\\n}\\n\\n.tc-drafts-list a {\\n padding: 6px 12px;\\n font-weight: bold;\\n border-top-left-radius: 6px;\\n border-top-right-radius: 6px;\\n display: inline-block;\\n}\\n\\n.nc-refs {\\n color: #888;\\n font-size: .9em;\\n}\\n\\n.nc-refs h4 {\\n margin-bottom: 4px;\\n}\\n\\n.nc-post-created {\\n color: #acacac;\\n font-size: .8em;\\n}\\n\"\n },\n \"$:/themes/nico/notebook/changelog\": {\n \"title\": \"$:/themes/nico/notebook/changelog\",\n \"caption\": \"ChangeLog\",\n \"created\": \"20201217180707912\",\n \"modified\": \"20210202214001915\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"! 1.4.1\\n\\n!! Fixes\\n\\n* Fix the transclusion mode of sidebar sections\\n* Fix section title rendering for tiddlers without a caption field\\n* Fix the colour of links in the sidebar when using Notebook palettes with Vanilla\\n\\n! 1.4.0\\n\\n!! Features\\n\\n* New redesigned topbar layout\\n* Add a configuration setting for the story width\\n* Add support for keyboard navigation in the search dropdown\\n\\n! 1.3.6\\n\\n!! Improvements\\n\\n* Improve the style of tabs\\n* New animation for drop-downs\\n* Use a lighter page background colour in the beige palette\\n\\n!! Fixes\\n\\n* Fix the default ctrl+shift+F shortcut for focusing the search input\\n\\n! 1.3.5\\n\\n!! Features\\n\\n* Add an option to reveal tiddler controls on mouseover\\n\\n! 1.3.4\\n\\n!! Improvements\\n\\n* Add a keyboard shortcut (alt+shift+s) to toggle Notebook sidebar\\n* Add missing colours to tiddler editor fields in the dark palette\\n\\n!! Fixes\\n\\n* Fix the size of toolbar button labels when the $:/config/Toolbar/Text is set to yes\\n\\n! 1.3.3\\n\\n!! Improvements\\n\\n* Make the sidebar more generic by using the default sidebar sections\\n\\n! 1.3.2\\n\\n!! Improvements\\n\\n* Add colours for messages in the dark palette\\n* Add colours for notification in the dark palette\\n* Set colours for messages in the beige palette\\n\\n! 1.3.1\\n\\n!! Features\\n\\n* New font family settings distinct from the Vanilla theme\\n\\n!! Improvements\\n\\n* Use a slightly lighter colour as the search input background\\n* Improve contrast of sidebar buttons in the dark palette\\n\\n!! Fixes\\n\\n* Fix tiddler control button colours in all three palettes\\n* Fix tab colours in palette-dark\\n\\n! 1.3.0\\n\\n!! Improvements\\n\\n* New dark colour palette\\n* Use a darker color for tiddler subtitles\\n* Add back the WebKit search cancel button in search inputs\\n\\n!! Fixes\\n\\n* Fix the z-index of the topbar for the zoomin story view\\n* Fix the font weight of tiddler titles in edit mode\\n\\n! 1.2.0\\n\\n!! Improvements\\n\\n* Better support for dark colour palettes\\n\\n!! Fixes\\n\\n* Fix rendering of overflowing/wrapping text in the sidebar\\n\\n! 1.1.0\\n\\n!! Features\\n\\n* New theme tweaks tab dedicated to Notebook in the control panel\\n* Inputs in the edit template are now styled consistently with other inputs\\n\\n!! Fixes\\n\\n* Fixes the position of sticky tiddler titles when the option is turned on\\n\"\n },\n \"$:/config/ShortcutInfo/notebook-focus-search\": {\n \"title\": \"$:/config/ShortcutInfo/notebook-focus-search\",\n \"text\": \"Focus on the topbar search field\"\n },\n \"$:/config/shortcuts/notebook-focus-search\": {\n \"title\": \"$:/config/shortcuts/notebook-focus-search\",\n \"text\": \"ctrl+shift+F\"\n },\n \"$:/config/Search/AutoFocus\": {\n \"title\": \"$:/config/Search/AutoFocus\",\n \"text\": \"false\"\n },\n \"$:/config/shortcuts/sidebar-search\": {\n \"title\": \"$:/config/shortcuts/sidebar-search\",\n \"text\": \"\"\n },\n \"$:/themes/nico/notebook/images/bars\": {\n \"title\": \"$:/themes/nico/notebook/images/bars\",\n \"created\": \"20200428212322206\",\n \"modified\": \"20201210210231235\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Csvg class=\\\"bars\\\" height=\\\"21pt\\\" viewBox=\\\"0 0 42 42\\\" enable-background=\\\"new 0 0 32 22.5\\\" version=\\\"1.1\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\">\\n \u003Cg class=\\\"svg-menu-toggle\\\" sketch:type=\\\"MSLayerGroup\\\">\\n \u003Crect class=\\\"bar\\\" x=\\\"8\\\" y=\\\"28\\\" width=\\\"26\\\" height=\\\"4\\\">\u003C/rect>\\n \u003Crect class=\\\"bar\\\" x=\\\"8\\\" y=\\\"19\\\" width=\\\"26\\\" height=\\\"4\\\">\u003C/rect>\\n \u003Crect class=\\\"bar\\\" x=\\\"8\\\" y=\\\"10\\\" width=\\\"26\\\" height=\\\"4\\\">\u003C/rect>\\n \u003C/g>\\n\u003C/svg>\\n\"\n },\n \"$:/themes/nico/notebook/images/caret-down\": {\n \"title\": \"$:/themes/nico/notebook/images/caret-down\",\n \"created\": \"20200429194348688\",\n \"modified\": \"20201210210230919\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Csvg width=\\\"6pt\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 320 512\\\">\u003Cpath d=\\\"M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z\\\"/>\u003C/svg>\\n\"\n },\n \"$:/themes/nico/notebook/images/caret-right\": {\n \"title\": \"$:/themes/nico/notebook/images/caret-right\",\n \"created\": \"20200429194305719\",\n \"modified\": \"20201210210230909\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Csvg width=\\\"4pt\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 192 512\\\">\u003Cpath d=\\\"M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z\\\"/>\u003C/svg>\\n\"\n },\n \"$:/themes/nico/notebook/images/color-switch\": {\n \"title\": \"$:/themes/nico/notebook/images/color-switch\",\n \"created\": \"20201210170859810\",\n \"creator\": \"nico\",\n \"modified\": \"20201210205606403\",\n \"modifier\": \"nico\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Csvg width=\\\"20px\\\" height=\\\"20px\\\" viewBox=\\\"0 0 16 16\\\" class=\\\"bi bi-circle-half\\\" fill=\\\"currentColor\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\">\\n \u003Cpath fill-rule=\\\"evenodd\\\" d=\\\"M8 15V1a7 7 0 1 1 0 14zm0 1A8 8 0 1 1 8 0a8 8 0 0 1 0 16z\\\"/>\\n\u003C/svg\\n\"\n },\n \"$:/themes/nico/notebook/metrics/bodyfontsize\": {\n \"title\": \"$:/themes/nico/notebook/metrics/bodyfontsize\",\n \"created\": \"20200428203454207\",\n \"modified\": \"20201210205606363\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"15px\\n\"\n },\n \"$:/themes/nico/notebook/metrics/bodylineheight\": {\n \"title\": \"$:/themes/nico/notebook/metrics/bodylineheight\",\n \"created\": \"20200428203454207\",\n \"modified\": \"20201210205606363\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"22px\"\n },\n \"$:/themes/nico/notebook/metrics/sidebar-width\": {\n \"title\": \"$:/themes/nico/notebook/metrics/sidebar-width\",\n \"created\": \"20200429144554294\",\n \"modified\": \"20201210210231246\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"350px\\n\"\n },\n \"$:/themes/nico/notebook/metrics/story-width\": {\n \"title\": \"$:/themes/nico/notebook/metrics/story-width\",\n \"created\": \"20210123210054185\",\n \"modified\": \"20210123211911688\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"800px\\n\"\n },\n \"$:/themes/nico/notebook/metrics/topbar-height\": {\n \"title\": \"$:/themes/nico/notebook/metrics/topbar-height\",\n \"created\": \"20200428203454207\",\n \"modified\": \"20201210205606363\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"52px\\n\"\n },\n \"$:/themes/nico/notebook/options/stickytitles\": {\n \"title\": \"$:/themes/nico/notebook/options/stickytitles\",\n \"text\": \"no\"\n },\n \"$:/themes/nico/notebook/options/codewrapping\": {\n \"title\": \"$:/themes/nico/notebook/options/codewrapping\",\n \"text\": \"pre-wrap\"\n },\n \"$:/themes/nico/notebook/options/reveal-tiddler-controls-on-hover\": {\n \"title\": \"$:/themes/nico/notebook/options/reveal-tiddler-controls-on-hover\",\n \"text\": \"no\"\n },\n \"$:/core/ui/PageTemplate/sidebar\": {\n \"title\": \"$:/core/ui/PageTemplate/sidebar\",\n \"created\": \"20200430072116835\",\n \"modified\": \"20201217174129501\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\\whitespace trim\\n\\\\define config-title()\\n$:/config/SideBarSegments/Visibility/$(listItem)$\\n\\\\end\\n\\nOverwritten by $:/themes/nico/notebook so that the default sidebar does not get rendered.\\n\"\n },\n \"$:/themes/tiddlywiki/vanilla/themetweaks\": {\n \"title\": \"$:/themes/tiddlywiki/vanilla/themetweaks\",\n \"caption\": \"{{$:/language/ThemeTweaks/ThemeTweaks}}\",\n \"created\": \"20201217163834291\",\n \"modified\": \"20201217163914434\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"Overwritten by $:/themes/nico/notebook so that the Vanilla theme tweaks do not appear in the control panel. \"\n },\n \"$:/themes/nico/notebook/palettes/palette-beige\": {\n \"title\": \"$:/themes/nico/notebook/palettes/palette-beige\",\n \"text\": \"alert-background: #ffe476\\nalert-border: #b99e2f\\nalert-highlight: #881122\\nalert-muted-foreground: #b99e2f\\nbackground: #ffffff\\nblockquote-bar: \u003C\u003Ccolour muted-foreground>>\\nbutton-background:\\nbutton-foreground:\\nbutton-border:\\ncode-background: #f7f7f9\\ncode-border: #e1e1e8\\ncode-foreground: #dd1144\\ndirty-indicator: #c63636\\ndownload-background: #66cccc\\ndownload-foreground: \u003C\u003Ccolour background>>\\ndragger-background: \u003C\u003Ccolour foreground>>\\ndragger-foreground: \u003C\u003Ccolour background>>\\ndropdown-background: \u003C\u003Ccolour background>>\\ndropdown-border: #ddd\\ndropdown-tab-background-selected: #fff\\ndropdown-tab-background: #ececec\\ndropzone-background: #da8548\\nexternal-link-background-hover: inherit\\nexternal-link-background-visited: inherit\\nexternal-link-background: inherit\\nexternal-link-foreground-hover: inherit\\nexternal-link-foreground-visited: #0000aa\\nexternal-link-foreground: #0000ee\\nforeground: #3F3B3B\\nmessage-background: #e6f5e8\\nmessage-border: #2b5532\\nmessage-foreground: #2b5532\\nmodal-backdrop: \u003C\u003Ccolour foreground>>\\nmodal-background: \u003C\u003Ccolour background>>\\nmodal-border: #999999\\nmodal-footer-background: #f5f5f5\\nmodal-footer-border: #dddddd\\nmodal-header-border: #eeeeee\\nmuted-foreground: #999999\\nnotification-background: #ffffdd\\nnotification-border: #999999\\npage-background: #f5f5ee\\npre-background: #f6f6f6\\npre-border: #cccccc\\nprimary: #7f4bca\\nselect-tag-background:\\nselect-tag-foreground:\\nsidebar-button-foreground: #a6a69c\\nsidebar-controls-foreground-hover: #000000\\nsidebar-controls-foreground: \u003C\u003Ccolour sidebar-button-foreground>>\\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\\nsidebar-foreground: #acacac\\nsidebar-muted-foreground-hover: #444444\\nsidebar-muted-foreground: #c0c0c0\\nsidebar-tab-background-selected: #ffffff\\nsidebar-tab-background: \u003C\u003Ccolour tab-background>>\\nsidebar-tab-border-selected: \u003C\u003Ccolour tab-border-selected>>\\nsidebar-tab-border: \u003C\u003Ccolour tab-border>>\\nsidebar-tab-divider: \u003C\u003Ccolour tab-divider>>\\nsidebar-tab-foreground-selected: \u003C\u003Ccolour tab-foreground-selected>>\\nsidebar-tab-foreground: \u003C\u003Ccolour tab-foreground>>\\nsidebar-tiddler-link-foreground-hover: \u003C\u003Ccolour primary>>\\nsidebar-tiddler-link-foreground: \u003C\u003Ccolour tab-foreground>>\\nsite-title-foreground: #353748\\nstatic-alert-foreground: #aaaaaa\\ntab-background-selected: #ffffff\\ntab-background: #eeeeee\\ntab-border-selected: #cccccc\\ntab-border: #cccccc\\ntab-divider: #d8d8d8\\ntab-foreground-selected: \u003C\u003Ccolour foreground>>\\ntab-foreground: #888888\\ntable-border: #dddddd\\ntable-footer-background: #a8a8a8\\ntable-header-background: #f0f0f0\\ntag-background: #ffeedd\\ntag-foreground: #000\\ntiddler-background: \u003C\u003Ccolour background>>\\ntiddler-border: #dbdbc7;\\ntiddler-controls-foreground-hover: #888888;\\ntiddler-controls-foreground-selected: #888888;\\ntiddler-controls-foreground: #cccccc\\ntiddler-editor-background: \u003C\u003Ccolour background>>\\ntiddler-editor-border-image: #ffffff\\ntiddler-editor-border: rgba(0,0,0,.2)\\ntiddler-editor-fields-even: #e0e8e0\\ntiddler-editor-fields-odd: #f0f4f0\\ntiddler-info-background: #f8f8f8\\ntiddler-info-border: #dddddd\\ntiddler-info-tab-background: #f8f8f8\\ntiddler-link-background: \u003C\u003Ccolour background>>\\ntiddler-link-foreground: \u003C\u003Ccolour primary>>\\ntiddler-subtitle-foreground: #aaaaaa\\ntiddler-title-foreground: #333\\ntoolbar-new-button:\\ntoolbar-options-button:\\ntoolbar-save-button:\\ntoolbar-info-button:\\ntoolbar-edit-button:\\ntoolbar-close-button:\\ntoolbar-delete-button:\\ntoolbar-cancel-button:\\ntoolbar-done-button:\\nuntagged-background: #999999\\nvery-muted-foreground: #888888\\n\",\n \"type\": \"application/x-tiddler-dictionary\",\n \"description\": \"A beige colour palette for Notebook\",\n \"name\": \"Notebook Beige\",\n \"tags\": \"$:/tags/Palette $:/tags/notebook/Palette\"\n },\n \"$:/themes/nico/notebook/palettes/palette-dark\": {\n \"title\": \"$:/themes/nico/notebook/palettes/palette-dark\",\n \"text\": \"alert-background: #643b43\\nalert-border: #3f181f\\nalert-highlight: #881122\\nalert-muted-foreground: #bc8b94\\nbackground: #383e49\\nblockquote-bar: \u003C\u003Ccolour muted-foreground>>\\nbutton-background:\\nbutton-border:\\nbutton-foreground:\\ncode-background: #2c323b\\ncode-border: #111\\ncode-foreground: #dd1144\\ndirty-indicator: #c63636\\ndownload-background: #98be65\\ndownload-foreground: \u003C\u003Ccolour background>>\\ndragger-background: \u003C\u003Ccolour foreground>>\\ndragger-foreground: \u003C\u003Ccolour background>>\\ndropdown-background: \u003C\u003Ccolour background>>\\ndropdown-border: #111\\ndropdown-tab-background-selected: #fff\\ndropdown-tab-background: #ececec\\ndropzone-background: #da8548\\nexternal-link-background-hover: inherit\\nexternal-link-background-visited: inherit\\nexternal-link-background: inherit\\nexternal-link-foreground-hover: inherit\\nexternal-link-foreground-visited: #61afef\\nexternal-link-foreground: #c678dd\\nforeground: #c8ced8\\nmessage-background: #2c323e\\nmessage-border: #111\\nmessage-foreground: #d5e2f1\\nmodal-backdrop: \u003C\u003Ccolour foreground>>\\nmodal-background: \u003C\u003Ccolour background>>\\nmodal-border: #999999\\nmodal-footer-background: #f5f5f5\\nmodal-footer-border: #dddddd\\nmodal-header-border: #eeeeee\\nmuted-foreground: #999999\\nnotification-background: #3a5e39\\nnotification-border: #192c19\\npage-background: #262b33\\npre-background: \u003C\u003Ccolour page-background>>\\npre-border: \u003C\u003Ccolour tiddler-border>>\\nprimary: #bf93ff\\nselect-tag-background:\\nselect-tag-foreground:\\nsidebar-button-foreground: #5e646f\\nsidebar-controls-foreground-hover: #cad2e5\\nsidebar-controls-foreground: \u003C\u003Ccolour sidebar-button-foreground>>\\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\\nsidebar-foreground: #cad2e5\\nsidebar-muted-foreground-hover: #444444\\nsidebar-muted-foreground: #c0c0c0\\nsidebar-tab-background-selected: \u003C\u003Ccolour tab-background-selected>>\\nsidebar-tab-background: \u003C\u003Ccolour tab-background>>\\nsidebar-tab-border-selected: \u003C\u003Ccolour tab-border-selected>>\\nsidebar-tab-border: \u003C\u003Ccolour tab-border>>\\nsidebar-tab-divider: \u003C\u003Ccolour tab-divider>>\\nsidebar-tab-foreground-selected: \u003C\u003Ccolour tab-foreground-selected>>\\nsidebar-tab-foreground: \u003C\u003Ccolour tab-foreground>>\\nsidebar-tiddler-link-foreground-hover: \u003C\u003Ccolour primary>>\\nsidebar-tiddler-link-foreground: \u003C\u003Ccolour tab-foreground>>\\nsite-title-foreground: \u003C\u003Ccolour foreground>>\\nstatic-alert-foreground: #aaaaaa\\ntab-background-selected: \u003C\u003Ccolour background>>\\ntab-background: \u003C\u003Ccolour page-background>>\\ntab-border-selected: \u003C\u003Ccolour foreground>>\\ntab-border: #cad2e5\\ntab-divider: #cad2e5\\ntab-foreground-selected: #ecf2ff\\ntab-foreground: #cad2e5\\ntable-border: #aaaaaa\\ntable-footer-background: #a8a8a8\\ntable-header-background: #262b33\\ntag-background: #fcb671\\ntag-foreground: #000\\ntiddler-background: \u003C\u003Ccolour background>>\\ntiddler-border: #111\\ntiddler-controls-foreground-hover: #cad2e5\\ntiddler-controls-foreground-selected: #cad2e5\\ntiddler-controls-foreground: #5e646f\\ntiddler-editor-background: \u003C\u003Ccolour background>>\\ntiddler-editor-border-image: #ffffff\\ntiddler-editor-border: rgba(255, 255, 255, 0.3)\\ntiddler-editor-fields-even: \u003C\u003Ccolour background>>\\ntiddler-editor-fields-odd: #2c323b\\ntiddler-info-background: #f8f8f8\\ntiddler-info-border: #dddddd\\ntiddler-info-tab-background: #f8f8f8\\ntiddler-link-background: \u003C\u003Ccolour background>>\\ntiddler-link-foreground: \u003C\u003Ccolour primary>>\\ntiddler-subtitle-foreground: #aaaaaa\\ntiddler-title-foreground: \u003C\u003Ccolour foreground>>\\ntoolbar-cancel-button:\\ntoolbar-close-button:\\ntoolbar-delete-button:\\ntoolbar-done-button:\\ntoolbar-edit-button:\\ntoolbar-info-button:\\ntoolbar-new-button:\\ntoolbar-options-button:\\ntoolbar-save-button:\\nuntagged-background: #999999\\nvery-muted-foreground: #888888\\n\",\n \"type\": \"application/x-tiddler-dictionary\",\n \"description\": \"A dark colour palette for Notebook\",\n \"name\": \"Notebook Dark\",\n \"tags\": \"$:/tags/Palette $:/tags/notebook/Palette\"\n },\n \"$:/themes/nico/notebook/palettes/palette-grey\": {\n \"title\": \"$:/themes/nico/notebook/palettes/palette-grey\",\n \"text\": \"alert-background: #ffe476\\nalert-border: #b99e2f\\nalert-highlight: #881122\\nalert-muted-foreground: #b99e2f\\nbackground: #ffffff\\nblockquote-bar: \u003C\u003Ccolour muted-foreground>>\\nbutton-background:\\nbutton-foreground:\\nbutton-border:\\ncode-background: #f7f7f9\\ncode-border: #e1e1e8\\ncode-foreground: #dd1144\\ndirty-indicator: #c63636\\ndownload-background: #66cccc\\ndownload-foreground: \u003C\u003Ccolour background>>\\ndragger-background: \u003C\u003Ccolour foreground>>\\ndragger-foreground: \u003C\u003Ccolour background>>\\ndropdown-background: \u003C\u003Ccolour background>>\\ndropdown-border: #ddd\\ndropdown-tab-background-selected: #fff\\ndropdown-tab-background: #ececec\\ndropzone-background: #da8548\\nexternal-link-background-hover: inherit\\nexternal-link-background-visited: inherit\\nexternal-link-background: inherit\\nexternal-link-foreground-hover: inherit\\nexternal-link-foreground-visited: #0000aa\\nexternal-link-foreground: #0000ee\\nforeground: #283c46\\nmessage-background: #ecf2ff\\nmessage-border: #cfd6e6\\nmessage-foreground: #547599\\nmodal-backdrop: \u003C\u003Ccolour foreground>>\\nmodal-background: \u003C\u003Ccolour background>>\\nmodal-border: #999999\\nmodal-footer-background: #f5f5f5\\nmodal-footer-border: #dddddd\\nmodal-header-border: #eeeeee\\nmuted-foreground: #999999\\nnotification-background: #ffffdd\\nnotification-border: #999999\\npage-background: #f4f4f4\\npre-background: #f6f6f6\\npre-border: #cccccc\\nprimary: #127edd\\nselect-tag-background:\\nselect-tag-foreground:\\nsidebar-button-foreground: #a6a69c\\nsidebar-controls-foreground-hover: #000000\\nsidebar-controls-foreground: \u003C\u003Ccolour sidebar-button-foreground>>\\nsidebar-foreground-shadow: rgba(255,255,255, 0.8)\\nsidebar-foreground: #acacac\\nsidebar-muted-foreground-hover: #444444\\nsidebar-muted-foreground: #c0c0c0\\nsidebar-tab-background-selected: #ffffff\\nsidebar-tab-background: \u003C\u003Ccolour tab-background>>\\nsidebar-tab-border-selected: \u003C\u003Ccolour tab-border-selected>>\\nsidebar-tab-border: \u003C\u003Ccolour tab-border>>\\nsidebar-tab-divider: \u003C\u003Ccolour tab-divider>>\\nsidebar-tab-foreground-selected: \u003C\u003Ccolour tab-foreground-selected>>\\nsidebar-tab-foreground: \u003C\u003Ccolour tab-foreground>>\\nsidebar-tiddler-link-foreground-hover: \u003C\u003Ccolour primary>>\\nsidebar-tiddler-link-foreground: \u003C\u003Ccolour tab-foreground>>\\nsite-title-foreground: #353748\\nstatic-alert-foreground: #aaaaaa\\ntab-background-selected: #ffffff\\ntab-background: #eeeeee\\ntab-border-selected: #cccccc\\ntab-border: #cccccc\\ntab-divider: #d8d8d8\\ntab-foreground-selected: \u003C\u003Ccolour foreground>>\\ntab-foreground: #888888\\ntable-border: #dddddd\\ntable-footer-background: #a8a8a8\\ntable-header-background: #f0f0f0\\ntag-background: #ffeedd\\ntag-foreground: #000\\ntiddler-background: \u003C\u003Ccolour background>>\\ntiddler-border: #ddd\\ntiddler-controls-foreground-hover: #888888;\\ntiddler-controls-foreground-selected: #888888;\\ntiddler-controls-foreground: #cccccc\\ntiddler-editor-background: \u003C\u003Ccolour background>>\\ntiddler-editor-border-image: #ffffff\\ntiddler-editor-border: rgba(0,0,0,.2)\\ntiddler-editor-fields-even: #e0e8e0\\ntiddler-editor-fields-odd: #f0f4f0\\ntiddler-info-background: #f8f8f8\\ntiddler-info-border: #dddddd\\ntiddler-info-tab-background: #f8f8f8\\ntiddler-link-background: \u003C\u003Ccolour background>>\\ntiddler-link-foreground: \u003C\u003Ccolour primary>>\\ntiddler-subtitle-foreground: #aaaaaa\\ntiddler-title-foreground: #333\\ntoolbar-new-button:\\ntoolbar-options-button:\\ntoolbar-save-button:\\ntoolbar-info-button:\\ntoolbar-edit-button:\\ntoolbar-close-button:\\ntoolbar-delete-button:\\ntoolbar-cancel-button:\\ntoolbar-done-button:\\nuntagged-background: #999999\\nvery-muted-foreground: #888888\\n\",\n \"type\": \"application/x-tiddler-dictionary\",\n \"description\": \"A grey color palette for Notebook\",\n \"name\": \"Notebook Grey\",\n \"tags\": \"$:/tags/Palette $:/tags/notebook/Palette\"\n },\n \"$:/themes/nico/notebook/settings/codefontfamily\": {\n \"title\": \"$:/themes/nico/notebook/settings/codefontfamily\",\n \"created\": \"20210101213404232\",\n \"modified\": \"20210101214210227\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\"Fira Mono\\\",\\\"Liberation Mono\\\",Menlo,Courier,monospace\\n\"\n },\n \"$:/themes/nico/notebook/settings/fontfamily\": {\n \"title\": \"$:/themes/nico/notebook/settings/fontfamily\",\n \"created\": \"20210101213404232\",\n \"modified\": \"20210101213411800\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\"Segoe UI\\\",Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\",\\\"Segoe UI Symbol\\\"\\n\"\n },\n \"$:/themes/nico/notebook/shortcuts/notebook-focus-search\": {\n \"title\": \"$:/themes/nico/notebook/shortcuts/notebook-focus-search\",\n \"created\": \"20201210122048919\",\n \"key\": \"((notebook-focus-search))\",\n \"modified\": \"20210115130024907\",\n \"tags\": \"$:/tags/KeyboardShortcut\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003C$action-sendmessage $message=\\\"tm-focus-selector\\\" $param=\\\".nc-topbar input\\\"/>\\n\"\n },\n \"$:/themes/nico/notebook/shortcuts/toggle-sidebar\": {\n \"title\": \"$:/themes/nico/notebook/shortcuts/toggle-sidebar\",\n \"created\": \"20210115130000707\",\n \"key\": \"((toggle-sidebar))\",\n \"modified\": \"20210115130021883\",\n \"tags\": \"$:/tags/KeyboardShortcut\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003C$list\\n filter=\\\"[[$:/state/notebook-sidebar]is[missing]] [{$:/state/notebook-sidebar}removeprefix[yes]]\\\"\\n emptyMessage=\\\"\\\"\\\"\u003C$action-setfield $tiddler=\\\"$:/state/notebook-sidebar\\\" text=\\\"yes\\\"/>\\\"\\\"\\\"\\n>\\n \u003C$action-setfield $tiddler=\\\"$:/state/notebook-sidebar\\\" text=\\\"no\\\"/>\\n\u003C/$list>\\n\"\n },\n \"$:/themes/nico/notebook/stickytitles\": {\n \"title\": \"$:/themes/nico/notebook/stickytitles\",\n \"created\": \"20201217172915960\",\n \"modified\": \"20201217180034682\",\n \"tags\": \"$:/tags/Stylesheet\",\n \"text\": \"\u003C$reveal state=\\\"$:/themes/nico/notebook/options/stickytitles\\\" type=\\\"match\\\" text=\\\"yes\\\">\\n\\n.tc-tiddler-title {\\n position: -webkit-sticky;\\n position: -moz-sticky;\\n position: -o-sticky;\\n position: -ms-sticky;\\n position: sticky;\\n top: {{$:/themes/nico/notebook/metrics/topbar-height}};\\n background: \u003C\u003Ccolour tiddler-background>>;\\n z-index: 500;\\n}\\n\\n@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics/sidebarbreakpoint}}) {\\n .tc-tiddler-title {\\n top: 0;\\n }\\n}\\n\\n\u003C$list filter=\\\"[range[100]]\\\">\\n`.tc-story-river .tc-tiddler-frame:nth-child(100n+`\u003C$text text=\u003C\u003CcurrentTiddler>>/>`) {\\nz-index: `\u003C$text text={{{ [[200]subtract\u003CcurrentTiddler>] }}}/>`;\\n}\\n`\\n\u003C/$list>\\n\u003C/$reveal>\\n\"\n },\n \"$:/themes/nico/notebook/tags/Sidebar\": {\n \"title\": \"$:/themes/nico/notebook/tags/Sidebar\",\n \"created\": \"20200429164516951\",\n \"list\": \"$:/themes/nico/notebook/ui/Buttons/menu $:/themes/nico/notebook/ui/Sidebar/Headings $:/themes/nico/notebook/ui/Sidebar/Search $:/themes/nico/notebook/Sidebar/Sections\",\n \"modified\": \"20201210205606504\",\n \"type\": \"text/vnd.tiddlywiki\"\n },\n \"$:/themes/nico/notebook/tags/SidebarSection\": {\n \"title\": \"$:/themes/nico/notebook/tags/SidebarSection\",\n \"created\": \"20200429201017275\",\n \"list\": \"$:/themes/nico/notebook/ui/Sidebar/Open $:/themes/nico/notebook/ui/Sidebar/Recent $:/themes/nico/notebook/ui/Sidebar/Tools $:/themes/nico/notebook/ui/Sidebar/More\",\n \"modified\": \"20201210215658901\",\n \"type\": \"text/vnd.tiddlywiki\"\n },\n \"$:/themes/nico/notebook/ui/Bottombar\": {\n \"title\": \"$:/themes/nico/notebook/ui/Bottombar\",\n \"created\": \"20200429113453340\",\n \"modified\": \"20201210210230886\",\n \"tags\": \"$:/tags/PageTemplate\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003C$reveal state=\\\"$:/state/notebook-bottombar\\\" type=\\\"match\\\" text=\\\"yes\\\" default=\\\"yes\\\" retain=\\\"yes\\\" animate=\\\"yes\\\">\\n \u003Cdiv class=\\\"nc-bar nc-bottombar\\\">\\n \u003C$list filter=\\\"[all[shadows+tiddlers]tag[$:/tags/NotebookTopbar]!has[draft.of]]\\\" variable=\\\"listItem\\\">\\n \u003C$reveal type=\\\"nomatch\\\" state=\u003C\u003Cconfig-title>> text=\\\"hide\\\" tag=\\\"div\\\">\\n \u003C$transclude tiddler=\u003C\u003ClistItem>> mode=\\\"block\\\"/>\\n \u003C/$reveal>\\n \u003C/$list>\\n \u003Cdiv class=\\\"left\\\">\\n {{$:/themes/nico/notebook/ui/Buttons/menu}}\\n \u003C/div>\\n \u003Cdiv class=\\\"right\\\">\\n {{$:/core/ui/SideBarSegments/page-controls}}\\n \u003C/div>\\n \u003C/div>\\n\u003C/$reveal>\\n\\n\"\n },\n \"$:/themes/nico/notebook/ui/Buttons/SwitchPalette\": {\n \"title\": \"$:/themes/nico/notebook/ui/Buttons/SwitchPalette\",\n \"created\": \"20201210171047824\",\n \"description\": \"Toggle between grey/beige colour palette\",\n \"modified\": \"20210118213335643\",\n \"tags\": \"$:/tags/PageControls\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Cspan class=\\\"desktop-only\\\">\\n \u003C$vars\\n palettes=\\\"[all[tiddlers+shadows]tag[$:/tags/notebook/Palette]]\\\"\\n popupTiddler=\u003C\u003Cqualify \\\"$:/state/notebook/palette-dropdown\\\">>\\n >\\n \u003C$button\\n popup=\u003C\u003CpopupTiddler>>\\n tooltip=\\\"Switch colours\\\"\\n aria-label=\\\"Switch colours\\\"\\n class=\u003C\u003Ctv-config-toolbar-class>>\\n >\\n \u003C$list filter=\\\"[\u003Ctv-config-toolbar-icons>match[yes]]\\\">\\n\\t{{$:/themes/nico/notebook/images/color-switch}}\\n \u003C/$list>\\n\\n \u003C$list filter=\\\"[\u003Ctv-config-toolbar-text>match[yes]]\\\">\\n\\t\u003Cspan class=\\\"tc-btn-text\\\">Switch colours\u003C/span>\\n \u003C/$list>\\n\\n \u003C$reveal state=\u003C\u003CpopupTiddler>> type=\\\"popup\\\" position=\\\"belowleft\\\" class=\\\"tc-drop-down\\\">\\n\\t\u003C$list filter=\u003C\u003Cpalettes>>>\\n\\t \u003C$button class=\\\"tc-btn-invisible\\\">\\n\\t {{!!name}}\\n\\t \u003C$action-setfield $tiddler=\\\"$:/palette\\\" text={{!!title}}/>\\n\\t \u003C/$button>\\n\\t\u003C/$list>\\n \u003C/$reveal>\\n\\n \u003C/$button>\\n \u003C/$vars>\\n\u003C/span>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Buttons/menu\": {\n \"title\": \"$:/themes/nico/notebook/ui/Buttons/menu\",\n \"created\": \"20200429115248943\",\n \"modified\": \"20210124211756417\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003C$reveal state=\\\"$:/state/notebook-sidebar\\\" type=\\\"match\\\" text=\\\"yes\\\" default=\\\"no\\\" retain=\\\"yes\\\" animate=\\\"no\\\">\\n \u003C$button set=\\\"$:/state/notebook-sidebar\\\" setTo=\\\"no\\\" tooltip=\\\"Toggle menu\\\" class=\\\"tc-btn-invisible sidebar-toggle open\\\">\\n {{$:/themes/nico/notebook/images/bars}}\\n \u003C/$button>\\n\u003C/$reveal>\\n\\n\u003C$reveal type=\\\"nomatch\\\" state=\\\"$:/state/notebook-sidebar\\\" text=\\\"yes\\\">\\n \u003C$button set=\\\"$:/state/notebook-sidebar\\\" setTo=\\\"yes\\\" tooltip=\\\"Toggle menu\\\" class=\\\"tc-btn-invisible sidebar-toggle\\\">\\n {{$:/themes/nico/notebook/images/bars}}\\n \u003C/$button>\\n\u003C/$reveal>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Search\": {\n \"title\": \"$:/themes/nico/notebook/ui/Search\",\n \"created\": \"20200429191943257\",\n \"modified\": \"20210126170723413\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\\define advanced-search-actions()\\n\u003C$action-setfield $tiddler=\\\"$:/temp/advancedsearch/input\\\" text={{$:/temp/notebook-search}}/>\\n\u003C$action-setfield $tiddler=\\\"$:/temp/advancedsearch/refresh\\\" text=\\\"yes\\\"/>\\n\u003C$action-navigate $to=\\\"$:/AdvancedSearch\\\"/>\\n\\\\end\\n\\n\\\\define input-accept-actions()\\n\u003C$list filter=\\\"[\u003C__tiddler__>get[text]!is[missing]] ~[\u003C__tiddler__>get[text]is[shadow]]\\\">\\n \u003C$action-navigate $to={{{ [\u003C__tiddler__>get[text]] }}}/>\\n \u003C$action-deletetiddler $filter=\\\"[[$:/temp/search]] [\u003CsearchTiddler>] [\u003CsearchListState>]\\\"/>\\n\u003C/$list>\\n\\\\end\\n\\n\\\\define cancel-search-actions()\\n\u003C$list filter=\\\"[\u003CsearchTiddler>get[text]!match{$:/temp/search}]\\\" emptyMessage=\\\"\\\"\\\"\u003C$action-deletetiddler $filter=\\\"[[$:/temp/search]] [\u003CsearchTiddler>] [\u003CsearchListState>]\\\"/>\\\"\\\"\\\">\\n \u003C$action-setfield $tiddler=\\\"$:/temp/search\\\" text={{{ [\u003CsearchTiddler>get[text]] }}}/>\\n \u003C$action-setfield $tiddler=\\\"$:/temp/search/refresh\\\" text=\\\"yes\\\"/>\u003C/$list>\\n\\\\end\\n\\n\u003C$vars editTiddler=\\\"$:/temp/search\\\"\\n searchTiddler=\\\"$:/temp/search/input\\\"\\n searchListState=\u003C\u003Cqualify \\\"$:/state/search-list/selected-item\\\">>>\\n \u003C$macrocall $name=\\\"keyboard-driven-input\\\"\\n\\t tiddler=\u003C\u003CeditTiddler>>\\n\\t storeTitle=\u003C\u003CsearchTiddler>>\\n\\t selectionStateTitle=\u003C\u003CsearchListState>>\\n\\t refreshTitle=\\\"$:/temp/search/refresh\\\"\\n\\t type=\\\"search\\\"\\n\\t tag=\\\"input\\\"\\n\\t focus={{$:/config/Search/AutoFocus}}\\n\\t focusPopup=\\\"$:/state/popup/notebook-search\\\"\\n\\t class=\\\"tc-popup-handle\\\"\\n\\t filterMinLength={{$:/config/Search/MinLength}}\\n\\t placeholder=\\\"Search...\\\"\\n\\t inputAcceptActions=\u003C\u003Cinput-accept-actions>>\\n\\t inputCancelActions=\u003C\u003Ccancel-search-actions>>\\n\\t cancelPopups=\\\"yes\\\"\\n\\t configTiddlerFilter=\\\"[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]\\\"\\n\\t />\\n \u003C$button\\n tooltip={{$:/language/Buttons/AdvancedSearch/Hint}}\\n aria-label={{$:/language/Buttons/AdvancedSearch/Caption}}\\n class=\\\"tc-btn-invisible tc-page-controls\\\"\\n >\\n {{$:/core/images/advanced-search-button}}\\n \u003C\u003Cadvanced-search-actions>>\\n \u003C/$button>\\n \u003C$reveal tag=\\\"div\\\" class=\\\"tc-block-dropdown-wrapper\\\" state=\\\"$:/state/popup/notebook-search\\\" type=\\\"nomatch\\\" text=\\\"\\\" default=\\\"\\\">\\n \u003C$list filter=\\\"[\u003CsearchTiddler>get[text]minlength{$:/config/Search/MinLength}limit[1]]\\\" emptyMessage=\\\"\\\" variable=\\\"listItem\\\">\\n \u003Cdiv class=\\\"tc-block-dropdown tc-search-drop-down\\\">\\n \u003C$tiddler tiddler=\u003C\u003CconfigTiddler>>>\\n {{$:/themes/nico/notebook/ui/Sidebar/SearchResults}}\\n \u003C/$tiddler>\\n \u003C/div>\\n \u003C/$list>\\n \u003C/$reveal>\\n\u003C/$vars>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Sidebar/Headings\": {\n \"title\": \"$:/themes/nico/notebook/ui/Sidebar/Headings\",\n \"created\": \"20200429160014174\",\n \"modified\": \"20201210210231267\",\n \"tags\": \"$:/themes/nico/notebook/tags/Sidebar\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Cdiv class=\\\"segment\\\">\\n \u003Cdiv class=\\\"content\\\">\\n \u003Ch1 class=\\\"tc-site-title\\\">\\n {{$:/SiteTitle}}\\n \u003C/h1>\\n \u003Cdiv class=\\\"tc-site-subtitle\\\">\\n {{$:/SiteSubtitle}}\\n \u003C/div>\\n \u003C/div>\\n\u003C/div>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Sidebar/Search\": {\n \"title\": \"$:/themes/nico/notebook/ui/Sidebar/Search\",\n \"created\": \"20200429191943257\",\n \"modified\": \"20210124220152702\",\n \"tags\": \"$:/themes/nico/notebook/tags/Sidebar\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003Cdiv class=\\\"mobile-only\\\">\\n \u003Cdiv class=\\\"segment\\\">\\n \u003Cdiv class=\\\"content search\\\">\\n {{$:/themes/nico/notebook/ui/Search}}\\n \u003C/div>\\n \u003C/div>\\n\u003C/div>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Sidebar/SearchResults\": {\n \"title\": \"$:/themes/nico/notebook/ui/Sidebar/SearchResults\",\n \"created\": \"20200429191943257\",\n \"modified\": \"20210126164631418\",\n \"tags\": \"\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\\define searchResultList()\\n \u003Csmall>{{$:/language/Search/Matches/Title}}\u003C/small>\\n\\n \u003C$list filter=\\\"[!is[system]search:title{$(searchTiddler)$}sort[title]limit[250]]\\\">\\n \u003Cspan class={{{[\u003CcurrentTiddler>addsuffix[-primaryList]] -[\u003CsearchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>\\n \u003C$transclude tiddler=\\\"$:/core/ui/ListItemTemplate\\\"/>\\n \u003C/span>\\n \u003C/$list>\\n\\n \u003Csmall>{{$:/language/Search/Matches/All}}\u003C/small>\\n\\n \u003C$list filter=\\\"[!is[system]search{$(searchTiddler)$}sort[title]limit[250]]\\\">\\n \u003Cspan class={{{[\u003CcurrentTiddler>addsuffix[-secondaryList]] -[\u003CsearchListState>get[text]] +[then[]else[tc-list-item-selected]] }}}>\\n \u003C$transclude tiddler=\\\"$:/core/ui/ListItemTemplate\\\"/>\\n \u003C/span>\\n \u003C/$list>\\n\\\\end\\n\\n\u003Cdiv class=\\\"tc-search-results\\\">\\n \u003C\u003CsearchResultList>>\\n\u003C/div>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Sidebar/SectionTemplate\": {\n \"title\": \"$:/themes/nico/notebook/ui/Sidebar/SectionTemplate\",\n \"created\": \"20200429161226897\",\n \"modified\": \"20210202213859460\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\\define sidebarHeading()\\n\u003C$vars tv-wikilinks=\\\"no\\\">\\n \u003C$transclude field=\\\"caption\\\">\\n \u003C$view field=\\\"title\\\"/>\\n \u003C/$transclude>\\n\u003C/$vars>\\n\\\\end\\n\\n\u003C$reveal state=\\\"$:/state/notebook-sidebar-section\\\" type=\\\"match\\\" text=\u003C\u003CcurrentTiddler>> default=\\\"no\\\" animate=\\\"no\\\">\\n \u003Cdiv class=\\\"segment section open\\\">\\n \u003C$button set=\\\"$:/state/notebook-sidebar-section\\\" setTo=\\\"\\\" class=\\\"tc-btn-invisible label\\\">\\n \u003C\u003CsidebarHeading>>\\n \u003Cspan class=\\\"caret\\\">{{$:/themes/nico/notebook/images/caret-down}}\u003C/span>\\n \u003C/$button>\\n \u003Cdiv class=\\\"content\\\">\\n \u003C$transclude $tiddler=\u003C\u003CcurrentTiddler>> mode=\\\"block\\\"/>\\n \u003C/div>\\n \u003C/div>\\n\u003C/$reveal>\\n\u003C$reveal state=\\\"$:/state/notebook-sidebar-section\\\" type=\\\"nomatch\\\" text=\u003C\u003CcurrentTiddler>> default=\\\"yes\\\" animate=\\\"no\\\">\\n \u003Cdiv class=\\\"segment section\\\">\\n \u003C$button set=\\\"$:/state/notebook-sidebar-section\\\" setTo=\u003C\u003CcurrentTiddler>> class=\\\"tc-btn-invisible label\\\">\\n \u003C\u003CsidebarHeading>>\\n \u003Cspan class=\\\"caret\\\">{{$:/themes/nico/notebook/images/caret-right}}\u003C/span>\\n \u003C/$button>\\n \u003C/div>\\n\u003C/$reveal>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Sidebar/Sections\": {\n \"title\": \"$:/themes/nico/notebook/ui/Sidebar/Sections\",\n \"created\": \"20200429163239707\",\n \"modified\": \"20210112213620486\",\n \"tags\": \"$:/themes/nico/notebook/tags/Sidebar\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003C$list filter=\\\"[all[shadows+tiddlers]!has[draft.of]tag[$:/tags/SideBar]]\\\">\\n {{||$:/themes/nico/notebook/ui/Sidebar/SectionTemplate}}\\n\u003C/$list>\\n\"\n },\n \"$:/themes/nico/notebook/ui/Sidebar\": {\n \"title\": \"$:/themes/nico/notebook/ui/Sidebar\",\n \"created\": \"20200428201218885\",\n \"modified\": \"20210112213605486\",\n \"tags\": \"$:/tags/PageTemplate\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\\\\whitespace trim\\n\\\\define config-title()\\n$:/config/SideBarSegments/Visibility/$(listItem)$\\n\\\\end\\n\\n\u003C$reveal state=\\\"$:/state/notebook-sidebar\\\" type=\\\"match\\\" text=\\\"yes\\\" default=\\\"no\\\" retain=\\\"yes\\\" animate=\\\"no\\\">\\n \u003C$scrollable fallthrough=\\\"no\\\">\\n \u003Cdiv class=\\\"nc-sidebar\\\">\\n \u003C$list filter=\\\"[all[shadows+tiddlers]tag[$:/themes/nico/notebook/tags/Sidebar]!has[draft.of]]\\\" variable=\\\"listItem\\\">\\n \u003C$reveal type=\\\"nomatch\\\" state=\u003C\u003Cconfig-title>> text=\\\"hide\\\" tag=\\\"div\\\">\\n \u003C$transclude tiddler=\u003C\u003ClistItem>> mode=\\\"inline\\\"/>\\n \u003C/$reveal>\\n \u003C/$list>\\n \u003C/div>\\n \u003C/$scrollable>\\n\u003C/$reveal>\\n\\n\"\n },\n \"$:/themes/nico/notebook/ui/Topbar\": {\n \"title\": \"$:/themes/nico/notebook/ui/Topbar\",\n \"created\": \"20200428203101797\",\n \"modified\": \"20210124213834458\",\n \"tags\": \"$:/tags/PageTemplate\",\n \"type\": \"text/vnd.tiddlywiki\",\n \"text\": \"\u003C$reveal state=\\\"$:/state/notebook-topbar\\\" type=\\\"match\\\" text=\\\"yes\\\" default=\\\"yes\\\" retain=\\\"yes\\\" animate=\\\"yes\\\">\\n \u003Cdiv class=\\\"nc-topbar-wrapper\\\">\\n \u003Cdiv class=\\\"nc-bar nc-topbar tc-adjust-top-of-scroll\\\">\\n \u003C$list filter=\\\"[all[shadows+tiddlers]tag[$:/tags/NotebookTopbar]!has[draft.of]]\\\" variable=\\\"listItem\\\">\\n \u003C$reveal type=\\\"nomatch\\\" state=\u003C\u003Cconfig-title>> text=\\\"hide\\\" tag=\\\"div\\\">\\n \u003C$transclude tiddler=\u003C\u003ClistItem>> mode=\\\"block\\\"/>\\n \u003C/$reveal>\\n \u003C/$list>\\n \u003Cdiv class=\\\"left\\\">\\n\\t{{$:/themes/nico/notebook/ui/Buttons/menu}}\\n {{$:/themes/nico/notebook/ui/Search}}\\n \u003C/div>\\n \u003Cdiv class=\\\"right\\\">\\n {{$:/core/ui/SideBarSegments/page-controls}}\\n \u003C/div>\\n \u003C/div>\\n \u003C/div>\\n\u003C/$reveal>\\n\\n\"\n }\n }\n}","bag":"default","revision":"0","version":"1.4.1","type":"application/json","title":"$:/themes/nico/notebook","source":"https://github.com/NicolasPetton/Notebook","plugin-type":"theme","name":"Notebook theme","list":"LICENSE changelog","description":"A clean, uncluttered TiddlyWiki theme","dependents":"$:/themes/tiddlywiki/vanilla $:/plugins/nico/notebook-mobile","core-version":">=5.1.22","author":"NicolasPetton","modified":"20240627123010609"}, {"created":"20200429144554294","title":"$:/themes/nico/notebook/metrics/sidebar-width","modified":"20230423163514560","tags":"","type":"text/vnd.tiddlywiki","text":"300px"}, @@ -1394,6 +1396,7 @@ button.sidebar-toggle{ {"created":"20230815155307052","text":"> ''IMPORTANT:'' `#pos=roomB` has been deprecated in favor of `#roomB` to simplify the spec.\n\nset the position of the camera ([[filtered|filters]] object(s)).\n\n| fragment | type | functionality |\n| \u003Cb>#roomB\u003C/b> | string | position camera to position of object with name `roomB` |\n| \u003Cb>#cam2\u003C/b> | string | position camera to position of camera with name `cam02`, and make it active camera [follow animation e.g.] |\n\n> the usercamera (default at `0,0,0`) is repositioned to the ''origin'' and ''upvector'' of the target object (1.6m height is added ''in VR only'')\n\nAnd to enable VR elevators e.g.:\n\n> the camera is attach/parented to that object (so it animates along with the object)\n\n\n\nYou can add this URI Fragment to the top-level URLbar, or as [[href]] value (to trigger via click) in a 3D model Editor (Blender e.g.):\u003Cbr>\u003Cbr>\n\n\u003Cdiv style=\"max-width:600px\">\n\u003C$videojs controls=\"controls\" aspectratio=\"16:9\" preload=\"auto\" poster=\"\" fluid=\"fluid\" class=\"vjs-big-play-centered\">\n \u003Csource src=\"https://coderofsalvation.codeberg.page/xrfragment.media/gettingstarted2024.mp4#t=295\" type=\"video/mp4\"/>\n\u003C/$videojs>\n\u003C/div>\n\n\u003Ch2>Developers only:\u003C/h2>\n\n[[Β» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]\u003Cbr>\n[[Β» discussion|https://github.com/coderofsalvation/xrfragment/issues/5]]\u003Cbr>\n\n!Spec\n\nBelow is the related section of the spec (full spec here: \u003Ca href=\"doc/RFC_XR_Fragments.html\" target=\"_blank\">HTML\u003C/a>, \u003Ca href=\"doc/RFC_XR_Fragments.txt\" target=\"_blank\">TXT\u003C/a>)\n\n\u003Ciframe sandbox=\"allow-scripts\" src=\"doc/RFC_XR_Fragments.html#navigating-3d\" frameborder=\"0\" class=\"spec\">\u003C/iframe>\n","tags":"level1 [[πŸ“œ level1: URL]] href","title":"teleport camera","modified":"20250928085400473","type":"text/vnd.tiddlywiki"}, {"created":"20230426160615931","text":"\u003Cdiv class=\"scene\">\u003C/div>\n\n\u003C\u003Cscript>>\n\u003Cscript>\n $scene = document.querySelector(\".scene\")\n\tscene = new THREE.Scene();\n camera = new THREE.PerspectiveCamera( 75, $scene.offsetWidth / $scene.offsetHeight, 0.1, 1000 );\n\n\trenderer = new THREE.WebGLRenderer();\n renderer.setSize( $scene.offsetWidth, $scene.offsetHeight );\n $scene.appendChild( renderer.domElement );\n\t\n\tvar geometry = new THREE.BoxGeometry( 1, 1, 1 );\n\tvar material = new THREE.MeshBasicMaterial( { color: 0x0a84ff } );\n\tvar cube = new THREE.Mesh( geometry, material );\n\tscene.add( cube );\n\tscene.background = new THREE.Color( 0x18181c );\n\n\tcamera.position.z = 2;\n\n\tfunction animate() {\n\t\trequestAnimationFrame( animate );\n\n\t\tcube.rotation.x += 0.004;\n\t\tcube.rotation.y += 0.004;\n\n\t\trenderer.render( scene, camera );\n\t}\n\n\tanimate();\t\n\tlog(\"hello world\")\n\u003C/script>","title":"THREE template","modified":"20230523125639178","tags":""}, {"created":"20230425154949623","text":"\u003Cscript async src=\"https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js\">\u003C/script>\n\n\u003Cscript type=\"importmap\">\n{\n\t\"imports\": {\n\t\t\"three\": \"https://unpkg.com/three@0.151.3/build/three.module.js\",\n\t\t\t\"three/addons/\": \"https://unpkg.com/three@0.151.3/examples/jsm/\"\n\t}\n}\n\u003C/script>\n\n\u003Cscript type=\"module\">\nimport * as THREE from 'three';\n\nimport { BoxLineGeometry } from 'three/addons/geometries/BoxLineGeometry.js';\nimport { VRButton } from 'three/addons/webxr/VRButton.js';\nimport { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js';\n\nlet camera, scene, raycaster, renderer;\nlet controller1, controller2;\nlet controllerGrip1, controllerGrip2;\n\nlet room, marker, floor, baseReferenceSpace;\n\nlet INTERSECTION;\nconst tempMatrix = new THREE.Matrix4();\n\ninit();\nanimate();\n\nfunction init() {\n\n\tscene = new THREE.Scene();\n\tscene.background = new THREE.Color( 0x505050 );\n\n\tcamera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 10 );\n\tcamera.position.set( 0, 1, 3 );\n\n\troom = new THREE.LineSegments(\n\t\t\tnew BoxLineGeometry( 6, 6, 6, 10, 10, 10 ).translate( 0, 3, 0 ),\n\t\t\tnew THREE.LineBasicMaterial( { color: 0x808080 } )\n\t\t\t);\n\tscene.add( room );\n\n\tscene.add( new THREE.HemisphereLight( 0x606060, 0x404040 ) );\n\n\tconst light = new THREE.DirectionalLight( 0xffffff );\n\tlight.position.set( 1, 1, 1 ).normalize();\n\tscene.add( light );\n\n\tmarker = new THREE.Mesh(\n\t\t\tnew THREE.CircleGeometry( 0.25, 32 ).rotateX( - Math.PI / 2 ),\n\t\t\tnew THREE.MeshBasicMaterial( { color: 0x808080 } )\n\t\t\t);\n\tscene.add( marker );\n\n\tfloor = new THREE.Mesh(\n\t\t\tnew THREE.PlaneGeometry( 4.8, 4.8, 2, 2 ).rotateX( - Math.PI / 2 ),\n\t\t\tnew THREE.MeshBasicMaterial( { color: 0x808080, transparent: true, opacity: 0.25 } )\n\t\t\t);\n\tscene.add( floor );\n\n\traycaster = new THREE.Raycaster();\n\n\trenderer = new THREE.WebGLRenderer( { antialias: true } );\n\trenderer.setPixelRatio( window.devicePixelRatio );\n\trenderer.setSize( window.innerWidth, window.innerHeight );\n\trenderer.outputEncoding = THREE.sRGBEncoding;\n\n\trenderer.xr.addEventListener( 'sessionstart', () => baseReferenceSpace = renderer.xr.getReferenceSpace() );\n\trenderer.xr.enabled = true;\n\n\tdocument.body.appendChild( renderer.domElement );\n\tdocument.body.appendChild( VRButton.createButton( renderer ) );\n\n\t// controllers\n\n\tfunction onSelectStart() {\n\n\t\tthis.userData.isSelecting = true;\n\n\t}\n\n\tfunction onSelectEnd() {\n\n\t\tthis.userData.isSelecting = false;\n\n\t\tif ( INTERSECTION ) {\n\n\t\t\tconst offsetPosition = { x: - INTERSECTION.x, y: - INTERSECTION.y, z: - INTERSECTION.z, w: 1 };\n\t\t\tconst offsetRotation = new THREE.Quaternion();\n\t\t\tconst transform = new XRRigidTransform( offsetPosition, offsetRotation );\n\t\t\tconst teleportSpaceOffset = baseReferenceSpace.getOffsetReferenceSpace( transform );\n\n\t\t\trenderer.xr.setReferenceSpace( teleportSpaceOffset );\n\n\t\t}\n\n\t}\n\n\tcontroller1 = renderer.xr.getController( 0 );\n\tcontroller1.addEventListener( 'selectstart', onSelectStart );\n\tcontroller1.addEventListener( 'selectend', onSelectEnd );\n\tcontroller1.addEventListener( 'connected', function ( event ) {\n\n\t\t\tthis.add( buildController( event.data ) );\n\n\t\t\t} );\n\tcontroller1.addEventListener( 'disconnected', function () {\n\n\t\t\tthis.remove( this.children[ 0 ] );\n\n\t\t\t} );\n\tscene.add( controller1 );\n\n\tcontroller2 = renderer.xr.getController( 1 );\n\tcontroller2.addEventListener( 'selectstart', onSelectStart );\n\tcontroller2.addEventListener( 'selectend', onSelectEnd );\n\tcontroller2.addEventListener( 'connected', function ( event ) {\n\n\t\t\tthis.add( buildController( event.data ) );\n\n\t\t\t} );\n\tcontroller2.addEventListener( 'disconnected', function () {\n\n\t\t\tthis.remove( this.children[ 0 ] );\n\n\t\t\t} );\n\tscene.add( controller2 );\n\n\t// The XRControllerModelFactory will automatically fetch controller models\n\t// that match what the user is holding as closely as possible. The models\n\t// should be attached to the object returned from getControllerGrip in\n\t// order to match the orientation of the held device.\n\n\tconst controllerModelFactory = new XRControllerModelFactory();\n\n\tcontrollerGrip1 = renderer.xr.getControllerGrip( 0 );\n\tcontrollerGrip1.add( controllerModelFactory.createControllerModel( controllerGrip1 ) );\n\tscene.add( controllerGrip1 );\n\n\tcontrollerGrip2 = renderer.xr.getControllerGrip( 1 );\n\tcontrollerGrip2.add( controllerModelFactory.createControllerModel( controllerGrip2 ) );\n\tscene.add( controllerGrip2 );\n\n\t//\n\n\twindow.addEventListener( 'resize', onWindowResize, false );\n\n}\n\nfunction buildController( data ) {\n\n\tlet geometry, material;\n\n\tswitch ( data.targetRayMode ) {\n\n\t\tcase 'tracked-pointer':\n\n\t\t\tgeometry = new THREE.BufferGeometry();\n\t\t\tgeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 0, 0, - 1 ], 3 ) );\n\t\t\tgeometry.setAttribute( 'color', new THREE.Float32BufferAttribute( [ 0.5, 0.5, 0.5, 0, 0, 0 ], 3 ) );\n\n\t\t\tmaterial = new THREE.LineBasicMaterial( { vertexColors: true, blending: THREE.AdditiveBlending } );\n\n\t\t\treturn new THREE.Line( geometry, material );\n\n\t\tcase 'gaze':\n\n\t\t\tgeometry = new THREE.RingGeometry( 0.02, 0.04, 32 ).translate( 0, 0, - 1 );\n\t\t\tmaterial = new THREE.MeshBasicMaterial( { opacity: 0.5, transparent: true } );\n\t\t\treturn new THREE.Mesh( geometry, material );\n\n\t}\n\n}\n\nfunction onWindowResize() {\n\n\tcamera.aspect = window.innerWidth / window.innerHeight;\n\tcamera.updateProjectionMatrix();\n\n\trenderer.setSize( window.innerWidth, window.innerHeight );\n\n}\n\n//\n\nfunction animate() {\n\trenderer.setAnimationLoop( render );\n}\n\nfunction render() {\n\n\tINTERSECTION = undefined;\n\n\tif ( controller1.userData.isSelecting === true ) {\n\t\ttempMatrix.identity().extractRotation( controller1.matrixWorld );\n\t\traycaster.ray.origin.setFromMatrixPosition( controller1.matrixWorld );\n\t\traycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );\n\t\tconst intersects = raycaster.intersectObjects( [ floor ] );\n\t\tif ( intersects.length > 0 ) {\n\t\t\tINTERSECTION = intersects[ 0 ].point;\n\t\t}\n\t} else if ( controller2.userData.isSelecting === true ) {\n\t\ttempMatrix.identity().extractRotation( controller2.matrixWorld );\n\t\traycaster.ray.origin.setFromMatrixPosition( controller2.matrixWorld );\n\t\traycaster.ray.direction.set( 0, 0, - 1 ).applyMatrix4( tempMatrix );\n\t\tconst intersects = raycaster.intersectObjects( [ floor ] );\n\t\tif ( intersects.length > 0 ) {\n\t\t\tINTERSECTION = intersects[ 0 ].point;\n\t\t}\n\t}\n\n\tif ( INTERSECTION ) marker.position.copy( INTERSECTION );\n\tmarker.visible = INTERSECTION !== undefined;\n\trenderer.render( scene, camera );\n\n}\n\n\u003C/script>\n","tags":"","title":"THREE template #online","modified":"20230523125650516","type":"text/html"}, +{"created":"20251023085406692","text":"when a loaded file contains a timeline (animations/subtitles e.g.), then:\n\n> All timelines must play (looped) by default (to enable [[XR Movies]])\n\nUnless an object has multiple animations (actions e.g.), then just play the first or with name `default`.\n\n","title":"timelines","modified":"20251023085452784","tags":"[[πŸ“œ level0: File]] level0"}, {"created":"20251021145538862","text":"> How to get things done without endlessly adding geometry/textures which bloat your 3D file?\n\n''Answer'': trim sheets\n\n!! 🧩 What’s a Trim Sheet?\n\nA ''trim sheet'' is a single texture packed with reusable material details β€” panels, bolts, edges, decals, etc.\nYou ''UV-map'' parts of your model onto sections of this sheet, instead of giving every object its own texture.\n\n[img[trimsheet.svg]]\n\n> think of it as a ''stylesheet''\n\n---\n\n!! ⚑ Superproductivity Benefits\n\n!!! One Texture, Endless Variety\n\n* Reuse trims across models for walls, pipes, floors, props.\n* Mix different UV regions for quick visual variety.\n* Perfect for modular environment design.\n\n!!! 2. ''Fast & Consistent''\n\n* Edit one sheet β†’ update all assets instantly.\n* Consistent texel density and material look across your whole scene.\n* Less time baking or re-exporting textures.\n\n---\n\n!! πŸ“¦ Tiny File Size Advantages\n\n* Fewer materials = fewer draw calls.\n* Shared texture = better batching and rendering performance.\n\n> read [[Why small file-size matters]] in XR\n\n---\n\n!! 🧠 Simple Blender Workflow\n\n1. Create your trimsheet in GIMP (put textures together into 1 file)\n\n2. Import your trim sheet.\n\n3. UV-map meshes to the desired trims.\n\n4. Align borders in the UV Editor.\n\n5. Done β€” detailed results from one small texture!\n\n---\n\n!! βœ… TL;DR\n\n| Benefit | Why It Matters |\n| ''Speed'' | Texture fast, reuse everything |\n| ''Consistency'' | Shared style across assets |\n| ''Efficiency'' | Small files, fast rendering |\n\n!! Free blender addons\n\n* https://extensions.blender.org/add-ons/magic-uv\n* https://github.com/LaXHeXLuX/Trimmer\n","tags":"[[Best practices]]","title":"Trimsheet textures","modified":"20251021152558850","type":"text/vnd.tiddlywiki"}, {"title":"trimsheet.svg","text":"\u003C?xml version=\"1.0\" standalone=\"no\"?>\n\u003C!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n\u003Csvg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 530.4122228067371 415\" width=\"530.4122228067371\" height=\"415\">\u003C!-- svg-source:excalidraw -->\u003Cmetadata>\u003C/metadata>\u003Cdefs>\u003Cstyle class=\"style-fonts\">\n @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,d09GMgABAAAAAA9YAA4AAAAAGhAAAA8GAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbhSQcNAZgAGwRCAqlEJtKCzQAATYCJANkBCAFgxgHIBsnFKOiitVE9o+EzE07zXiJXi1rrYgHYVmtTO2x4j7v+WZXztw5R1A/9tu7b1hSSxYJyaxZVSmRoVRaIRESRMhEkzdE27xPaKEVi7YxwIlNCWIiZmE0YuIiu+bVmW+v9vubJAeuTTG5KwEaCtOnscPurPIqiO3Age3QQSFXIJQs///XWn67izbt4qWJxvhn/M7HEue8GcQ8raS4odFEvDEksVD3dEIiR2qF0tik85luTqc83MtDo8sIQBsxr/r3RiFcQSBAixAa6MJSShYQHDodjUBw6qhqAIKr8vZmIIACN48hcXnsiIMIGQmUhRMHOBiQ4cLRzfy6cR8MGQsoL7ClPHCEEGvN/zk9Q7HdFpS/yx7GMfeHYEgUMbEmHYF2h78QCRkNHRMLG/8IAyYiMAXVZyZMAmFLJscjIhYTQC5MxpCAYpJjeASA5wEYKqIhs4gANVvHPp2w1wZ5OCoiTAmLcTYMdDYyUDVA0C00mnLqCuP8zAkTVpUXAfMc1fxLMysmwBBzVOYB1mk1sSPML1g/nLqwaUoDB4BQV6XzH8MmB0bnKAC3AHFTTfPouY/KBJ2mhCgDlTfajgHZC6ygix1UpY5dVykI0pYuV6OR4zuWpyLK6zJX0pKU6TIFgoiCMo30PjS99hhQnwAa43uryYNeW6fAIcgKWzKx27e5Oh67WMmR88Nj6H6dOXqBhyxF7+bl7xI+U5hsSlcQJ6lmlY413PuhSEMKw129WxixDYjNoHqJGSgRqxIDI4M8fQrIV4D19kbvjdrI1cK9e+V6Bw1rVtAv2GSyAaYmhUbNIKWUQkoA2SWGpEZbYfIQ+Sd40DUSv2tZK3U3iACzAhD6N3ZxjrJsgKZrXTM4ftpsu/U8VxVuVQ2MMWMMZbpe55bcncp3Uk5Ie0rYhEB5WW66LWzhdbsfuk8Wyrmbvc+reBuR0AfyBt8epKn1Qe194s7nO9670rk1QiwbMO1UNHATmzQBWZdUGWKRtoTrCwfVXo7G9sBMff5cGGctWNwMJvrPXsHU6g6HQf8v+JOu9QFqRABha34I+3I9fdaHFJCek+RrWCW5daujXjzAemEGDk0pgCmkDpVwDkJCQLKDMS5CKHKFcIPal4NvKvXOzt3l6+y63vr+32/dXK6oeLFayTlvfOmSpigIZ7jzg7fk9KIcC2/3xgsJxTnx62pm4HOEQEJ9ir80+O4vPML3UX5k3uu8OfhCbe8+6k+EYaEBcMJQG7H7YPRznd8MYXg6lTWP9jV/18jBaxiK8rKulLMoi1bFq/CZuGPFSo9r9BEMl9u+3RAFrRgazkkYAmLg6nP35Spx6q3bfGYGlvJIZuTHhDetjirP6sJ3cvmUOJYY+Ey1oU3Jk4tna92T3aL2dNsqsUO4uZealKZBYHZflOMzVfywN174/7ObZYNSuzY0A0hf9VcHVveesmJVfmvgE4/zpTNq7xMzOOwD38CIncgezo4TQEi/Pzc1A/WjrHaa6XqIWqIg7ObtdbOryN+4Op+X8mrytSfA7C5i4A1Mr0d1bnXUdF6ayVeuZBxdSs0K7iBtXy5TXtcMJp7J5XLMJ3jJTZJ9Rlm7HD9ZTTlFn5Dup01wLVkzQCzPUVSOt9Oi3wqnoN9saAWe1MGIzbejaX1GVabVitgMJnwKHapNCqGFstUqUkCcUYlFup5x6z4sNpa/qQxLT1an67WhKi/UFifuOA3OdBgWSIIye0mbTeuRQXrYBcA+QOcRkGSI6brBgLDJ37UNoXwFa+vuwMDRv5ooNKoH9FhZ9RLT60MYFEPNb2p8YcHiw6E13MnTOVqUmuO3tBCQxHl///H8Uo/VrSfeEzOQh+UmYZNR8t4LlKqwKGIDlBsYJID0wMMCabQ0OgfT64QwxlDu1vO66qjyzJ+zXTNYLZ1fdlOcGOUHDF9owgkLvZvBRuUO3h97aIe7H21Pb97b++Lkh919zQc9A2fIGI2PzwIyCyaLNCQNAoiBn5fcttsuxzWeQko13/F4bL3bTxcX0w9mUOMxynKUu2wQofbei8oL0uDwPF9rHL8loyQBpAEfyQmp+fbbfM/9v++vYXfb5XxlvDRCCcAjdC36Zh1r74OTlj7c3i9SCVd3P3S3b18c64FkJADeBi6YRf56mtY4wuLfI17NabE4CWZ7X0+R0d84y24k6kFqEbZ/rwF7jqLpSOlc19lKPrT4otnT88CsNrmeptQM1iqv0rnAH2dymsL+mA+avlzSGicOZmjwekO+NDrSLje0/7DGnxWlUwzDPqS3of0X+DC24sq9tXw1NS9jZ+x4Oz2ZCQgZwdjBSSlLt0TT06VSPdLHHqvzg35aH2pauISafLhgWfE9vetkQEM4Dc4VabE2fKPKfCs/yDlDVn9M2PI/XvLQ+O6KYLXfvrUCnZVFyFn5TD45nVJaehi4KWlbX7ebqRc9yNOyoSmGEbyZHAr1MR62y2ZbzlghYVsul+R+61j4ZV5Qgv4npwgaBLXYN3B2A0Kdi8QLhyC4QjCTDrMmHh4ugyjQymchylSmGSNmsWedXIp/xe1CXdv1LbYQBchV/BTp74Tk2+cCPdBpUgw4IQHTiDrsKaf2x/BIY5zIIfoBCjIWGNFmmzf3ChlhER9MPKIPwpTwPW0yZAlz0JwFbJP318Ys3DDYXKT1YsiZOtYuddbsHXaDDrPQGCUDJ/m+k4ZxGfpqjrPLhIhJs90Ys9QeHBvSO+n7QHiyNeSI1S1+ONfYURj1K76dREmEb4KgOmj5UC/x7rzasSzUOft7aDa0xUfxYN4jpoj5ULIwnEzt0Ftpnu6+pBSpuAvK6udX0uvzELprRkjzrPPiE26/kC05yob/tIXDonPq+eagtRpppYMNv1PxWoZvVUp9i729JSxwCH+sdZWPrb+Rns31h/wTdgbaxBMTXdIJzLpZ6jNFheP4aXxxoetYejr6G2ABFSuMh6WqlTytj741S1fMvA71qUpEugmqJFQ5OW+zHa0TADLFZvJLUpCKoMy+eJY79x2NW3+HOZ3s8QFzGe7hMgaxDJC+8Eqc5a2wiNX2kdNTVKH5OYzjPSeOZzFNX17NC5Smk/Yb72WfZhaAItoBQcanSsbtX7ixefwgXqnPC81xUfXFeNnxA8ilr5GXpr6c+NFXtRvWRS/5HPY7FdrUgDlUBNfuYrCMFXry1rqfeEYsgZQ+uCeN+jDJNw4hIE4CHsKzpbEYJXDMjg9W9+kqYJFRG6TeqVJNeXCuh7smyet1OIHT9M6tudnFZD58XLXEvlXE/54bGDuVuxA2kbKqlMAn54i0uj4uI8X1U+WB1ox4OZqRj/C4ysZ7J+nLK1IGswcev613yMScR8MsvIx0VOdnkBS86sLavmrJnnDmE+W4Vi7ndFjNQsDpZBsjCppma9zSyvms3YZJ38UIuDWIlFrCQjPgcb1Co4dHJZLD82q/p0WYAEYJoWBd2xIsfz81GMWG6GjzqupdzNtSoY5T6k3snIssHyYF7uo56d519C6hbfadwBfgIyTKrwQ4+C76F7v9GlTmWhr1GoU/QgwQlBasDIGTWUghzKP/8WNjat3Esg0Q+H8OE/RHP8cTyo0FdquSxxMlcrzz5nvk+UMRrIRWMP7go5+eQvKyQeVspsU6VTMirEfihCKZuczhrmeWAJqnO8FCyCMIPF/Kj57nNrVcDiKKgyE42K8eDGTzj9+D+rrSCGTKCQFMORfo5Hl4w/0xxESmBdF2EqaaISRBuH4xrec46AFLyqTz4M9RPOrEwtLwOb8f5/nt+MqJaGPHZj68sX5K0gFiPpS733O2nNp1KOt/8+yooD5wJSk009DNnJs+V5nydjJ8Jz6X0gaHgl4pytLRYDNMdmNV17C0RfJ1iXwxThRpI8KtbEVa60LDHm8zZaonloqQGPoPwsP1AfQISL/pqiSnRXJLI1pcP6Fhk5cpm5WBHIQEr4S14A7qX7fP/Butq/evW6f1nRGfNCL+uNK4Nr6pr8fXKnuIMNk3h2dWGynaBTWQOEsR6H10FzNrooHoE0CByE0fNjWAOQ67/VbOXqaPibycCKoFkLWIZOj/4SQ7gUaY3OEVkviX2u9dc5z4llU1FyXBw0SE+ijbpJm9pu2LceeaE41Z62TfKMku8/vSe8B4yWS6gYNtFFP5SjENWryAv3RM4aBSDkYSjE3kUFeY+o4ks2WjgINHGxMZvfThxVg6YkZ4sAFoE9hXZeqw155LNmooHqcmh3cGzUvVZQu04caKS+540/MiaSYGi5CPoZsNnYlc61As48OWjt/Xrwz9/n5z9se8CF3JIwKzVdSvH+CoLxbKLm2TUXrLOYk5+kM3SJ4bK24/0Eey86gH1DU7anlLFD6IvVoWemuj9uLS1WBg+XcjYyO/2OiiJqevF/yrUoV8tmzWDknoqutjQjs46w5cvJuhKesdkWppFfYDt6g4IUo78kX/KlcrHNfb6S1csmlYuHLFRFcogZJNwxXf2OLQgSZEqIClsqhg6/kK38Mkzz1J1R5JvuqzawkIWraYLgoOkKvRWJrp0x9WPrhHYB7eeVJd7GZZ38X3HAjEkAhILV9BGKJ3axg+fMe8z4//iF1zF8wVXCu88iwTn7FRiB5IcSE8UGu7DVkJxWMi7mqXMW0ifYgWJ4BjdERIuax7WDt9aIsyGpoD43IaM0DMzB1A6GRmFXv2NWJT/fW5yVpH9SM5YtaLkvEAludRRdWc0MxNkU+g+dkfyzUT1plaVUliXZzx3ENul7s1qqEWAAjxjq9Tj4NSl5g3oom8AHhyThkA4HnR697l+r83+qq6G9AELqB/j7bUWIrUvz/RvxSftq9SISEmANFOl0uA/ELJdtLUkGeA8PhBmMX80o17+CkDMkK4LxgeAlVOF5N0EJl5QtJNRMwRmt580w+UUn82DdByq6AGc/tcB7j5D0iLt87AqxoKIKAqCQBXLvlFEI59RTC6DUUIf8OKUFIVRZg4UuDwVMCibpXKNapTrUWzdkGsqtTo0KicQ06IHdqUKswWCqUQIjmaST3sZFdriFRSIozgKygsbgQ/lVcijKxs4waZTNJEF4qE2Eroie2cCtSxZG1D8GXAjzhMyBIqlys41xFFYWMPl+uiAGhjaNTDisu2EKqIqtAJ4zYKyJ+keP8wCA==); }\u003C/style>\u003C/defs>\u003Cg stroke-linecap=\"round\" transform=\"translate(71.16960548162467 59) rotate(0 202 173)\">\u003Cpath d=\"M0 0 C156.47 0.43, 312.69 0.63, 404 0 M0 0 C93.02 -0.52, 185.26 -0.41, 404 0 M404 0 C403.61 93.68, 402.76 189.2, 404 346 M404 0 C403.68 128.57, 403.87 255.87, 404 346 M404 346 C286.02 347.75, 170.25 348.04, 0 346 M404 346 C321.38 345.73, 238.33 346.13, 0 346 M0 346 C1.5 246.76, 0.58 145.03, 0 0 M0 346 C-0.77 209.75, -0.55 72.58, 0 0\" stroke=\"#1e1e1e\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(75.16960548162467 64) rotate(0 197.5 14.5)\">\u003Cpath d=\"M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0 M0.13 12.04 C3.31 8.28, 4.65 6.16, 10.63 -0.03 M0.13 12.04 C4.56 8.43, 7.39 3.13, 10.63 -0.03 M0.27 24.08 C5.73 20.47, 8.65 12.52, 21.26 -0.07 M0.27 24.08 C4.41 19.74, 8.54 14.55, 21.26 -0.07 M3.68 32.35 C12.36 23.73, 21.74 14.24, 31.89 -0.1 M3.68 32.35 C14.57 19.58, 24.01 8.89, 31.89 -0.1 M14.31 32.31 C25.26 20.16, 34.29 8.3, 42.52 -0.14 M14.31 32.31 C19.44 24.51, 26.17 18.86, 42.52 -0.14 M24.94 32.28 C32.62 21.15, 44.17 8.79, 53.15 -0.17 M24.94 32.28 C31.8 25.13, 37.05 18.94, 53.15 -0.17 M35.57 32.25 C43.08 23.7, 50.24 17.24, 63.78 -0.21 M35.57 32.25 C44.87 20.23, 56.6 9.36, 63.78 -0.21 M46.2 32.21 C57.24 19.93, 64.9 9.21, 74.41 -0.24 M46.2 32.21 C55.05 22.61, 61.55 13.28, 74.41 -0.24 M56.83 32.18 C60.9 24.46, 69.66 20.28, 85.04 -0.28 M56.83 32.18 C63.22 25.14, 69.95 17.8, 85.04 -0.28 M67.46 32.14 C74.86 23.34, 79.86 16.5, 95.67 -0.31 M67.46 32.14 C77.22 18.96, 89.33 6.55, 95.67 -0.31 M78.09 32.11 C90.24 20.76, 99.07 8.71, 106.3 -0.34 M78.09 32.11 C87.91 20.16, 96.83 9.4, 106.3 -0.34 M88.72 32.07 C95.3 25.52, 101.24 18.04, 116.27 0.38 M88.72 32.07 C96.85 22.54, 105.23 11.33, 116.27 0.38 M99.35 32.04 C105.95 24.78, 114.05 16.4, 126.91 0.34 M99.35 32.04 C105.02 24.5, 110.94 19.8, 126.91 0.34 M109.98 32 C120.63 21.08, 129.77 5.64, 137.54 0.31 M109.98 32 C119.49 21.76, 128.64 10.81, 137.54 0.31 M120.61 31.97 C127.86 22.52, 136.99 13.64, 148.17 0.27 M120.61 31.97 C130.46 20.32, 140.74 7.87, 148.17 0.27 M131.24 31.94 C137.36 25.45, 145.7 15.74, 158.8 0.24 M131.24 31.94 C139.98 21.25, 149.99 10.41, 158.8 0.24 M141.87 31.9 C147.48 23.29, 155.4 15.07, 169.43 0.2 M141.87 31.9 C152.8 19.45, 161.89 8.21, 169.43 0.2 M151.84 32.62 C156.67 24.09, 165.82 19.03, 180.06 0.17 M151.84 32.62 C161.64 19.81, 173.79 9.04, 180.06 0.17 M162.48 32.59 C172.4 19.8, 183.15 10.61, 190.69 0.13 M162.48 32.59 C173.57 20.78, 184.37 8, 190.69 0.13 M173.11 32.55 C185.19 21.97, 192.55 8.68, 201.32 0.1 M173.11 32.55 C183.31 19.77, 193.47 8.65, 201.32 0.1 M183.74 32.52 C191.98 21.68, 201.35 12.07, 211.95 0.06 M183.74 32.52 C194.98 19.19, 205.45 7.12, 211.95 0.06 M194.37 32.48 C204.72 18.47, 216.62 9.08, 222.58 0.03 M194.37 32.48 C202.32 24.39, 209.15 15.7, 222.58 0.03 M205 32.45 C216.82 17.79, 228.56 7.66, 233.21 0 M205 32.45 C212.33 24.7, 220.96 15.34, 233.21 0 M215.63 32.41 C224.87 25.95, 231.64 17.19, 243.84 -0.04 M215.63 32.41 C221.18 25.43, 227.23 19.14, 243.84 -0.04 M226.26 32.38 C236.29 21.53, 243.78 10.78, 254.47 -0.07 M226.26 32.38 C236.59 20.78, 247.89 8.18, 254.47 -0.07 M236.89 32.34 C245.22 25.19, 252.45 13.72, 265.1 -0.11 M236.89 32.34 C246.9 20.91, 258.22 8.53, 265.1 -0.11 M247.52 32.31 C256.13 25.71, 260.45 18.41, 275.73 -0.14 M247.52 32.31 C254.45 24.29, 261.17 16.07, 275.73 -0.14 M258.15 32.28 C266.02 23.35, 271.25 15.05, 286.36 -0.18 M258.15 32.28 C268.05 20.08, 278.84 8.37, 286.36 -0.18 M268.78 32.24 C277.99 20.68, 286.77 10.14, 296.99 -0.21 M268.78 32.24 C279.13 21.02, 287.31 11.44, 296.99 -0.21 M279.41 32.21 C286.52 26.45, 292.84 18.28, 307.62 -0.25 M279.41 32.21 C285.6 24.36, 291.15 18.69, 307.62 -0.25 M290.04 32.17 C299.3 18.27, 310.17 9.09, 318.25 -0.28 M290.04 32.17 C300.58 21.37, 311.38 8.35, 318.25 -0.28 M300.67 32.14 C306.28 25.15, 311.99 15.02, 328.88 -0.31 M300.67 32.14 C309.6 19.94, 321.19 9.54, 328.88 -0.31 M311.3 32.1 C318.06 23.81, 325.47 17, 339.51 -0.35 M311.3 32.1 C316.72 24.93, 322.86 19.07, 339.51 -0.35 M321.93 32.07 C330.68 21.43, 340.98 12.72, 349.48 0.37 M321.93 32.07 C327.57 24.77, 335.68 15.71, 349.48 0.37 M332.56 32.03 C340.75 19.33, 351.45 10.17, 360.11 0.34 M332.56 32.03 C341.84 21.75, 349.12 12.67, 360.11 0.34 M343.19 32 C350.78 26.08, 356.87 17.72, 370.74 0.3 M343.19 32 C353.37 20.78, 363.95 9.33, 370.74 0.3 M353.82 31.97 C362.87 25.09, 367.28 15.78, 381.37 0.27 M353.82 31.97 C362.86 21.5, 372.61 10.14, 381.37 0.27 M364.45 31.93 C372.44 25.31, 375.53 17.55, 392 0.23 M364.45 31.93 C372.39 23.44, 378.1 14.97, 392 0.23 M375.08 31.9 C381.55 25.67, 385.53 18.29, 399.35 3.97 M375.08 31.9 C380.24 26.68, 384.69 19.61, 399.35 3.97 M385.05 32.62 C388.87 25.37, 394.72 23.02, 399.48 16.01 M385.05 32.62 C387.89 28.16, 391.11 25.12, 399.48 16.01 M-0.02 28.98 C-0.02 28.98, -0.02 28.98, -0.02 28.98 M-0.02 28.98 C-0.02 28.98, -0.02 28.98, -0.02 28.98 M12.02 28.85 C7.21 25.71, 3.8 21.32, -0.05 18.35 M12.02 28.85 C7.39 25.41, 3.77 22.23, -0.05 18.35 M24.06 28.72 C16.72 21.98, 7.92 15.15, -0.09 7.72 M24.06 28.72 C16.92 21.49, 8.09 15.43, -0.09 7.72 M36.86 29.24 C26.09 21.04, 18.82 9.81, 1.39 -1.6 M36.86 29.24 C25.51 20.54, 14.58 10.91, 1.39 -1.6 M48.9 29.11 C39.19 21.64, 28.95 10.33, 13.43 -1.73 M48.9 29.11 C35.88 17.91, 24.14 7.43, 13.43 -1.73 M60.94 28.97 C49.04 19.67, 36.99 5.25, 25.47 -1.86 M60.94 28.97 C50.78 20.98, 40.5 12.28, 25.47 -1.86 M72.98 28.84 C64.85 23.75, 57.29 17.45, 38.26 -1.34 M72.98 28.84 C62.79 18.36, 50.74 8.74, 38.26 -1.34 M85.02 28.71 C75.69 20.76, 68.51 12.23, 50.3 -1.47 M85.02 28.71 C75.97 20.52, 66.6 13.2, 50.3 -1.47 M97.82 29.23 C86.27 18.8, 72.39 9.05, 62.35 -1.6 M97.82 29.23 C85.59 18.03, 70.96 5.71, 62.35 -1.6 M109.86 29.1 C101.5 23.84, 93.03 15.29, 74.39 -1.74 M109.86 29.1 C100.94 21.48, 93.52 14.26, 74.39 -1.74 M121.9 28.96 C112.14 18.06, 100.93 10.23, 86.43 -1.87 M121.9 28.96 C111.33 19.36, 102.14 10.63, 86.43 -1.87 M133.94 28.83 C123.84 22.05, 113.3 12.35, 99.22 -1.35 M133.94 28.83 C126.43 22.84, 118.58 16.99, 99.22 -1.35 M145.98 28.7 C138.13 21.5, 131.17 15.41, 111.26 -1.48 M145.98 28.7 C136.36 21.01, 126 11.24, 111.26 -1.48 M158.78 29.22 C149.47 20.05, 136.62 11.85, 123.3 -1.61 M158.78 29.22 C151.27 22.44, 143.32 15.71, 123.3 -1.61 M170.82 29.09 C159.75 17.96, 148.78 10.62, 135.35 -1.75 M170.82 29.09 C157.24 16.34, 142.94 5.72, 135.35 -1.75 M182.86 28.95 C169.78 17.84, 158.09 9.06, 147.39 -1.88 M182.86 28.95 C169.62 18.01, 156.18 4.7, 147.39 -1.88 M194.9 28.82 C184.73 18.82, 171.47 9.28, 160.18 -1.36 M194.9 28.82 C185.13 21.04, 175.66 12.32, 160.18 -1.36 M206.94 28.69 C196.26 19.13, 189.01 10.87, 172.22 -1.49 M206.94 28.69 C195.46 17.5, 182.84 7.67, 172.22 -1.49 M219.73 29.21 C211.09 23.81, 203.64 14.91, 184.26 -1.62 M219.73 29.21 C211.58 21.83, 204.27 16.52, 184.26 -1.62 M231.78 29.08 C224.67 21.86, 214.04 12.02, 196.3 -1.76 M231.78 29.08 C220.22 18.51, 209.75 9.93, 196.3 -1.76 M243.82 28.94 C233.33 18.2, 222.92 11.01, 208.35 -1.89 M243.82 28.94 C231.81 18.76, 219.11 6.68, 208.35 -1.89 M255.86 28.81 C247.83 22.74, 241.04 15.75, 221.14 -1.37 M255.86 28.81 C243.34 18.57, 230.82 7.53, 221.14 -1.37 M267.9 28.68 C254.91 16.42, 245.63 9.43, 233.18 -1.5 M267.9 28.68 C260.72 22.4, 250.83 15.75, 233.18 -1.5 M280.69 29.2 C270.79 19.27, 258.32 10.95, 245.22 -1.63 M280.69 29.2 C268.59 18.93, 256.75 7.8, 245.22 -1.63 M292.73 29.07 C277.85 18.27, 264.03 5.82, 257.26 -1.77 M292.73 29.07 C285.1 21.96, 277.09 16.36, 257.26 -1.77 M304.78 28.93 C292.58 19.17, 277.23 4.41, 269.3 -1.9 M304.78 28.93 C297.16 21.49, 288.04 15.37, 269.3 -1.9 M316.82 28.8 C308.93 21.43, 301.16 14.76, 282.1 -1.38 M316.82 28.8 C306.48 19.98, 293.8 10.04, 282.1 -1.38 M329.61 29.32 C316.7 17.54, 306.59 7.93, 294.14 -1.51 M329.61 29.32 C317.78 18.92, 306.99 9.62, 294.14 -1.51 M341.65 29.19 C329.7 17.68, 317.04 10.23, 306.18 -1.64 M341.65 29.19 C329.03 18.24, 314.91 6.44, 306.18 -1.64 M353.69 29.06 C342.56 19.19, 332.98 13.43, 318.22 -1.78 M353.69 29.06 C345.92 22.33, 339.74 16.29, 318.22 -1.78 M365.73 28.93 C354.21 18.91, 343.11 9.41, 330.26 -1.91 M365.73 28.93 C357.01 22.46, 348.11 14.68, 330.26 -1.91 M377.78 28.79 C369.25 21.82, 363.6 14.25, 343.06 -1.39 M377.78 28.79 C369.7 20.6, 360.46 13.62, 343.06 -1.39 M390.57 29.31 C380.05 20.02, 368.68 8.93, 355.1 -1.52 M390.57 29.31 C376.11 16.78, 362.27 5.09, 355.1 -1.52 M398.08 25.25 C389.45 19.83, 381.44 11.16, 367.14 -1.65 M398.08 25.25 C385.99 16.52, 376.64 6.03, 367.14 -1.65 M398.05 14.62 C394.51 9.67, 389.18 6.23, 379.18 -1.79 M398.05 14.62 C390.05 8.14, 384.31 1.47, 379.18 -1.79 M398.01 3.99 C396.49 2.55, 394.3 1.32, 391.22 -1.92 M398.01 3.99 C395.84 1.94, 394.29 0.63, 391.22 -1.92\" stroke=\"#96f2d7\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003Cpath d=\"M0 0 C97.34 0.42, 194.42 1.57, 395 0 M0 0 C134.38 -1.6, 269.2 -2.12, 395 0 M395 0 C393.89 7.66, 395.05 12.71, 395 29 M395 0 C394.18 5.61, 395.43 12.45, 395 29 M395 29 C276.85 28.94, 160.28 29.05, 0 29 M395 29 C282.77 28.64, 170.87 28.44, 0 29 M0 29 C0.73 18.79, 1.55 12.44, 0 0 M0 29 C-0.68 23.81, 0.53 17.63, 0 0\" stroke=\"transparent\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(75.16960548162467 99) rotate(0 197.5 16)\">\u003Cpath d=\"M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0 M0.13 12.04 C2.35 9.38, 6.08 6.1, 10.63 -0.03 M0.13 12.04 C3.52 8.32, 6.33 4.79, 10.63 -0.03 M0.27 24.08 C6.84 16.93, 12.7 11.36, 21.26 -0.07 M0.27 24.08 C8.41 15.22, 14.89 6.63, 21.26 -0.07 M2.37 33.86 C12.73 20.11, 27.02 4.85, 31.89 -0.1 M2.37 33.86 C8.73 26.24, 16.11 18.26, 31.89 -0.1 M13 33.82 C24.62 20.14, 35.34 8.33, 42.52 -0.14 M13 33.82 C22.04 23.02, 31.01 12.63, 42.52 -0.14 M23.63 33.79 C32.25 22.89, 42.6 14.23, 53.15 -0.17 M23.63 33.79 C32.52 22.53, 42.08 12.52, 53.15 -0.17 M34.26 33.75 C42.33 23.52, 49.4 15.6, 63.78 -0.21 M34.26 33.75 C41.51 26.77, 47.03 17.96, 63.78 -0.21 M44.89 33.72 C50.04 24.8, 56.74 20.23, 74.41 -0.24 M44.89 33.72 C52.3 23.07, 60.9 14.78, 74.41 -0.24 M55.52 33.69 C65.01 21.69, 74.52 10.49, 85.04 -0.28 M55.52 33.69 C66.58 20.67, 78.93 7.37, 85.04 -0.28 M66.15 33.65 C77.28 24.35, 86.69 10.3, 95.67 -0.31 M66.15 33.65 C75.79 22.59, 84.06 11.48, 95.67 -0.31 M76.78 33.62 C88.41 21.15, 96.77 9.81, 106.3 -0.34 M76.78 33.62 C85.67 22.47, 95.36 10.55, 106.3 -0.34 M86.75 34.34 C95.45 23.47, 102.87 14.17, 116.27 0.38 M86.75 34.34 C98.12 21.52, 110.43 7.56, 116.27 0.38 M97.38 34.3 C105.57 23.43, 115.02 12.48, 126.91 0.34 M97.38 34.3 C108.51 22.54, 118.82 12.09, 126.91 0.34 M108.01 34.27 C115.94 25.84, 128.03 14.97, 137.54 0.31 M108.01 34.27 C117.75 22.33, 128.11 10.88, 137.54 0.31 M118.64 34.23 C125.67 24.81, 136.01 12.81, 148.17 0.27 M118.64 34.23 C125.31 25.62, 133.36 17.98, 148.17 0.27 M129.27 34.2 C138.33 24.08, 149.86 12.84, 158.8 0.24 M129.27 34.2 C135.11 25.93, 142.91 18.97, 158.8 0.24 M139.9 34.16 C152.67 23.84, 162.8 9.25, 169.43 0.2 M139.9 34.16 C151.13 21.16, 162.43 7.98, 169.43 0.2 M150.53 34.13 C161.69 23.18, 170.21 9.56, 180.06 0.17 M150.53 34.13 C159.14 22.62, 168.9 12.02, 180.06 0.17 M161.16 34.1 C169.4 23.19, 179.14 11.82, 190.69 0.13 M161.16 34.1 C167.02 28.09, 172.75 19.92, 190.69 0.13 M171.79 34.06 C181.87 22.87, 194.3 10.88, 201.32 0.1 M171.79 34.06 C181.73 22.62, 191.18 10.53, 201.32 0.1 M182.42 34.03 C192.05 20.5, 201.64 8.57, 211.95 0.06 M182.42 34.03 C191.84 22.78, 203.2 11.81, 211.95 0.06 M193.05 33.99 C201.55 25.62, 206.98 17.33, 222.58 0.03 M193.05 33.99 C199.26 25.49, 205.12 19.62, 222.58 0.03 M203.68 33.96 C215.04 22.88, 222.94 12.46, 233.21 0 M203.68 33.96 C212.64 22.64, 222.13 12.04, 233.21 0 M214.31 33.92 C226.61 20.82, 236.65 9.27, 243.84 -0.04 M214.31 33.92 C225.32 21.55, 234.9 11.62, 243.84 -0.04 M224.94 33.89 C232.84 24.27, 237.3 17.15, 254.47 -0.07 M224.94 33.89 C236.39 22.13, 246.35 8.36, 254.47 -0.07 M235.57 33.85 C247.54 23.78, 257.39 12.2, 265.1 -0.11 M235.57 33.85 C242.43 24.42, 251.87 15.39, 265.1 -0.11 M246.2 33.82 C259.28 23.21, 269.86 7.97, 275.73 -0.14 M246.2 33.82 C254.67 22.94, 264.35 12.77, 275.73 -0.14 M256.83 33.79 C269.83 22.54, 280.63 6.4, 286.36 -0.18 M256.83 33.79 C264.21 25.72, 272.01 15.44, 286.36 -0.18 M267.46 33.75 C273.99 28.09, 279.64 19.93, 296.99 -0.21 M267.46 33.75 C274.53 26.8, 280.77 19.15, 296.99 -0.21 M278.09 33.72 C287.43 24.28, 291.1 16.98, 307.62 -0.25 M278.09 33.72 C289.64 21.38, 298.59 9.42, 307.62 -0.25 M288.72 33.68 C296.91 22.51, 305.09 15.13, 318.25 -0.28 M288.72 33.68 C299.27 22.9, 309.26 9.51, 318.25 -0.28 M299.35 33.65 C306.11 25.5, 313.78 15.18, 328.88 -0.31 M299.35 33.65 C307.21 25.05, 312.41 18.34, 328.88 -0.31 M309.98 33.61 C318.53 24.52, 327.26 13.95, 339.51 -0.35 M309.98 33.61 C318.18 23.24, 326.67 14.47, 339.51 -0.35 M319.96 34.33 C324.68 25.37, 331.61 20.62, 349.48 0.37 M319.96 34.33 C332.34 20.92, 342.65 8.64, 349.48 0.37 M330.59 34.3 C338.62 24.94, 344.03 20.6, 360.11 0.34 M330.59 34.3 C339.88 24.24, 347.64 13.37, 360.11 0.34 M341.22 34.26 C350.56 23.76, 358.55 17.23, 370.74 0.3 M341.22 34.26 C352.9 21.8, 363.25 9.38, 370.74 0.3 M351.85 34.23 C357.67 26.55, 363.55 21.14, 381.37 0.27 M351.85 34.23 C359.48 25.28, 366.38 17.49, 381.37 0.27 M362.48 34.2 C369.47 24.88, 377.75 16.16, 392 0.23 M362.48 34.2 C372.46 21.97, 383.38 10.72, 392 0.23 M373.11 34.16 C381.37 24.05, 389.87 15.36, 399.35 3.97 M373.11 34.16 C379.56 26.39, 386.46 19.58, 399.35 3.97 M383.74 34.13 C388.05 30.89, 390.84 28.37, 399.48 16.01 M383.74 34.13 C389.17 27.97, 392.55 22.79, 399.48 16.01\" stroke=\"#96f2d7\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003Cpath d=\"M0 0 C99.99 0.39, 200.69 0.79, 395 0 M0 0 C139.44 -1.5, 279.11 -1.61, 395 0 M395 0 C393.6 14.08, 395.58 23.97, 395 32 M395 0 C395.32 5.81, 395.9 12.4, 395 32 M395 32 C310.18 30.57, 225.64 29.37, 0 32 M395 32 C256.38 29.76, 118.04 30.04, 0 32 M0 32 C-1.77 20.83, 0.19 7.15, 0 0 M0 32 C0.06 25.75, -1.04 18.4, 0 0\" stroke=\"transparent\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(77.16960548162467 139) rotate(0 196.5 16)\">\u003Cpath d=\"M-0.48 0.78 L394.81 0.57 L393.39 32.31 L0.97 33.11\" stroke=\"none\" stroke-width=\"0\" fill=\"#96f2d7\">\u003C/path>\u003Cpath d=\"M0 0 C112.01 -0.16, 225.36 -0.15, 393 0 M0 0 C91.49 2.56, 183.71 2.47, 393 0 M393 0 C393.1 5.35, 394.15 14.46, 393 32 M393 0 C392.4 9.32, 392.44 19.44, 393 32 M393 32 C298.29 30.39, 205.53 28.85, 0 32 M393 32 C280.27 32.92, 167.47 32.17, 0 32 M0 32 C-0.71 23.45, 0.55 20.51, 0 0 M0 32 C-0.84 22.28, -0.89 12.31, 0 0\" stroke=\"transparent\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(79.16960548162467 180) rotate(0 80.5 62)\">\u003Cpath d=\"M-1.55 0.95 L161.87 -0.1 L161.14 125.5 L-0.7 125.64\" stroke=\"none\" stroke-width=\"0\" fill=\"#e9ecef\">\u003C/path>\u003Cpath d=\"M0 0 C54.26 -2.13, 106.32 0.61, 161 0 M0 0 C35.2 1.29, 69.9 0.58, 161 0 M161 0 C160.53 39.48, 160.03 76.82, 161 124 M161 0 C159.43 34.62, 159.96 68.82, 161 124 M161 124 C119.56 123.04, 76.61 122.27, 0 124 M161 124 C119 122.34, 76.68 122.74, 0 124 M0 124 C1.7 78.65, -0.63 33.9, 0 0 M0 124 C-1.72 74.53, -0.46 24.19, 0 0\" stroke=\"#343a40\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(82.16960548162467 264) rotate(0 59.5 -15)\">\u003Cpath d=\"M0 0 C26.02 -12.7, 51.23 -26.81, 75 -41 M0 0 C21.23 -12.1, 43.51 -23.82, 75 -41 M75 -41 C91.11 -20.79, 107.48 -2.19, 119 11 M75 -41 C85.37 -26.54, 97.43 -13.69, 119 11\" stroke=\"#343a40\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(182.16960548162467 250) rotate(0 28 -5.5)\">\u003Cpath d=\"M0 0 C11.88 -7.15, 21.84 -14.48, 27 -18 M0 0 C6.98 -4.19, 14.2 -9.33, 27 -18 M27 -18 C37.26 -10.58, 42.62 -3.22, 56 7 M27 -18 C34.42 -12.38, 40.23 -6.86, 56 7\" stroke=\"#343a40\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\" transform=\"translate(196.16960548162467 189) rotate(0 13.569992065429688 14.5)\">\u003Cpath d=\"M11.43 -0.27 C14.15 -0.93, 18.04 0.13, 20.59 1.83 C23.14 3.53, 25.77 6.99, 26.74 9.94 C27.71 12.89, 27.58 16.66, 26.43 19.54 C25.28 22.41, 22.32 25.71, 19.83 27.19 C17.34 28.68, 14.33 29.12, 11.5 28.48 C8.67 27.83, 4.78 25.71, 2.85 23.31 C0.92 20.91, -0.17 17.09, -0.08 14.07 C0.01 11.05, 1.34 7.57, 3.39 5.18 C5.43 2.8, 10.68 0.62, 12.18 -0.24 C13.68 -1.11, 12.43 -0.25, 12.41 -0.02 M15.26 -0.41 C18.06 -0.29, 21.03 2.12, 22.91 4.48 C24.79 6.84, 26.24 10.65, 26.52 13.74 C26.81 16.83, 26.04 20.51, 24.6 23.02 C23.15 25.53, 20.57 28.11, 17.85 28.8 C15.13 29.48, 10.99 28.49, 8.3 27.12 C5.6 25.76, 2.97 23.39, 1.68 20.59 C0.38 17.8, -0.07 13.24, 0.52 10.34 C1.12 7.45, 2.83 4.89, 5.26 3.22 C7.69 1.54, 13.6 0.83, 15.09 0.28 C16.58 -0.27, 14.45 -0.24, 14.22 -0.09\" stroke=\"none\" stroke-width=\"0\" fill=\"#e9ecef\">\u003C/path>\u003Cpath d=\"M11.17 0.79 C13.77 -0.03, 17.52 0.11, 19.94 1.42 C22.35 2.72, 24.48 5.66, 25.65 8.64 C26.82 11.62, 27.7 16.22, 26.96 19.28 C26.22 22.33, 23.82 25.33, 21.21 26.97 C18.6 28.6, 14.3 29.55, 11.29 29.09 C8.29 28.62, 5.11 26.5, 3.2 24.16 C1.28 21.82, -0.14 18.14, -0.19 15.07 C-0.25 12, 0.93 8.29, 2.87 5.73 C4.82 3.17, 9.98 0.65, 11.49 -0.26 C13 -1.18, 11.98 -0.02, 11.95 0.25 M15.81 0.71 C18.64 1.16, 22.39 3.2, 24.23 5.58 C26.08 7.96, 26.98 11.86, 26.87 14.99 C26.76 18.13, 25.34 22.04, 23.56 24.39 C21.78 26.75, 19.1 28.58, 16.17 29.1 C13.24 29.62, 8.6 29.22, 5.98 27.5 C3.36 25.79, 1.4 21.77, 0.45 18.82 C-0.49 15.87, -0.76 12.57, 0.32 9.81 C1.39 7.06, 4.33 3.99, 6.89 2.28 C9.45 0.57, 14.03 -0.27, 15.69 -0.45 C17.34 -0.63, 16.7 0.88, 16.82 1.2\" stroke=\"#343a40\" stroke-width=\"2\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(256.16960548162467 185) rotate(0 16 16)\">\u003Cpath d=\"M7.06 2.16 C7.06 2.16, 7.06 2.16, 7.06 2.16 M7.06 2.16 C7.06 2.16, 7.06 2.16, 7.06 2.16 M1.55 14.6 C5.38 9.25, 10.76 4.79, 13.36 1.01 M1.55 14.6 C4.88 10.29, 8.71 6.13, 13.36 1.01 M1.29 21 C6.98 15.84, 11.42 9.62, 19 0.62 M1.29 21 C6.51 15.38, 11.65 9.4, 19 0.62 M3.65 24.37 C8.27 19.32, 11.64 15.52, 22.68 2.49 M3.65 24.37 C10.55 16.6, 17 9.2, 22.68 2.49 M6.01 27.75 C10.87 21.72, 15.15 16.21, 26.35 4.36 M6.01 27.75 C10.19 22.3, 14.38 17.15, 26.35 4.36 M9.03 30.38 C16.2 22.06, 22.79 12.49, 29.37 6.98 M9.03 30.38 C17.29 21.06, 24.63 12.12, 29.37 6.98 M13.36 31.49 C19.03 24.14, 27.18 15.32, 31.08 11.11 M13.36 31.49 C18.08 25.47, 23.52 20.1, 31.08 11.11 M18.35 31.85 C23.28 26.61, 28.74 19.7, 32.78 15.25 M18.35 31.85 C22.56 26.5, 26.67 21.85, 32.78 15.25 M8.44 29.93 C8.44 29.93, 8.44 29.93, 8.44 29.93 M8.44 29.93 C8.44 29.93, 8.44 29.93, 8.44 29.93 M15.59 30.84 C10.95 26.61, 5.57 22.34, 0.5 17.72 M15.59 30.84 C11.08 26.45, 5.71 22.6, 0.5 17.72 M21.23 30.45 C15.05 25.76, 10.67 19.5, 0.86 12.73 M21.23 30.45 C14.81 25.43, 8.55 19.92, 0.86 12.73 M24.61 28.09 C18.65 23.42, 12.38 16.76, 2.72 9.06 M24.61 28.09 C16.69 21.24, 9.39 14.75, 2.72 9.06 M27.99 25.72 C20.05 19.35, 12.01 10.38, 4.59 5.38 M27.99 25.72 C21.38 20.36, 14.68 14.66, 4.59 5.38 M29.86 22.05 C24.68 18.56, 19.8 14.46, 7.22 2.37 M29.86 22.05 C23.17 15.43, 15.5 9.2, 7.22 2.37 M31.73 18.37 C26.45 13.92, 22.29 9.15, 12.11 1.32 M31.73 18.37 C26.56 13.79, 21.27 9.59, 12.11 1.32 M31.33 12.73 C26.72 8.55, 20.98 4.66, 17 0.26 M31.33 12.73 C26.47 8.24, 20.43 3.18, 17 0.26\" stroke=\"#eebefa\" stroke-width=\"0.5\" fill=\"none\">\u003C/path>\u003Cpath d=\"M18.2 -0.28 C21.43 -0.13, 25.65 2.47, 27.96 4.98 C30.27 7.5, 31.96 11.32, 32.05 14.82 C32.14 18.32, 30.52 23.17, 28.5 25.99 C26.47 28.82, 23.23 31.11, 19.9 31.77 C16.56 32.43, 11.66 31.58, 8.47 29.95 C5.28 28.33, 2.01 25.09, 0.75 22.02 C-0.5 18.95, -0.1 14.84, 0.94 11.55 C1.98 8.25, 3.99 4.1, 6.97 2.26 C9.95 0.43, 16.67 0.87, 18.81 0.53 C20.94 0.2, 19.9 0, 19.78 0.25 M19.03 -0.16 C22.37 0.4, 27.11 4.1, 29.25 6.84 C31.39 9.58, 32.25 12.85, 31.89 16.3 C31.52 19.75, 29.35 25.03, 27.05 27.55 C24.75 30.07, 21.37 31.01, 18.07 31.4 C14.76 31.78, 10.1 31.7, 7.21 29.87 C4.32 28.03, 1.65 23.73, 0.73 20.37 C-0.19 17.02, 0.45 12.91, 1.69 9.74 C2.94 6.56, 5.28 2.99, 8.22 1.34 C11.15 -0.32, 17.43 0.01, 19.3 -0.19 C21.16 -0.4, 19.3 -0.25, 19.42 0.13\" stroke=\"#343a40\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(256.16960548162467 226) rotate(0 16 16)\">\u003Cpath d=\"M13.85 -0.19 C17.14 -0.75, 22.36 0.55, 25.22 2.43 C28.08 4.3, 30.19 7.68, 31.02 11.07 C31.85 14.46, 31.51 19.48, 30.19 22.76 C28.87 26.04, 26.11 29.26, 23.1 30.74 C20.08 32.22, 15.51 32.6, 12.1 31.64 C8.69 30.69, 4.56 27.73, 2.63 25 C0.69 22.27, 0.16 18.55, 0.49 15.27 C0.82 11.98, 2.2 7.89, 4.63 5.31 C7.05 2.73, 13.12 0.55, 15.04 -0.22 C16.97 -0.98, 16.05 0.43, 16.16 0.71 M11.75 0.35 C14.94 -0.69, 20.76 -0.04, 23.83 1.5 C26.9 3.03, 28.94 6.25, 30.17 9.55 C31.39 12.86, 32.04 18.01, 31.19 21.32 C30.34 24.64, 28.01 27.69, 25.07 29.45 C22.13 31.2, 16.96 32.22, 13.55 31.85 C10.15 31.49, 6.99 29.77, 4.64 27.26 C2.29 24.76, -0.32 20.19, -0.54 16.82 C-0.76 13.45, 1.15 9.89, 3.3 7.06 C5.45 4.22, 10.86 0.91, 12.34 -0.2 C13.83 -1.3, 12.16 0.17, 12.22 0.44\" stroke=\"none\" stroke-width=\"0\" fill=\"#a5d8ff\">\u003C/path>\u003Cpath d=\"M19.92 0.87 C23.05 1.49, 26.27 4.05, 28.33 6.64 C30.39 9.23, 32.34 12.98, 32.3 16.4 C32.26 19.83, 30.4 24.67, 28.08 27.18 C25.75 29.69, 21.86 31.12, 18.36 31.47 C14.87 31.81, 9.99 31.01, 7.1 29.23 C4.22 27.46, 2.04 23.99, 1.06 20.81 C0.08 17.63, -0.11 13.33, 1.22 10.14 C2.55 6.94, 5.93 3.21, 9.03 1.64 C12.12 0.08, 17.93 0.87, 19.77 0.75 C21.61 0.64, 20 0.66, 20.04 0.95 M18.66 -0.02 C21.68 0.22, 24.81 2.5, 27.07 5.07 C29.34 7.63, 31.89 12.01, 32.26 15.39 C32.62 18.78, 31.49 22.56, 29.25 25.38 C27.01 28.2, 22.12 31.42, 18.8 32.3 C15.47 33.18, 12.27 32.37, 9.3 30.67 C6.34 28.96, 2.35 25.27, 0.99 22.07 C-0.36 18.87, 0.13 14.81, 1.19 11.46 C2.26 8.1, 4.45 3.94, 7.38 1.94 C10.32 -0.06, 16.9 -0.16, 18.79 -0.52 C20.69 -0.88, 19 -0.64, 18.77 -0.19\" stroke=\"#1e1e1e\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(298.16960548162467 180) rotate(0 84.5 21)\">\u003Cpath d=\"M1.23 0.46 L169.25 0.76 L169.49 41.96 L-0.5 41.91\" stroke=\"none\" stroke-width=\"0\" fill=\"#a5d8ff\">\u003C/path>\u003Cpath d=\"M0 0 C37.05 -0.44, 71.43 -1.95, 169 0 M0 0 C35.61 -0.33, 70.26 -1.56, 169 0 M169 0 C168.69 11.51, 169.95 27.78, 169 42 M169 0 C168.65 8.4, 168.73 18.1, 169 42 M169 42 C101.77 42.01, 38.19 42.98, 0 42 M169 42 C131.91 42.18, 92.24 41.92, 0 42 M0 42 C1.03 29.34, -0.11 18.51, 0 0 M0 42 C-0.93 32.43, 0.06 24.03, 0 0\" stroke=\"#1e1e1e\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(332.16960548162467 194) rotate(0 44.109954833984375 12.5)\">\u003Ctext x=\"0\" y=\"17.619999999999997\" font-family=\"Excalifont, Xiaolai, sans-serif, Segoe UI Emoji\" font-size=\"20px\" fill=\"#1e1e1e\" text-anchor=\"start\" style=\"white-space: pre;\" direction=\"ltr\" dominant-baseline=\"alphabetic\">button A\u003C/text>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(297.66960548162467 234) rotate(0 84.5 21)\">\u003Cpath d=\"M0.03 -1.58 L170.06 -1.63 L168.75 42.31 L-0.3 41.34\" stroke=\"none\" stroke-width=\"0\" fill=\"#b2f2bb\">\u003C/path>\u003Cpath d=\"M0 0 C53.28 -1.21, 104.34 -0.92, 169 0 M0 0 C53.01 -0.56, 104.4 0.01, 169 0 M169 0 C167.38 14.12, 169.21 26.87, 169 42 M169 0 C168.27 17.39, 168.26 32.66, 169 42 M169 42 C125.76 41.48, 81.42 42.59, 0 42 M169 42 C126.04 43.79, 82.72 42.84, 0 42 M0 42 C-0.63 31.93, -1.08 21.21, 0 0 M0 42 C-0.74 25.09, 1.14 8.26, 0 0\" stroke=\"#1e1e1e\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(332.66960548162467 246) rotate(0 44.95995330810547 12.5)\">\u003Ctext x=\"0\" y=\"17.619999999999997\" font-family=\"Excalifont, Xiaolai, sans-serif, Segoe UI Emoji\" font-size=\"20px\" fill=\"#1e1e1e\" text-anchor=\"start\" style=\"white-space: pre;\" direction=\"ltr\" dominant-baseline=\"alphabetic\">button B\u003C/text>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(80.16960548162467 319) rotate(0 24 24.5)\">\u003Cpath d=\"M25.49 -0.09 C30.32 -0.03, 36.49 2.93, 40.21 6.65 C43.93 10.37, 47.24 16.98, 47.82 22.22 C48.39 27.46, 46.46 33.7, 43.64 38.08 C40.82 42.47, 35.74 47.05, 30.88 48.51 C26.02 49.96, 19.29 49.02, 14.49 46.81 C9.69 44.6, 4.31 39.98, 2.08 35.27 C-0.15 30.56, -0.23 23.62, 1.1 18.57 C2.43 13.52, 5.79 7.99, 10.03 4.97 C14.27 1.94, 23.72 1.13, 26.54 0.44 C29.36 -0.24, 27.02 0.47, 26.96 0.87 M25.61 0.15 C30.39 -0.15, 36.01 2.02, 39.83 5.61 C43.65 9.21, 47.85 16.32, 48.51 21.71 C49.17 27.1, 46.62 33.5, 43.8 37.97 C40.98 42.45, 36.33 47.14, 31.59 48.56 C26.86 49.98, 20.07 48.57, 15.37 46.5 C10.67 44.43, 5.92 40.69, 3.41 36.13 C0.9 31.57, -0.77 24.28, 0.3 19.13 C1.37 13.98, 5.7 8.29, 9.83 5.22 C13.97 2.15, 22.53 1.46, 25.09 0.71 C27.66 -0.04, 25.4 0.39, 25.24 0.73\" stroke=\"none\" stroke-width=\"0\" fill=\"#a5d8ff\">\u003C/path>\u003Cpath d=\"M20.83 0.68 C25.58 -0.37, 32.16 0.99, 36.51 3.64 C40.85 6.28, 45.26 11.53, 46.92 16.56 C48.58 21.58, 48.41 28.84, 46.48 33.77 C44.56 38.7, 39.91 43.69, 35.35 46.12 C30.79 48.55, 24.13 49.44, 19.1 48.35 C14.06 47.26, 8.33 43.72, 5.14 39.6 C1.94 35.47, -0.17 28.78, -0.06 23.62 C0.04 18.46, 2.09 12.52, 5.74 8.64 C9.4 4.76, 18.88 1.77, 21.88 0.36 C24.88 -1.05, 23.62 -0.19, 23.76 0.16 M28.12 -0.27 C32.83 0.43, 38.55 5.03, 41.79 9.04 C45.03 13.06, 47.54 18.73, 47.57 23.81 C47.6 28.89, 45.04 35.47, 41.96 39.53 C38.88 43.59, 34.16 47.12, 29.09 48.18 C24.03 49.23, 16.09 48.41, 11.57 45.84 C7.05 43.28, 3.76 37.59, 2 32.78 C0.23 27.97, -0.75 21.85, 0.98 16.98 C2.72 12.1, 7.92 6.41, 12.4 3.53 C16.89 0.64, 25.32 0.11, 27.91 -0.34 C30.49 -0.78, 28.04 0.38, 27.92 0.84\" stroke=\"#1e1e1e\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(97.91905158324516 331.1758838609296) rotate(0 6.279991149902344 12.5)\">\u003Ctext x=\"6.279991149902344\" y=\"17.619999999999997\" font-family=\"Excalifont, Xiaolai, sans-serif, Segoe UI Emoji\" font-size=\"20px\" fill=\"#1e1e1e\" text-anchor=\"middle\" style=\"white-space: pre;\" direction=\"ltr\" dominant-baseline=\"alphabetic\">X\u003C/text>\u003C/g>\u003Cg stroke-linecap=\"round\" transform=\"translate(140.16960548162467 320) rotate(0 25 25.5)\">\u003Cpath d=\"M25.54 0.02 L48.81 27.1 L25.55 50.19 L-0.9 26.62\" stroke=\"none\" stroke-width=\"0\" fill=\"#b2f2bb\" fill-rule=\"evenodd\">\u003C/path>\u003Cpath d=\"M26 0 C35.6 8.59, 44.01 19.05, 50 26 M26 0 C35.23 8.85, 43.01 17.77, 50 26 M50 26 C41.06 34.23, 30.25 47.17, 26 51 M50 26 C44.33 32.32, 36.56 39.2, 26 51 M26 51 C20.51 43.02, 12.84 40.33, 0 26 M26 51 C18.61 44.79, 11.46 37.85, 0 26 M0 26 C8.17 18.61, 18.08 9.62, 26 0 M0 26 C5.72 18.94, 12.23 12.8, 26 0\" stroke=\"#1e1e1e\" stroke-width=\"1\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(230.2096521735192 313.5) rotate(0 106.66643524169922 35)\">\u003Ctext x=\"0\" y=\"24.668\" font-family=\"Excalifont, Xiaolai, sans-serif, Segoe UI Emoji\" font-size=\"28px\" fill=\"#1e1e1e\" text-anchor=\"start\" style=\"white-space: pre;\" direction=\"ltr\" dominant-baseline=\"alphabetic\">welcome to this\u003C/text>\u003Ctext x=\"0\" y=\"59.668\" font-family=\"Excalifont, Xiaolai, sans-serif, Segoe UI Emoji\" font-size=\"28px\" fill=\"#1e1e1e\" text-anchor=\"start\" style=\"white-space: pre;\" direction=\"ltr\" dominant-baseline=\"alphabetic\">virtual world\u003C/text>\u003C/g>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(101.16960548162467 155) rotate(0 -45 -1)\">\u003Cpath d=\"M-0.15 -0.69 C-15.21 -0.72, -74.52 -0.66, -89.6 -0.97\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\" stroke-dasharray=\"8 9\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(101.16960548162467 155) rotate(0 -45 -1)\">\u003Cpath d=\"M-66.04 -9.32 C-75.84 -5.64, -81.56 -4.34, -89.6 -0.97\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(101.16960548162467 155) rotate(0 -45 -1)\">\u003Cpath d=\"M-66.18 7.78 C-75.82 5.22, -81.48 0.29, -89.6 -0.97\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(100.04652185812597 118.83041009530427) rotate(0 -45 -1)\">\u003Cpath d=\"M-0.93 0.31 C-15.71 -0.16, -74.76 -2.38, -89.65 -2.73\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\" stroke-dasharray=\"8 9\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(100.04652185812597 118.83041009530427) rotate(0 -45 -1)\">\u003Cpath d=\"M-65.9 -10.54 C-70.56 -8.43, -77.48 -7.8, -89.65 -2.73\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(100.04652185812597 118.83041009530427) rotate(0 -45 -1)\">\u003Cpath d=\"M-66.44 6.56 C-71 4.93, -77.8 1.84, -89.65 -2.73\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(100.04652185812597 79.83041009530427) rotate(0 -45 -1)\">\u003Cpath d=\"M1.15 -1.14 C-13.77 -1.33, -74.72 -1.06, -90.05 -1.26\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\" stroke-dasharray=\"8 9\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(100.04652185812597 79.83041009530427) rotate(0 -45 -1)\">\u003Cpath d=\"M-66.53 -9.73 C-74.38 -7.44, -77.19 -6.55, -90.05 -1.26\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(100.04652185812597 79.83041009530427) rotate(0 -45 -1)\">\u003Cpath d=\"M-66.58 7.37 C-74.4 5.33, -77.2 1.91, -90.05 -1.26\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(443.6190429724753 78.19712085351347) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M0.37 0.59 C13.18 0.43, 63.6 -0.2, 76.37 -0.21\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\" stroke-dasharray=\"8 9\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(443.6190429724753 78.19712085351347) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M52.95 8.52 C59.96 5.88, 64.72 4.64, 76.37 -0.21\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(443.6190429724753 78.19712085351347) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M52.82 -8.59 C59.97 -6.78, 64.76 -3.57, 76.37 -0.21\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(442.7996299665423 111.81335102692253) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M0.31 0.51 C13.29 0.66, 64.44 0.31, 77.13 0.13\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\" stroke-dasharray=\"8 9\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(442.7996299665423 111.81335102692253) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M53.72 8.9 C60.1 7.76, 64.96 4.6, 77.13 0.13\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(442.7996299665423 111.81335102692253) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M53.56 -8.2 C59.87 -5.34, 64.76 -4.5, 77.13 0.13\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg stroke-linecap=\"round\">\u003Cg transform=\"translate(442.7996299665423 151.81335102692253) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M1.1 0.27 C13.96 0.01, 64.97 -1.1, 77.61 -1.13\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\" stroke-dasharray=\"8 9\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(442.7996299665423 151.81335102692253) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M54.24 7.74 C62.5 6.32, 68 2.22, 77.61 -1.13\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003Cg transform=\"translate(442.7996299665423 151.81335102692253) rotate(0 38.27528125457468 0)\">\u003Cpath d=\"M54 -9.36 C62.41 -5.05, 67.98 -3.41, 77.61 -1.13\" stroke=\"#1e1e1e\" stroke-width=\"1.5\" fill=\"none\">\u003C/path>\u003C/g>\u003C/g>\u003Cmask>\u003C/mask>\u003Cg transform=\"translate(74.16960548162467 10) rotate(0 91.29436492919922 17.5)\">\u003Ctext x=\"0\" y=\"24.668\" font-family=\"Excalifont, Xiaolai, sans-serif, Segoe UI Emoji\" font-size=\"28px\" fill=\"#1e1e1e\" text-anchor=\"start\" style=\"white-space: pre;\" direction=\"ltr\" dominant-baseline=\"alphabetic\">trimsheet.png\u003C/text>\u003C/g>\u003C/svg>","type":"image/svg+xml"}, {"created":"20251008094554737","text":"> Got a light? Nope..too expensive (but I've got a texture for you)\n\n[img[unlit.jpg]]\n\n> The above scene results in a ''9 kilobytes'' 3D file-size [ [[.glb|https://coderofsalvation.codeberg.page/xrfragment.media/example/unlit.glb]] [[.blend|https://coderofsalvation.codeberg.page/xrfragment.media/example/unlit.blend]] ] using a texture as color-lookup table.\n\nWith unlit materials we achieve:\n\n* a gradient horizon mapped onto a sphere (orange area)\n* a plane with an (unlit) checkers pattern\n* a unlit cube\n\n\n> Read more about saving unlit materials into glTF ''3D files'' for Blender [[here|https://docs.blender.org/manual/en/latest/addons/import_export/scene_gltf2.html#exporting-a-shadeless-unlit-material]]\n\nTo render all objects in our 3D file, we ''don't need to introduce more'' resource-heavy [[lights|Lights]].\u003Cbr>Instead we use an ''single unlit'' texture as a color lookup table (via uvmapping).\n\nUtilizing ''unlit materials'' for distant or intrinsically bright objects in ''Extended Reality (XR)'' is a critical optimization strategy because it drastically reduces the ''computational burden'' on resource-constrained mobile VR/AR devices.\n\nUnlike ''lit materials'', which require the GPU to perform expensive, real-time lighting calculations \n\n> including determining light direction, shadows, specularity, and reflections for every pixel of every mesh under the influence of every light \n\nAn unlit shader renders the object using only the texture's raw color (or its ''emissive color''), bypassing these complex and time-consuming processes entirely. \n\nThis is especially advantageous for far-off background elements, which lose visual detail at a distance, and for objects that are meant to *be* the light source (like the sun, stars, or a neon sign), where lighting calculations are redundant or undesirable.\n\nIntroducing ''multiple real-time light sources'' is highly detrimental to performance in XR, as the rendering cost often multiplies with each light affecting a surface, potentially causing the scene to drop below the minimum required frame rate (e.g., and leading to user discomfort or motion sickness (\"jank\").\n","tags":"[[Best practices]]","title":"Unlit textures","modified":"20251008101740242","type":"text/vnd.tiddlywiki"},