From 7f42e7f5aa792aa39c10517da39840abcf458bf2 Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Fri, 19 Sep 2025 19:19:37 +0200 Subject: [PATCH] updated spec & website --- doc/RFC_XR_Fragments.html | 1381 ++++++++---------------- doc/RFC_XR_Fragments.md | 1017 +++++++----------- doc/RFC_XR_Fragments.txt | 2128 ++++++++++++------------------------- doc/RFC_XR_Fragments.xml | 1312 +++++++---------------- index.html | 22 +- 5 files changed, 1895 insertions(+), 3965 deletions(-) diff --git a/doc/RFC_XR_Fragments.html b/doc/RFC_XR_Fragments.html index 5f10a2e..b3c61e6 100644 --- a/doc/RFC_XR_Fragments.html +++ b/doc/RFC_XR_Fragments.html @@ -82,12 +82,12 @@ value: draft-XRFRAGMENTS-leonvankammen-00

An open specification for hyperlinking & deeplinking 3D fileformats. This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
-The specification uses W3C Media Fragments and URI Templates (RFC6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like URI Fragments.
-XR Fragments views XR experiences thru the lens of 3D object URI’s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).

+XR Fragments views XR experiences thru the lens of 3D deeplinked URI’s, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). +The standard comprises of various (optional) support levels, which also include W3C Media Fragments and URI Templates (RFC6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.

-

XR Fragments is a heuristical 3D format which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
+

XR Fragments is in a sense, a heuristical 3D format or meta-format, which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing higher interop between fileformats, 3D editors, viewers and game-engines.

Almost every idea in this document is demonstrated at https://xrfragment.org

@@ -100,7 +100,7 @@ Historically, there’s many attempts to create the ultimate 3D fileformat.< The lowest common denominator is: designers describing/tagging/naming things using plain text.
XR Fragments exploits the fact that all 3D models already contain such metadata:

-

XR Fragments allows controlling of metadata in 3D scene(files) using URI’s

+

XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments

It solves:

@@ -116,153 +116,33 @@ XR Fragments exploits the fact that all 3D models already contain such metadata:

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

-

Core principle

- -

XR Fragments allows controlling 3D models using URLs, based on (non)existing metadata via URI’s

- -

XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.
-Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments integrates all which allows a universal viewing experience.

- -
  +───────────────────────────────────────────────────────────────────────────────────────────────+
-  │                                                                                               │
-  │                          U R N                                                                │
-  │ U R L                      |                                                                  │
-  │  |       |-----------------+--------|                                                         │
-  │  +--------------------------------------------------|                                         │
-  │  |                                                                                            │
-  │  + https://foo.com/some/foo/scene.glb#someview             <-- http URI (=URL and has URN)    │
-  │  |                                                                                            │
-  │  + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview             <-- an IPFS URI (=URL and has URN) │
-  │                                                                                               │
-  │  ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe      <-- an interpeer URI               │
-  │                                                                                               │
-  │                                                                                               │
-  │  |------------------------+-------------------------|                                         │
-  │                           |                                                                   │
-  │                         U R I                                                                 │
-  │                                                                                               │
-  +───────────────────────────────────────────────────────────────────────────────────────────────+
-
-
- -

Fact: our typical browser URL’s are just a possible implementation of URI’s (for untapped humancentric potential of URI’s see interpeer.io)

- -
-

XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.
But approaches things from a higherlevel feedbackloop/hypermedia browser-perspective.

-
- -

Below you can see how this translates back into good-old URLs:

- -
 +───────────────────────────────────────────────────────────────────────────────────────────────+
- │                                                                                               │
- │   the soul of any URL:       ://macro        /meso           ?micro      #nano                │
- │                                                                                               │
- │                2D URL:       ://library.com  /document       ?search     #chapter             │
- │                                                                                       xrf://  │
- │                4D URL:       ://park.com     /4Dscene.fbx ─> ?other.glb ─> #view ───> hashbus │
- │                                                │                           #filter     │      │
- │                                                │                           #tag        │      │
- │                                                │     (hypermediatic)       #material   │      │
- │                                                │     (  feedback   )       #animation  │      │
- │                                                │     (    loop     )       #texture    │      │
- │                                                │                           #variable   │      │
- │                                                │                                       │      │
- │                                               XRWG <─────────────────────<─────────────+      │
- │                                                │                                       │      │
- │                                                └─ objects  ──────────────>─────────────+      │
- │                                                                                               │
- │                                                                                               │
- +───────────────────────────────────────────────────────────────────────────────────────────────+
-
-
- -
-

?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation.

-
- -

Traditional webbrowsers can become 4D document-ready by:

- -

The XR Fragments Trinity

+

What is XR Fragments

XR Fragments utilizes URLs:

    -
  1. for 3D viewers/browser to manipulate the camera or objects (via URLbar)
  2. -
  3. as implicit metadata to reference (nested) objects inside 3D scene-file (local and remote)
  4. -
  5. via explicit metadata (‘extras’) inside 3D scene-files (interaction e.g.) or
  6. -
  7. [optionally for developers] via explicit metadata outside 3D scene-files (via sidecarfile)
  8. +
  9. for 3D viewers/browser to manipulate the camera or objects (via URI fragments)
  10. +
  11. implicitly: by mapping 3D objectnames (of a 3D scene/file) to URI fragments (3D deeplinking)
  12. +
  13. explicitly: by scanning href metadata inside 3D scene-files to enable interactions
  14. +
  15. externally: progressively enhance a 3D (file) into an experience via sidecarfiles
-

List of URI Fragments

- - - - - - - - - - - - - - - - - - - - - - - - - - -
fragmenttypeexampleinfo
#......vector3#room1 #room2 #cam2positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector
Media Fragmentsmedia fragment#t=0,2&loopplay (and loop) 3D animation from 0 seconds till 2 seconds
- -

List of *explicit metadata

- -

These are the possible ‘extras’ for 3D nodes and sidecar-files

- - - - - - - - - - - - - - - - - - - - - -
keytypeexample (JSON)functionexisting compatibility
hrefstring"href": "b.gltf"XR teleportcustom property in 3D fileformats
-

HFL (Hypermediatic Feedback Loop) for XR Browsers

-

href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://#....) or navigate (xrf://#...) - as well (which allows many extra interactions which otherwise need a scripting language). This is known as hashbus-only events (see image above).

+

href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://....) via the xrf:// scheme, which does not change the top-level URL-adress (of the browser). +This allows for many extra interactions via URLs, which otherwise needs a scripting language. +These are called hashbus-only events/

-

Being able to use the same URI Fragment DSL for navigation (href: #foo) as well as interactions (href: xrf://#bar) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.

+

Being able to use the same URI Fragment DSL for navigation (href: #foo) as well as interactions (href: xrf://#foo) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.

This opens up the following benefits for traditional & future webbrowsers:

@@ -272,7 +152,7 @@ Instead of forcing authors to combine 3D/2D objects programmatically (publishing principle -XR 4D URL +3D URL HTML 2D URL @@ -376,7 +256,7 @@ sub-delims = "," / "=" -room1&rot=0,90,0&cam1 +room1&cam1 combinators @@ -392,7 +272,8 @@ That way, if the link gets shared, the XR Fragments implementation at http

Spatial Referencing 3D

-

XR Fragments assume the following objectname-to-URIFragment mapping:

+

3D files contain an hierarchy of objects.
+XR Fragments assumes the following objectname-to-URI-Fragment mapping, in order to deeplink 3D objects:


   my.io/scene.fbx
@@ -421,57 +302,102 @@ For example, to render a portal with a preview-version of the scene, create an 3
 
 
  • href: https://scene.fbx
  • -
  • src: https://otherworld.gltf#mainobject

It also allows sourceportation, which basically means the enduser can teleport to the original XR Document of an src embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.

-
+

Level0: Files

-

non-normative

+

These are optional auto-loaded side-car files to enable hasslefree XR Movies.
+they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.).

-

The following below is non-normative heuristics which are not part officially part of the spec.

+

via href metadata

-

additional explicit metadata

+
scene.glb  <--- 'href' extra [heuristic] detected inside!
+scene.png  (preview thumbnail)
+scene.ogg  (soundtrack to plays when global 3D animation starts)
+scene.vtt  (subtitles for accessibility or screenreaders)
+scene.json (sidecar JSON-file with explicit metadata)
+
-

| #rot | vector3 | #rot=0,90,0 | rotates camera to xyz-coord 0.5,0,0 | -| src | string | "src": "#cube" | XR embed / teleport | custom property in 3D fileformats | -| tag | string | "tag": "cubes geo" | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats | -| # | string | "#": "#mypreset | trigger default fragment on load | custom property in 3D fileformats |

+

heuristics:

+ +
    +
  • if at least one href custom property/extra is found in a 3D scene
  • +
  • The viewer should poll for the above mentioned sidecar-file extensions (and present accordingly)
  • +
+ +

via chained extension

+ +
scene.xrf.glb  <--- '.xrf.' sidecar file heuristic detected!
+scene.xrf.png  (preview thumbnail)
+scene.xrf.ogg  (soundtrack to plays when global 3D animation starts)
+scene.xrf.vtt  (subtitles for accessibility or screenreaders)
+scene.xrf.json (sidecar JSON-file with explicit metadata)
+
-

Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, .usdz, .json (THREE.js), .dae and so on.

+

A fallback-mechanism to turn 3D files into XR Movies without editing them.

-

Sidecar-file

+

heuristics:

+ +
    +
  • the chained-extension heuristic .xrf. should be present in the filename (scene.xrf.glb e.g.)
  • +
+ +

via subdocuments/xattr

+ +

More secure protocols (Nextgraph e.g.) don’t allow for simply polling files. +In such case, subdocuments or extended attributes should be polled:

-

NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.).

+

NOTE: in the examples below we use the href-heuristic, but also the .xrf. chained-extension applies here.

-

For developers, sidecar-file can allow for defining explicit XR Fragments metadata, outside of the 3D file.
-This can be done via a JSON-pointers RFC6901 in a JSON sidecar-file:

+
myspreadsheet.ods
+└── explainer.glb      <--- 'href' extra [heuristic] detected inside!
+    ├── explainer.ogg  (soundtrack to play when global 3D animation starts)
+    ├── explainer.png  (preview thumnbnail)
+    ├── explainer.json (sidecar JSON-file with explicit metadata)
+    └── explainer.vtt  (subtitles for accessibility or screenreaders)
+
+ +

If only extended attributes (xattr) are available, the respective referenced file can be embedded:

+ +
$ setfattr -n explainer.ogg -v "soundtrack.ogg" explainer.glb
+$ setfattr -n explainer.png -v "thumbnail.png" explainer.glb
+$ setfattr -n explainer.vtt -v "subtitles.vtt" explainer.glb
+
+ +
+

NOTE: Linux’s setfattr/getfattr is xattr on mac, and Set-Content/Get-content on Windows. See pxattr for lowlevel access.

+
+ +

JSON sidecar-file

+ +

For developers, sidecar-file can allow for defining explicit XR Fragments links (>level1), outside of the 3D file.
+This can be done via (objectname/metadata) key/value-pairs in a JSON sidecar-file:

  • experience.glb
  • -
  • experience.json
  • +
  • experience.json <----
{
-  "/":{
-    "#":                 "#-penguin",
+  "/":
     "aria-description": "description of scene",
   },
-  "/room/chair": {
-    "href": "#penguin"
+  "button": {
+    "href": "#roomB"
   }
 }
 
-

This would mean: hide object(s) with name or tag-value ‘penguin’ upon scene-load, and show it when the user clicks the chair

+

This will make object button clickable, and teleport the user to object roomB.

So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata.
@@ -481,25 +407,83 @@ The sidecar will define (or override already existing) extras,

In THREE.js-code this would boil down to:

-
 scene.userData['#'] = "#chair&penguin"
- scene.userData['aria-description'] = "description of scene"
- scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin"
+
 scene.userData['aria-description'] = "description of scene"
+ scene.getObjectByName("button").userData.href = "#roomB"
 
  // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene 
 
-

Level2: Implicit URI Fragments

+

Level1: URI

-

Warning: non-normative

+

XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments

-

These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser:

+

XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.
+Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments integrates all which allows a universal viewing experience.

+ +
  +───────────────────────────────────────────────────────────────────────────────────────────────+
+  │                                                                                               │
+  │                          U R N                                                                │
+  │ U R L                      |                                                                  │
+  │  |       |-----------------+--------|                                                         │
+  │  +--------------------------------------------------|                                         │
+  │  |                                                                                            │
+  │  + https://foo.com/some/foo/scene.glb#someview             <-- http URI (=URL and has URN)    │
+  │  |                                                                                            │
+  │  + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview             <-- an IPFS URI (=URL and has URN) │
+  │                                                                                               │
+  │  ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe      <-- an interpeer URI               │
+  │                                                                                               │
+  │                                                                                               │
+  │  |------------------------+-------------------------|                                         │
+  │                           |                                                                   │
+  │                         U R I                                                                 │
+  │                                                                                               │
+  +───────────────────────────────────────────────────────────────────────────────────────────────+
+
+
+ +

Fact: our typical browser URL’s are just a possible implementation of URI’s (for untapped humancentric potential of URI’s see interpeer.io or NextGraph )

+ +
+

XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.
But approaches things from a higherlevel local-first 3D hypermedia browser-perspective.

+
+ +

Below you can see how this translates back into good-old URLs:

+ +
 +───────────────────────────────────────────────────────────────────────────────────────────────+
+ │                                                                                               │
+ │   the soul of any URL:       ://macro        /meso           ?micro      #nano                │
+ │                                                                                               │
+ │                2D URL:       ://library.com  /document       ?search     #chapter             │
+ │                                                                                       xrf://  │
+ │                4D URL:       ://park.com     /4Dscene.fbx ─> ?other.glb ─> #object ─> hashbus │
+ │                                                │                           #filter     │      │
+ │                                                │                           #tag        │      │
+ │                                                │     (hypermediatic)       #material   │      │
+ │                                                │     (  feedback   )       #animation  │      │
+ │                                                │     (    loop     )       #texture    │      │
+ │                                                │                           #variable   │      │
+ │                                                │                                       │      │
+ │                                               XRWG <─────────────────────<─────────────+      │
+ │                                                │                                       │      │
+ │                                                └─ objects  ──────────────>─────────────+      │
+ │                                                                                               │
+ │                                                                                               │
+ +───────────────────────────────────────────────────────────────────────────────────────────────+
+
+
+ +
+

?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation.

+
+ +

List of URI Fragments

- @@ -509,385 +493,325 @@ The sidecar will define (or override already existing) extras, - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +
fragment type example
PRESET#<preset>string#cubesevaluates preset (#foo&bar) when a scene contains extra (#cubes: #foo&bar e.g.) while URL-browserbar reflects #cubes. Only works when metadata-key starts with ##......vector3#room1 #room2 #cam2positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector
FOCUSxrf://#<tag_or_objectname>string#person(and show) object(s) with tag: person or name person (XRWG lookup)
FILTERS#[!][-]<tag_or_objectname>[*]string#person (#-person)will reset (!), show/focus or hide (-) focus object(s) with tag: person or name person by looking up XRWG (*=including children)
MATERIALUPDATE#<tag_or_objectname>[*]=<materialname>string=string#car=metallicsets material of car to material with name metallic (*=including children)
#soldout*=halfopacityset material of objects tagged with product to material with name metallic
VARIABLE UPDATE#<variable>=<metadata-key>string=string#foo=barsets URI Template variable foo to the value #t=0 from existing object metadata (bar:#t=0 e.g.), This allows for reactive URI Template defined in object metadata elsewhere (src:://m.com/cat.mp4#{foo} e.g., to play media using media fragment URI). NOTE: metadata-key should not start with #
ANIMATION#<tag_or_objectname>=<animationname>string=string#people=walk #people=noanimassign a different animation to object(s)Media Fragmentsmedia fragment#t=0,2&loopplay (and loop) 3D animation from 0 seconds till 2 seconds
-

media fragments and datatypes

+

List of *explicit metadata

-
-

Warning: non-normative (below the word ‘play’ applies to 3D animations embedded in the 3D scene(file) but also media defined in src-metadata like audio/video-files (mp3/mp4 e.g.))

-
+

These are the possible ‘extras’ for 3D nodes and sidecar-files

+ - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +
key typesyntaxexampleinfoexample (JSON)functionexisting compatibility
vector2x,y2,3.02-dimensional vector
vector3x,y,z2,3.0,43-dimensional vector
temporal W3C media fragmentt=x0play from 0 seconds to end (and stop)
temporal W3C media fragmentt=x,y0,2play from 0 seconds till 2 seconds (and stop)
temporal W3C media fragment *s=x1set playback speed of audio/video/3D anim
temporal W3C media fragment *[-]looploopenable looped playback of audio/video/3D anim
-loopdisable looped playback (does not affect playbackstate of media)
vector2uv=u,v,uspeed,vspeed0,0set uv offset instantly (default speed = 1,1)
+0.5,+0.5scroll instantly by adding 0.5 to the current uv coordinates
0.2,1,0.1,0.1scroll (lerp) to uv coordinate 0,2,1 with 0.1 units per second
0,0,0,+0.1scroll v coordinates with 0.1 units per second (infinitely)
+0.5,+0.5scroll instantly by adding 0.5 to the current uv coordinates
media parameter (shader uniform)u:= -floatvec2hrefstring"href": "b.gltf"XR teleportcustom property in 3D fileformats
-
-

* = this is extending the W3C media fragments with (missing) playback/viewport-control. Normally #t=0,2 implies setting start/stop-values AND starting playback, whereas #s=0&loop allows pausing a video, speeding up/slowing down media, as well as enabling/disabling looping.

+

Level2: href links

-

The rationale for uv is that the xywh Media Fragment deals with rectangular media, which does not translate well to 3D models (which use triangular polygons, not rectangular) positioned by uv-coordinates. This also explains the absense of a scale or rotate primitive, which is challenged by this, as well as multiple origins (mesh- or texture).

+

Explicit href metadata (‘extras’) in a 3D object (of a 3D file), hint the viewer that the user “can interact” with that object :

+ +

| fragment | type | example value | +|href| string (uri or predefined view) | #pyramid
#lastvisit
xrf://#-someobject
://somefile.gltf#foo
|

+ +

Interaction behaviour

+ +

When clicking an “href”-value, the user(camera) is teleport to the referenced object.

+ +

The imported/teleported destination can be another object in the same scene-file, or a different file.

+ +

XR Viewer implementation

+ +

| spec | action | feature | +|-|-|-| +| level0+1 | hover 3D file href | show the preview PNG thumbnail (if any). | +| level0+1 | launch 3D file href | replace the current scene with a new 3D file (href: other.glb e.g.) | +| level2 | click internal 3D file href (#roomB e.g.) | teleport the camera to the origin of object(name roomB). See [[teleport camera]].| +| level2 | click external 3D file href (foo.glb e.g.) | replace the current scene with a new 3D file (href: other.glb e.g.) | +| level2 | hover external 3D file href | show the preview PNG thumbnail (if any sidecar, see level0) | +| level2 | click href | hashbus: execute without changing the toplevel URL location (href: xrf://#someObjectName e.g.) | +| level3 | click href | set the global 3D animation timeline to its Media Fragment value (#t=2,3 e.g.) |

+ +
+

NOTE: hashbus links (xrf://#foo&bar) don’t change the toplevel URL, which makes it ideal for interactions (in contrast to typical #roomC navigation, which benefit back/forward browser-buttons), see hashbus for more info.

-

Example URI’s:

+

Level3: Media Fragments

+ +
+

these allow for XR Movies with a controllable timeline using href URI’s with Media Fragments

+
+ +

Just like with 2D media-files, W3C mediafragments (#t=1,2) can be used to control a timeline via the #t primitive. +XR Fragments Level3 makes the 3D timeline, as well as URL-referenced files controllable via Media Fragments like:

    -
  • https://images.org/credits.jpg#uv=0,0,0,+0.1 (infinite vertical texturescrolling)
  • -
  • https://video.org/organogram.mp4#t=0&loop&uv=0.1,0.1,0.3,0.3 (animated tween towards region in looped video)
  • -
  • https://shaders.org/plasma.glsl#t=0&u:col2=0,1,0 (red-green shader plasma starts playing from time-offset 0)
  • +
  • level2 hrefs (href: #t=4 e.g. to control 3D timeline)
  • +
  • level4: xrf: URI scheme: + +
      +
    • href: xrf:foo.wav#t=0 to play a wav
    • +
    • href: xrf:news.glb?clone#t=0 to instance and play another experience
    • +
-
  +──────────────────────────────────────────────────────────+  
-  │                                                          │ 
-  │  index.gltf#playall                                      │ 
-  │    │                                                     │ 
-  │    ├ #        : #t=0&shared=play                         │ apply default XR Fragment on load (`t` plays global 3D animation timeline)
-  │    ├ play     : #t=0&loop                                │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
-  │    │                                                     │ 
-  │    ├── ◻ plane (with material)                           │    
-  │    │      └ #: #uv=0,0,0,+0.1                            │ infinite texturescroll `v` of uv·coordinates with 0.1/fps
-  │    │                                                     │ 
-  │    ├── ◻ plane                                           │    
-  │    │      └ src: foo.jpg#uv=0,0,0,+0.1                   │ infinite texturescroll `v` of uv·coordinates with 0.1/fps
-  │    │                                                     │ 
-  │    ├── ◻ media                                           │   
-  │    │      └ src:  cat.mp4#t=l:2,10&uv=0.5,0.5            │ loop cat.mp4 (or mp3/wav/jpg) between 2 and 10 seconds (uv's shifted with 0.5,0.5)
-  │    │                                                     │ 
-  │    └── ◻ wall                                            │        
-  │           ├ href:  #color=blue                           │ updates uniform values (IFS shader e.g.)
-  │           ├ blue:  t=0&u:col=0,0,1                       │ variable for [Level1 URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
-  │           └ src:   ://a.com/art.glsl#{color}&{shared}    │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570)
-  │                                                          │    
-  │                                                          │
-  +──────────────────────────────────────────────────────────+
+

Animation(s) timeline

-> NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work). +

controls the animation(s) of the scene (or src resource which contains a timeline)

+ +

| fragment | type | functionality | +| #t=start,stop | [vector2] | start,stop (in seconds |

+ +

| Example Value | Explanation | +| #t=1 | play (3D) animations from 1 seconds till end (and stop) | +| #t=1,100 | play (3D) animations from 1 till 100 seconds (and stop) | +| #t=0,0 | stop (3D) animations at frame 0 |

+ +
+

Use [[#s 🌱]] to control playback speed

+
+ +

Specify playback loopmode

+ +

This compensates a missing element from Media Fragments to enable/disable temporal looping. .

+ +

| fragment | type | functionality | +| #loop | string | enables animation/video/audio loop | +| #-loop | string | disables animation/video/audio loop |

+ +

Controlling embedded content

+ +

use [[URI Templates]] to control embedded media, for example a simple video-player:

+ +
 foo.usdz                                            
+    │                                                 
+    ├── ◻ loopbutton_enable
+    │      └ href: #loop           <-- enable global loop 
+    │                                                 
+    ├── ◻ loopbutton_enable
+    │      └ href: #-loop          <-- disable global loop 
+    │                                                 
+    ├── ◻ playbutton 
+    │      └ href: #t=10&loop      <-- play global 3D timeline (all anims) (looped)
+    │                                                 
+    └── ◻ playbutton_external                        
+           └ href: https://my.org/animation.glb#!&t=3,10   <-- import & play external anim
 
 
-

Navigating 3D

+

Level4: prefix operators

- - - - - - - - +

Prefixing objectnames with the following simple operators allow for extremely powerful XR interactions:

- - - - - - - -
fragmenttypefunctionality
#=room1stringposition camera to position and upvector of objectname room1 (+userheight in VR)
-

» example implementation
-» discussion

+
    +
  • #!
  • +
  • #*
  • +
  • #+ or #-
  • +
  • #|
  • +
  • xrf: URI scheme
  • +
-

Here’s the basic level1 flow (with optional level2 features):

+
+

Examples: #+menu to show a object, #-menu to hide a menu, #!menu to teleport a menu, #*block to clone a grabbable block, #|object to share an object

+
+ +

Object teleports (!)

+ +

Prefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.

+ +

[img[objecteleport.png]]

+ +

Usecases: +* show/hide objects/buttons (menu e.g.) in front of user +* embed remote (object within) 3D file via remote URL +* instance an interactive object near the user regardless of location +* instance HUD or semi-transparent-textured-sphere (LUT) around the user

+ +

+ #!menu +
+

+ +

Clicking the href-value above will:

    -
  1. the Y-coordinate of `room1 identifies the floorposition. This means that desktop-projections usually need to add 1.5m (average person height) on top (which is done automatically by VR/AR headsets), except in case of camera-switching.
  2. -
  3. set the position of the camera accordingly to the vector3 values of room1
  4. -
  5. set the upvector of the camera accordingly to the vector3 values of room1 (local gravity as pioneered by Patrick Lichty)
  6. -
  7. if the referenced #room1 object is animated, parent the current camera to that object (so it animates too)
  8. -
  9. in case a href does not mention any 3D object, the current position will be assumed
  10. +
  11. reposition the referenced object (menu) to the usercamera’s-coordinates.
  12. +
  13. zoom in case of (non-empty) mesh-object: rescale to 1 m³, and position 1m in front of the camera
  14. +
  15. toggle behaviour: revert values if 12 were already applied
  16. +
  17. #+ is always implied (objects are always made visible)
-

Here’s an ascii representation of a 3D scene-graph which contains 3D objects and their metadata:

+

This tiny but powerful symbol allows incredible interactive possibilities, by carefully positioning re-usable objects outside of a scene (below the usercamera’s floor e.g.).

-
  +────────────────────────────────────────────────────────+ 
-  │                                                        │
-  │  index.gltf                                            │
-  │    │                                                   │
-  │    ├── ◻ buttonA                                       │
-  │    │      └ href: #room1&t=100,200                 │
-  │    │                                                   │
-  │    └── ◻ buttonB                                       │
-  │           └ href: other.fbx                            │   <── file─agnostic (can be .gltf .obj etc)
-  │                                                        │
-  +────────────────────────────────────────────────────────+
+
    +
  • href: #whiteroom&!explainer&!exitmenu
  • +
-
+
+

This will teleport the user to whiteroom and moves object explainer and exitmenu in front of the user.

+
-

An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the buttonA and buttonB.
-In case of buttonA the end-user will be teleported to another location and time in the current loaded scene, but buttonB will replace the current scene with a new one, like other.fbx, and assume camera coordinate 0,0,0

+ -

Non-normative:

+

Clicking the href-value above will:

-
    -
  1. rot sets the rotation of the camera (only for non-VR/AR headsets, however a camera-value overrules this)
  2. -
  3. level2: mediafragment t in the top-URL sets the playbackspeed and animation-range of the global scene animation
  4. -
  5. before scene load: the scene is cleared
  6. -
  7. level2: after scene load: in case the scene (rootnode) contains an # default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)
  8. -
  9. level2: after scene load: in case the scene (rootnode) contains an # default view with a fragment value: execute positional fragment via the hashbus + update top-level URL
  10. -
  11. level2: in case of no default # view on the scene (rootnode), default player(rig) position 0,0,0 is assumed.
  12. +
      +
    1. import foo.glb from my.org’s webserver
    2. +
    3. show it in front of the user (because #! indicates object teleport)
    +
      +
    • href: https://foo.glb#roomB&!bar
    • +
    + +

    Clicking the href-value above will:

    + +
      +
    1. replace the current scene with foo.glb
    2. +
    3. teleport the user to #roomB inside foo.glb
    4. +
    5. instance the referenced object (bar inside foo.glb) in front of the user.
    6. +
    7. it will update the top-Level URL (because xrf: was not used)
    8. +
    9. hide the instanced object when clicked again (toggle visibility)
    10. +
    + +
    +

    NOTE: level2 teleportation links, as well as instancing mitigates the ‘broken embedded image’-issue of HTML: always attaching the href-values to a 3D (preview) object (that way broken links will not break the design).

    +
    + +

    Example: clicking a 3D button with title ‘menu’ and href-value xrf:menu.glb?instance#t=4,5 would instance a 3D menu (menu.glb) in front of the user, and loop its animation between from 4-5 seconds (t=4,5)

    + +
    +

    NOTE: combining instance-operators allows dynamic construction of 3D scenes (#london&!welcomeMenu&!fadeBox e.g.)

    +
    + +

    Object multipliers (*)

    + +

    The star-prefix will clone a (local or remote) referenced object to the usercamera’s location, and make it grabbable.
    +Usecases: +* object-picker (build stuff with objects)

    + +
    +

    NOTE: this is basically the #! operator which infinitely clones the referenced object (instead of repositioning the object).

    +
    + +

    De/selectors (+ and -)

    + +
      +
    • href: #-welcome (or #+welcome)
    • +
    + +

    Clicking href-value above will do:

    + +
      +
    1. show/hide the target object (and children)
    2. +
    + +
      +
    • href: #https://my.org/foo.glb/#bar&-welcome
    • +
    + +
    +

    NOTE: the latter shows that (de)selectors can also be with regular href-values

    +
    + +

    Sharing object or file (#|)

    + +

    The pipe-symbol (|) sends a (targeted) object to the OS. +Clicking the href-value below will:

    + +
      +
    1. share the (targeted object in the) file to a another application
    2. +
    + +
    +

    This URL can be fed straight into Web Share API or xdg-open

    +
    + +
      +
    • href: xrf://#|bar
    • +
    + +
    +

    NOTE: sharing is limited to (internal objects) via xrf: scheme-only

    +
    + +

    xrf:// URI scheme

    + +

    Prefixing the xrf: to href-values will prevent level2 href-values from changing the top-Level URL.

    + +
    +

    Usecase: for non-shareable URLs like href: xrf:#t=4,5, to display a stateful msg e.g.).

    +
    + +

    Reason: XR Fragments is inspired by HTML’s href-attribute, which does various things:

    + +
      +
    1. it updates the browser-location
    2. +
    3. it makes something clickable
    4. +
    5. it jumps to another document / elsewhere in the same document
    6. +
    7. and more
    8. +
    + +

    The xrf: scheme will just do 2 & 3 (so the URL-values will not leak into the top-level URL).

    + +
    +

    compliance with RFC 3986: unimplemented/unknown URI schemes (xrf:... e.g.) will not update the top-level URL

    +
    +

    Top-level URL processing

    -

    Example URL: ://foo/world.gltf#room1&t=10

    +

    Example URL: ://foo/world.gltf#room1&t=10&cam

    The URL-processing-flow for hypermedia browsers goes like this:

      -
    1. IF a #room1 matches a custom property-key (of an object) in the 3D file/scene (#room1: #......) THEN execute that predefined_view.
    2. IF scene operators and/or animation operator (t) are present in the URL then (re)position the camera (to room1) and/or animation-range (10) accordingly.
    3. IF no camera-position has been set in step 1 or 2 assume 0,0,0 as camera coordinate (XR: add user-height) (example)
    4. +
    5. IF a camera-object exists with name cam assume that user(camera) position
    -

    Non-normative / Deprecated:

    +

    UX

    -
      -
    1. IF a #cube matches the name (of an object) in the 3D file/scene then draw a line from the enduser(’s heart) to that object (to highlight it).
    2. -
    3. IF a #cube matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).
    4. -
    - -

    Embedding XR content using src

    - -
    -

    NOTE: only adviced for local-first experiences (where resources can be cached).

    -
    - -

    src is the 3D version of the iframe.
    -It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.

    - - - - - - - - - - - - - - - - - -
    fragmenttypeexample value
    srcstring (uri, hashtag/filter)#cube
    #sometag
    #cube&-ball_inside_cube<br>#-sky&-rain<br>#-language&english<br>#price=>5<br>https://linux.org/penguin.png`
    https://linux.world/distrowatch.gltf#t=1,100
    linuxapp://conference/nixworkshop/apply.gltf#-cta&cta_apply
    androidapp://page1?tutorial#room1&t1,100
    foo.mp3#0,0,0
    -

    Here’s an ascii representation of a 3D scene-graph with 3D objects which embeds remote & local 3D objects with/out using filters:

    - -
      +────────────────────────────────────────────────────────+  +─────────────────────────+ 
    -  │                                                        │  │                         │
    -  │  index.gltf                                            │  │ ocean.com/aquarium.fbx  │
    -  │    │                                                   │  │   ├ room                │
    -  │    ├── ◻ canvas                                        │  │   └── ◻ fishbowl        │
    -  │    │      └ src: painting.png                          │  │         ├─ ◻ bass       │
    -  │    │                                                   │  │         └─ ◻ tuna       │
    -  │    ├── ◻ aquariumcube                                  │  │                         │       
    -  │    │      └ src: ://rescue.com/fish.gltf#fishbowl      │  +─────────────────────────+
    -  │    │                                                   │    
    -  │    ├── ◻ bedroom                                       │   
    -  │    │      └ src: #canvas                               │
    -  │    │                                                   │   
    -  │    └── ◻ livingroom                                    │      
    -  │           └ src: #canvas                               │
    -  │                                                        │
    -  +────────────────────────────────────────────────────────+
    -
    - -

    An XR Fragment-compatible browser viewing this scene, lazy-loads and projects painting.png onto the (plane) object called canvas (which is copy-instanced in the bed and livingroom).
    -Also, after lazy-loading ocean.com/aquarium.gltf, only the queried objects fishbowl (and bass and tuna) will be instanced inside aquariumcube.
    -Resizing will be happen accordingly to its placeholder object aquariumcube, see chapter Scaling.

    - -
    -

    Instead of cherrypicking a rootobject #fishbowl with src, additional filters can be used to include/exclude certain objects. See next chapter on filtering below.

    -
    - -

    Specification:

    +

    End-users should always have read/write access to:

      -
    1. local/remote content is instanced by the src (filter) value (and attaches it to the placeholder mesh containing the src property)
    2. -
    3. by default all objects are loaded into the instanced src (scene) object (but not shown yet)
    4. -
    5. local src values (#... e.g.) starting with a non-negating filter (#cube e.g.) will (deep)reparent that object (with name cube) as the new root of the scene at position 0,0,0
    6. -
    7. local src values should respect (negative) filters (#-foo&price=>3)
    8. -
    9. the instanced scene (from a src value) should be scaled accordingly to its placeholder object or scaled relatively based on the scale-property (of a geometry-less placeholder, an ‘empty’-object in blender e.g.). For more info see Chapter Scaling.
    10. -
    11. external src values should be served with appropriate mimetype (so the XR Fragment-compatible browser will now how to render it). The bare minimum supported mimetypes are:
    12. -
    13. src values should make its placeholder object invisible, and only flush its children when the resolved content can succesfully be retrieved (see broken links)
    14. -
    15. external src values should respect the fallback link mechanism (see broken links
    16. -
    17. when the placeholder object is a 2D plane, but the mimetype is 3D, then render the spatial content on that plane via a stencil buffer.
    18. -
    19. src-values are non-recursive: when linking to an external object (src: foo.fbx#bar), then src-metadata on object bar should be ignored.
    20. -
    21. an external src-value should always allow a sourceportation icon within 3 meter: teleporting to the origin URI to which the object belongs.
    22. -
    23. when only one object was cherrypicked (#cube e.g.), set its position to 0,0,0
    24. -
    25. when the enduser clicks an href with #t=1,0,0 (play) will be applied to all src mediacontent with a timeline (mp4/mp3 e.g.)
    26. -
    27. a non-euclidian portal can be rendered for flat 3D objects (using stencil buffer e.g.) in case ofspatial src-values (an object #world3 or URL world3.fbx e.g.).
    28. +
    29. the current (toplevel) URL (an URLbar etc)
    30. +
    31. URL-history (a back/forward button e.g.)
    32. +
    33. Clicking/Touching an href navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).
    -
      -
    • model/gltf-binary
    • -
    • model/gltf+json
    • -
    • image/png
    • -
    • image/jpg
    • -
    • text/plain;charset=utf-8
    • -
    - -

    » example implementation
    -» example 3D asset
    -» discussion

    - -

    Navigating content href portals

    +

    Example: Navigating content href portals

    navigation, portals & mutations

    @@ -904,13 +828,13 @@ Resizing will be happen accordingly to its placeholder object aquariumcube href string (uri or predefined view) -#room1
    #room1&rot=90,0,0
    ://somefile.gltf#room1
    +#room1
    #room1
    ://somefile.gltf#room1
      -
    1. clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes room2&rot=0,0,0 by default (unless specified)

    2. +
    3. clicking an outbound “external”- or “file URI” fully replaces the current scene and assumes room2 by default (unless specified)

    4. relocation/reorientation should happen locally for local URI’s (#....)

    5. @@ -935,457 +859,23 @@ Resizing will be happen accordingly to its placeholder object aquariumcube

      Walking surfaces

      +
      +

      By default position 0,0,0 of the 3D scene represents the walkable plane, however this is overridden when the following applies:

      +
      +

      XR Fragment-compatible viewers can infer this data based scanning the scene for:

        -
      1. materialless (nameless & textureless) mesh-objects (without src and href)
      2. +
      3. materialless (nameless & textureless) mesh-objects (without href and >0 faces)

      optionally the viewer can offer thumbstick, mouse or joystick teleport-tools for non-roomscale VR/AR setups.

      -

      UX spec

      +

      Virtual world rings

      -

      End-users should always have read/write access to:

      - -
        -
      1. the current (toplevel) URL (an URLbar etc)
      2. -
      3. URL-history (a back/forward button e.g.)
      4. -
      5. Clicking/Touching an href navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).
      6. -
      - -

      Scaling instanced content

      - -

      Sometimes embedded properties (like src) instance new objects.
      -But what about their scale?
      -How does the scale of the object (with the embedded properties) impact the scale of the referenced content?

      - -
      -

      Rule of thumb: visible placeholder objects act as a ‘3D canvas’ for the referenced scene (a plane acts like a 2D canvas for images e, a cube as a 3D canvas e.g.).

      -
      - -
        -
      1. IF an embedded property (src e.g.) is set on an non-empty placeholder object (geometry of >2 vertices):
      2. -
      - -
        -
      • calculate the bounding box of the “placeholder” object (maxsize=1.4 e.g.)
      • -
      • hide the “placeholder” object (material e.g.)
      • -
      • instance the src scene as a child of the existing object
      • -
      • calculate the bounding box of the instanced scene, and scale it accordingly (to 1.4 e.g.)
      • -
      - -
      -

      REASON: non-empty placeholder object can act as a protective bounding-box (for remote content of which might grow over time e.g.)

      -
      - -
        -
      1. ELSE multiply the scale-vector of the instanced scene with the scale-vector (a common property of a 3D node) of the placeholder object.
      2. -
      - -
      -

      TODO: needs intermediate visuals to make things more obvious

      -
      - -

      XR Fragment: pos

      - -

      [[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]

      - -

      XR Fragment: rot

      - -

      [[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]

      - -

      XR Fragment: t

      - -

      [[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]]

      - -

      XR audio/video integration

      - -

      To play global audio/video items:

      - -
        -
      1. add a src: foo.mp3 or src: bar.mp4 metadata to a 3D object (cube e.g.)
      2. -
      3. to enable auto-play and global timeline ([[#t=|t]]) control: hardcode a [[#t=|t]] XR Fragment: (src: bar.mp3#t=0&loop e.g.)
      4. -
      5. to play it, add href: #cube somewhere else
      6. -
      7. to enable enduser-triggered play, use a [[URI Template]] XR Fragment: (src: bar.mp3#{player} and play: t=0&loop and href: xrf://#player=play e.g.)
      8. -
      9. when the enduser clicks the href, #t=0&loop (play) will be applied to the src value
      10. -
      - -
      -

      NOTE: hardcoded framestart/framestop uses sampleRate/fps of embedded audio/video, otherwise the global fps applies. For more info see [[#t|t]].

      -
      - -

      XR Fragment filters

      - -

      Include, exclude, hide/shows objects using space-separated strings:

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      exampleoutcome
      #-skyshow everything except object named sky
      #-language&englishhide everything with tag language, but show all tag english objects
      #-price&price=>10hide all objects with property price, then only show object with price above 10
      #-house*hide house object and everything inside (=*)
      -

      It’s simple but powerful syntax which allows filtering the scene using searchengine prompt-style feeling:

      - -
        -
      1. filters are a way to traverse a scene, and filter objects based on their name, tag- or property-values.
      2. -
      - - - -

      including/excluding

      - -

      By default, selectors work like photoshop-layers: they scan for matching layer(name/properties) within the scene-graph. -Each matched object (not their children) will be toggled (in)visible when selecting.

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      operatorinfo
      -hides object(s) (#-myobject&-objects e.g.
      =indicates an object-embedded custom property key/value (#price=4&category=foo e.g.)
      => =<compare float or int number (#price=>4 e.g.)
      *deepselect: automatically select children of selected object, including local (nonremote) embedded objects (starting with #)
      - -
      -

      NOTE 1: after an external embedded object has been instanced (src: https://y.com/bar.fbx#room e.g.), filters do not affect them anymore (reason: local tag/name collisions can be mitigated easily, but not in case of remote content).

      - -

      NOTE 2: depending on the used 3D framework, toggling objects (in)visible should happen by enabling/disableing writing to the colorbuffer (to allow children being still visible while their parents are invisible).

      -
      - -

      » example implementation -» example 3D asset -» discussion

      - -

      Filter Parser

      - -

      Here’s how to write a filter parser:

      - -
        -
      1. create an associative array/object to store filter-arguments as objects
      2. -
      3. detect object id’s & properties foo=1 and foo (reference regex= ~/^.*=[><=]?/ )
      4. -
      5. detect excluders like -foo,-foo=1,-.foo,-/foo (reference regex= /^-/ )
      6. -
      7. detect root selectors like /foo (reference regex= /^[-]?\// )
      8. -
      9. detect number values like foo=1 (reference regex= /^[0-9\.]+$/ )
      10. -
      11. detect operators so you can easily strip keys (reference regex= /(^-|\*$)/ )
      12. -
      13. detect exclude keys like -foo (reference regex= /^-/ )
      14. -
      15. for every filter token split string on =
      16. -
      17. and we set root to true or false (true=/ root selector is present)
      18. -
      19. therefore we we set show to true or false (false=excluder -)
      20. -
      - -
      -

      An example filter-parser (which compiles to many languages) can be found here

      -
      - -

      Visible links

      - -

      When predefined views, XRWG fragments and ID fragments (#cube or #mytag e.g.) are triggered by the enduser (via toplevel URL or clicking href):

      - -
        -
      1. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) matching that ID (objectname)
      2. -
      3. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) matching that tag value
      4. -
      5. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) containing that in their src or href value
      6. -
      - -

      The obvious approach for this, is to consult the XRWG (example), which basically has all these things already collected/organized for you during scene-load.

      - -

      UX

      - -
        -
      1. do not update the wires when the enduser moves, leave them as is
      2. -
      3. offer a control near the back/forward button which allows the user to (turn off) control the correlation-intensity of the XRWG
      4. -
      - -

      Text in XR (tagging,linking to spatial objects)

      - -

      How does XR Fragments interlink text with objects?

      - -
      -

      The XR Fragments does this by collapsing space into a Word Graph (the XRWG example), augmented by Bib(s)Tex.

      -
      - -

      Instead of just throwing together all kinds media types into one experience (games), what about their tagged/semantical relationships?
      -Perhaps the following question is related: why is HTML adopted less in games outside the browser?

      - -

      Hence:

      - -
        -
      1. XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG (example)
      2. -
      3. XR Fragments primes the XRWG, by collecting words from the tag and name-property of 3D objects.
      4. -
      5. XR Fragments primes the XRWG, by collecting words from optional metadata at the end of content of text (see default mimetype & Data URI)
      6. -
      7. XR Fragments primes the XRWG, by collecting tags/id’s from linked hypermedia (URI fragments for HTML e.g.)
      8. -
      9. The XRWG should be recalculated when textvalues (in src) change
      10. -
      11. HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content)
      12. -
      13. Applications don’t have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes.
      14. -
      15. The XR Fragment focuses on fast and easy-to-generate end-user controllable word graphs (instead of complex implementations that try to defeat word ambiguity)
      16. -
      17. Instead of exact lowercase word-matching, levensteihn-distance-based matching is preferred
      18. -
      - -

      Example of generating XRWG out of the XRWG and textdata with hashtags:

      - -
        http://y.io/z.fbx                                                           | Derived XRWG (expressed as JSON)
      -  ----------------------------------------------------------------------------+--------------------------------------
      -                                                                              | Chapter: ['#mydoc']
      -  +-[src: data:.....]----------------------+   +-[3D mesh]-+                  | one:     ['#mydoc']
      -  | Chapter one                            |   |    / \    |                  | houses:  ['#castle','#mydoc','#house']
      -  |                                        |   |   /   \   |                  | baroque: ['#mydoc','#castle']
      -  | John built houses in baroque style.    |   |  /     \  |                  | castle:  ['#baroque','#house']
      -  |                                        |   |  |_____|  |                  | john:    ['#john','#mydoc']
      -  |                                        |   +-----│-----+                  | mydoc:   ['#mydoc']
      -  |                                        |         │                        |
      -  |                                        |         ├─ name: castle          | 
      -  |                                        |         └─ tag: house baroque    | 
      -  +----------------------------------------+                                  |
      -                 └─ name: mydoc                [3D mesh-+                     |
      -                                               |    O   ├─ name: john         |                           
      -                                               |   /|\  |                     |
      -                                               |   / \  |                     |    ^ ^ ^
      -                                               +--------+                     |    | | |  
      -                                                                              |         
      -           [remotestorage.io]+  [ localstorage]-+                             | <- the XR Fragment-compatible 
      -           | XRWG (JSON)     |  | XRWG (JSON    |                             | <- 3D hypermedia viewer should
      -           |                 |  |               |                             | <- be able to select the active XRWG
      -           +-----------------+  +---------------+                             |
      -
      - -

      This allows hasslefree authoring and copy-paste of associations for and by humans, but also makes these URLs possible:

      - - - - - - - - - - - - - - - - - - - - - - - - - -
      URL exampleResult
      https://my.com/foo.gltf#baroquedraws lines between 3D mesh castle, and mydoc’s text baroque
      https://my.com/foo.gltf#johndraws lines between mesh john, and the text John of mydoc
      https://my.com/foo.gltf#housedraws lines between mesh castle, and other objects with tag house or todo
      - -
      -

      the URI fragment #john&mydoc&house would draw a connection between these 3 meshes.

      -
      - -

      The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels:

      - -
        -
      • wordmatch inside src text
      • -
      • wordmatch inside href text
      • -
      • wordmatch object-names
      • -
      • wordmatch object-tagnames
      • -
      - -

      Spatial wires can be rendered between words/objects etc.
      -Some pointers for good UX (but not necessary to be XR Fragment compatible):

      - -
        -
      1. The XR Browser needs to adjust tag-scope based on the endusers needs/focus (infinite tagging only makes sense when environment is scaled down significantly)
      2. -
      3. The XR Browser should always allow the human to view/edit the metadata, by clicking ‘toggle metadata’ on the ‘back’ (contextmenu e.g.) of any XR text, anywhere anytime.
      4. -
      5. respect multi-line BiBTeX metadata in text because of the core principle
      6. -
      7. Default font (unless specified otherwise) is a modern monospace font, for maximized tabular expressiveness (see the core principle).
      8. -
      9. anti-pattern: hardcoupling an XR Browser with a mandatory markup/scripting-language which departs from onubtrusive plain text (HTML/VRML/Javascript) (see the core principle)
      10. -
      11. anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.
      12. -
      - -

      Default Data URI mimetype

      - -

      The src-values work as expected (respecting mime-types), however:

      - -

      The XR Fragment specification advices to bump the traditional default browser-mimetype

      - -

      text/plain;charset=US-ASCII

      - -

      to a hashtag-friendly one:

      - -

      text/plain;charset=utf-8;hashtag

      - -

      This indicates that:

      - -
        -
      • utf-8 is supported by default
      • -
      • words beginning with # (hashtags) will prime the XRWG by adding the hashtag to the XRWG, linking to the current sentence/paragraph/alltext (depending on ‘.’) to the XRWG
      • -
      - -

      Advantages:

      - -
        -
      • out-of-the-box (de)multiplex human text and metadata in one go (see the core principle)
      • -
      • no network-overhead for metadata (see the core principle)
      • -
      • ensuring high FPS: realtime HTML/RDF historically is too ‘requesty’/‘parsy’ for game studios
      • -
      • rich send/receive/copy-paste everywhere by default, metadata being retained (see the core principle)
      • -
      • netto result: less webservices, therefore less servers, and overall better FPS in XR
      • -
      - -
      -

      This significantly expands expressiveness and portability of human tagged text, by postponing machine-concerns to the end of the human text in contrast to literal interweaving of content and markupsymbols (or extra network requests, webservices e.g.).

      -
      - -

      For all other purposes, regular mimetypes can be used (but are not required by the spec).

      - -

      URL and Data URI

      - -
        +--------------------------------------------------------------+  +------------------------+
      -  |                                                              |  | author.com/article.txt |
      -  |  index.gltf                                                  |  +------------------------+
      -  |    │                                                         |  |                        |
      -  |    ├── ◻ article_canvas                                      |  | Hello #friends         |
      -  |    │    └ src: ://author.com/article.txt                     |  |                        |
      -  |    │                                                         |  +------------------------+
      -  |    └── ◻ note_canvas                                         |  
      -  |           └ src:`data:welcome human\n@book{sunday...}`       |  
      -  |                                                              |  
      -  |                                                              |
      -  +--------------------------------------------------------------+
      -
      - -

      The enduser will only see welcome human and Hello friends rendered verbatim (see mimetype). -The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata). -In both cases, the text gets rendered immediately (onto a plane geometry, hence the name ‘_canvas’). -The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.).

      - -
      -

      additional tagging using bibs: to tag spatial object note_canvas with ‘todo’, the enduser can type or speak #note_canvas@todo

      -
      - -

      Importing/exporting

      - -

      For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play.

      - -
        -
      1. export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.
      2. -
      - -

      Reflection Mapping

      - -

      Environment mapping is crucial for creating realistic reflections and lighting effects on 3D objects. -To apply environment mapping efficiently in a 3D scene, traverse the scene graph and assign each object’s environment map based on the nearest ancestor’s texture map. This ensures that objects inherit the correct environment mapping from their closest parent with a texture, enhancing the visual consistency and realism.

      - -
        +--------------------------------+  
      -  |                                |  
      -  |  index.usdz                    |  
      -  |    │                           |  
      -  |    └── ◻ sphere (texture:foo)  | 
      -  |        └ ◻ cube (texture:bar)  | envMap = foo 
      -  |         └ ◻ cylinder           | envMap = bar
      -  +--------------------------------+
      -
      - -

      Most 3D viewers apply one and the same environment map for various models, however this logic -allows a more natural & automatic strategy for reflection mapping:

      - -
        -
      1. traverse the scene graph depth-first
      2. -
      3. remember the most recent parentnode (P) with a texture material
      4. -
      5. for every non-root node with a texture material -3.1 clone that material (as materials might be shared across objects) -3.2 set the environmentmap to the last known parent texture (P)
      6. -
      - -

      Transclusion (broken link) resolution

      - -

      In spirit of Ted Nelson’s ‘transclusion resolution’, there’s a soft-mechanism to harden links & minimize broken links in various ways:

      - -
        -
      1. defining a different transport protocol (https vs ipfs or DAT) in src or href values can make a difference
      2. -
      3. mirroring files on another protocol using (HTTP) errorcode tags in src or href properties
      4. -
      5. in case of src: nesting a copy of the embedded object in the placeholder object (embeddedObject) will not be replaced when the request fails
      6. -
      - -
      -

      due to the popularity, maturity and extensiveness of HTTP codes for client/server communication, non-HTTP protocols easily map to HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.)

      -
      - -

      For example:

      - -
        +────────────────────────────────────────────────────────+ 
      -  │                                                        │
      -  │  index.gltf                                            │
      -  │    │                                                   │
      -  │    │ #: #-offlinetext                                  │
      -  │    │                                                   │
      -  │    ├── ◻ buttonA                                       │
      -  │    │      └ href:     http://foo.io/campagne.fbx       │
      -  │    │      └ href@404: ipfs://foo.io/campagne.fbx       │
      -  │    │      └ href@400: #clienterrortext                 │
      -  │    │      └ ◻ offlinetext                              │
      -  │    │                                                   │
      -  │    └── ◻ embeddedObject                          <--------- the meshdata inside embeddedObject will (not)
      -  │           └ src: https://foo.io/bar.gltf               │    be flushed when the request (does not) succeed.
      -  │           └ src@404: http://foo.io/bar.gltf            │    So worstcase the 3D data (of the time of publishing index.gltf)
      -  │           └ src@400: https://archive.org/l2kj43.gltf   │    will be displayed.
      -  │                                                        │
      -  +────────────────────────────────────────────────────────+
      -
      -
      - -

      Topic-based index-less Webrings

      - -

      As hashtags in URLs map to the XWRG, href-values can be used to promote topic-based index-less webrings.
      -Consider 3D scenes linking to eachother using these href values:

      +

      Consider 3D scenes linking to eachother using these href values, attached to 3D button-objects:

      • href: schoolA.edu/projects.gltf#math
      • @@ -1393,47 +883,19 @@ Consider 3D scenes linking to eachother using these href values:

        href: university.edu/projects.gltf#math
      -

      These links would all show visible links to math-tagged objects in the scene.
      -To filter out non-related objects one could take it a step further using filters:

      +

      This would teleport users to the math-projects of those universities.
      +Now consider adding a ‘webring index’-button to each file, with this href-value:

        -
      • href: schoolA.edu/projects.gltf#math&-topics math
      • -
      • href: schoolB.edu/projects.gltf#math&-courses math
      • -
      • href: university.edu/projects.gltf#math&-theme math
      • +
      • href: workgroup.edu/webrings.glb#!webringmenu
      -
      -

      This would hide all object tagged with topic, courses or theme (including math) so that later only objects tagged with math will be visible

      -
      +

      This would allow displaying the (remote 3D file) webring menu with various href-buttons inside, all centrally curated by the workgroup.

      -

      This makes spatial content multi-purpose, without the need to separate content into separate files, or show/hide things using a complex logiclayer like javascript.

      - -

      URI Templates (RFC6570)

      +

      Level5: URI Templates (RFC6570)

      XR Fragments adopts Level1 URI Fragment expansion to provide safe interactivity.
      -The following demonstrates a simple video player:

      - -
      
      -  +─────────────────────────────────────────────+
      -  │                                             │
      -  │   foo.usdz                                  │          
      -  │     │                                       │          
      -  │     │                                       │          
      -  │     ├── ◻ stopbutton                        │
      -  │     │      ├ #:    #-stopbutton             │
      -  │     │      └ href: #player=stop&-stopbutton │  (stop and hide stop-button)
      -  │     │                                       │          
      -  │     └── ◻ plane                             │
      -  │            ├ play: #t=l:0,10                │
      -  │            ├ stop: #t=0,0                   │
      -  │            ├ href: #player=play&stopbutton  │  (play and show stop-button)
      -  │            └ src:  cat.mp4#{player}         │
      -  │                                             │
      -  │                                             │
      -  +─────────────────────────────────────────────+
      -
      -
      -
      +This is non-normative, and the draft spec is available on request.

      Additional scene metadata

      @@ -1443,10 +905,13 @@ Instead, it encourages browsers to scan nodes for the following custom propertie
      • SPDX license information
      • ARIA attributes (aria-*: .....)
      • +
      • datapackage.json findability, accessibility, interoperability, and reusability of data
      +

      ARIA’s aria-description-metadata is normative, to aid accessibility and scene transcripts

      +
      -

      SPDX and ARIA’s aria-description are normative, as they promote accessibility and scene transcripts: please start aria-description with a verb to aid transcripts.

      +

      NOTE: please always start aria-description with a verb to aid transcripts.

      The following metadata are non-normative but encouraged, since they are popular and cheap to parse:

      diff --git a/doc/RFC_XR_Fragments.md b/doc/RFC_XR_Fragments.md index 4bf3471..abee146 100644 --- a/doc/RFC_XR_Fragments.md +++ b/doc/RFC_XR_Fragments.md @@ -95,11 +95,11 @@ value: draft-XRFRAGMENTS-leonvankammen-00 An open specification for hyperlinking & deeplinking 3D fileformats. This draft is a specification for interactive URI-controllable 3D files, enabling [hypermediatic](https://github.com/coderofsalvation/hypermediatic) navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
      -The specification uses [W3C Media Fragments](https://www.w3.org/TR/media-frags/) and [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
      XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like [URI Fragments](https://en.wikipedia.org/wiki/URI_fragment).
      -XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). +XR Fragments views XR experiences thru the lens of 3D deeplinked URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). +The standard comprises of various (optional) support levels, which also include [W3C Media Fragments](https://www.w3.org/TR/media-frags/) and [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
      -> XR Fragments is a heuristical 3D format which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
      +> XR Fragments is in a sense, a heuristical 3D format or meta-format, which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
      These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing higher interop between fileformats, 3D editors, viewers and game-engines. > Almost every idea in this document is demonstrated at [https://xrfragment.org](https://xrfragment.org) @@ -113,7 +113,7 @@ Historically, there's many attempts to create the ultimate 3D fileformat.
      The lowest common denominator is: designers describing/tagging/naming things using **plain text**.
      XR Fragments exploits the fact that all 3D models already contain such metadata: -**XR Fragments allows controlling of metadata in 3D scene(files) using URI's** +**XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments** It solves: @@ -125,113 +125,35 @@ It solves: > NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible -# Core principle - -**XR Fragments allows controlling 3D models using URLs, based on (non)existing metadata via URI's** - -XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.
      -Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments **integrates all** which allows a universal viewing experience.
      - -``` - +───────────────────────────────────────────────────────────────────────────────────────────────+ - │ │ - │ U R N │ - │ U R L | │ - │ | |-----------------+--------| │ - │ +--------------------------------------------------| │ - │ | │ - │ + https://foo.com/some/foo/scene.glb#someview <-- http URI (=URL and has URN) │ - │ | │ - │ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN) │ - │ │ - │ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │ - │ │ - │ │ - │ |------------------------+-------------------------| │ - │ | │ - │ U R I │ - │ │ - +───────────────────────────────────────────────────────────────────────────────────────────────+ - -``` - -Fact: our typical browser URL's are just **a possible implementation** of URI's (for untapped humancentric potential of URI's [see interpeer.io](https://interpeer.io)) - -> XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.
      But approaches things from a higherlevel feedbackloop/hypermedia browser-perspective. - -Below you can see how this translates back into good-old URLs: - -``` - +───────────────────────────────────────────────────────────────────────────────────────────────+ - │ │ - │ the soul of any URL: ://macro /meso ?micro #nano │ - │ │ - │ 2D URL: ://library.com /document ?search #chapter │ - │ xrf:// │ - │ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #view ───> hashbus │ - │ │ #filter │ │ - │ │ #tag │ │ - │ │ (hypermediatic) #material │ │ - │ │ ( feedback ) #animation │ │ - │ │ ( loop ) #texture │ │ - │ │ #variable │ │ - │ │ │ │ - │ XRWG <─────────────────────<─────────────+ │ - │ │ │ │ - │ └─ objects ──────────────>─────────────+ │ - │ │ - │ │ - +───────────────────────────────────────────────────────────────────────────────────────────────+ - -``` - -> ?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation. - -Traditional webbrowsers can become 4D document-ready by: - -# The XR Fragments Trinity +# What is XR Fragments XR Fragments utilizes URLs: -1. for 3D viewers/browser to manipulate the camera or objects (via URLbar) -2. as **implicit** metadata to reference (nested) objects **inside** 3D scene-file (local and remote) -3. via **explicit** metadata ('extras') **inside** 3D scene-files (interaction e.g.) or -4. [optionally for developers] via **explicit** metadata **outside** 3D scene-files (via [sidecarfile](https://en.wikipedia.org/wiki/Sidecar_file)) +1. for 3D viewers/browser to manipulate the camera or objects (via URI fragments) +2. implicitly: by mapping 3D objectnames (of a 3D scene/file) to URI fragments (3D deeplinking) +3. explicitly: by scanning `href` metadata **inside** 3D scene-files to enable interactions +4. externally: progressively enhance a 3D (file) into an experience via [sidecarfiles](https://en.wikipedia.org/wiki/Sidecar_file) -# List of URI Fragments - -| fragment | type | example | info | -|-------------------|------------|--------------------|----------------------------------------------------------------------| -| `#......` | vector3 | `#room1` `#room2` `#cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector | -| [Media Fragments](https://www.w3.org/TR/media-frags/) | [media fragment](#media%20fragments%20and%20datatypes) | `#t=0,2&loop` | play (and loop) 3D animation from 0 seconds till 2 seconds| - - -# List of **explicit* metadata - -These are the possible 'extras' for 3D nodes and sidecar-files - -| key | type | example (JSON) | function | existing compatibility | -|--------------|----------|------------------------|---------------------|----------------------------------------| -| `href` | string | `"href": "b.gltf"` | XR teleport | custom property in 3D fileformats | # HFL (Hypermediatic Feedback Loop) for XR Browsers -`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://#....`) or **navigate** (`xrf://#...`) - as well (which allows many extra interactions which otherwise need a scripting language). This is known as **hashbus**-only events (see image above). +`href` metadata traditionally implies **click** AND **navigate**, however XR Fragments adds stateless **click** (`xrf://....`) via the `xrf://` scheme, which does not change the top-level URL-adress (of the browser). +This allows for many extra interactions via URLs, which otherwise needs a scripting language. +These are called **hashbus**-only events/ -> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#bar`) greatly simplifies implementation, increases HFL, and reduces need for scripting languages. +> Being able to use the same URI Fragment DSL for navigation (`href: #foo`) as well as interactions (`href: xrf://#foo`) greatly simplifies implementation, increases HFL, and reduces need for scripting languages. This opens up the following benefits for traditional & future webbrowsers: * [hypermediatic](https://github.com/coderofsalvation/hypermediatic) loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML). -* allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the `xrf://` hashbus (`xrf://#person=walk` to trigger `walk`-animation for object `person`) -* collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus +* potentially allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the `xrf://` hashbus (`xrf://#person=walk` to trigger `walk`-animation for object `person`) +* potentially collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus * completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources) XR Fragments itself are [hypermediatic](https://github.com/coderofsalvation/hypermediatic) and HTML-agnostic, though pseudo-XR Fragment browsers **can** be implemented on top of HTML/Javascript. -| principle | XR 4D URL | HTML 2D URL | +| principle | 3D URL | HTML 2D URL | |-----------------------------|-------------------------------------------------|---------------------------------------| | the XRWG | wordgraph (collapses 3D scene to tags) | Ctrl-F (find) | | the hashbus | hashtags alter camera/scene/object-projections | hashtags alter document positions | @@ -265,7 +187,7 @@ sub-delims = "," / "=" | Demo | Explanation | |-------------------------------|---------------------------------| | `room1` | vector/coordinate argument e.g. | -| `room1&rot=0,90,0&cam1` | combinators | +| `room1&cam1` | combinators | > this is already implemented in all browsers @@ -275,7 +197,8 @@ That way, if the link gets shared, the XR Fragments implementation at `https://m # Spatial Referencing 3D -XR Fragments assume the following objectname-to-URIFragment mapping: +3D files contain an hierarchy of objects.
      +XR Fragments assumes the following objectname-to-URI-Fragment mapping, in order to deeplink 3D objects: ``` @@ -302,50 +225,92 @@ Clever nested design of 3D scenes allow great ways for re-using content, and/or For example, to render a portal with a preview-version of the scene, create an 3D object with: * href: `https://scene.fbx` -* src: `https://otherworld.gltf#mainobject` > It also allows **sourceportation**, which basically means the enduser can teleport to the original XR Document of an `src` embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it. +# Level0: Files ---- +These 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.). -# non-normative +## via href metadata -The following below is non-normative heuristics which are not part officially part of the spec. +``` +scene.glb <--- 'href' extra [heuristic] detected inside! +scene.png (preview thumbnail) +scene.ogg (soundtrack to plays when global 3D animation starts) +scene.vtt (subtitles for accessibility or screenreaders) +scene.json (sidecar JSON-file with explicit metadata) +``` -# additional **explicit** metadata +**heuristics**: -| `#rot` | vector3 | `#rot=0,90,0` | rotates camera to xyz-coord 0.5,0,0 | -| `src` | string | `"src": "#cube"` | XR embed / teleport | custom property in 3D fileformats | -| `tag` | string | `"tag": "cubes geo"` | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats | -| `#` | string | `"#": "#mypreset` | trigger default fragment on load | custom property in 3D fileformats | +* if at least one `href` custom property/extra is found in a 3D scene +* The viewer should poll for the above mentioned sidecar-file extensions (and present accordingly) -> Supported popular compatible 3D fileformats: `.gltf`, `.obj`, `.fbx`, `.usdz`, `.json` (THREE.js), `.dae` and so on. +## via chained extension -## Sidecar-file +``` +scene.xrf.glb <--- '.xrf.' sidecar file heuristic detected! +scene.xrf.png (preview thumbnail) +scene.xrf.ogg (soundtrack to plays when global 3D animation starts) +scene.xrf.vtt (subtitles for accessibility or screenreaders) +scene.xrf.json (sidecar JSON-file with explicit metadata) +``` -> NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a `.glb` e.g.). +> A fallback-mechanism to turn 3D files into [XR Movies](#XR%20Movies) without editing them. -For developers, sidecar-file can allow for defining **explicit** XR Fragments metadata, outside of the 3D file.
      -This can be done via a JSON-pointers [RFC6901](https://www.rfc-editor.org/rfc/rfc6901) in a JSON [sidecar-file](https://en.wikipedia.org/wiki/Sidecar_file): +**heuristics**: + +* the chained-extension heuristic `.xrf.` should be present in the filename (`scene.xrf.glb` e.g.) + +## via subdocuments/xattr + +More secure protocols (Nextgraph e.g.) don't allow for simply polling files. +In such case, subdocuments or extended attributes should be polled: + +> NOTE: in the examples below we use the href-heuristic, but also the `.xrf.` chained-extension applies here. + +``` +myspreadsheet.ods +└── explainer.glb <--- 'href' extra [heuristic] detected inside! + ├── explainer.ogg (soundtrack to play when global 3D animation starts) + ├── explainer.png (preview thumnbnail) + ├── explainer.json (sidecar JSON-file with explicit metadata) + └── explainer.vtt (subtitles for accessibility or screenreaders) +``` + +If only extended attributes (xattr) are available, the respective referenced file can be embedded: + +``` +$ setfattr -n explainer.ogg -v "soundtrack.ogg" explainer.glb +$ setfattr -n explainer.png -v "thumbnail.png" explainer.glb +$ setfattr -n explainer.vtt -v "subtitles.vtt" explainer.glb +``` + +> NOTE: Linux's `setfattr/getfattr` is `xattr` on mac, and `Set-Content/Get-content` on Windows. See [pxattr](https://www.lesbonscomptes.com/pxattr/index.html) for lowlevel access. + +## JSON sidecar-file + +For developers, sidecar-file can allow for defining **explicit** XR Fragments links (>level1), outside of the 3D file.
      +This can be done via (objectname/metadata) key/value-pairs in a JSON [sidecar-file](https://en.wikipedia.org/wiki/Sidecar_file): * experience.glb -* experience.json +* experience.json `<----` ```json { - "/":{ - "#": "#-penguin", + "/": "aria-description": "description of scene", }, - "/room/chair": { - "href": "#penguin" + "button": { + "href": "#roomB" } } ``` -> This would mean: hide object(s) with name or `tag`-value 'penguin' upon scene-load, and show it when the user clicks the chair +> This will make object `button` clickable, and teleport the user to object `roomB`. So after loading `experience.glb` the existence of `experience.json` is detected, to apply the explicit metadata.
      The sidecar will define (or **override** already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users). @@ -353,227 +318,319 @@ The sidecar will define (or **override** already existing) extras, which can be > In THREE.js-code this would boil down to: ```javascript - scene.userData['#'] = "#chair&penguin" scene.userData['aria-description'] = "description of scene" - scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin" + scene.getObjectByName("button").userData.href = "#roomB" // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene ``` +# Level1: URI +> **XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments** - -## Level2: Implicit URI Fragments - -> Warning: non-normative - -These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser: - -| |fragment | type | example | info | -|------|------------------|----------|-------------------|-------------------------------------------------------------------------------| -| **PRESET** | `#` | string | `#cubes` | evaluates preset (`#foo&bar`) when a scene contains extra (`#cubes: #foo&bar` e.g.) while URL-browserbar reflects `#cubes`. Only works when metadata-key starts with `#` | -| **FOCUS** | `xrf://#` | string | `#person` | (and show) object(s) with `tag: person` or name `person` (XRWG lookup) | -| **FILTERS** | `#[!][-][*]` | string | `#person` (`#-person`) | will reset (`!`), show/focus or hide (`-`) focus object(s) with `tag: person` or name `person` by looking up XRWG (`*`=including children) | -| **MATERIALUPDATE** | `#[*]=` | string=string | `#car=metallic`| sets material of car to material with name `metallic` (`*`=including children)| -| | | | `#soldout*=halfopacity`| set material of objects tagged with `product` to material with name `metallic` | -| **VARIABLE UPDATE** | `#=` | string=string | `#foo=bar` | sets [URI Template](https://www.rfc-editor.org/rfc/rfc6570) variable `foo` to the value `#t=0` from **existing** object metadata (`bar`:`#t=0` e.g.), This allows for reactive [URI Template](https://www.rfc-editor.org/rfc/rfc6570) defined in object metadata elsewhere (`src`:`://m.com/cat.mp4#{foo}` e.g., to play media using [media fragment URI](https://www.w3.org/TR/media-frags/#valid-uri)). NOTE: metadata-key should not start with `#` | -| **ANIMATION** | `#=` | string=string | `#people=walk` `#people=noanim` | assign a different animation to object(s) | - -## media fragments and datatypes - -> Warning: **non-normative** (below the word 'play' applies to 3D animations embedded in the 3D scene(file) **but also** media defined in `src`-metadata like audio/video-files (mp3/mp4 e.g.)) - -| type | syntax | example | info | -|-------------------------------|-----------------------------------|-----------------|----------------------| -| vector2 | x,y | 2,3.0 | 2-dimensional vector | -| vector3 | x,y,z | 2,3.0,4 | 3-dimensional vector | -| temporal W3C media fragment | t=x | 0 | play from 0 seconds to end (and stop) | -| temporal W3C media fragment | t=x,y | 0,2 | play from 0 seconds till 2 seconds (and stop) | -| temporal W3C media fragment * | s=x | 1 | set playback speed of audio/video/3D anim | -| temporal W3C media fragment * | [-]loop | loop | enable looped playback of audio/video/3D anim | -| | | -loop | disable looped playback (does not affect playbackstate of media) | -| vector2 | uv=u,v,uspeed,vspeed | 0,0 | set uv offset instantly (default speed = `1,1`) | -| | | +0.5,+0.5 | scroll instantly by adding 0.5 to the current uv coordinates | -| | | 0.2,1,0.1,0.1 | scroll (lerp) to uv coordinate `0,2,1` with `0.1` units per second | -| | | 0,0,0,+0.1 | scroll v coordinates with `0.1` units per second (infinitely) | -| | | +0.5,+0.5 | scroll instantly by adding 0.5 to the current uv coordinates | -| media parameter (shader uniform) | u:= | u:color=1,0,0 | set shader uniform value | - -> \* = this is extending the [W3C media fragments](https://www.w3.org/TR/media-frags/#mf-advanced) with (missing) playback/viewport-control. Normally `#t=0,2` implies setting start/stop-values AND starting playback, whereas `#s=0&loop` allows pausing a video, speeding up/slowing down media, as well as enabling/disabling looping. - -> The rationale for `uv` is that the `xywh` Media Fragment deals with rectangular media, which does not translate well to 3D models (which use triangular polygons, not rectangular) positioned by uv-coordinates. This also explains the absense of a `scale` or `rotate` primitive, which is challenged by this, as well as multiple origins (mesh- or texture). - -Example URI's: - -* `https://images.org/credits.jpg#uv=0,0,0,+0.1` (infinite vertical texturescrolling) -* `https://video.org/organogram.mp4#t=0&loop&uv=0.1,0.1,0.3,0.3` (animated tween towards region in looped video) -* `https://shaders.org/plasma.glsl#t=0&u:col2=0,1,0` (red-green shader plasma starts playing from time-offset 0) +XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.
      +Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments **integrates all** which allows a universal viewing experience.
      ``` - +──────────────────────────────────────────────────────────+ - │ │ - │ index.gltf#playall │ - │ │ │ - │ ├ # : #t=0&shared=play │ apply default XR Fragment on load (`t` plays global 3D animation timeline) - │ ├ play : #t=0&loop │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) - │ │ │ - │ ├── ◻ plane (with material) │ - │ │ └ #: #uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps - │ │ │ - │ ├── ◻ plane │ - │ │ └ src: foo.jpg#uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps - │ │ │ - │ ├── ◻ media │ - │ │ └ src: cat.mp4#t=l:2,10&uv=0.5,0.5 │ loop cat.mp4 (or mp3/wav/jpg) between 2 and 10 seconds (uv's shifted with 0.5,0.5) - │ │ │ - │ └── ◻ wall │ - │ ├ href: #color=blue │ updates uniform values (IFS shader e.g.) - │ ├ blue: t=0&u:col=0,0,1 │ variable for [Level1 URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) - │ └ src: ://a.com/art.glsl#{color}&{shared} │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) - │ │ - │ │ - +──────────────────────────────────────────────────────────+ - -> NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work). + +───────────────────────────────────────────────────────────────────────────────────────────────+ + │ │ + │ U R N │ + │ U R L | │ + │ | |-----------------+--------| │ + │ +--------------------------------------------------| │ + │ | │ + │ + https://foo.com/some/foo/scene.glb#someview <-- http URI (=URL and has URN) │ + │ | │ + │ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN) │ + │ │ + │ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │ + │ │ + │ │ + │ |------------------------+-------------------------| │ + │ | │ + │ U R I │ + │ │ + +───────────────────────────────────────────────────────────────────────────────────────────────+ ``` -# Navigating 3D +Fact: our typical browser URL's are just **a possible implementation** of URI's (for untapped humancentric potential of URI's [see interpeer.io](https://interpeer.io) or [NextGraph](https://nextgraph.org) ) + +> XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.
      But approaches things from a higherlevel local-first 3D hypermedia browser-perspective. + +Below you can see how this translates back into good-old URLs: + +``` + +───────────────────────────────────────────────────────────────────────────────────────────────+ + │ │ + │ the soul of any URL: ://macro /meso ?micro #nano │ + │ │ + │ 2D URL: ://library.com /document ?search #chapter │ + │ xrf:// │ + │ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #object ─> hashbus │ + │ │ #filter │ │ + │ │ #tag │ │ + │ │ (hypermediatic) #material │ │ + │ │ ( feedback ) #animation │ │ + │ │ ( loop ) #texture │ │ + │ │ #variable │ │ + │ │ │ │ + │ XRWG <─────────────────────<─────────────+ │ + │ │ │ │ + │ └─ objects ──────────────>─────────────+ │ + │ │ + │ │ + +───────────────────────────────────────────────────────────────────────────────────────────────+ + +``` + +> ?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation. + +# List of URI Fragments + +| fragment | type | example | info | +|-------------------|------------|--------------------|----------------------------------------------------------------------| +| `#......` | vector3 | `#room1` `#room2` `#cam2` | positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector | +| [Media Fragments](https://www.w3.org/TR/media-frags/) | [media fragment](#media%20fragments%20and%20datatypes) | `#t=0,2&loop` | play (and loop) 3D animation from 0 seconds till 2 seconds| + + +# List of **explicit* metadata + +These are the possible 'extras' for 3D nodes and sidecar-files + +| key | type | example (JSON) | function | existing compatibility | +|--------------|----------|------------------------|---------------------|----------------------------------------| +| `href` | string | `"href": "b.gltf"` | XR teleport | custom property in 3D fileformats | + + +# Level2: href links + +Explicit href metadata ('extras') in a 3D object (of a 3D file), hint the viewer that the user ''can interact'' with that object : + +| fragment | type | example value | +|`href`| string (uri or predefined view) | `#pyramid`
      `#lastvisit`
      `xrf://#-someobject`
      `://somefile.gltf#foo`
      | + +## Interaction behaviour + +When clicking an ''href''-value, the user(camera) is teleport to the referenced object. + +The imported/teleported destination can be another object in the same scene-file, or a different file. + +## XR Viewer implementation + +| **spec** | **action** | **feature** | +|-|-|-| +| level0+1 | hover 3D file [href](#via-href-metadata) | show the preview PNG thumbnail (if any). | +| level0+1 | launch 3D file [href](#via-href-metadata) | replace the current scene with a new 3D file (`href: other.glb` e.g.) | +| level2 | click internal 3D file [href](#via-href-metadata) (`#roomB` e.g.) | teleport the camera to the origin of object(name `roomB`). See [[teleport camera]].| +| level2 | click external 3D file [href](#via-href-metadata) (`foo.glb` e.g.) | replace the current scene with a new 3D file (`href: other.glb` e.g.) | +| level2 | hover external 3D file [href](#via-href-metadata) | show the preview PNG thumbnail (if any sidecar, see level0) | +| level2 | click [href](#via-href-metadata) | hashbus: execute without changing the toplevel URL location (`href: xrf://#someObjectName` e.g.) | +| level3 | click [href](#via-href-metadata) | set the global 3D animation timeline to its Media Fragment value (`#t=2,3` e.g.) | + +> NOTE: hashbus links (`xrf://#foo&bar`) don't change the toplevel URL, which makes it ideal for interactions (in contrast to typical `#roomC` navigation, which benefit back/forward browser-buttons), see hashbus for more info. + +# Level3: Media Fragments + +> these allow for XR Movies with a controllable timeline using `href` URI's with Media Fragments + +Just like with 2D media-files, W3C mediafragments (`#t=1,2`) can be used to control a timeline via the [#t](##t) primitive. +XR Fragments Level3 makes the 3D timeline, as well as URL-referenced files **controllable** via Media Fragments like: + +* level2 hrefs (`href: #t=4` e.g. to control 3D timeline) +* level4: `xrf:` URI scheme: + * `href: xrf:foo.wav#t=0` to play a wav + * `href: xrf:news.glb?clone#t=0` to instance and play another experience + +## Animation(s) timeline + +controls the animation(s) of the scene (or `src` resource which contains a timeline) | fragment | type | functionality | -|----------|--------|------------------------------| -| #=room1 | string | position camera to position and upvector of objectname `room1` (+userheight in VR) | +| #t=start,stop | [[vector2]] (default:`#t=0,0`) | start,stop (in seconds | -[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js)
      -[» discussion](https://github.com/coderofsalvation/xrfragment/issues/5)
      -Here's the basic **level1** flow (with optional level2 features): +| Example Value | Explanation | +| `#t=1` | play (3D) animations from 1 seconds till end (and stop) | +| `#t=1,100` | play (3D) animations from 1 till 100 seconds (and stop) | +| `#t=0,0` | stop (3D) animations at frame 0 | -1. the Y-coordinate of `room1 identifies the floorposition. This means that desktop-projections usually need to add 1.5m (average person height) on top (which is done automatically by VR/AR headsets), except in case of camera-switching. -2. set the position of the camera accordingly to the vector3 values of `room1` -3. set the upvector of the camera accordingly to the vector3 values of `room1` (local gravity as pioneered by Patrick Lichty) -3. if the referenced `#room1` object is animated, parent the current camera to that object (so it animates too) -4. in case a `href` does not mention any 3D object, the current position will be assumed +> Use [[#s 🌱]] to control playback speed -Here's an ascii representation of a 3D scene-graph which contains 3D objects `◻` and their metadata: +## Specify playback loopmode + +This compensates a missing element from Media Fragments to enable/disable temporal looping. . + +| fragment | type | functionality | +| #loop | string | enables animation/video/audio loop | +| #-loop | string | disables animation/video/audio loop | + + +## Controlling embedded content + +use [[URI Templates]] to control embedded media, for example a simple video-player: ``` - +────────────────────────────────────────────────────────+ - │ │ - │ index.gltf │ - │ │ │ - │ ├── ◻ buttonA │ - │ │ └ href: #room1&t=100,200 │ - │ │ │ - │ └── ◻ buttonB │ - │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc) - │ │ - +────────────────────────────────────────────────────────+ + foo.usdz + │ + ├── ◻ loopbutton_enable + │ └ href: #loop <-- enable global loop + │ + ├── ◻ loopbutton_enable + │ └ href: #-loop <-- disable global loop + │ + ├── ◻ playbutton + │ └ href: #t=10&loop <-- play global 3D timeline (all anims) (looped) + │ + └── ◻ playbutton_external + └ href: https://my.org/animation.glb#!&t=3,10 <-- import & play external anim ``` -An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the `buttonA` and `buttonB`.
      -In case of `buttonA` the end-user will be teleported to another location and time in the **current loaded scene**, but `buttonB` will **replace the current scene** with a new one, like `other.fbx`, and assume camera coordinate `0,0,0` +# Level4: prefix operators -**Non-normative**: +Prefixing objectnames with the following simple operators allow for **extremely powerful** XR interactions: -5. `rot` sets the rotation of the camera (only for non-VR/AR headsets, however a camera-value overrules this) -6. **level2**: mediafragment `t` in the top-URL sets the playbackspeed and animation-range of the global scene animation -7. before scene load: the scene is cleared -8. **level2**: after scene load: in case the scene (rootnode) contains an `#` default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change) -9. **level2**: after scene load: in case the scene (rootnode) contains an `#` default view with a fragment value: execute positional fragment via the hashbus + update top-level URL -10. **level2**: in case of no default `#` view on the scene (rootnode), default player(rig) position `0,0,0` is assumed. +* #! +* #* +* #+ or #- +* #| +* xrf: URI scheme + +> **Examples:** `#+menu` to show a object, `#-menu` to hide a menu, `#!menu` to teleport a menu, `#*block` to clone a grabbable block, `#|object` to share an object + + +## Object teleports (!) + +Prefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.
      + +[img[objecteleport.png]] + +Usecases: +* show/hide objects/buttons (menu e.g.) in front of user +* embed remote (object within) 3D file via remote URL +* instance an interactive object near the user regardless of location +* instance HUD or semi-transparent-textured-sphere (LUT) around the user + +
      + #!menu +
      +
      + +Clicking the [href](#via-href-metadata)-value above will: + +1. **reposition the referenced object** (menu) to the usercamera's-coordinates. +2. **zoom** in case of (non-empty) mesh-object: rescale to 1 m³, and position 1m in front of the camera +3. toggle behaviour: revert values if 1/2 were already applied +4. `#+` is always implied (objects are always made visible) + +This tiny but powerful symbol allows incredible interactive possibilities, by carefully positioning re-usable objects outside of a scene (below the usercamera's floor e.g.). + +* href: `#whiteroom&!explainer&!exitmenu` + +> This will teleport the user to `whiteroom` and moves object `explainer` and `exitmenu` in front of the user. + +* href: `https://my.org/foo.glb#! + +Clicking the [href](#via-href-metadata)-value above will: + +1. import `foo.glb` from `my.org`'s webserver +2. show it in front of the user (because `#!` indicates object teleport) + +* href: `https://foo.glb#roomB&!bar` + +Clicking the [href](#via-href-metadata)-value above will: + +1. replace the current scene with `foo.glb` +2. teleport the user to #roomB inside `foo.glb` +3. **instance the referenced object** (bar inside foo.glb) in front of the user. +4. it will update the top-Level URL (because `xrf:` was not used) +5. hide the **instanced object** when clicked again (toggle visibility) + +> **NOTE**: level2 teleportation links, as well as instancing mitigates the 'broken embedded image'-issue of HTML: **always** attaching the href-values to **a 3D (preview) object** (that way broken links will not break the design). + +**Example:** clicking a 3D button with title 'menu' and [href](#href)-value `xrf:menu.glb?instance#t=4,5` would instance a 3D menu (`menu.glb`) in front of the user, and loop its animation between from 4-5 seconds (`t=4,5`) + +> **NOTE**: combining instance-operators allows dynamic construction of 3D scenes (`#london&!welcomeMenu&!fadeBox` e.g.) + +## Object multipliers (*) + +The star-prefix will clone a (local or remote) referenced object to the usercamera's location, and make it grabbable.
      +Usecases: +* object-picker (build stuff with objects) + +> **NOTE**: this is basically the [#! operator](#%23%21) which infinitely **clones** the referenced object (instead of repositioning the object). + +## De/selectors (+ and -) + +* href: `#-welcome` (or `#+welcome`) + +Clicking href-value above will do: + +1. show/hide the target object (and children) + +* href: `#https://my.org/foo.glb/#bar&-welcome` + +> **NOTE:** the latter shows that (de)selectors can also be with regular [href](#href)-values + +## Sharing object or file (#|) + +The pipe-symbol (`|`) sends a (targeted) object to the OS. +Clicking the href-value below will: + +1. share the (targeted object in the) file to a another application + +> This URL can be fed straight into [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API) or [xdg-open](https://www.freedesktop.org/wiki/Software/xdg-utils/) + +* href: `xrf://#|bar` + +> **NOTE**: sharing is limited to (internal objects) via `xrf:` scheme-only + +## xrf:// URI scheme + +Prefixing the `xrf:` to [href](#href)-values **will prevent** [level2](#📜%20level2:%20explicit%20links) [href](#href)-values from changing the top-Level URL. + +> **Usecase**: for non-shareable URLs like `href: xrf:#t=4,5`, to display a stateful msg e.g.). + +**Reason:** XR Fragments is inspired by HTML's [href-attribute](https://en.wikipedia.org/wiki/Hyperlink), which does various things: + +1. it updates the browser-location +2. it makes something clickable +3. it jumps to another document / elsewhere in the same document +4. and more + +The `xrf:` scheme will just do 2 & 3 (so the URL-values will not leak into the top-level URL). + +> **compliance with RFC 3986**: unimplemented/unknown URI schemes (`xrf:...` e.g.) will not update the top-level URL # Top-level URL processing -> Example URL: `://foo/world.gltf#room1&t=10` +> Example URL: `://foo/world.gltf#room1&t=10&cam` The URL-processing-flow for hypermedia browsers goes like this: -1. IF a `#room1` matches a custom property-key (of an object) in the 3D file/scene (`#room1`: `#......`) THEN execute that predefined_view. -2. IF scene operators and/or animation operator (`t`) are present in the URL then (re)position the camera (to `room1`) and/or animation-range (`10`) accordingly. -3. IF no camera-position has been set in step 1 or 2 assume `0,0,0` as camera coordinate (XR: add user-height) ([example](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]])) +1. IF scene operators and/or animation operator (`t`) are present in the URL then (re)position the camera (to `room1`) and/or animation-range (`10`) accordingly. +2. IF no camera-position has been set in step 1 or 2 assume `0,0,0` as camera coordinate (XR: add user-height) ([example](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/navigator.js#L31]])) +3. IF a camera-object exists with name `cam` assume that user(camera) position -**Non-normative / Deprecated**: +## UX -4. IF a `#cube` matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it). -5. IF a `#cube` matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects). +End-users should always have read/write access to: -# Embedding XR content using src +1. the current (toplevel) URL (an URLbar etc) +2. URL-history (a back/forward button e.g.) +3. Clicking/Touching an `href` navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments). -> NOTE: only adviced for local-first experiences (where resources can be cached). -`src` is the 3D version of the iframe.
      -It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera. - -| fragment | type | example value | -|----------|------|---------------| -|`src`| string (uri, hashtag/filter) | `#cube`
      `#sometag`
      #cube&-ball_inside_cube`
      `#-sky&-rain`
      `#-language&english`
      `#price=>5`
      `https://linux.org/penguin.png`
      `https://linux.world/distrowatch.gltf#t=1,100`
      `linuxapp://conference/nixworkshop/apply.gltf#-cta&cta_apply`
      `androidapp://page1?tutorial#room1&t1,100`
      `foo.mp3#0,0,0`| - -Here's an ascii representation of a 3D scene-graph with 3D objects `◻` which embeds remote & local 3D objects `◻` with/out using filters: - -``` - +────────────────────────────────────────────────────────+ +─────────────────────────+ - │ │ │ │ - │ index.gltf │ │ ocean.com/aquarium.fbx │ - │ │ │ │ ├ room │ - │ ├── ◻ canvas │ │ └── ◻ fishbowl │ - │ │ └ src: painting.png │ │ ├─ ◻ bass │ - │ │ │ │ └─ ◻ tuna │ - │ ├── ◻ aquariumcube │ │ │ - │ │ └ src: ://rescue.com/fish.gltf#fishbowl │ +─────────────────────────+ - │ │ │ - │ ├── ◻ bedroom │ - │ │ └ src: #canvas │ - │ │ │ - │ └── ◻ livingroom │ - │ └ src: #canvas │ - │ │ - +────────────────────────────────────────────────────────+ -``` - -An XR Fragment-compatible browser viewing this scene, lazy-loads and projects `painting.png` onto the (plane) object called `canvas` (which is copy-instanced in the bed and livingroom).
      -Also, after lazy-loading `ocean.com/aquarium.gltf`, only the queried objects `fishbowl` (and `bass` and `tuna`) will be instanced inside `aquariumcube`.
      -Resizing will be happen accordingly to its placeholder object `aquariumcube`, see chapter Scaling.
      - -> Instead of cherrypicking a rootobject `#fishbowl` with `src`, additional filters can be used to include/exclude certain objects. See next chapter on filtering below. - -**Specification**: - -1. local/remote content is instanced by the `src` (filter) value (and attaches it to the placeholder mesh containing the `src` property) -2. by default all objects are loaded into the instanced src (scene) object (but not shown yet) -2. local `src` values (`#...` e.g.) starting with a non-negating filter (`#cube` e.g.) will (deep)reparent that object (with name `cube`) as the new root of the scene at position 0,0,0 -3. local `src` values should respect (negative) filters (`#-foo&price=>3`) -4. the instanced scene (from a `src` value) should be scaled accordingly to its placeholder object or scaled relatively based on the scale-property (of a geometry-less placeholder, an 'empty'-object in blender e.g.). For more info see Chapter Scaling. -5. external `src` values should be served with appropriate mimetype (so the XR Fragment-compatible browser will now how to render it). The bare minimum supported mimetypes are: -6. `src` values should make its placeholder object invisible, and only flush its children when the resolved content can succesfully be retrieved (see [broken links](#links)) -7. external `src` values should respect the fallback link mechanism (see [broken links](#broken-links) -8. when the placeholder object is a 2D plane, but the mimetype is 3D, then render the spatial content on that plane via a stencil buffer. -9. src-values are non-recursive: when linking to an external object (`src: foo.fbx#bar`), then `src`-metadata on object `bar` should be ignored. -10. an external `src`-value should always allow a sourceportation icon within 3 meter: teleporting to the origin URI to which the object belongs. -11. when only one object was cherrypicked (`#cube` e.g.), set its position to `0,0,0` -12. when the enduser clicks an href with `#t=1,0,0` (play) will be applied to all src mediacontent with a timeline (mp4/mp3 e.g.) -13. a non-euclidian portal can be rendered for flat 3D objects (using stencil buffer e.g.) in case ofspatial `src`-values (an object `#world3` or URL `world3.fbx` e.g.). - -* `model/gltf-binary` -* `model/gltf+json` -* `image/png` -* `image/jpg` -* `text/plain;charset=utf-8` - -[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/src.js)
      -[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/src.gltf#L192)
      -[» discussion](https://github.com/coderofsalvation/xrfragment/issues/4)
      - -# Navigating content href portals +# Example: Navigating content href portals navigation, portals & mutations | fragment | type | example value | |----------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------| -|`href` | string (uri or predefined view) | `#room1`
      `#room1&rot=90,0,0`
      `://somefile.gltf#room1`
      | +|`href` | string (uri or predefined view) | `#room1`
      `#room1`
      `://somefile.gltf#room1`
      | -1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `room2&rot=0,0,0` by default (unless specified) +1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes `room2` by default (unless specified) 2. relocation/reorientation should happen locally for local URI's (`#....`) @@ -597,377 +654,34 @@ navigation, portals & mutations ## Walking surfaces +> By default position `0,0,0` of the 3D scene represents the walkable plane, however this is overridden when the following applies: + XR Fragment-compatible viewers can infer this data based scanning the scene for: -1. materialless (nameless & textureless) mesh-objects (without `src` and `href`) +1. materialless (nameless & textureless) mesh-objects (without `href` and >0 faces) > optionally the viewer can offer thumbstick, mouse or joystick teleport-tools for non-roomscale VR/AR setups. -## UX spec +# Virtual world rings -End-users should always have read/write access to: - -1. the current (toplevel) URL (an URLbar etc) -2. URL-history (a back/forward button e.g.) -3. Clicking/Touching an `href` navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments). - - -## Scaling instanced content - -Sometimes embedded properties (like `src`) instance new objects.
      -But what about their scale?
      -How does the scale of the object (with the embedded properties) impact the scale of the referenced content?
      - -> Rule of thumb: visible placeholder objects act as a '3D canvas' for the referenced scene (a plane acts like a 2D canvas for images e, a cube as a 3D canvas e.g.). - -1. IF an embedded property (`src` e.g.) is set on an non-empty placeholder object (geometry of >2 vertices): - -* calculate the bounding box of the ''placeholder'' object (maxsize=1.4 e.g.) -* hide the ''placeholder'' object (material e.g.) -* instance the `src` scene as a child of the existing object -* calculate the bounding box of the instanced scene, and scale it accordingly (to 1.4 e.g.) - -> REASON: non-empty placeholder object can act as a protective bounding-box (for remote content of which might grow over time e.g.) - -2. ELSE multiply the scale-vector of the instanced scene with the scale-vector (a common property of a 3D node) of the placeholder object. - -> TODO: needs intermediate visuals to make things more obvious - -# XR Fragment: pos - -[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]
      - -# XR Fragment: rot - -[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]
      - -# XR Fragment: t - -[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]]
      - -# XR audio/video integration - -To play global audio/video items: - -1. add a `src: foo.mp3` or `src: bar.mp4` metadata to a 3D object (`cube` e.g.) -1. to enable auto-play and global timeline ([[#t=|t]]) control: hardcode a [[#t=|t]] XR Fragment: (`src: bar.mp3#t=0&loop` e.g.) -1. to play it, add `href: #cube` somewhere else -1. to enable enduser-triggered play, use a [[URI Template]] XR Fragment: (`src: bar.mp3#{player}` and `play: t=0&loop` and `href: xrf://#player=play` e.g.) -1. when the enduser clicks the `href`, `#t=0&loop` (play) will be applied to the `src` value - -> NOTE: hardcoded framestart/framestop uses sampleRate/fps of embedded audio/video, otherwise the global fps applies. For more info see [[#t|t]]. - -# XR Fragment filters - -Include, exclude, hide/shows objects using space-separated strings: - -| example | outcome | -|----------------------------------|------------------------------------------------------------------------------------| -| `#-sky` | show everything except object named `sky` | -| `#-language&english` | hide everything with tag `language`, but show all tag `english` objects | -| `#-price&price=>10` | hide all objects with property `price`, then only show object with price above 10 | -| `#-house*` | hide `house` object and everything inside (=`*`) | - -It's simple but powerful syntax which allows filtering the scene using searchengine prompt-style feeling: - -1. filters are a way to traverse a scene, and filter objects based on their name, tag- or property-values. - -* see [an (outdated) example video here](https://coderofsalvation.github.io/xrfragment.media/queries.mp4) which used a dedicated `q=` variable (now deprecated and usable directly) - -## including/excluding - -By default, selectors work like photoshop-layers: they scan for matching layer(name/properties) within the scene-graph. -Each matched object (not their children) will be toggled (in)visible when selecting. - -| operator | info | -|----------|-------------------------------------------------------------------------------------------------------------------------------| -| `-` | hides object(s) (`#-myobject&-objects` e.g. | -| `=` | indicates an object-embedded custom property key/value (`#price=4&category=foo` e.g.) | -| `=>` `=<`| compare float or int number (`#price=>4` e.g.) | -| `*` | deepselect: automatically select children of selected object, including local (nonremote) embedded objects (starting with `#`)| - -> NOTE 1: after an external embedded object has been instanced (`src: https://y.com/bar.fbx#room` e.g.), filters do not affect them anymore (reason: local tag/name collisions can be mitigated easily, but not in case of remote content). - -> NOTE 2: depending on the used 3D framework, toggling objects (in)visible should happen by enabling/disableing writing to the colorbuffer (to allow children being still visible while their parents are invisible). - -[» example implementation](https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/q.js) -[» example 3D asset](https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/filter.gltf#L192) -[» discussion](https://github.com/coderofsalvation/xrfragment/issues/3) - -## Filter Parser - -Here's how to write a filter parser: - -1. create an associative array/object to store filter-arguments as objects -1. detect object id's & properties `foo=1` and `foo` (reference regex= `~/^.*=[><=]?/` ) -1. detect excluders like `-foo`,`-foo=1`,`-.foo`,`-/foo` (reference regex= `/^-/` ) -1. detect root selectors like `/foo` (reference regex= `/^[-]?\//` ) -1. detect number values like `foo=1` (reference regex= `/^[0-9\.]+$/` ) -1. detect operators so you can easily strip keys (reference regex= `/(^-|\*$)/` ) -1. detect exclude keys like `-foo` (reference regex= `/^-/` ) -1. for every filter token split string on `=` -1. and we set `root` to `true` or `false` (true=`/` root selector is present) -1. therefore we we set `show` to `true` or `false` (false=excluder `-`) - -> An example filter-parser (which compiles to many languages) can be [found here](https://github.com/coderofsalvation/xrfragment/blob/main/src/xrfragment/Filter.hx) - -# Visible links - -When predefined views, XRWG fragments and ID fragments (`#cube` or `#mytag` e.g.) are triggered by the enduser (via toplevel URL or clicking `href`): - -1. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) matching that ID (objectname) -2. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) matching that `tag` value -3. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) containing that in their `src` or `href` value - -The obvious approach for this, is to consult the XRWG ([example](https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js)), which basically has all these things already collected/organized for you during scene-load. - -**UX** - -4. do not update the wires when the enduser moves, leave them as is -5. offer a control near the back/forward button which allows the user to (turn off) control the correlation-intensity of the XRWG - -# Text in XR (tagging,linking to spatial objects) - -How does XR Fragments interlink text with objects? - -> The XR Fragments does this by collapsing space into a **Word Graph** (the **XRWG** [example](https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js)), augmented by Bib(s)Tex. - -Instead of just throwing together all kinds media types into one experience (games), what about their tagged/semantical relationships?
      -Perhaps the following question is related: why is HTML adopted less in games outside the browser? - -Hence: - -1. XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG ([example](https://github.com/coderofsalvation/xrfragment/blob/feat/macros/src/3rd/js/XRWG.js)) -2. XR Fragments primes the XRWG, by collecting words from the `tag` and name-property of 3D objects. -3. XR Fragments primes the XRWG, by collecting words from **optional** metadata **at the end of content** of text (see default mimetype & Data URI) -4. XR Fragments primes the XRWG, by collecting tags/id's from linked hypermedia (URI fragments for HTML e.g.) -5. The XRWG should be recalculated when textvalues (in `src`) change -6. HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content) -7. Applications don't have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes. -8. The XR Fragment focuses on fast and easy-to-generate end-user controllable word graphs (instead of complex implementations that try to defeat word ambiguity) -9. Instead of exact lowercase word-matching, levensteihn-distance-based matching is preferred - -Example of generating XRWG out of the XRWG and textdata with hashtags: - -``` - http://y.io/z.fbx | Derived XRWG (expressed as JSON) - ----------------------------------------------------------------------------+-------------------------------------- - | Chapter: ['#mydoc'] - +-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc'] - | Chapter one | | / \ | | houses: ['#castle','#mydoc','#house'] - | | | / \ | | baroque: ['#mydoc','#castle'] - | John built houses in baroque style. | | / \ | | castle: ['#baroque','#house'] - | | | |_____| | | john: ['#john','#mydoc'] - | | +-----│-----+ | mydoc: ['#mydoc'] - | | │ | - | | ├─ name: castle | - | | └─ tag: house baroque | - +----------------------------------------+ | - └─ name: mydoc [3D mesh-+ | - | O ├─ name: john | - | /|\ | | - | / \ | | ^ ^ ^ - +--------+ | | | | - | - [remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible - | XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should - | | | | | <- be able to select the active XRWG - +-----------------+ +---------------+ | -``` - - -This allows hasslefree authoring and copy-paste of associations **for and by humans**, but also makes these URLs possible: - -| URL example | Result | -|---------------------------------------|---------------------------------------------------------------------------| -| `https://my.com/foo.gltf#baroque` | draws lines between 3D mesh `castle`, and `mydoc`'s text `baroque` | -| `https://my.com/foo.gltf#john` | draws lines between mesh `john`, and the text `John` of `mydoc` | -| `https://my.com/foo.gltf#house` | draws lines between mesh `castle`, and other objects with tag `house` or `todo` | - -> the URI fragment `#john&mydoc&house` would draw a connection between these 3 meshes. - -The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels: - -* wordmatch **inside** `src` text -* wordmatch **inside** `href` text -* wordmatch object-names -* wordmatch object-tagnames - -Spatial wires can be rendered between words/objects etc.
      -Some pointers for good UX (but not necessary to be XR Fragment compatible): - -9. The XR Browser needs to adjust tag-scope based on the endusers needs/focus (infinite tagging only makes sense when environment is scaled down significantly) -10. The XR Browser should always allow the human to view/edit the metadata, by clicking 'toggle metadata' on the 'back' (contextmenu e.g.) of any XR text, anywhere anytime. -12. respect multi-line BiBTeX metadata in text because of [the core principle](#core-principle) -13. Default font (unless specified otherwise) is a modern monospace font, for maximized tabular expressiveness (see [the core principle](#core-principle)). -14. anti-pattern: hardcoupling an XR Browser with a mandatory **markup/scripting-language** which departs from onubtrusive plain text (HTML/VRML/Javascript) (see [the core principle](#core-principle)) -15. anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen. - -## Default Data URI mimetype - -The `src`-values work as expected (respecting mime-types), however: - -The XR Fragment specification advices to bump the traditional default browser-mimetype - -`text/plain;charset=US-ASCII` - -to a hashtag-friendly one: - -`text/plain;charset=utf-8;hashtag` - -This indicates that: - -* utf-8 is supported by default -* words beginning with `#` (hashtags) will prime the XRWG by adding the hashtag to the XRWG, linking to the current sentence/paragraph/alltext (depending on '.') to the XRWG - -Advantages: - -* out-of-the-box (de)multiplex human text and metadata in one go (see [the core principle](#core-principle)) -* no network-overhead for metadata (see [the core principle](#core-principle)) -* ensuring high FPS: realtime HTML/RDF historically is too 'requesty'/'parsy' for game studios -* rich send/receive/copy-paste everywhere by default, metadata being retained (see [the core principle](#core-principle)) -* netto result: less webservices, therefore less servers, and overall better FPS in XR - -> This significantly expands expressiveness and portability of human tagged text, by **postponing machine-concerns to the end of the human text** in contrast to literal interweaving of content and markupsymbols (or extra network requests, webservices e.g.). - -For all other purposes, regular mimetypes can be used (but are not required by the spec).
      - -## URL and Data URI - -``` - +--------------------------------------------------------------+ +------------------------+ - | | | author.com/article.txt | - | index.gltf | +------------------------+ - | │ | | | - | ├── ◻ article_canvas | | Hello #friends | - | │ └ src: ://author.com/article.txt | | | - | │ | +------------------------+ - | └── ◻ note_canvas | - | └ src:`data:welcome human\n@book{sunday...}` | - | | - | | - +--------------------------------------------------------------+ -``` - -The enduser will only see `welcome human` and `Hello friends` rendered verbatim (see mimetype). -The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata). -In both cases, the text gets rendered immediately (onto a plane geometry, hence the name '_canvas'). -The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.). - -> additional tagging using [bibs](https://github.com/coderofsalvation/hashtagbibs): to tag spatial object `note_canvas` with 'todo', the enduser can type or speak `#note_canvas@todo` - -# Importing/exporting - -For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play. - -1. export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values. - -# Reflection Mapping - -Environment mapping is crucial for creating realistic reflections and lighting effects on 3D objects. -To apply environment mapping efficiently in a 3D scene, traverse the scene graph and assign each object's environment map based on the nearest ancestor's texture map. This ensures that objects inherit the correct environment mapping from their closest parent with a texture, enhancing the visual consistency and realism. - -``` - +--------------------------------+ - | | - | index.usdz | - | │ | - | └── ◻ sphere (texture:foo) | - | └ ◻ cube (texture:bar) | envMap = foo - | └ ◻ cylinder | envMap = bar - +--------------------------------+ -``` - -Most 3D viewers apply one and the same environment map for various models, however this logic -allows a more natural & automatic strategy for reflection mapping: - -1. traverse the scene graph depth-first -2. remember the most recent parentnode (P) with a texture material -3. for every non-root node with a texture material -3.1 clone that material (as materials might be shared across objects) -3.2 set the environmentmap to the last known parent texture (P) - -# Transclusion (broken link) resolution - -In spirit of Ted Nelson's 'transclusion resolution', there's a soft-mechanism to harden links & minimize broken links in various ways: - -1. defining a different transport protocol (https vs ipfs or DAT) in `src` or `href` values can make a difference -2. mirroring files on another protocol using (HTTP) errorcode tags in `src` or `href` properties -3. in case of `src`: nesting a copy of the embedded object in the placeholder object (`embeddedObject`) will not be replaced when the request fails - -> due to the popularity, maturity and extensiveness of HTTP codes for client/server communication, non-HTTP protocols easily map to HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.) - -For example: - -``` - +────────────────────────────────────────────────────────+ - │ │ - │ index.gltf │ - │ │ │ - │ │ #: #-offlinetext │ - │ │ │ - │ ├── ◻ buttonA │ - │ │ └ href: http://foo.io/campagne.fbx │ - │ │ └ href@404: ipfs://foo.io/campagne.fbx │ - │ │ └ href@400: #clienterrortext │ - │ │ └ ◻ offlinetext │ - │ │ │ - │ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not) - │ └ src: https://foo.io/bar.gltf │ be flushed when the request (does not) succeed. - │ └ src@404: http://foo.io/bar.gltf │ So worstcase the 3D data (of the time of publishing index.gltf) - │ └ src@400: https://archive.org/l2kj43.gltf │ will be displayed. - │ │ - +────────────────────────────────────────────────────────+ - -``` - -# Topic-based index-less Webrings - -As hashtags in URLs map to the XWRG, `href`-values can be used to promote topic-based index-less webrings.
      -Consider 3D scenes linking to eachother using these `href` values: +Consider 3D scenes linking to eachother using these `href` values, attached to 3D button-objects: * `href: schoolA.edu/projects.gltf#math` * `href: schoolB.edu/projects.gltf#math` * `href: university.edu/projects.gltf#math` -These links would all show visible links to math-tagged objects in the scene.
      -To filter out non-related objects one could take it a step further using filters: +This would teleport users to the math-projects of those universities.
      +Now consider adding a 'webring index'-button to each file, with this href-value: -* `href: schoolA.edu/projects.gltf#math&-topics math` -* `href: schoolB.edu/projects.gltf#math&-courses math` -* `href: university.edu/projects.gltf#math&-theme math` -> This would hide all object tagged with `topic`, `courses` or `theme` (including math) so that later only objects tagged with `math` will be visible +* href: workgroup.edu/webrings.glb#!webringmenu -This makes spatial content multi-purpose, without the need to separate content into separate files, or show/hide things using a complex logiclayer like javascript. +This would allow displaying the (remote 3D file) webring menu with various href-buttons inside, all centrally curated by the workgroup. -# URI Templates (RFC6570) +# Level5: URI Templates (RFC6570) XR Fragments adopts Level1 URI **Fragment** expansion to provide safe interactivity.
      -The following demonstrates a simple video player: - -``` - - +─────────────────────────────────────────────+ - │ │ - │ foo.usdz │ - │ │ │ - │ │ │ - │ ├── ◻ stopbutton │ - │ │ ├ #: #-stopbutton │ - │ │ └ href: #player=stop&-stopbutton │ (stop and hide stop-button) - │ │ │ - │ └── ◻ plane │ - │ ├ play: #t=l:0,10 │ - │ ├ stop: #t=0,0 │ - │ ├ href: #player=play&stopbutton │ (play and show stop-button) - │ └ src: cat.mp4#{player} │ - │ │ - │ │ - +─────────────────────────────────────────────+ - - -``` +This is non-normative, and the draft spec is available on request. # Additional scene metadata @@ -976,8 +690,11 @@ Instead, it encourages browsers to scan nodes for the following custom propertie * [SPDX](https://spdx.dev/) license information * [ARIA](https://www.w3.org/WAI/standards-guidelines/aria/) attributes (`aria-*: .....`) +* [datapackage.json](https://datapackage.org) findability, accessibility, interoperability, and reusability of data -> SPDX and ARIA's `aria-description` are normative, as they promote accessibility and scene transcripts: please start `aria-description` with a verb to aid transcripts. +ARIA's `aria-description`-metadata is normative, to aid accessibility and scene transcripts + +> **NOTE**: please always start `aria-description` with a verb to aid transcripts. The following metadata are non-normative but encouraged, since they are popular and cheap to parse: diff --git a/doc/RFC_XR_Fragments.txt b/doc/RFC_XR_Fragments.txt index f200296..638cb7b 100644 --- a/doc/RFC_XR_Fragments.txt +++ b/doc/RFC_XR_Fragments.txt @@ -3,7 +3,7 @@ Jens & Leon Internet Engineering Task Force L.R. van Kammen -Internet-Draft 1 September 2025 +Internet-Draft 19 September 2025 Intended status: Informational @@ -18,20 +18,22 @@ Abstract files, enabling hypermediatic (https://github.com/coderofsalvation/ hypermediatic) navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection. - The specification uses W3C Media Fragments (https://www.w3.org/TR/ - media-frags/) and URI Templates (RFC6570) (https://www.rfc- - editor.org/rfc/rfc6570) to promote spatial addressibility, sharing, - navigation, filtering and databinding objects for (XR) Browsers. XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like URI Fragments (https://en.wikipedia.org/wiki/URI_fragment). - XR Fragments views XR experiences thru the lens of 3D object URI's, - rather than thru code(frameworks) or protocol-specific browsers - (webbrowser e.g.). + XR Fragments views XR experiences thru the lens of 3D deeplinked + URI's, rather than thru code(frameworks) or protocol-specific + browsers (webbrowser e.g.). The standard comprises of various + (optional) support levels, which also include W3C Media Fragments + (https://www.w3.org/TR/media-frags/) and URI Templates (RFC6570) + (https://www.rfc-editor.org/rfc/rfc6570) to promote spatial + addressibility, sharing, navigation, filtering and databinding + objects for (XR) Browsers. - XR Fragments is a heuristical 3D format which leverages - heuristic rules derived from any 3D scene or well-established 3D file - formats, to extract meaningful features from scene hierarchies. + XR Fragments is in a sense, a heuristical 3D format or meta- + format, which leverages heuristic rules derived from any 3D scene or + well-established 3D file formats, to extract meaningful features from + scene hierarchies. These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing higher interop between fileformats, 3D editors, viewers and game- @@ -45,25 +47,28 @@ Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. + + + + + + +van Kammen Expires 23 March 2026 [Page 1] + +Internet-Draft XR Fragments September 2025 + + 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/. - - - -van Kammen Expires 5 March 2026 [Page 1] - -Internet-Draft XR Fragments September 2025 - - 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 5 March 2026. + This Internet-Draft will expire on 23 March 2026. Copyright Notice @@ -82,61 +87,57 @@ Copyright Notice Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 - 2. Core principle . . . . . . . . . . . . . . . . . . . . . . . 4 - 3. The XR Fragments Trinity . . . . . . . . . . . . . . . . . . 5 - 4. List of URI Fragments . . . . . . . . . . . . . . . . . . . . 6 - 5. List of *_explicit_ metadata . . . . . . . . . . . . . . . . 6 - 6. HFL (Hypermediatic Feedback Loop) for XR Browsers . . . . . . 6 - 7. Conventions and Definitions . . . . . . . . . . . . . . . . . 9 - 7.1. XR Fragment URL Grammar . . . . . . . . . . . . . . . . . 9 - 8. Spatial Referencing 3D . . . . . . . . . . . . . . . . . . . 9 - 9. non-normative . . . . . . . . . . . . . . . . . . . . . . . . 10 - 10. additional *explicit* metadata . . . . . . . . . . . . . . . 10 - 10.1. Sidecar-file . . . . . . . . . . . . . . . . . . . . . . 11 - 10.2. Level2: Implicit URI Fragments . . . . . . . . . . . . . 11 - 10.3. media fragments and datatypes . . . . . . . . . . . . . 13 - 11. Navigating 3D . . . . . . . . . . . . . . . . . . . . . . . . 16 - 12. Top-level URL processing . . . . . . . . . . . . . . . . . . 18 - 13. Embedding XR content using src . . . . . . . . . . . . . . . 18 - 14. Navigating content href portals . . . . . . . . . . . . . . . 21 - 14.1. Walking surfaces . . . . . . . . . . . . . . . . . . . . 22 - 14.2. UX spec . . . . . . . . . . . . . . . . . . . . . . . . 22 - 14.3. Scaling instanced content . . . . . . . . . . . . . . . 23 - 15. XR Fragment: pos . . . . . . . . . . . . . . . . . . . . . . 23 - 16. XR Fragment: rot . . . . . . . . . . . . . . . . . . . . . . 23 - 17. XR Fragment: t . . . . . . . . . . . . . . . . . . . . . . . 24 - 18. XR audio/video integration . . . . . . . . . . . . . . . . . 24 + 2. What is XR Fragments . . . . . . . . . . . . . . . . . . . . 4 + 3. HFL (Hypermediatic Feedback Loop) for XR Browsers . . . . . . 4 + 4. Conventions and Definitions . . . . . . . . . . . . . . . . . 6 + 4.1. XR Fragment URL Grammar . . . . . . . . . . . . . . . . . 6 + 5. Spatial Referencing 3D . . . . . . . . . . . . . . . . . . . 6 + 6. Level0: Files . . . . . . . . . . . . . . . . . . . . . . . . 7 + 6.1. via href metadata . . . . . . . . . . . . . . . . . . . . 7 + 6.2. via chained extension . . . . . . . . . . . . . . . . . . 8 + 6.3. via subdocuments/xattr . . . . . . . . . . . . . . . . . 8 + 6.4. JSON sidecar-file . . . . . . . . . . . . . . . . . . . . 9 + 7. Level1: URI . . . . . . . . . . . . . . . . . . . . . . . . . 9 + 8. List of URI Fragments . . . . . . . . . . . . . . . . . . . . 11 + 9. List of *_explicit_ metadata . . . . . . . . . . . . . . . . 12 + 10. Level2: href links . . . . . . . . . . . . . . . . . . . . . 12 + 10.1. Interaction behaviour . . . . . . . . . . . . . . . . . 12 + 10.2. XR Viewer implementation . . . . . . . . . . . . . . . . 12 + 11. Level3: Media Fragments . . . . . . . . . . . . . . . . . . . 13 + 11.1. Animation(s) timeline . . . . . . . . . . . . . . . . . 13 + 11.2. Specify playback loopmode . . . . . . . . . . . . . . . 13 -van Kammen Expires 5 March 2026 [Page 2] +van Kammen Expires 23 March 2026 [Page 2] Internet-Draft XR Fragments September 2025 - 19. XR Fragment filters . . . . . . . . . . . . . . . . . . . . . 24 - 19.1. including/excluding . . . . . . . . . . . . . . . . . . 25 - 19.2. Filter Parser . . . . . . . . . . . . . . . . . . . . . 26 - 20. Visible links . . . . . . . . . . . . . . . . . . . . . . . . 26 - 21. Text in XR (tagging,linking to spatial objects) . . . . . . . 27 - 21.1. Default Data URI mimetype . . . . . . . . . . . . . . . 29 - 21.2. URL and Data URI . . . . . . . . . . . . . . . . . . . . 30 - 22. Importing/exporting . . . . . . . . . . . . . . . . . . . . . 31 - 23. Reflection Mapping . . . . . . . . . . . . . . . . . . . . . 31 - 24. Transclusion (broken link) resolution . . . . . . . . . . . . 31 - 25. Topic-based index-less Webrings . . . . . . . . . . . . . . . 32 - 26. URI Templates (RFC6570) . . . . . . . . . . . . . . . . . . . 33 - 27. Additional scene metadata . . . . . . . . . . . . . . . . . . 33 - 28. Accessibility interface . . . . . . . . . . . . . . . . . . . 35 - 28.1. Two-button navigation . . . . . . . . . . . . . . . . . 36 - 28.2. Overlap with fileformat-specific extensions . . . . . . 36 - 28.3. Vendor Prefixes . . . . . . . . . . . . . . . . . . . . 37 - 29. Security Considerations . . . . . . . . . . . . . . . . . . . 39 - 30. FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 - 31. authors . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 - 32. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40 - 33. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 40 - 34. Appendix: Definitions . . . . . . . . . . . . . . . . . . . . 40 + 11.3. Controlling embedded content . . . . . . . . . . . . . . 14 + 12. Level4: prefix operators . . . . . . . . . . . . . . . . . . 14 + 12.1. Object teleports (!) . . . . . . . . . . . . . . . . . . 14 + 12.2. Object multipliers (*) . . . . . . . . . . . . . . . . . 16 + 12.3. De/selectors (+ and -) . . . . . . . . . . . . . . . . . 16 + 12.4. Sharing object or file (#|) . . . . . . . . . . . . . . 16 + 12.5. xrf:// URI scheme . . . . . . . . . . . . . . . . . . . 17 + 13. Top-level URL processing . . . . . . . . . . . . . . . . . . 17 + 13.1. UX . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 + 14. Example: Navigating content href portals . . . . . . . . . . 18 + 14.1. Walking surfaces . . . . . . . . . . . . . . . . . . . . 19 + 15. Virtual world rings . . . . . . . . . . . . . . . . . . . . . 19 + 16. Level5: URI Templates (RFC6570) . . . . . . . . . . . . . . . 20 + 17. Additional scene metadata . . . . . . . . . . . . . . . . . . 20 + 18. Accessibility interface . . . . . . . . . . . . . . . . . . . 21 + 18.1. Two-button navigation . . . . . . . . . . . . . . . . . 22 + 18.2. Overlap with fileformat-specific extensions . . . . . . 22 + 18.3. Vendor Prefixes . . . . . . . . . . . . . . . . . . . . 23 + 19. Security Considerations . . . . . . . . . . . . . . . . . . . 26 + 20. FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 + 21. authors . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 + 22. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 27 + 23. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 27 + 24. Appendix: Definitions . . . . . . . . . . . . . . . . . . . . 27 1. Introduction @@ -149,8 +150,8 @@ Internet-Draft XR Fragments September 2025 XR Fragments exploits the fact that all 3D models already contain such metadata: - *XR Fragments allows controlling of metadata in 3D scene(files) using - URI's* + *XR Fragments allows deeplinking of 3D objects by mapping objectnames + to URI fragments* It solves: @@ -160,16 +161,17 @@ Internet-Draft XR Fragments September 2025 URI_fragment) using src/href spatial metadata 2. Interlinking text & spatial objects by collapsing space into a Word Graph (XRWG) to show visible links (#visible-links) - 3. unlocking spatial potential of the (originally 2D) hashtag (which - jumps to a chapter) for navigating XR documents -van Kammen Expires 5 March 2026 [Page 3] + +van Kammen Expires 23 March 2026 [Page 3] Internet-Draft XR Fragments September 2025 + 3. unlocking spatial potential of the (originally 2D) hashtag (which + jumps to a chapter) for navigating XR documents 4. refraining from introducing scripting-engines for mundane tasks (and preventing its inevitable security-headaches) 5. the gap between text an 3d objects: object-names directly map to @@ -178,168 +180,30 @@ Internet-Draft XR Fragments September 2025 | NOTE: The chapters in this document are ordered from highlevel to | lowlevel (technical) as much as possible -2. Core principle - - *XR Fragments allows controlling 3D models using URLs, based on - (non)existing metadata via URI's* - - XR Fragments tries to seek to connect the world of text (semantical - web / RDF), and the world of pixels. - Instead of forcing authors to combine 3D/2D objects programmatically - (publishing thru a game-editor e.g.), XR Fragments *integrates all* - which allows a universal viewing experience. - - +───────────────────────────────────────────────────────────────────────────────────────────────+ - │ │ - │ U R N │ - │ U R L | │ - │ | |-----------------+--------| │ - │ +--------------------------------------------------| │ - │ | │ - │ + https://foo.com/some/foo/scene.glb#someview <-- http URI (=URL and has URN) │ - │ | │ - │ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN) │ - │ │ - │ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │ - │ │ - │ │ - │ |------------------------+-------------------------| │ - │ | │ - │ U R I │ - │ │ - +───────────────────────────────────────────────────────────────────────────────────────────────+ - - Fact: our typical browser URL's are just *a possible implementation* - of URI's (for untapped humancentric potential of URI's see - interpeer.io (https://interpeer.io)) - - | XR Fragments does not look at XR (or the web) thru the lens of - | HTML or URLs. - | But approaches things from a higherlevel feedbackloop/hypermedia - | browser-perspective. - - - - -van Kammen Expires 5 March 2026 [Page 4] - -Internet-Draft XR Fragments September 2025 - - - Below you can see how this translates back into good-old URLs: - - +───────────────────────────────────────────────────────────────────────────────────────────────+ - │ │ - │ the soul of any URL: ://macro /meso ?micro #nano │ - │ │ - │ 2D URL: ://library.com /document ?search #chapter │ - │ xrf:// │ - │ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #view ───> hashbus │ - │ │ #filter │ │ - │ │ #tag │ │ - │ │ (hypermediatic) #material │ │ - │ │ ( feedback ) #animation │ │ - │ │ ( loop ) #texture │ │ - │ │ #variable │ │ - │ │ │ │ - │ XRWG <─────────────────────<─────────────+ │ - │ │ │ │ - │ └─ objects ──────────────>─────────────+ │ - │ │ - │ │ - +───────────────────────────────────────────────────────────────────────────────────────────────+ - - | ?-linked and #-linked navigation are JUST one possible way to - | implement XR Fragments: the essential goal is to allow a - | Hypermediatic FeedbackLoop (HFL) between external and internal 4D - | navigation. - - Traditional webbrowsers can become 4D document-ready by: - -3. The XR Fragments Trinity +2. What is XR Fragments XR Fragments utilizes URLs: 1. for 3D viewers/browser to manipulate the camera or objects (via - URLbar) - 2. as *implicit* metadata to reference (nested) objects *inside* 3D - scene-file (local and remote) - 3. via *explicit* metadata ('extras') *inside* 3D scene-files - (interaction e.g.) or - 4. [optionally for developers] via *explicit* metadata *outside* 3D - scene-files (via sidecarfile (https://en.wikipedia.org/wiki/ - Sidecar_file)) + URI fragments) + 2. implicitly: by mapping 3D objectnames (of a 3D scene/file) to URI + fragments (3D deeplinking) + 3. explicitly: by scanning href metadata *inside* 3D scene-files to + enable interactions + 4. externally: progressively enhance a 3D (file) into an experience + via sidecarfiles (https://en.wikipedia.org/wiki/Sidecar_file) - - - - - - - -van Kammen Expires 5 March 2026 [Page 5] - -Internet-Draft XR Fragments September 2025 - - -4. List of URI Fragments - - +=======================+======================================+===========+=============+ - |fragment |type |example |info | - +=======================+======================================+===========+=============+ - |#...... |vector3 |#room1 |positions/ | - | | |#room2 |parents | - | | |#cam2 |camera(rig) | - | | | |(or XR floor)| - | | | |to xyz- | - | | | |coord/object/| - | | | |camera and | - | | | |upvector | - +-----------------------+--------------------------------------+-----------+-------------+ - |Media Fragments |media fragment |#t=0,2&loop|play (and | - |(https://www.w3.org/TR/|(#media%20fragments%20and%20datatypes)| |loop) 3D | - |media-frags/) | | |animation | - | | | |from 0 | - | | | |seconds till | - | | | |2 seconds | - +-----------------------+--------------------------------------+-----------+-------------+ - - Table 1 - -5. List of *_explicit_ metadata - - These are the possible 'extras' for 3D nodes and sidecar-files - - +======+========+================+==========+===================+ - | key | type | example (JSON) | function | existing | - | | | | | compatibility | - +======+========+================+==========+===================+ - | href | string | "href": | XR | custom property | - | | | "b.gltf" | teleport | in 3D fileformats | - +------+--------+----------------+----------+-------------------+ - - Table 2 - -6. HFL (Hypermediatic Feedback Loop) for XR Browsers +3. HFL (Hypermediatic Feedback Loop) for XR Browsers href metadata traditionally implies *click* AND *navigate*, however - XR Fragments adds stateless *click* (xrf://#....) or *navigate* - (xrf://#...) as well (which allows many extra interactions which - otherwise need a scripting language). This is known as *hashbus*- - only events (see image above). - - - - - - -van Kammen Expires 5 March 2026 [Page 6] - -Internet-Draft XR Fragments September 2025 - + XR Fragments adds stateless *click* (xrf://....) via the xrf:// + scheme, which does not change the top-level URL-adress (of the + browser). This allows for many extra interactions via URLs, which + otherwise needs a scripting language. These are called *hashbus*- + only events/ | Being able to use the same URI Fragment DSL for navigation (href: - | #foo) as well as interactions (href: xrf://#bar) greatly + | #foo) as well as interactions (href: xrf://#foo) greatly | simplifies implementation, increases HFL, and reduces need for | scripting languages. @@ -349,11 +213,19 @@ Internet-Draft XR Fragments September 2025 * hypermediatic (https://github.com/coderofsalvation/hypermediatic) loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML). - * allowing 3D assets/nodes to publish XR Fragments to themselves/ - eachother using the xrf:// hashbus (xrf://#person=walk to trigger - walk-animation for object person) - * collapsing the 3D scene to an wordgraph (for essential navigation - purposes) controllable thru a hash(tag)bus + * potentially allowing 3D assets/nodes to publish XR Fragments to + themselves/eachother using the xrf:// hashbus (xrf://#person=walk + to trigger walk-animation for object person) + * potentially collapsing the 3D scene to an wordgraph (for essential + navigation purposes) controllable thru a hash(tag)bus + + + +van Kammen Expires 23 March 2026 [Page 4] + +Internet-Draft XR Fragments September 2025 + + * completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources) @@ -362,40 +234,8 @@ Internet-Draft XR Fragments September 2025 agnostic, though pseudo-XR Fragment browsers *can* be implemented on top of HTML/Javascript. - - - - - - - - - - - - - - - - - - - - - - - - - - - -van Kammen Expires 5 March 2026 [Page 7] - -Internet-Draft XR Fragments September 2025 - - +=========+======================+=====================================+ - |principle|XR 4D URL |HTML 2D URL | + |principle|3D URL |HTML 2D URL | +=========+======================+=====================================+ |the XRWG |wordgraph (collapses |Ctrl-F (find) | | |3D scene to tags) | | @@ -431,7 +271,16 @@ Internet-Draft XR Fragments September 2025 | |topLevel URI) |hypermediatic) | +---------+----------------------+-------------------------------------+ - Table 3 + Table 1 + + + + + +van Kammen Expires 23 March 2026 [Page 5] + +Internet-Draft XR Fragments September 2025 + | An important aspect of HFL is that URI Fragments can be triggered | without updating the top-level URI (default href-behaviour) thru @@ -439,22 +288,11 @@ Internet-Draft XR Fragments September 2025 | navigation and interaction prevents non-standard things like | (href:javascript:dosomething()). - - - - - - -van Kammen Expires 5 March 2026 [Page 8] - -Internet-Draft XR Fragments September 2025 - - -7. Conventions and Definitions +4. Conventions and Definitions See appendix below in case certain terms are not clear. -7.1. XR Fragment URL Grammar +4.1. XR Fragment URL Grammar For typical HTTP-like browsers/applications: @@ -464,15 +302,15 @@ Internet-Draft XR Fragments September 2025 | Example: ://foo.com/my3d.gltf#room1&prio=-5&t=0,100 - +=======================+=================================+ - | Demo | Explanation | - +=======================+=================================+ - | room1 | vector/coordinate argument e.g. | - +-----------------------+---------------------------------+ - | room1&rot=0,90,0&cam1 | combinators | - +-----------------------+---------------------------------+ + +============+=================================+ + | Demo | Explanation | + +============+=================================+ + | room1 | vector/coordinate argument e.g. | + +------------+---------------------------------+ + | room1&cam1 | combinators | + +------------+---------------------------------+ - Table 4 + Table 2 | this is already implemented in all browsers @@ -486,22 +324,16 @@ Internet-Draft XR Fragments September 2025 https://me.com can load the latter (and still indicates which XR Fragments entrypoint-experience/client was used). -8. Spatial Referencing 3D +5. Spatial Referencing 3D - XR Fragments assume the following objectname-to-URIFragment mapping: + 3D files contain an hierarchy of objects. + XR Fragments assumes the following objectname-to-URI-Fragment + mapping, in order to deeplink 3D objects: - - - - - - - - -van Kammen Expires 5 March 2026 [Page 9] +van Kammen Expires 23 March 2026 [Page 6] Internet-Draft XR Fragments September 2025 @@ -530,7 +362,6 @@ Internet-Draft XR Fragments September 2025 create an 3D object with: * href: https://scene.fbx - * src: https://otherworld.gltf#mainobject | It also allows *sourceportation*, which basically means the | enduser can teleport to the original XR Document of an src @@ -538,59 +369,108 @@ Internet-Draft XR Fragments September 2025 | embedded object. Basically an embedded link becoming an outbound | link by activating it. -9. non-normative +6. Level0: Files - The following below is non-normative heuristics which are not part - officially part of the spec. + These 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.). -10. additional *explicit* metadata +6.1. via href metadata - | #rot | vector3 | #rot=0,90,0 | rotates camera to xyz-coord - 0.5,0,0 | | src | string | "src": "#cube" | XR embed / teleport | - custom property in 3D fileformats | | tag | string | "tag": "cubes - geo" | tag object (for filter-use / XRWG highlighting) | custom - property in 3D fileformats | | # | string | "#": "#mypreset | trigger - default fragment on load | custom property in 3D fileformats | + scene.glb <--- 'href' extra [heuristic] detected inside! + scene.png (preview thumbnail) + scene.ogg (soundtrack to plays when global 3D animation starts) + scene.vtt (subtitles for accessibility or screenreaders) + scene.json (sidecar JSON-file with explicit metadata) - | Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, - | .usdz, .json (THREE.js), .dae and so on. + *heuristics*: -van Kammen Expires 5 March 2026 [Page 10] + +van Kammen Expires 23 March 2026 [Page 7] Internet-Draft XR Fragments September 2025 -10.1. Sidecar-file + * if at least one href custom property/extra is found in a 3D scene + * The viewer should poll for the above mentioned sidecar-file + extensions (and present accordingly) - | NOTE: sidecar-files break the portability of XR (Fragments) - | experiences, therefore side-car files are discouraged for consumer - | usage/sharing. However, they can accomodate developers or - | applications who (for whatever reason) must not modify the 3D - | scene-file (a .glb e.g.). +6.2. via chained extension + + scene.xrf.glb <--- '.xrf.' sidecar file heuristic detected! + scene.xrf.png (preview thumbnail) + scene.xrf.ogg (soundtrack to plays when global 3D animation starts) + scene.xrf.vtt (subtitles for accessibility or screenreaders) + scene.xrf.json (sidecar JSON-file with explicit metadata) + + | A fallback-mechanism to turn 3D files into XR Movies + | (#XR%20Movies) without editing them. + + *heuristics*: + + * the chained-extension heuristic .xrf. should be present in the + filename (scene.xrf.glb e.g.) + +6.3. via subdocuments/xattr + + More secure protocols (Nextgraph e.g.) don't allow for simply polling + files. In such case, subdocuments or extended attributes should be + polled: + + | NOTE: in the examples below we use the href-heuristic, but also + | the .xrf. chained-extension applies here. + +myspreadsheet.ods +└── explainer.glb <--- 'href' extra [heuristic] detected inside! + ├── explainer.ogg (soundtrack to play when global 3D animation starts) + ├── explainer.png (preview thumnbnail) + ├── explainer.json (sidecar JSON-file with explicit metadata) + └── explainer.vtt (subtitles for accessibility or screenreaders) + + If only extended attributes (xattr) are available, the respective + referenced file can be embedded: + + $ setfattr -n explainer.ogg -v "soundtrack.ogg" explainer.glb + $ setfattr -n explainer.png -v "thumbnail.png" explainer.glb + $ setfattr -n explainer.vtt -v "subtitles.vtt" explainer.glb + + | NOTE: Linux's setfattr/getfattr is xattr on mac, and Set-Content/ + | Get-content on Windows. See pxattr + | (https://www.lesbonscomptes.com/pxattr/index.html) for lowlevel + | access. + + + + +van Kammen Expires 23 March 2026 [Page 8] + +Internet-Draft XR Fragments September 2025 + + +6.4. JSON sidecar-file For developers, sidecar-file can allow for defining *explicit* XR - Fragments metadata, outside of the 3D file. - This can be done via a JSON-pointers RFC6901 (https://www.rfc- - editor.org/rfc/rfc6901) in a JSON sidecar-file - (https://en.wikipedia.org/wiki/Sidecar_file): + Fragments links (>level1), outside of the 3D file. + This can be done via (objectname/metadata) key/value-pairs in a JSON + sidecar-file (https://en.wikipedia.org/wiki/Sidecar_file): * experience.glb - * experience.json + * experience.json <---- { - "/":{ - "#": "#-penguin", + "/": "aria-description": "description of scene", }, - "/room/chair": { - "href": "#penguin" + "button": { + "href": "#roomB" } } - | This would mean: hide object(s) with name or tag-value 'penguin' - | upon scene-load, and show it when the user clicks the chair + | This will make object button clickable, and teleport the user to + | object roomB. So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata. @@ -600,541 +480,485 @@ Internet-Draft XR Fragments September 2025 | In THREE.js-code this would boil down to: - scene.userData['#'] = "#chair&penguin" scene.userData['aria-description'] = "description of scene" - scene.getObjectByName("room").getObjectByName("chair").userData.href = "#penguin" + scene.getObjectByName("button").userData.href = "#roomB" // now the XR Fragments parser can process the XR Fragments userData 'extras' in the scene -10.2. Level2: Implicit URI Fragments +7. Level1: URI - | Warning: non-normative + | *XR Fragments allows deeplinking of 3D objects by mapping + | objectnames to URI fragments* + + XR Fragments tries to seek to connect the world of text (semantical + web / RDF), and the world of pixels. + Instead of forcing authors to combine 3D/2D objects programmatically + (publishing thru a game-editor e.g.), XR Fragments *integrates all* + which allows a universal viewing experience. -van Kammen Expires 5 March 2026 [Page 11] + + +van Kammen Expires 23 March 2026 [Page 9] Internet-Draft XR Fragments September 2025 - These fragments are derived from objectnames (or their extras) within - a 3D scene, and trigger certain actions when evaluated by the - browser: + +───────────────────────────────────────────────────────────────────────────────────────────────+ + │ │ + │ U R N │ + │ U R L | │ + │ | |-----------------+--------| │ + │ +--------------------------------------------------| │ + │ | │ + │ + https://foo.com/some/foo/scene.glb#someview <-- http URI (=URL and has URN) │ + │ | │ + │ + ipfs://cfe0987ec9r9098ecr/cats.fbx#someview <-- an IPFS URI (=URL and has URN) │ + │ │ + │ ec09f7e9cf8e7f09c8e7f98e79c09ef89e000efece8f7ecfe9fe <-- an interpeer URI │ + │ │ + │ │ + │ |------------------------+-------------------------| │ + │ | │ + │ U R I │ + │ │ + +───────────────────────────────────────────────────────────────────────────────────────────────+ - +================+======================================+=============+=====================+=======================+ - | |fragment |type |example |info | - +================+======================================+=============+=====================+=======================+ - |*PRESET* |# |string |#cubes |evaluates preset | - | | | | |(#foo&bar) when a scene| - | | | | |contains extra (#cubes:| - | | | | |#foo&bar e.g.) while | - | | | | |URL-browserbar reflects| - | | | | |#cubes. Only works | - | | | | |when metadata-key | - | | | | |starts with # | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - |*FOCUS* |xrf://# |string |#person |(and show) object(s) | - | | | | |with tag: person or | - | | | | |name person (XRWG | - | | | | |lookup) | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - |*FILTERS* |#[!][-][*] |string |#person (#-person) |will reset (!), show/ | - | | | | |focus or hide (-) focus| - | | | | |object(s) with tag: | - | | | | |person or name person | - | | | | |by looking up XRWG | - | | | | |(*=including children) | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - |*MATERIALUPDATE*|#[*]=|string=string|#car=metallic |sets material of car to| - | | | | |material with name | - | | | | |metallic (*=including | - | | | | |children) | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - | | | |#soldout*=halfopacity|set material of objects| - | | | | |tagged with product to | - | | | | |material with name | - | | | | |metallic | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - |*VARIABLE |#= |string=string|#foo=bar |sets URI Template | - |UPDATE* | | | |(https://www.rfc- | - | | | | |editor.org/rfc/rfc6570)| - | | | | |variable foo to the | - | | | | |value #t=0 from | - | | | | |*existing* object | - | | | | |metadata (bar:#t=0 | - | | | | |e.g.), This allows for | - | | | | |reactive URI Template | - | | | | |(https://www.rfc- | + Fact: our typical browser URL's are just *a possible implementation* + of URI's (for untapped humancentric potential of URI's see + interpeer.io (https://interpeer.io) or NextGraph + (https://nextgraph.org) ) + + | XR Fragments does not look at XR (or the web) thru the lens of + | HTML or URLs. + | But approaches things from a higherlevel local-first 3D hypermedia + | browser-perspective. + + Below you can see how this translates back into good-old URLs: -van Kammen Expires 5 March 2026 [Page 12] + + + + + + + + + + + + + + + + + +van Kammen Expires 23 March 2026 [Page 10] Internet-Draft XR Fragments September 2025 - | | | | |editor.org/rfc/rfc6570)| - | | | | |defined in object | - | | | | |metadata elsewhere | - | | | | |(src:://m.com/ | - | | | | |cat.mp4#{foo} e.g., to | - | | | | |play media using media | - | | | | |fragment URI | - | | | | |(https://www.w3.org/TR/| - | | | | |media-frags/#valid- | - | | | | |uri)). NOTE: metadata-| - | | | | |key should not start | - | | | | |with # | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ - |*ANIMATION* |#= |string=string|#people=walk |assign a different | - | | | |#people=noanim |animation to object(s) | - +----------------+--------------------------------------+-------------+---------------------+-----------------------+ + +───────────────────────────────────────────────────────────────────────────────────────────────+ + │ │ + │ the soul of any URL: ://macro /meso ?micro #nano │ + │ │ + │ 2D URL: ://library.com /document ?search #chapter │ + │ xrf:// │ + │ 4D URL: ://park.com /4Dscene.fbx ─> ?other.glb ─> #object ─> hashbus │ + │ │ #filter │ │ + │ │ #tag │ │ + │ │ (hypermediatic) #material │ │ + │ │ ( feedback ) #animation │ │ + │ │ ( loop ) #texture │ │ + │ │ #variable │ │ + │ │ │ │ + │ XRWG <─────────────────────<─────────────+ │ + │ │ │ │ + │ └─ objects ──────────────>─────────────+ │ + │ │ + │ │ + +───────────────────────────────────────────────────────────────────────────────────────────────+ - Table 5 + | ?-linked and #-linked navigation are JUST one possible way to + | implement XR Fragments: the essential goal is to allow a + | Hypermediatic FeedbackLoop (HFL) between external and internal 4D + | navigation. -10.3. media fragments and datatypes +8. List of URI Fragments - | Warning: *non-normative* (below the word 'play' applies to 3D - | animations embedded in the 3D scene(file) *but also* media defined - | in src-metadata like audio/video-files (mp3/mp4 e.g.)) - - +===========+======================+===============+================+ - | type | syntax | example | info | - +===========+======================+===============+================+ - | vector2 | x,y | 2,3.0 | 2-dimensional | - | | | | vector | - +-----------+----------------------+---------------+----------------+ - | vector3 | x,y,z | 2,3.0,4 | 3-dimensional | - | | | | vector | - +-----------+----------------------+---------------+----------------+ - | temporal | t=x | 0 | play from 0 | - | W3C media | | | seconds to | - | fragment | | | end (and | - | | | | stop) | - +-----------+----------------------+---------------+----------------+ - | temporal | t=x,y | 0,2 | play from 0 | - | W3C media | | | seconds till | - | fragment | | | 2 seconds | - | | | | (and stop) | - +-----------+----------------------+---------------+----------------+ - | temporal | s=x | 1 | set playback | - | W3C media | | | speed of | - | fragment | | | audio/ | - | * | | | video/3D anim | + +=======================+======================================+===========+=============+ + |fragment |type |example |info | + +=======================+======================================+===========+=============+ + |#...... |vector3 |#room1 |positions/ | + | | |#room2 |parents | + | | |#cam2 |camera(rig) | + | | | |(or XR floor)| + | | | |to xyz- | + | | | |coord/object/| + | | | |camera and | + | | | |upvector | + +-----------------------+--------------------------------------+-----------+-------------+ + |Media Fragments |media fragment |#t=0,2&loop|play (and | + |(https://www.w3.org/TR/|(#media%20fragments%20and%20datatypes)| |loop) 3D | + |media-frags/) | | |animation | + | | | |from 0 | + | | | |seconds till | + | | | |2 seconds | + +-----------------------+--------------------------------------+-----------+-------------+ -van Kammen Expires 5 March 2026 [Page 13] + +van Kammen Expires 23 March 2026 [Page 11] Internet-Draft XR Fragments September 2025 - +-----------+----------------------+---------------+----------------+ - | temporal | [-]loop | loop | enable looped | - | W3C media | | | playback of | - | fragment | | | audio/ | - | * | | | video/3D anim | - +-----------+----------------------+---------------+----------------+ - | | | -loop | disable | - | | | | looped | - | | | | playback | - | | | | (does not | - | | | | affect | - | | | | playbackstate | - | | | | of media) | - +-----------+----------------------+---------------+----------------+ - | vector2 | uv=u,v,uspeed,vspeed | 0,0 | set uv offset | - | | | | instantly | - | | | | (default | - | | | | speed = 1,1) | - +-----------+----------------------+---------------+----------------+ - | | | +0.5,+0.5 | scroll | - | | | | instantly by | - | | | | adding 0.5 to | - | | | | the current | - | | | | uv | - | | | | coordinates | - +-----------+----------------------+---------------+----------------+ - | | | 0.2,1,0.1,0.1 | scroll (lerp) | - | | | | to uv | - | | | | coordinate | - | | | | 0,2,1 with | - | | | | 0.1 units per | - | | | | second | - +-----------+----------------------+---------------+----------------+ - | | | 0,0,0,+0.1 | scroll v | - | | | | coordinates | - | | | | with 0.1 | - | | | | units per | - | | | | second | - | | | | (infinitely) | - +-----------+----------------------+---------------+----------------+ - | | | +0.5,+0.5 | scroll | - | | | | instantly by | - | | | | adding 0.5 to | - | | | | the current | - | | | | uv | - | | | | coordinates | - +-----------+----------------------+---------------+----------------+ - | media | u:=hashbus for more info. - | * = this is extending the W3C media fragments - | (https://www.w3.org/TR/media-frags/#mf-advanced) with (missing) - | playback/viewport-control. Normally #t=0,2 implies setting start/ - | stop-values AND starting playback, whereas #s=0&loop allows - | pausing a video, speeding up/slowing down media, as well as - | enabling/disabling looping. - | - | The rationale for uv is that the xywh Media Fragment deals with - | rectangular media, which does not translate well to 3D models - | (which use triangular polygons, not rectangular) positioned by uv- - | coordinates. This also explains the absense of a scale or rotate - | primitive, which is challenged by this, as well as multiple - | origins (mesh- or texture). +11. Level3: Media Fragments - Example URI's: + | these allow for XR Movies with a controllable timeline using href + | URI's with Media Fragments - * https://images.org/credits.jpg#uv=0,0,0,+0.1 (infinite vertical - texturescrolling) - * https://video.org/organogram.mp4#t=0&loop&uv=0.1,0.1,0.3,0.3 - (animated tween towards region in looped video) - * https://shaders.org/plasma.glsl#t=0&u:col2=0,1,0 (red-green shader - plasma starts playing from time-offset 0) + Just like with 2D media-files, W3C mediafragments (#t=1,2) can be + used to control a timeline via the #t (##t) primitive. XR Fragments + Level3 makes the 3D timeline, as well as URL-referenced files + *controllable* via Media Fragments like: + + * level2 hrefs (href: #t=4 e.g. to control 3D timeline) + * level4: xrf: URI scheme: + - href: xrf:foo.wav#t=0 to play a wav + - href: xrf:news.glb?clone#t=0 to instance and play another + experience + +11.1. Animation(s) timeline + + controls the animation(s) of the scene (or src resource which + contains a timeline) + + | fragment | type | functionality | | #t=start,stop | + [vector2] (default:`#t=0,0`) | start,stop (in seconds | + + | Example Value | Explanation | | #t=1 | play (3D) animations from 1 + seconds till end (and stop) | | #t=1,100 | play (3D) animations from + 1 till 100 seconds (and stop) | | #t=0,0 | stop (3D) animations at + frame 0 | + + | Use [[#s 🌱]] to control playback speed + +11.2. Specify playback loopmode + + This compensates a missing element from Media Fragments to enable/ + disable temporal looping. . - - - - - - - - - - - - - - - - - -van Kammen Expires 5 March 2026 [Page 15] +van Kammen Expires 23 March 2026 [Page 13] Internet-Draft XR Fragments September 2025 - +──────────────────────────────────────────────────────────+ - │ │ - │ index.gltf#playall │ - │ │ │ - │ ├ # : #t=0&shared=play │ apply default XR Fragment on load (`t` plays global 3D animation timeline) - │ ├ play : #t=0&loop │ variable for [URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) - │ │ │ - │ ├── ◻ plane (with material) │ - │ │ └ #: #uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps - │ │ │ - │ ├── ◻ plane │ - │ │ └ src: foo.jpg#uv=0,0,0,+0.1 │ infinite texturescroll `v` of uv·coordinates with 0.1/fps - │ │ │ - │ ├── ◻ media │ - │ │ └ src: cat.mp4#t=l:2,10&uv=0.5,0.5 │ loop cat.mp4 (or mp3/wav/jpg) between 2 and 10 seconds (uv's shifted with 0.5,0.5) - │ │ │ - │ └── ◻ wall │ - │ ├ href: #color=blue │ updates uniform values (IFS shader e.g.) - │ ├ blue: t=0&u:col=0,0,1 │ variable for [Level1 URI Templates (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) - │ └ src: ://a.com/art.glsl#{color}&{shared} │ .fs/.vs/.glsl/.wgsl etc shader [Level1 URI Template (RFC6570)](https://www.rfc-editor.org/rfc/rfc6570) - │ │ - │ │ - +──────────────────────────────────────────────────────────+ + | fragment | type | functionality | | #loop | string | enables + animation/video/audio loop | | #-loop | string | disables + animation/video/audio loop | -> NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work). +11.3. Controlling embedded content -11. Navigating 3D + use [[URI Templates]] to control embedded media, for example a simple + video-player: - +================+========+=============================+ - | fragment | type | functionality | - +================+========+=============================+ - | #=room1 | string | position camera to position | - | | | and upvector of objectname | - | | | room1 (+userheight in VR) | - +----------------+--------+-----------------------------+ + foo.usdz + │ + ├── ◻ loopbutton_enable + │ └ href: #loop <-- enable global loop + │ + ├── ◻ loopbutton_enable + │ └ href: #-loop <-- disable global loop + │ + ├── ◻ playbutton + │ └ href: #t=10&loop <-- play global 3D timeline (all anims) (looped) + │ + └── ◻ playbutton_external + └ href: https://my.org/animation.glb#!&t=3,10 <-- import & play external anim - Table 7 +12. Level4: prefix operators - » example implementation - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/pos.js) - » discussion (https://github.com/coderofsalvation/xrfragment/ - issues/5) + Prefixing objectnames with the following simple operators allow for + *extremely powerful* XR interactions: - Here's the basic *level1* flow (with optional level2 features): + * #! + * #* + * #+ or #- + * #| + * xrf: URI scheme + + | *Examples:* #+menu to show a object, #-menu to hide a menu, #!menu + | to teleport a menu, #*block to clone a grabbable block, #|object + | to share an object + +12.1. Object teleports (!) + + Prefixing an object with an exclamation-symbol, will teleport a + (local or remote) referenced object from/to its original/usercamera + location. + + [img[objecteleport.png]] -van Kammen Expires 5 March 2026 [Page 16] +van Kammen Expires 23 March 2026 [Page 14] Internet-Draft XR Fragments September 2025 - 1. the Y-coordinate of `room1 identifies the floorposition. This - means that desktop-projections usually need to add 1.5m (average - person height) on top (which is done automatically by VR/AR - headsets), except in case of camera-switching. - 2. set the position of the camera accordingly to the vector3 values - of room1 - 3. set the upvector of the camera accordingly to the vector3 values - of room1 (local gravity as pioneered by Patrick Lichty) - 4. if the referenced #room1 object is animated, parent the current - camera to that object (so it animates too) - 5. in case a href does not mention any 3D object, the current - position will be assumed + Usecases: * show/hide objects/buttons (menu e.g.) in front of user * + embed remote (object within) 3D file via remote URL * instance an + interactive object near the user regardless of location * instance + HUD or semi-transparent-textured-sphere (LUT) around the user - Here's an ascii representation of a 3D scene-graph which contains 3D - objects ◻ and their metadata: +
      #!menu
      - +────────────────────────────────────────────────────────+ - │ │ - │ index.gltf │ - │ │ │ - │ ├── ◻ buttonA │ - │ │ └ href: #room1&t=100,200 │ - │ │ │ - │ └── ◻ buttonB │ - │ └ href: other.fbx │ <── file─agnostic (can be .gltf .obj etc) - │ │ - +────────────────────────────────────────────────────────+ + Clicking the href (#via-href-metadata)-value above will: - An XR Fragment-compatible browser viewing this scene, allows the end- - user to interact with the buttonA and buttonB. - In case of buttonA the end-user will be teleported to another - location and time in the *current loaded scene*, but buttonB will - *replace the current scene* with a new one, like other.fbx, and - assume camera coordinate 0,0,0 + 1. *reposition the referenced object* (menu) to the + usercamera's-coordinates. + 2. *zoom* in case of (non-empty) mesh-object: rescale to 1 m³, and + position 1m in front of the camera + 3. toggle behaviour: revert values if 1/2 were already applied + 4. #+ is always implied (objects are always made visible) - *Non-normative*: + This tiny but powerful symbol allows incredible interactive + possibilities, by carefully positioning re-usable objects outside of + a scene (below the usercamera's floor e.g.). - 5. rot sets the rotation of the camera (only for non-VR/AR headsets, - however a camera-value overrules this) - 6. *level2*: mediafragment t in the top-URL sets the playbackspeed - and animation-range of the global scene animation - 7. before scene load: the scene is cleared - 8. *level2*: after scene load: in case the scene (rootnode) contains - an # default view with a fragment value: execute non-positional - fragments via the hashbus (no top-level URL change) - 9. *level2*: after scene load: in case the scene (rootnode) contains - an # default view with a fragment value: execute positional - fragment via the hashbus + update top-level URL + * href: #whiteroom&!explainer&!exitmenu + + | This will teleport the user to whiteroom and moves object + | explainer and exitmenu in front of the user. + + * href: `https://my.org/foo.glb#! (https://my.org/foo.glb#!) + + Clicking the href (#via-href-metadata)-value above will: + + 1. import foo.glb from my.org's webserver + 2. show it in front of the user (because #! indicates object + teleport) + + * href: https://foo.glb#roomB&!bar + + Clicking the href (#via-href-metadata)-value above will: + + 1. replace the current scene with foo.glb + 2. teleport the user to #roomB inside foo.glb + 3. *instance the referenced object* (bar inside foo.glb) in front of + the user. + 4. it will update the top-Level URL (because xrf: was not used) + 5. hide the *instanced object* when clicked again (toggle + visibility) -van Kammen Expires 5 March 2026 [Page 17] + + + +van Kammen Expires 23 March 2026 [Page 15] Internet-Draft XR Fragments September 2025 - 10. *level2*: in case of no default # view on the scene (rootnode), - default player(rig) position 0,0,0 is assumed. + | *NOTE*: level2 teleportation links, as well as instancing + | mitigates the 'broken embedded image'-issue of HTML: *always* + | attaching the href-values to *a 3D (preview) object* (that way + | broken links will not break the design). -12. Top-level URL processing + *Example:* clicking a 3D button with title 'menu' and href (#href)- + value xrf:menu.glb?instance#t=4,5 would instance a 3D menu (menu.glb) + in front of the user, and loop its animation between from 4-5 seconds + (t=4,5) - | Example URL: ://foo/world.gltf#room1&t=10 + | *NOTE*: combining instance-operators allows dynamic construction + | of 3D scenes (#london&!welcomeMenu&!fadeBox e.g.) + +12.2. Object multipliers (*) + + The star-prefix will clone a (local or remote) referenced object to + the usercamera's location, and make it grabbable. + Usecases: * object-picker (build stuff with objects) + + | *NOTE*: this is basically the #! operator (#%23%21) which + | infinitely *clones* the referenced object (instead of + | repositioning the object). + +12.3. De/selectors (+ and -) + + * href: #-welcome (or #+welcome) + + Clicking href-value above will do: + + 1. show/hide the target object (and children) + + * href: #https://my.org/foo.glb/#bar&-welcome + + | *NOTE:* the latter shows that (de)selectors can also be with + | regular href (#href)-values + +12.4. Sharing object or file (#|) + + The pipe-symbol (|) sends a (targeted) object to the OS. Clicking + the href-value below will: + + 1. share the (targeted object in the) file to a another application + + | This URL can be fed straight into Web Share API + | (https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API) + | or xdg-open (https://www.freedesktop.org/wiki/Software/xdg-utils/) + + * href: xrf://#|bar + + + +van Kammen Expires 23 March 2026 [Page 16] + +Internet-Draft XR Fragments September 2025 + + + | *NOTE*: sharing is limited to (internal objects) via xrf: scheme- + | only + +12.5. xrf:// URI scheme + + Prefixing the xrf: to href (#href)-values *will prevent* level2 + (#📜%20level2:%20explicit%20links) href (#href)-values from changing + the top-Level URL. + + | *Usecase*: for non-shareable URLs like href: xrf:#t=4,5, to + | display a stateful msg e.g.). + + *Reason:* XR Fragments is inspired by HTML's href-attribute + (https://en.wikipedia.org/wiki/Hyperlink), which does various things: + + 1. it updates the browser-location + 2. it makes something clickable + 3. it jumps to another document / elsewhere in the same document + 4. and more + + The xrf: scheme will just do 2 & 3 (so the URL-values will not leak + into the top-level URL). + + | *compliance with RFC 3986*: unimplemented/unknown URI schemes + | (xrf:... e.g.) will not update the top-level URL + +13. Top-level URL processing + + | Example URL: ://foo/world.gltf#room1&t=10&cam The URL-processing-flow for hypermedia browsers goes like this: - 1. IF a #room1 matches a custom property-key (of an object) in the - 3D file/scene (#room1: #......) THEN execute that - predefined_view. - 2. IF scene operators and/or animation operator (t) are present in + 1. IF scene operators and/or animation operator (t) are present in the URL then (re)position the camera (to room1) and/or animation- range (10) accordingly. - 3. IF no camera-position has been set in step 1 or 2 assume + 2. IF no camera-position has been set in step 1 or 2 assume 0,0,0 as camera coordinate (XR: add user-height) (example (https: //github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ three/navigator.js#L31]])) + 3. IF a camera-object exists with name cam assume that user(camera) + position - *Non-normative / Deprecated*: +13.1. UX - 4. IF a #cube matches the name (of an object) in the 3D file/scene - then draw a line from the enduser('s heart) to that object (to - highlight it). - 5. IF a #cube matches anything else in the XR Word Graph (XRWG) draw - wires to them (text or related objects). + End-users should always have read/write access to: -13. Embedding XR content using src - - | NOTE: only adviced for local-first experiences (where resources - | can be cached). - - src is the 3D version of the iframe. - It instances content (in objects) in the current scene/asset, and - follows similar logic like the previous chapter, except that it does - not modify the camera. + 1. the current (toplevel) URL (an URLbar etc) + 2. URL-history (a back/forward button e.g.) - - - - - - - - - - -van Kammen Expires 5 March 2026 [Page 18] +van Kammen Expires 23 March 2026 [Page 17] Internet-Draft XR Fragments September 2025 - +========+========+===================================================+ - |fragment|type |example value | - +========+========+===================================================+ - |src |string |#cube | - | |(uri, |#sometag | - | |hashtag/|#cube&-ball_inside_cube
      #-sky&-rain
      #- | - | |filter) |language&english
      #price=>5
      https://linux.org/| - | | |penguin.png` (https://linux.org/penguin.png`) | - | | |https://linux.world/distrowatch.gltf#t=1,100 | - | | |linuxapp://conference/nixworkshop/apply.gltf#- | - | | |cta&cta_apply | - | | |androidapp://page1?tutorial#room1&t1,100 | - | | |foo.mp3#0,0,0 | - +--------+--------+---------------------------------------------------+ + 3. Clicking/Touching an href navigates (and updates the URL) to + another scene/file (and coordinate e.g. in case the URL contains + XR Fragments). - Table 8 - - Here's an ascii representation of a 3D scene-graph with 3D objects ◻ - which embeds remote & local 3D objects ◻ with/out using filters: - - +────────────────────────────────────────────────────────+ +─────────────────────────+ - │ │ │ │ - │ index.gltf │ │ ocean.com/aquarium.fbx │ - │ │ │ │ ├ room │ - │ ├── ◻ canvas │ │ └── ◻ fishbowl │ - │ │ └ src: painting.png │ │ ├─ ◻ bass │ - │ │ │ │ └─ ◻ tuna │ - │ ├── ◻ aquariumcube │ │ │ - │ │ └ src: ://rescue.com/fish.gltf#fishbowl │ +─────────────────────────+ - │ │ │ - │ ├── ◻ bedroom │ - │ │ └ src: #canvas │ - │ │ │ - │ └── ◻ livingroom │ - │ └ src: #canvas │ - │ │ - +────────────────────────────────────────────────────────+ - - An XR Fragment-compatible browser viewing this scene, lazy-loads and - projects painting.png onto the (plane) object called canvas (which is - copy-instanced in the bed and livingroom). - Also, after lazy-loading ocean.com/aquarium.gltf, only the queried - objects fishbowl (and bass and tuna) will be instanced inside - aquariumcube. - Resizing will be happen accordingly to its placeholder object - aquariumcube, see chapter Scaling. - - - - - -van Kammen Expires 5 March 2026 [Page 19] - -Internet-Draft XR Fragments September 2025 - - - | Instead of cherrypicking a rootobject #fishbowl with src, - | additional filters can be used to include/exclude certain objects. - | See next chapter on filtering below. - - *Specification*: - - 1. local/remote content is instanced by the src (filter) value (and - attaches it to the placeholder mesh containing the src property) - 2. by default all objects are loaded into the instanced src (scene) - object (but not shown yet) - 3. local src values (#... e.g.) starting with a non-negating - filter (#cube e.g.) will (deep)reparent that object (with name - cube) as the new root of the scene at position 0,0,0 - 4. local src values should respect (negative) filters - (#-foo&price=>3) - 5. the instanced scene (from a src value) should be scaled - accordingly to its placeholder object or scaled - relatively based on the scale-property (of a geometry-less - placeholder, an 'empty'-object in blender e.g.). For more info - see Chapter Scaling. - 6. external src values should be served with appropriate - mimetype (so the XR Fragment-compatible browser will now how to - render it). The bare minimum supported mimetypes are: - 7. src values should make its placeholder object invisible, and - only flush its children when the resolved content can - succesfully be retrieved (see broken links (#links)) - 8. external src values should respect the fallback link - mechanism (see broken links (#broken-links) - 9. when the placeholder object is a 2D plane, but the mimetype is - 3D, then render the spatial content on that plane via a stencil - buffer. - 10. src-values are non-recursive: when linking to an external object - (src: foo.fbx#bar), then src-metadata on object bar should be - ignored. - 11. an external src-value should always allow a sourceportation icon - within 3 meter: teleporting to the origin URI to which the - object belongs. - 12. when only one object was cherrypicked (#cube e.g.), set its - position to 0,0,0 - 13. when the enduser clicks an href with #t=1,0,0 (play) will be - applied to all src mediacontent with a timeline (mp4/mp3 e.g.) - 14. a non-euclidian portal can be rendered for flat 3D objects - (using stencil buffer e.g.) in case ofspatial src-values (an - object #world3 or URL world3.fbx e.g.). - - * model/gltf-binary - * model/gltf+json - * image/png - - - -van Kammen Expires 5 March 2026 [Page 20] - -Internet-Draft XR Fragments September 2025 - - - * image/jpg - * text/plain;charset=utf-8 - - » example implementation - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/src.js) - » example 3D asset - (https://github.com/coderofsalvation/xrfragment/blob/main/example/ - assets/src.gltf#L192) - » discussion (https://github.com/coderofsalvation/xrfragment/ - issues/4) - -14. Navigating content href portals +14. Example: Navigating content href portals navigation, portals & mutations @@ -1142,15 +966,14 @@ Internet-Draft XR Fragments September 2025 | fragment | type | example value | +==========+==================+========================+ | href | string (uri or | #room1 | - | | predefined view) | #room1&rot=90,0,0 | + | | predefined view) | #room1 | | | | ://somefile.gltf#room1 | +----------+------------------+------------------------+ - Table 9 + Table 5 1. clicking an outbound ''external''- or ''file URI'' fully replaces - the current scene and assumes room2&rot=0,0,0 by default (unless - specified) + the current scene and assumes room2 by default (unless specified) 2. relocation/reorientation should happen locally for local URI's (#....) @@ -1170,14 +993,6 @@ Internet-Draft XR Fragments September 2025 (https://github.com/coderofsalvation/xrfragment/blob/dev/example/ aframe/sandbox/index.html#L26-L29) for an example wearable) - - - -van Kammen Expires 5 March 2026 [Page 21] - -Internet-Draft XR Fragments September 2025 - - 6. make sure that the ''back-button'' of the ''browser-history'' always refers to the previous position (see [here (https://github .com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/ @@ -1187,6 +1002,14 @@ Internet-Draft XR Fragments September 2025 using camera-portal collision (the back-button could cause a teleport-loop if the previous position is too close) + + + +van Kammen Expires 23 March 2026 [Page 18] + +Internet-Draft XR Fragments September 2025 + + 8. href-events should bubble upward the node-tree (from children to ancestors, so that ancestors can also conain an href), however only 1 href can be executed at the same time. @@ -1206,627 +1029,50 @@ Internet-Draft XR Fragments September 2025 14.1. Walking surfaces + | By default position 0,0,0 of the 3D scene represents the walkable + | plane, however this is overridden when the following applies: + XR Fragment-compatible viewers can infer this data based scanning the scene for: - 1. materialless (nameless & textureless) mesh-objects (without src - and href) + 1. materialless (nameless & textureless) mesh-objects (without href + and >0 faces) | optionally the viewer can offer thumbstick, mouse or joystick | teleport-tools for non-roomscale VR/AR setups. -14.2. UX spec +15. Virtual world rings - End-users should always have read/write access to: - - 1. the current (toplevel) URL (an URLbar etc) - 2. URL-history (a back/forward button e.g.) - 3. Clicking/Touching an href navigates (and updates the URL) to - another scene/file (and coordinate e.g. in case the URL contains - XR Fragments). - - - - - -van Kammen Expires 5 March 2026 [Page 22] - -Internet-Draft XR Fragments September 2025 - - -14.3. Scaling instanced content - - Sometimes embedded properties (like src) instance new objects. - But what about their scale? - How does the scale of the object (with the embedded properties) - impact the scale of the referenced content? - - | Rule of thumb: visible placeholder objects act as a '3D canvas' - | for the referenced scene (a plane acts like a 2D canvas for images - | e, a cube as a 3D canvas e.g.). - - 1. IF an embedded property (src e.g.) is set on an non-empty - placeholder object (geometry of >2 vertices): - - * calculate the bounding box of the ''placeholder'' object - (maxsize=1.4 e.g.) - * hide the ''placeholder'' object (material e.g.) - * instance the src scene as a child of the existing object - * calculate the bounding box of the instanced scene, and - scale it accordingly (to 1.4 e.g.) - - | REASON: non-empty placeholder object can act as a protective - | bounding-box (for remote content of which might grow over time - | e.g.) - - 2. ELSE multiply the scale-vector of the instanced scene with the - scale-vector (a common property of a 3D node) of the - placeholder object. - - | TODO: needs intermediate visuals to make things more obvious - -15. XR Fragment: pos - - [[» example implementation|https://github.com/coderofsalvation/xrfrag - ment/blob/main/src/3rd/js/three/xrf/pos.js] - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/pos.js])] - -16. XR Fragment: rot - - [[» example implementation|https://github.com/coderofsalvation/xrfrag - ment/blob/main/src/3rd/js/three/xrf/pos.js] - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/pos.js])] - - - - - - - -van Kammen Expires 5 March 2026 [Page 23] - -Internet-Draft XR Fragments September 2025 - - -17. XR Fragment: t - - [[» example implementation|https://github.com/coderofsalvation/xrfrag - ment/blob/main/src/3rd/js/three/xrf/t.js] - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/t.js])] - -18. XR audio/video integration - - To play global audio/video items: - - 1. add a src: foo.mp3 or src: bar.mp4 metadata to a 3D object (cube - e.g.) - 2. to enable auto-play and global timeline ([[#t=|t]]) control: - hardcode a [[#t=|t]] XR Fragment: (src: bar.mp3#t=0&loop e.g.) - 3. to play it, add href: #cube somewhere else - 4. to enable enduser-triggered play, use a [[URI Template]] XR - Fragment: (src: bar.mp3#{player} and play: t=0&loop and href: - xrf://#player=play e.g.) - 5. when the enduser clicks the href, #t=0&loop (play) will be - applied to the src value - - | NOTE: hardcoded framestart/framestop uses sampleRate/fps of - | embedded audio/video, otherwise the global fps applies. For more - | info see [[#t|t]]. - -19. XR Fragment filters - - Include, exclude, hide/shows objects using space-separated strings: - - +====================+===========================================+ - | example | outcome | - +====================+===========================================+ - | #-sky | show everything except object named sky | - +--------------------+-------------------------------------------+ - | #-language&english | hide everything with tag language, but | - | | show all tag english objects | - +--------------------+-------------------------------------------+ - | #-price&price=>10 | hide all objects with property price, | - | | then only show object with price above 10 | - +--------------------+-------------------------------------------+ - | #-house* | hide house object and everything inside | - | | (=*) | - +--------------------+-------------------------------------------+ - - Table 10 - - - - - -van Kammen Expires 5 March 2026 [Page 24] - -Internet-Draft XR Fragments September 2025 - - - It's simple but powerful syntax which allows filtering the scene - using searchengine prompt-style feeling: - - 1. filters are a way to traverse a scene, and filter objects based - on their name, tag- or property-values. - - * see an (outdated) example video here - (https://coderofsalvation.github.io/xrfragment.media/queries.mp4) - which used a dedicated q= variable (now deprecated and usable - directly) - -19.1. including/excluding - - By default, selectors work like photoshop-layers: they scan for - matching layer(name/properties) within the scene-graph. Each matched - object (not their children) will be toggled (in)visible when - selecting. - - +==========+==============================================+ - | operator | info | - +==========+==============================================+ - | - | hides object(s) (#-myobject&-objects e.g. | - +----------+----------------------------------------------+ - | = | indicates an object-embedded custom property | - | | key/value (#price=4&category=foo e.g.) | - +----------+----------------------------------------------+ - | => =< | compare float or int number (#price=>4 e.g.) | - +----------+----------------------------------------------+ - | * | deepselect: automatically select children of | - | | selected object, including local (nonremote) | - | | embedded objects (starting with #) | - +----------+----------------------------------------------+ - - Table 11 - - | NOTE 1: after an external embedded object has been instanced (src: - | https://y.com/bar.fbx#room e.g.), filters do not affect them - | anymore (reason: local tag/name collisions can be mitigated - | easily, but not in case of remote content). - | - | NOTE 2: depending on the used 3D framework, toggling objects - | (in)visible should happen by enabling/disableing writing to the - | colorbuffer (to allow children being still visible while their - | parents are invisible). - - » example implementation - (https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/ - three/xrf/q.js) » example 3D asset - - - -van Kammen Expires 5 March 2026 [Page 25] - -Internet-Draft XR Fragments September 2025 - - - (https://github.com/coderofsalvation/xrfragment/blob/main/example/ - assets/filter.gltf#L192) » discussion - (https://github.com/coderofsalvation/xrfragment/issues/3) - -19.2. Filter Parser - - Here's how to write a filter parser: - - 1. create an associative array/object to store filter-arguments as - objects - 2. detect object id's & properties foo=1 and foo (reference regex= - ~/^.*=[><=]?/ ) - 3. detect excluders like -foo,-foo=1,-.foo,-/foo (reference regex= - /^-/ ) - 4. detect root selectors like /foo (reference regex= /^[-]?\// ) - 5. detect number values like foo=1 (reference regex= /^[0-9\.]+$/ ) - 6. detect operators so you can easily strip keys (reference regex= - /(^-|\*$)/ ) - 7. detect exclude keys like -foo (reference regex= /^-/ ) - 8. for every filter token split string on = - 9. and we set root to true or false (true=/ root selector is - present) - 10. therefore we we set show to true or false (false=excluder -) - - | An example filter-parser (which compiles to many languages) can be - | found here - | (https://github.com/coderofsalvation/xrfragment/blob/main/src/ - | xrfragment/Filter.hx) - -20. Visible links - - When predefined views, XRWG fragments and ID fragments (#cube or - #mytag e.g.) are triggered by the enduser (via toplevel URL or - clicking href): - - 1. draw a wire from the enduser (preferabbly a bit below the camera, - heartposition) to object(s) matching that ID (objectname) - 2. draw a wire from the enduser (preferabbly a bit below the camera, - heartposition) to object(s) matching that tag value - 3. draw a wire from the enduser (preferabbly a bit below the camera, - heartposition) to object(s) containing that in their src or href - value - - The obvious approach for this, is to consult the XRWG (example - (https://github.com/coderofsalvation/xrfragment/blob/feat/macros/ - src/3rd/js/XRWG.js)), which basically has all these things already - collected/organized for you during scene-load. - - - - -van Kammen Expires 5 March 2026 [Page 26] - -Internet-Draft XR Fragments September 2025 - - - *UX* - - 4. do not update the wires when the enduser moves, leave them as is - 5. offer a control near the back/forward button which allows the - user to (turn off) control the correlation-intensity of the XRWG - -21. Text in XR (tagging,linking to spatial objects) - - How does XR Fragments interlink text with objects? - - | The XR Fragments does this by collapsing space into a *Word Graph* - | (the *XRWG* example - | (https://github.com/coderofsalvation/xrfragment/blob/feat/macros/ - | src/3rd/js/XRWG.js)), augmented by Bib(s)Tex. - - Instead of just throwing together all kinds media types into one - experience (games), what about their tagged/semantical relationships? - Perhaps the following question is related: why is HTML adopted less - in games outside the browser? - - Hence: - - 1. XR Fragments promotes (de)serializing a scene to a (lowercase) - XRWG (example - (https://github.com/coderofsalvation/xrfragment/blob/feat/macros/ - src/3rd/js/XRWG.js)) - 2. XR Fragments primes the XRWG, by collecting words from the tag - and name-property of 3D objects. - 3. XR Fragments primes the XRWG, by collecting words from *optional* - metadata *at the end of content* of text (see default mimetype & - Data URI) - 4. XR Fragments primes the XRWG, by collecting tags/id's from linked - hypermedia (URI fragments for HTML e.g.) - 5. The XRWG should be recalculated when textvalues (in src) change - 6. HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they - fit better in the application-layer, or as embedded src content) - 7. Applications don't have to be able to access the XRWG - programmatically, as they can easily generate one themselves by - traversing the scene-nodes. - 8. The XR Fragment focuses on fast and easy-to-generate end-user - controllable word graphs (instead of complex implementations that - try to defeat word ambiguity) - 9. Instead of exact lowercase word-matching, levensteihn-distance- - based matching is preferred - - Example of generating XRWG out of the XRWG and textdata with - hashtags: - - - - -van Kammen Expires 5 March 2026 [Page 27] - -Internet-Draft XR Fragments September 2025 - - - http://y.io/z.fbx | Derived XRWG (expressed as JSON) - ----------------------------------------------------------------------------+-------------------------------------- - | Chapter: ['#mydoc'] - +-[src: data:.....]----------------------+ +-[3D mesh]-+ | one: ['#mydoc'] - | Chapter one | | / \ | | houses: ['#castle','#mydoc','#house'] - | | | / \ | | baroque: ['#mydoc','#castle'] - | John built houses in baroque style. | | / \ | | castle: ['#baroque','#house'] - | | | |_____| | | john: ['#john','#mydoc'] - | | +-----│-----+ | mydoc: ['#mydoc'] - | | │ | - | | ├─ name: castle | - | | └─ tag: house baroque | - +----------------------------------------+ | - └─ name: mydoc [3D mesh-+ | - | O ├─ name: john | - | /|\ | | - | / \ | | ^ ^ ^ - +--------+ | | | | - | - [remotestorage.io]+ [ localstorage]-+ | <- the XR Fragment-compatible - | XRWG (JSON) | | XRWG (JSON | | <- 3D hypermedia viewer should - | | | | | <- be able to select the active XRWG - +-----------------+ +---------------+ | - - This allows hasslefree authoring and copy-paste of associations *for - and by humans*, but also makes these URLs possible: - - +==================+======================================+ - | URL example | Result | - +==================+======================================+ - | https://my.com/ | draws lines between 3D mesh castle, | - | foo.gltf#baroque | and mydoc's text baroque | - +------------------+--------------------------------------+ - | https://my.com/ | draws lines between mesh john, and | - | foo.gltf#john | the text John of mydoc | - +------------------+--------------------------------------+ - | https://my.com/ | draws lines between mesh castle, and | - | foo.gltf#house | other objects with tag house or todo | - +------------------+--------------------------------------+ - - Table 12 - - | the URI fragment #john&mydoc&house would draw a connection between - | these 3 meshes. - - The XRWG allows endusers to show/hide relationships in realtime in XR - Browsers at various levels: - - - - -van Kammen Expires 5 March 2026 [Page 28] - -Internet-Draft XR Fragments September 2025 - - - * wordmatch *inside* src text - * wordmatch *inside* href text - * wordmatch object-names - * wordmatch object-tagnames - - Spatial wires can be rendered between words/objects etc. - Some pointers for good UX (but not necessary to be XR Fragment - compatible): - - 9. The XR Browser needs to adjust tag-scope based on the endusers - needs/focus (infinite tagging only makes sense when environment - is scaled down significantly) - 10. The XR Browser should always allow the human to view/edit the - metadata, by clicking 'toggle metadata' on the 'back' - (contextmenu e.g.) of any XR text, anywhere anytime. - 11. respect multi-line BiBTeX metadata in text because of the core - principle (#core-principle) - 12. Default font (unless specified otherwise) is a modern monospace - font, for maximized tabular expressiveness (see the core - principle (#core-principle)). - 13. anti-pattern: hardcoupling an XR Browser with a mandatory - *markup/scripting-language* which departs from onubtrusive plain - text (HTML/VRML/Javascript) (see the core principle (#core- - principle)) - 14. anti-pattern: limiting human introspection, by abandoning plain - text as first tag citizen. - -21.1. Default Data URI mimetype - - The src-values work as expected (respecting mime-types), however: - - The XR Fragment specification advices to bump the traditional default - browser-mimetype - - text/plain;charset=US-ASCII - - to a hashtag-friendly one: - - text/plain;charset=utf-8;hashtag - - This indicates that: - - * utf-8 is supported by default - * words beginning with # (hashtags) will prime the XRWG by adding - the hashtag to the XRWG, linking to the current - sentence/paragraph/alltext (depending on '.') to the XRWG - - Advantages: - - - -van Kammen Expires 5 March 2026 [Page 29] - -Internet-Draft XR Fragments September 2025 - - - * out-of-the-box (de)multiplex human text and metadata in one go - (see the core principle (#core-principle)) - * no network-overhead for metadata (see the core principle (#core- - principle)) - * ensuring high FPS: realtime HTML/RDF historically is too - 'requesty'/'parsy' for game studios - * rich send/receive/copy-paste everywhere by default, metadata being - retained (see the core principle (#core-principle)) - * netto result: less webservices, therefore less servers, and - overall better FPS in XR - - | This significantly expands expressiveness and portability of human - | tagged text, by *postponing machine-concerns to the end of the - | human text* in contrast to literal interweaving of content and - | markupsymbols (or extra network requests, webservices e.g.). - - For all other purposes, regular mimetypes can be used (but are not - required by the spec). - -21.2. URL and Data URI - - +--------------------------------------------------------------+ +------------------------+ - | | | author.com/article.txt | - | index.gltf | +------------------------+ - | │ | | | - | ├── ◻ article_canvas | | Hello #friends | - | │ └ src: ://author.com/article.txt | | | - | │ | +------------------------+ - | └── ◻ note_canvas | - | └ src:`data:welcome human\n@book{sunday...}` | - | | - | | - +--------------------------------------------------------------+ - - The enduser will only see welcome human and Hello friends rendered - verbatim (see mimetype). The beauty is that text in Data URI - automatically promotes rich copy-paste (retaining metadata). In both - cases, the text gets rendered immediately (onto a plane geometry, - hence the name '_canvas'). The XR Fragment-compatible browser can - let the enduser access visual-meta(data)-fields after interacting - with the object (contextmenu e.g.). - - | additional tagging using bibs - | (https://github.com/coderofsalvation/hashtagbibs): to tag spatial - | object note_canvas with 'todo', the enduser can type or speak - | #note_canvas@todo - - - - - -van Kammen Expires 5 March 2026 [Page 30] - -Internet-Draft XR Fragments September 2025 - - -22. Importing/exporting - - For usecases like importing/exporting/p2p casting a scene, the issue - of external files comes into play. - - 1. export: if the 3D scene contains relative src/href values, - rewrite them into absolute URL values. - -23. Reflection Mapping - - Environment mapping is crucial for creating realistic reflections and - lighting effects on 3D objects. To apply environment mapping - efficiently in a 3D scene, traverse the scene graph and assign each - object's environment map based on the nearest ancestor's texture map. - This ensures that objects inherit the correct environment mapping - from their closest parent with a texture, enhancing the visual - consistency and realism. - - +--------------------------------+ - | | - | index.usdz | - | │ | - | └── ◻ sphere (texture:foo) | - | └ ◻ cube (texture:bar) | envMap = foo - | └ ◻ cylinder | envMap = bar - +--------------------------------+ - - Most 3D viewers apply one and the same environment map for various - models, however this logic allows a more natural & automatic strategy - for reflection mapping: - - 1. traverse the scene graph depth-first - 2. remember the most recent parentnode (P) with a texture material - 3. for every non-root node with a texture material 3.1 clone that - material (as materials might be shared across objects) 3.2 set - the environmentmap to the last known parent texture (P) - -24. Transclusion (broken link) resolution - - In spirit of Ted Nelson's 'transclusion resolution', there's a soft- - mechanism to harden links & minimize broken links in various ways: - - 1. defining a different transport protocol (https vs ipfs or DAT) in - src or href values can make a difference - 2. mirroring files on another protocol using (HTTP) errorcode tags - in src or href properties - - - - - -van Kammen Expires 5 March 2026 [Page 31] - -Internet-Draft XR Fragments September 2025 - - - 3. in case of src: nesting a copy of the embedded object in the - placeholder object (embeddedObject) will not be replaced when the - request fails - - | due to the popularity, maturity and extensiveness of HTTP codes - | for client/server communication, non-HTTP protocols easily map to - | HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.) - - For example: - - +────────────────────────────────────────────────────────+ - │ │ - │ index.gltf │ - │ │ │ - │ │ #: #-offlinetext │ - │ │ │ - │ ├── ◻ buttonA │ - │ │ └ href: http://foo.io/campagne.fbx │ - │ │ └ href@404: ipfs://foo.io/campagne.fbx │ - │ │ └ href@400: #clienterrortext │ - │ │ └ ◻ offlinetext │ - │ │ │ - │ └── ◻ embeddedObject <--------- the meshdata inside embeddedObject will (not) - │ └ src: https://foo.io/bar.gltf │ be flushed when the request (does not) succeed. - │ └ src@404: http://foo.io/bar.gltf │ So worstcase the 3D data (of the time of publishing index.gltf) - │ └ src@400: https://archive.org/l2kj43.gltf │ will be displayed. - │ │ - +────────────────────────────────────────────────────────+ - -25. Topic-based index-less Webrings - - As hashtags in URLs map to the XWRG, href-values can be used to - promote topic-based index-less webrings. - Consider 3D scenes linking to eachother using these href values: + Consider 3D scenes linking to eachother using these href values, + attached to 3D button-objects: * href: schoolA.edu/projects.gltf#math * href: schoolB.edu/projects.gltf#math * href: university.edu/projects.gltf#math - These links would all show visible links to math-tagged objects in - the scene. - To filter out non-related objects one could take it a step further - using filters: + This would teleport users to the math-projects of those universities. + Now consider adding a 'webring index'-button to each file, with this + href-value: - * href: schoolA.edu/projects.gltf#math&-topics math - * href: schoolB.edu/projects.gltf#math&-courses math - * href: university.edu/projects.gltf#math&-theme math + * href: workgroup.edu/webrings.glb#!webringmenu + + This would allow displaying the (remote 3D file) webring menu with + various href-buttons inside, all centrally curated by the workgroup. - -van Kammen Expires 5 March 2026 [Page 32] +van Kammen Expires 23 March 2026 [Page 19] Internet-Draft XR Fragments September 2025 - | This would hide all object tagged with topic, courses or theme - | (including math) so that later only objects tagged with math will - | be visible - - This makes spatial content multi-purpose, without the need to - separate content into separate files, or show/hide things using a - complex logiclayer like javascript. - -26. URI Templates (RFC6570) +16. Level5: URI Templates (RFC6570) XR Fragments adopts Level1 URI *Fragment* expansion to provide safe interactivity. - The following demonstrates a simple video player: + This is non-normative, and the draft spec is available on request. - +─────────────────────────────────────────────+ - │ │ - │ foo.usdz │ - │ │ │ - │ │ │ - │ ├── ◻ stopbutton │ - │ │ ├ #: #-stopbutton │ - │ │ └ href: #player=stop&-stopbutton │ (stop and hide stop-button) - │ │ │ - │ └── ◻ plane │ - │ ├ play: #t=l:0,10 │ - │ ├ stop: #t=0,0 │ - │ ├ href: #player=play&stopbutton │ (play and show stop-button) - │ └ src: cat.mp4#{player} │ - │ │ - │ │ - +─────────────────────────────────────────────+ - -27. Additional scene metadata +17. Additional scene metadata XR Fragments does not aim to redefine the metadata-space or accessibility-space by introducing its own cataloging-metadata @@ -1836,19 +1082,14 @@ Internet-Draft XR Fragments September 2025 * SPDX (https://spdx.dev/) license information * ARIA (https://www.w3.org/WAI/standards-guidelines/aria/) attributes (aria-*: .....) + * datapackage.json (https://datapackage.org) findability, + accessibility, interoperability, and reusability of data - | SPDX and ARIA's aria-description are normative, as they promote - | accessibility and scene transcripts: please start aria-description - | with a verb to aid transcripts. - - - - - -van Kammen Expires 5 March 2026 [Page 33] - -Internet-Draft XR Fragments September 2025 + ARIA's aria-description-metadata is normative, to aid accessibility + and scene transcripts + | *NOTE*: please always start aria-description with a verb to aid + | transcripts. The following metadata are non-normative but encouraged, since they are popular and cheap to parse: @@ -1873,6 +1114,14 @@ Internet-Draft XR Fragments September 2025 Individual nodes can be enriched with such metadata, but most importantly the scene node: + + + +van Kammen Expires 23 March 2026 [Page 20] + +Internet-Draft XR Fragments September 2025 + + +================================+=========================+ | metadata key | example value | +================================+=========================+ @@ -1896,15 +1145,7 @@ Internet-Draft XR Fragments September 2025 | journal (bibTeX) | {Future Of Text Vol 3}, | +--------------------------------+-------------------------+ - Table 13 - - - - -van Kammen Expires 5 March 2026 [Page 34] - -Internet-Draft XR Fragments September 2025 - + Table 6 | * = these are interchangable (only one needs to be defined) @@ -1914,7 +1155,7 @@ Internet-Draft XR Fragments September 2025 | These attributes can be scanned and presented during an href or | src eye/mouse-over. -28. Accessibility interface +18. Accessibility interface The addressibility of XR Fragments allows for unique 3D-to-text transcripts, as well as an textual interface to navigate 3D content. @@ -1929,6 +1170,14 @@ Internet-Draft XR Fragments September 2025 to read (via screenreader, screen, or TTS e.g.) 4. the textlog contains aria-descriptions, and its narration (Screenreader e.g.) can be skipped (via 2-button navigation) + + + +van Kammen Expires 23 March 2026 [Page 21] + +Internet-Draft XR Fragments September 2025 + + 5. The back command should navigate back to the previous URL (alias for browser-backbutton) 6. The forward command should navigate back to the next URL (alias @@ -1952,21 +1201,11 @@ Internet-Draft XR Fragments September 2025 current #... (3D object) value (including its children) 16. The do command should list all possible href values which don't contain an #... XR Fragment - - - - - -van Kammen Expires 5 March 2026 [Page 35] - -Internet-Draft XR Fragments September 2025 - - 17. The (dynamic) do abc command should navigate/execute https://.../... in case a 3D node exist with name abc and href value https://.../... -28.1. Two-button navigation +18.1. Two-button navigation For specific user-profiles, gyroscope/mouse/keyboard/audio/visuals will not be available. @@ -1980,7 +1219,7 @@ Internet-Draft XR Fragments September 2025 3. the TTS reads the href-value (and/or aria-description if available) -28.2. Overlap with fileformat-specific extensions +18.2. Overlap with fileformat-specific extensions Some 3D scene-fileformats have support for extensions. What if the functionality of those overlap? For example, GLTF has the OMI_LINK @@ -1988,6 +1227,13 @@ Internet-Draft XR Fragments September 2025 | Priority Order and Precedence, otherwise fallback applies + + +van Kammen Expires 23 March 2026 [Page 22] + +Internet-Draft XR Fragments September 2025 + + 1.*Extensions Take Precedence*: Since glTF-specific extensions are designed with the format’s specific needs and optimizations in mind, they should take precedence over extras metadata in cases where both @@ -2009,21 +1255,12 @@ Internet-Draft XR Fragments September 2025 | teleport should be performed only (and other [overlapping] | metadata should be ignored). | - - - - -van Kammen Expires 5 March 2026 [Page 36] - -Internet-Draft XR Fragments September 2025 - - | *Example 2* If an Extensions uses XR Fragments in URI's (href: | #otherroom or href: xrf://-walls in OMI_LINK e.g.), then perform | them according to XR Fragment spec (teleport user). But only | once: ignore further overlapping metadata for that usecase. -28.3. Vendor Prefixes +18.3. Vendor Prefixes Vendor-specific metadata in a 3D scenefiles, are similar to vendor- specific CSS-prefixes (https://en.wikipedia.org/wiki/ @@ -2034,6 +1271,25 @@ Internet-Draft XR Fragments September 2025 Vendor Prefixes allows embedding 3D engines/framework-specific features a 3D file via metadata: + + + + + + + + + + + + + + +van Kammen Expires 23 March 2026 [Page 23] + +Internet-Draft XR Fragments September 2025 + + +===========+===================+==============================+ | what | XR metadata | Lowest common denominator | +===========+===================+==============================+ @@ -2047,7 +1303,7 @@ Internet-Draft XR Fragments September 2025 | prefixs | | implementation | +-----------+-------------------+------------------------------+ - Table 14 + Table 7 | Why? Because not all XR interactions can/should be solved/ | standardized by embedding XR Fragments into any 3D file. The @@ -2069,7 +1325,23 @@ Internet-Draft XR Fragments September 2025 -van Kammen Expires 5 March 2026 [Page 37] + + + + + + + + + + + + + + + + +van Kammen Expires 23 March 2026 [Page 24] Internet-Draft XR Fragments September 2025 @@ -2125,12 +1397,12 @@ Internet-Draft XR Fragments September 2025 -van Kammen Expires 5 March 2026 [Page 38] +van Kammen Expires 23 March 2026 [Page 25] Internet-Draft XR Fragments September 2025 -29. Security Considerations +19. Security Considerations The only dynamic parts are W3C Media Fragments (https://www.w3.org/TR/media-frags/) and URI Templates (RFC6570) @@ -2140,7 +1412,7 @@ Internet-Draft XR Fragments September 2025 n fact, it is much safer than relying on a scripting language (javascript) which can change URN too. -30. FAQ +20. FAQ *Q:* Why is everything HTTP GET-based, what about POST/PUT/DELETE HATEOS @@ -2173,7 +1445,7 @@ Internet-Draft XR Fragments September 2025 place, to 'extend' experiences, in contrast to code/javascript inside hypermedia documents (this turned out as a hypermedia antipattern). -31. authors +21. authors * Leon van Kammen (@lvk@mastodon.online) * Jens Finkhäuser (@jens@social.finkhaeuser.de) @@ -2181,16 +1453,16 @@ Internet-Draft XR Fragments September 2025 -van Kammen Expires 5 March 2026 [Page 39] +van Kammen Expires 23 March 2026 [Page 26] Internet-Draft XR Fragments September 2025 -32. IANA Considerations +22. IANA Considerations This document has no IANA actions. -33. Acknowledgments +23. Acknowledgments * NLNET (https://nlnet.nl) * Future of Text (https://futureoftext.org) @@ -2205,7 +1477,7 @@ Internet-Draft XR Fragments September 2025 * Brandel Zackernuk * Mark Anderson -34. Appendix: Definitions +24. Appendix: Definitions +=================+=============================================+ | definition | explanation | @@ -2237,7 +1509,7 @@ Internet-Draft XR Fragments September 2025 -van Kammen Expires 5 March 2026 [Page 40] +van Kammen Expires 23 March 2026 [Page 27] Internet-Draft XR Fragments September 2025 @@ -2293,7 +1565,7 @@ Internet-Draft XR Fragments September 2025 -van Kammen Expires 5 March 2026 [Page 41] +van Kammen Expires 23 March 2026 [Page 28] Internet-Draft XR Fragments September 2025 @@ -2319,7 +1591,7 @@ Internet-Draft XR Fragments September 2025 | | XML | +-----------------+---------------------------------------------+ - Table 15 + Table 8 @@ -2349,4 +1621,4 @@ Internet-Draft XR Fragments September 2025 -van Kammen Expires 5 March 2026 [Page 42] +van Kammen Expires 23 March 2026 [Page 29] diff --git a/doc/RFC_XR_Fragments.xml b/doc/RFC_XR_Fragments.xml index 85325c9..9492de8 100644 --- a/doc/RFC_XR_Fragments.xml +++ b/doc/RFC_XR_Fragments.xml @@ -13,12 +13,12 @@ An open specification for hyperlinking & deeplinking 3D fileformats. This draft is a specification for interactive URI-controllable 3D files, enabling hypermediatic navigation, to enable a spatial web for hypermedia browsers with- or without a network-connection.
      -The specification uses W3C Media Fragments and URI Templates (RFC6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
      - XR Fragments allows us to better use implicit metadata inside 3D scene(files), by mapping it to proven technologies like URI Fragments.
      -XR Fragments views XR experiences thru the lens of 3D object URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.).
      -XR Fragments is a <b>heuristical 3D format</b> which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
      +XR Fragments views XR experiences thru the lens of 3D deeplinked URI's, rather than thru code(frameworks) or protocol-specific browsers (webbrowser e.g.). +The standard comprises of various (optional) support levels, which also include W3C Media Fragments and URI Templates (RFC6570) to promote spatial addressibility, sharing, navigation, filtering and databinding objects for (XR) Browsers.
      +
      +XR Fragments is in a sense, a <b>heuristical 3D format</b> or meta-format, which leverages heuristic rules derived from any 3D scene or well-established 3D file formats, to extract meaningful features from scene hierarchies.
      These heuristics, enable features that are both meaningful and consistent across different scene representations, allowing <b>higher interop</b> between fileformats, 3D editors, viewers and game-engines.
      Almost every idea in this document is demonstrated at https://xrfragment.org @@ -36,7 +36,7 @@ Historically, there's many attempts to create the ultimate 3D fileformat.
      The lowest common denominator is: designers describing/tagging/naming things using plain text.
      XR Fragments exploits the fact that all 3D models already contain such metadata: -XR Fragments allows controlling of metadata in 3D scene(files) using URI's +XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments It solves:
        @@ -49,140 +49,28 @@ XR Fragments exploits the fact that all 3D models already contain such metadata:
        NOTE: The chapters in this document are ordered from highlevel to lowlevel (technical) as much as possible
        -
        Core principle -XR Fragments allows controlling 3D models using URLs, based on (non)existing metadata via URI's -XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.
        - -Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments integrates all which allows a universal viewing experience.
        -
        - - - -Fact: our typical browser URL's are just a possible implementation of URI's (for untapped humancentric potential of URI's see interpeer.io) -
        XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.
        -But approaches things from a higherlevel feedbackloop/hypermedia browser-perspective.
        -
        Below you can see how this translates back into good-old URLs: - - ?other.glb ─> #view ───> hashbus │ - │ │ #filter │ │ - │ │ #tag │ │ - │ │ (hypermediatic) #material │ │ - │ │ ( feedback ) #animation │ │ - │ │ ( loop ) #texture │ │ - │ │ #variable │ │ - │ │ │ │ - │ XRWG <─────────────────────<─────────────+ │ - │ │ │ │ - │ └─ objects ──────────────>─────────────+ │ - │ │ - │ │ - +───────────────────────────────────────────────────────────────────────────────────────────────+ - -]]> - -
        ?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation. -
        Traditional webbrowsers can become 4D document-ready by: -
        - -
        The XR Fragments Trinity +
        What is XR Fragments XR Fragments utilizes URLs:
          -
        1. for 3D viewers/browser to manipulate the camera or objects (via URLbar)
        2. -
        3. as implicit metadata to reference (nested) objects inside 3D scene-file (local and remote)
        4. -
        5. via explicit metadata ('extras') inside 3D scene-files (interaction e.g.) or
        6. -
        7. [optionally for developers] via explicit metadata outside 3D scene-files (via sidecarfile)
        8. +
        9. for 3D viewers/browser to manipulate the camera or objects (via URI fragments)
        10. +
        11. implicitly: by mapping 3D objectnames (of a 3D scene/file) to URI fragments (3D deeplinking)
        12. +
        13. explicitly: by scanning href metadata inside 3D scene-files to enable interactions
        14. +
        15. externally: progressively enhance a 3D (file) into an experience via sidecarfiles
        -
        List of URI Fragments - - - - - - - - - - - - - - - - - - - - - - - - - -
        fragmenttypeexampleinfo
        #......vector3#room1 #room2 #cam2positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector
        Media Fragmentsmedia fragment#t=0,2&loopplay (and loop) 3D animation from 0 seconds till 2 seconds
        - -
        List of *explicit metadata -These are the possible 'extras' for 3D nodes and sidecar-files - - - - - - - - - - - - - - - - - - - - -
        keytypeexample (JSON)functionexisting compatibility
        hrefstring"href": "b.gltf"XR teleportcustom property in 3D fileformats
        -
        HFL (Hypermediatic Feedback Loop) for XR Browsers -href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://#....) or navigate (xrf://#...) - as well (which allows many extra interactions which otherwise need a scripting language). This is known as hashbus-only events (see image above). -
        Being able to use the same URI Fragment DSL for navigation (href: #foo) as well as interactions (href: xrf://#bar) greatly simplifies implementation, increases HFL, and reduces need for scripting languages. +href metadata traditionally implies click AND navigate, however XR Fragments adds stateless click (xrf://....) via the xrf:// scheme, which does not change the top-level URL-adress (of the browser). +This allows for many extra interactions via URLs, which otherwise needs a scripting language. +These are called hashbus-only events/ +
        Being able to use the same URI Fragment DSL for navigation (href: #foo) as well as interactions (href: xrf://#foo) greatly simplifies implementation, increases HFL, and reduces need for scripting languages.
        This opens up the following benefits for traditional & future webbrowsers:
        • hypermediatic loading/clicking 3D assets (gltf/fbx e.g.) natively (with or without using HTML).
        • -
        • allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the xrf:// hashbus (xrf://#person=walk to trigger walk-animation for object person)
        • -
        • collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus
        • +
        • potentially allowing 3D assets/nodes to publish XR Fragments to themselves/eachother using the xrf:// hashbus (xrf://#person=walk to trigger walk-animation for object person)
        • +
        • potentially collapsing the 3D scene to an wordgraph (for essential navigation purposes) controllable thru a hash(tag)bus
        • completely bypassing the security-trap of loading external scripts (by loading 3D model-files, not HTML-javascriptable resources)
        XR Fragments itself are hypermediatic and HTML-agnostic, though pseudo-XR Fragment browsers can be implemented on top of HTML/Javascript. @@ -190,7 +78,7 @@ But approaches things from a higherlevel feedbackloop/hypermedia browser-perspec principle -XR 4D URL +3D URL HTML 2D URL @@ -286,7 +174,7 @@ sub-delims = "," / "=" -room1&rot=0,90,0&cam1 +room1&cam1 combinators @@ -300,7 +188,9 @@ That way, if the link gets shared, the XR Fragments implementation at https:
        Spatial Referencing 3D -XR Fragments assume the following objectname-to-URIFragment mapping: +3D files contain an hierarchy of objects.
        + +XR Fragments assumes the following objectname-to-URI-Fragment mapping, in order to deeplink 3D objects:
      1. href: https://scene.fbx
      2. -
      3. src: https://otherworld.gltf#mainobject
      4. It also allows sourceportation, which basically means the enduser can teleport to the original XR Document of an src embedded object, and see a visible connection to the particular embedded object. Basically an embedded link becoming an outbound link by activating it.
        -
        non-normative -The following below is non-normative heuristics which are not part officially part of the spec. +
        Level0: Files +These are optional auto-loaded side-car files to enable hasslefree XR Movies.
        + +they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.).
        + +
        via href metadata + + + +heuristics: + +
          +
        • if at least one href custom property/extra is found in a 3D scene
        • +
        • The viewer should poll for the above mentioned sidecar-file extensions (and present accordingly)
        • +
        -
        additional explicit metadata -| #rot | vector3 | #rot=0,90,0 | rotates camera to xyz-coord 0.5,0,0 | -| src | string | "src": "#cube" | XR embed / teleport | custom property in 3D fileformats | -| tag | string | "tag": "cubes geo" | tag object (for filter-use / XRWG highlighting) | custom property in 3D fileformats | -| # | string | "#": "#mypreset | trigger default fragment on load | custom property in 3D fileformats | -
        Supported popular compatible 3D fileformats: .gltf, .obj, .fbx, .usdz, .json (THREE.js), .dae and so on. -
        -
        Sidecar-file -
        NOTE: sidecar-files break the portability of XR (Fragments) experiences, therefore side-car files are discouraged for consumer usage/sharing. However, they can accomodate developers or applications who (for whatever reason) must not modify the 3D scene-file (a .glb e.g.). -
        For developers, sidecar-file can allow for defining explicit XR Fragments metadata, outside of the 3D file.
        +
        via chained extension -This can be done via a JSON-pointers RFC6901 in a JSON sidecar-file: + + +
        A fallback-mechanism to turn 3D files into XR Movies without editing them. +
        heuristics: + +
          +
        • the chained-extension heuristic .xrf. should be present in the filename (scene.xrf.glb e.g.)
        • +
        +
        + +
        via subdocuments/xattr +More secure protocols (Nextgraph e.g.) don't allow for simply polling files. +In such case, subdocuments or extended attributes should be polled: +
        NOTE: in the examples below we use the href-heuristic, but also the .xrf. chained-extension applies here. +
        + + +If only extended attributes (xattr) are available, the respective referenced file can be embedded: + + + +
        NOTE: Linux's setfattr/getfattr is xattr on mac, and Set-Content/Get-content on Windows. See pxattr for lowlevel access. +
        + +
        JSON sidecar-file +For developers, sidecar-file can allow for defining explicit XR Fragments links (>level1), outside of the 3D file.
        + +This can be done via (objectname/metadata) key/value-pairs in a JSON sidecar-file:
        • experience.glb
        • -
        • experience.json
        • +
        • experience.json <----
        -
        This would mean: hide object(s) with name or tag-value 'penguin' upon scene-load, and show it when the user clicks the chair +
        This will make object button clickable, and teleport the user to object roomB.
        So after loading experience.glb the existence of experience.json is detected, to apply the explicit metadata.
        The sidecar will define (or override already existing) extras, which can be handy for multi-user platforms (offer 3D scene customization/personalization to users).
        In THREE.js-code this would boil down to:
        -
        +
        -
        Level2: Implicit URI Fragments -
        Warning: non-normative -
        These fragments are derived from objectnames (or their extras) within a 3D scene, and trigger certain actions when evaluated by the browser: +
        Level1: URI +
        XR Fragments allows deeplinking of 3D objects by mapping objectnames to URI fragments +
        XR Fragments tries to seek to connect the world of text (semantical web / RDF), and the world of pixels.
        + +Instead of forcing authors to combine 3D/2D objects programmatically (publishing thru a game-editor e.g.), XR Fragments integrates all which allows a universal viewing experience.
        +
        + + + +Fact: our typical browser URL's are just a possible implementation of URI's (for untapped humancentric potential of URI's see interpeer.io or NextGraph ) +
        XR Fragments does not look at XR (or the web) thru the lens of HTML or URLs.
        +But approaches things from a higherlevel local-first 3D hypermedia browser-perspective.
        +
        Below you can see how this translates back into good-old URLs: + + ?other.glb ─> #object ─> hashbus │ + │ │ #filter │ │ + │ │ #tag │ │ + │ │ (hypermediatic) #material │ │ + │ │ ( feedback ) #animation │ │ + │ │ ( loop ) #texture │ │ + │ │ #variable │ │ + │ │ │ │ + │ XRWG <─────────────────────<─────────────+ │ + │ │ │ │ + │ └─ objects ──────────────>─────────────+ │ + │ │ + │ │ + +───────────────────────────────────────────────────────────────────────────────────────────────+ + +]]> + +
        ?-linked and #-linked navigation are JUST one possible way to implement XR Fragments: the essential goal is to allow a Hypermediatic FeedbackLoop (HFL) between external and internal 4D navigation. +
        + +
        List of URI Fragments - @@ -396,376 +391,274 @@ The sidecar will define (or override already existing) extras, - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +
        fragment type example
        PRESET#<preset>string#cubesevaluates preset (#foo&bar) when a scene contains extra (#cubes: #foo&bar e.g.) while URL-browserbar reflects #cubes. Only works when metadata-key starts with ##......vector3#room1 #room2 #cam2positions/parents camera(rig) (or XR floor) to xyz-coord/object/camera and upvector
        FOCUSxrf://#<tag_or_objectname>string#person(and show) object(s) with tag: person or name person (XRWG lookup)
        FILTERS#[!][-]<tag_or_objectname>[*]string#person (#-person)will reset (!), show/focus or hide (-) focus object(s) with tag: person or name person by looking up XRWG (*=including children)
        MATERIALUPDATE#<tag_or_objectname>[*]=<materialname>string=string#car=metallicsets material of car to material with name metallic (*=including children)
        #soldout*=halfopacityset material of objects tagged with product to material with name metallic
        VARIABLE UPDATE#<variable>=<metadata-key>string=string#foo=barsets URI Template variable foo to the value #t=0 from existing object metadata (bar:#t=0 e.g.), This allows for reactive URI Template defined in object metadata elsewhere (src:://m.com/cat.mp4#{foo} e.g., to play media using media fragment URI). NOTE: metadata-key should not start with #
        ANIMATION#<tag_or_objectname>=<animationname>string=string#people=walk #people=noanimassign a different animation to object(s)Media Fragmentsmedia fragment#t=0,2&loopplay (and loop) 3D animation from 0 seconds till 2 seconds
        -
        media fragments and datatypes -
        Warning: non-normative (below the word 'play' applies to 3D animations embedded in the 3D scene(file) but also media defined in src-metadata like audio/video-files (mp3/mp4 e.g.)) -
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        typesyntaxexampleinfo
        vector2x,y2,3.02-dimensional vector
        vector3x,y,z2,3.0,43-dimensional vector
        temporal W3C media fragmentt=x0play from 0 seconds to end (and stop)
        temporal W3C media fragmentt=x,y0,2play from 0 seconds till 2 seconds (and stop)
        temporal W3C media fragment *s=x1set playback speed of audio/video/3D anim
        temporal W3C media fragment *[-]looploopenable looped playback of audio/video/3D anim
        -loopdisable looped playback (does not affect playbackstate of media)
        vector2uv=u,v,uspeed,vspeed0,0set uv offset instantly (default speed = 1,1)
        +0.5,+0.5scroll instantly by adding 0.5 to the current uv coordinates
        0.2,1,0.1,0.1scroll (lerp) to uv coordinate 0,2,1 with 0.1 units per second
        0,0,0,+0.1scroll v coordinates with 0.1 units per second (infinitely)
        +0.5,+0.5scroll instantly by adding 0.5 to the current uv coordinates
        media parameter (shader uniform)u:<uniform>=<stringfloatvec2
        * = this is extending the W3C media fragments with (missing) playback/viewport-control. Normally #t=0,2 implies setting start/stop-values AND starting playback, whereas #s=0&loop allows pausing a video, speeding up/slowing down media, as well as enabling/disabling looping. -The rationale for uv is that the xywh Media Fragment deals with rectangular media, which does not translate well to 3D models (which use triangular polygons, not rectangular) positioned by uv-coordinates. This also explains the absense of a scale or rotate primitive, which is challenged by this, as well as multiple origins (mesh- or texture). -
        Example URI's: - -
          -
        • https://images.org/credits.jpg#uv=0,0,0,+0.1 (infinite vertical texturescrolling)
        • -
        • https://video.org/organogram.mp4#t=0&loop&uv=0.1,0.1,0.3,0.3 (animated tween towards region in looped video)
        • -
        • https://shaders.org/plasma.glsl#t=0&u:col2=0,1,0 (red-green shader plasma starts playing from time-offset 0)
        • -
        - - NOTE: URI Template variables are immutable and respect scope: in other words, the end-user cannot modify `blue` by entering an URL like `#blue=.....` in the browser URL, and `blue` is not accessible by the plane/media-object (however `{play}` would work). - -]]> - -
        -
        - -
        Navigating 3D +
        List of *explicit metadata +These are the possible 'extras' for 3D nodes and sidecar-files - + - + + + - + - + + + -
        fragmentkey typefunctionalityexample (JSON)functionexisting compatibility
        <b>#</b>=room1href stringposition camera to position and upvector of objectname room1 (+userheight in VR)"href": "b.gltf"XR teleportcustom property in 3D fileformats
        » example implementation
        +
        -» discussion
        - -Here's the basic level1 flow (with optional level2 features): +
        Level2: href links +Explicit href metadata ('extras') in a 3D object (of a 3D file), hint the viewer that the user ''can interact'' with that object : +| fragment | type | example value | +|href| string (uri or predefined view) | #pyramid
        +#lastvisit
        +xrf://#-someobject
        +://somefile.gltf#foo
        + |
        -
          -
        1. the Y-coordinate of `room1 identifies the floorposition. This means that desktop-projections usually need to add 1.5m (average person height) on top (which is done automatically by VR/AR headsets), except in case of camera-switching.
        2. -
        3. set the position of the camera accordingly to the vector3 values of room1
        4. -
        5. set the upvector of the camera accordingly to the vector3 values of room1 (local gravity as pioneered by Patrick Lichty)
        6. -
        7. if the referenced #room1 object is animated, parent the current camera to that object (so it animates too)
        8. -
        9. in case a href does not mention any 3D object, the current position will be assumed
        10. -
        -Here's an ascii representation of a 3D scene-graph which contains 3D objects and their metadata: +
        Interaction behaviour +When clicking an ''href''-value, the user(camera) is teleport to the referenced object. +The imported/teleported destination can be another object in the same scene-file, or a different file. +
        -XR Viewer implementation +| spec | action | feature | +|-|-|-| +| level0+1 | hover 3D file href | show the preview PNG thumbnail (if any). | +| level0+1 | launch 3D file href | replace the current scene with a new 3D file (href: other.glb e.g.) | +| level2 | click internal 3D file href (#roomB e.g.) | teleport the camera to the origin of object(name roomB). See [[teleport camera]].| +| level2 | click external 3D file href (foo.glb e.g.) | replace the current scene with a new 3D file (href: other.glb e.g.) | +| level2 | hover external 3D file href | show the preview PNG thumbnail (if any sidecar, see level0) | +| level2 | click href | hashbus: execute without changing the toplevel URL location (href: xrf://#someObjectName e.g.) | +| level3 | click href | set the global 3D animation timeline to its Media Fragment value (#t=2,3 e.g.) | +
        NOTE: hashbus links (xrf://#foo&bar) don't change the toplevel URL, which makes it ideal for interactions (in contrast to typical #roomC navigation, which benefit back/forward browser-buttons), see <a href="#hashbus">hashbus</a> for more info. +
        +
        + +
        Level3: Media Fragments +
        these allow for XR Movies with a controllable timeline using href URI's with Media Fragments +
        Just like with 2D media-files, W3C mediafragments (#t=1,2) can be used to control a timeline via the #t primitive. +XR Fragments Level3 makes the 3D timeline, as well as URL-referenced files controllable via Media Fragments like: + +
          +
        • level2 hrefs (href: #t=4 e.g. to control 3D timeline)
        • +
        • level4: xrf: URI scheme: + +
            +
          • href: xrf:foo.wav#t=0 to play a wav
          • +
          • href: xrf:news.glb?clone#t=0 to instance and play another experience
          • +
        • +
        + +
        Animation(s) timeline +controls the animation(s) of the scene (or src resource which contains a timeline) +| fragment | type | functionality | +| <b>#t</b>=start,stop | [vector2] | start,stop (in seconds | +| Example Value | Explanation | +| #t=1 | play (3D) animations from 1 seconds till end (and stop) | +| #t=1,100 | play (3D) animations from 1 till 100 seconds (and stop) | +| #t=0,0 | stop (3D) animations at frame 0 | +
        Use [[#s 🌱]] to control playback speed +
        + +
        Specify playback loopmode +This compensates a missing element from Media Fragments to enable/disable temporal looping. . +| fragment | type | functionality | +| <b>#loop</b> | string | enables animation/video/audio loop | +| <b>#-loop</b> | string | disables animation/video/audio loop | +
        + +
        Controlling embedded content +use [[URI Templates]] to control embedded media, for example a simple video-player: + + -An XR Fragment-compatible browser viewing this scene, allows the end-user to interact with the buttonA and buttonB.
        +
        +
        -In case of buttonA the end-user will be teleported to another location and time in the current loaded scene, but buttonB will replace the current scene with a new one, like other.fbx, and assume camera coordinate 0,0,0 -Non-normative: +
        Level4: prefix operators +Prefixing objectnames with the following simple operators allow for extremely powerful XR interactions: -
          -
        1. rot sets the rotation of the camera (only for non-VR/AR headsets, however a camera-value overrules this)
        2. -
        3. level2: mediafragment t in the top-URL sets the playbackspeed and animation-range of the global scene animation
        4. -
        5. before scene load: the scene is cleared
        6. -
        7. level2: after scene load: in case the scene (rootnode) contains an # default view with a fragment value: execute non-positional fragments via the hashbus (no top-level URL change)
        8. -
        9. level2: after scene load: in case the scene (rootnode) contains an # default view with a fragment value: execute positional fragment via the hashbus + update top-level URL
        10. -
        11. level2: in case of no default # view on the scene (rootnode), default player(rig) position 0,0,0 is assumed.
        12. +
            +
          • #!
          • +
          • #*
          • +
          • #+ or #-
          • +
          • #|
          • +
          • xrf: URI scheme
          • +
          +
          Examples: #+menu to show a object, #-menu to hide a menu, #!menu to teleport a menu, #*block to clone a grabbable block, #|object to share an object +
          +
          Object teleports (!) +Prefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.
          +
          +[img[objecteleport.png]] +Usecases: +* show/hide objects/buttons (menu e.g.) in front of user +* embed remote (object within) 3D file via remote URL +* instance an interactive object near the user regardless of location +* instance HUD or semi-transparent-textured-sphere (LUT) around the user +<div class="border padding" style="border:4px solid #888"> + <span class="big hi1">#!menu</span> +</div> +
          +
          +Clicking the href-value above will: + +
            +
          1. reposition the referenced object (menu) to the usercamera's-coordinates.
          2. +
          3. zoom in case of (non-empty) mesh-object: rescale to 1 m³, and position 1m in front of the camera
          4. +
          5. toggle behaviour: revert values if 1/2 were already applied
          6. +
          7. #+ is always implied (objects are always made visible)
          +This tiny but powerful symbol allows incredible interactive possibilities, by carefully positioning re-usable objects outside of a scene (below the usercamera's floor e.g.). + +
            +
          • href: #whiteroom&!explainer&!exitmenu
          • +
          +
          This will teleport the user to whiteroom and moves object explainer and exitmenu in front of the user. +
          +
            +
          • href: `https://my.org/foo.glb#!
          • +
          +Clicking the href-value above will: + +
            +
          1. import foo.glb from my.org's webserver
          2. +
          3. show it in front of the user (because #! indicates object teleport)
          4. +
          + +
            +
          • href: https://foo.glb#roomB&!bar
          • +
          +Clicking the href-value above will: + +
            +
          1. replace the current scene with foo.glb
          2. +
          3. teleport the user to #roomB inside foo.glb
          4. +
          5. instance the referenced object (bar inside foo.glb) in front of the user.
          6. +
          7. it will update the top-Level URL (because xrf: was not used)
          8. +
          9. hide the instanced object when clicked again (toggle visibility)
          10. +
          +
          NOTE: level2 teleportation links, as well as instancing mitigates the 'broken embedded image'-issue of HTML: always attaching the href-values to a 3D (preview) object (that way broken links will not break the design). +
          Example: clicking a 3D button with title 'menu' and href-value xrf:menu.glb?instance#t=4,5 would instance a 3D menu (menu.glb) in front of the user, and loop its animation between from 4-5 seconds (t=4,5) +
          NOTE: combining instance-operators allows dynamic construction of 3D scenes (#london&!welcomeMenu&!fadeBox e.g.) +
          + +
          Object multipliers (*) +The star-prefix will clone a (local or remote) referenced object to the usercamera's location, and make it grabbable.
          + +Usecases: +* object-picker (build stuff with objects)
          +
          NOTE: this is basically the #! operator which infinitely clones the referenced object (instead of repositioning the object). +
          + +
          De/selectors (+ and -) + +
            +
          • href: #-welcome (or #+welcome)
          • +
          +Clicking href-value above will do: + +
            +
          1. show/hide the target object (and children)
          2. +
          + +
            +
          • href: #https://my.org/foo.glb/#bar&-welcome
          • +
          +
          NOTE: the latter shows that (de)selectors can also be with regular href-values +
          + +
          Sharing object or file (#|) +The pipe-symbol (|) sends a (targeted) object to the OS. +Clicking the href-value below will: + +
            +
          1. share the (targeted object in the) file to a another application
          2. +
          +
          This URL can be fed straight into Web Share API or xdg-open +
          +
            +
          • href: xrf://#|bar
          • +
          +
          NOTE: sharing is limited to (internal objects) via xrf: scheme-only +
          + +
          xrf:// URI scheme +Prefixing the xrf: to href-values will prevent level2 href-values from changing the top-Level URL. +
          Usecase: for non-shareable URLs like href: xrf:#t=4,5, to display a stateful msg e.g.). +
          Reason: XR Fragments is inspired by HTML's href-attribute, which does various things: + +
            +
          1. it updates the browser-location
          2. +
          3. it makes something clickable
          4. +
          5. it jumps to another document / elsewhere in the same document
          6. +
          7. and more
          8. +
          +The xrf: scheme will just do 2 & 3 (so the URL-values will not leak into the top-level URL). +
          compliance with RFC 3986: unimplemented/unknown URI schemes (xrf:... e.g.) will not update the top-level URL +
        Top-level URL processing -
        Example URL: ://foo/world.gltf#room1&t=10 +
        Example URL: ://foo/world.gltf#room1&t=10&cam
        The URL-processing-flow for hypermedia browsers goes like this:
          -
        1. IF a #room1 matches a custom property-key (of an object) in the 3D file/scene (#room1: #......) <b>THEN</b> execute that predefined_view.
        2. IF scene operators and/or animation operator (t) are present in the URL then (re)position the camera (to room1) and/or animation-range (10) accordingly.
        3. IF no camera-position has been set in <b>step 1 or 2</b> assume 0,0,0 as camera coordinate (XR: add user-height) (example)
        4. +
        5. IF a camera-object exists with name cam assume that user(camera) position
        -Non-normative / Deprecated: -
          -
        1. IF a #cube matches the name (of an object) in the 3D file/scene then draw a line from the enduser('s heart) to that object (to highlight it).
        2. -
        3. IF a #cube matches anything else in the XR Word Graph (XRWG) draw wires to them (text or related objects).
        4. -
        -
        - -
        Embedding XR content using src -
        NOTE: only adviced for local-first experiences (where resources can be cached). -
        src is the 3D version of the <a target="_blank" href="https://www.w3.org/html/wiki/Elements/iframe">iframe</a>.
        - -It instances content (in objects) in the current scene/asset, and follows similar logic like the previous chapter, except that it does not modify the camera.
        - - - - - - - - - - - - - - - - -
        fragmenttypeexample value
        srcstring (uri, hashtag/filter)#cube
        -#sometag
        -#cube&-ball_inside_cube<br>#-sky&-rain<br>#-language&english<br>#price=>5<br>https://linux.org/penguin.png`
        -https://linux.world/distrowatch.gltf#t=1,100
        -linuxapp://conference/nixworkshop/apply.gltf#-cta&cta_apply
        -androidapp://page1?tutorial#room1&t1,100
        -foo.mp3#0,0,0
        Here's an ascii representation of a 3D scene-graph with 3D objects which embeds remote & local 3D objects with/out using filters: - - - -An XR Fragment-compatible browser viewing this scene, lazy-loads and projects painting.png onto the (plane) object called canvas (which is copy-instanced in the bed and livingroom).
        - -Also, after lazy-loading ocean.com/aquarium.gltf, only the queried objects fishbowl (and bass and tuna) will be instanced inside aquariumcube.
        - -Resizing will be happen accordingly to its placeholder object aquariumcube, see chapter Scaling.
        -
        -
        Instead of cherrypicking a rootobject #fishbowl with src, additional filters can be used to include/exclude certain objects. See next chapter on filtering below. -
        Specification: +
        UX +End-users should always have read/write access to:
          -
        1. local/remote content is instanced by the src (filter) value (and attaches it to the placeholder mesh containing the src property)
        2. -
        3. by default all objects are loaded into the instanced src (scene) object (but not shown yet)
        4. -
        5. <b>local</b> src values (#... e.g.) starting with a non-negating filter (#cube e.g.) will (deep)reparent that object (with name cube) as the new root of the scene at position 0,0,0
        6. -
        7. <b>local</b> src values should respect (negative) filters (#-foo&price=>3)
        8. -
        9. the instanced scene (from a src value) should be <b>scaled accordingly</b> to its placeholder object or <b>scaled relatively</b> based on the scale-property (of a geometry-less placeholder, an 'empty'-object in blender e.g.). For more info see Chapter Scaling.
        10. -
        11. <b>external</b> src values should be served with appropriate mimetype (so the XR Fragment-compatible browser will now how to render it). The bare minimum supported mimetypes are:
        12. -
        13. src values should make its placeholder object invisible, and only flush its children when the resolved content can succesfully be retrieved (see broken links)
        14. -
        15. <b>external</b> src values should respect the fallback link mechanism (see broken links
        16. -
        17. when the placeholder object is a 2D plane, but the mimetype is 3D, then render the spatial content on that plane via a stencil buffer.
        18. -
        19. src-values are non-recursive: when linking to an external object (src: foo.fbx#bar), then src-metadata on object bar should be ignored.
        20. -
        21. an external src-value should always allow a sourceportation icon within 3 meter: teleporting to the origin URI to which the object belongs.
        22. -
        23. when only one object was cherrypicked (#cube e.g.), set its position to 0,0,0
        24. -
        25. when the enduser clicks an href with #t=1,0,0 (play) will be applied to all src mediacontent with a timeline (mp4/mp3 e.g.)
        26. -
        27. a non-euclidian portal can be rendered for flat 3D objects (using stencil buffer e.g.) in case ofspatial src-values (an object #world3 or URL world3.fbx e.g.).
        28. +
        29. the current (toplevel) <b>URL</b> (an URLbar etc)
        30. +
        31. URL-history (a <b>back/forward</b> button e.g.)
        32. +
        33. Clicking/Touching an href navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).
        - -
          -
        • model/gltf-binary
        • -
        • model/gltf+json
        • -
        • image/png
        • -
        • image/jpg
        • -
        • text/plain;charset=utf-8
        • -
        -» example implementation
        - -» example 3D asset
        - -» discussion
        -
        +
        -
        Navigating content href portals +
        Example: Navigating content href portals navigation, portals & mutations @@ -781,14 +674,14 @@ Resizing will be happen accordingly to its placeholder object aquariumcubehref
        string (uri or predefined view) #room1
        -#room1&rot=90,0,0
        +#room1
        ://somefile.gltf#room1
          -
        1. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes room2&rot=0,0,0 by default (unless specified) +
        2. clicking an outbound ''external''- or ''file URI'' fully replaces the current scene and assumes room2 by default (unless specified)
        3. relocation/reorientation should happen locally for local URI's (#....)
        4. @@ -815,457 +708,38 @@ Resizing will be happen accordingly to its placeholder object aquariumcube
          Walking surfaces -XR Fragment-compatible viewers can infer this data based scanning the scene for: +
          By default position 0,0,0 of the 3D scene represents the walkable plane, however this is overridden when the following applies: +
          XR Fragment-compatible viewers can infer this data based scanning the scene for:
            -
          1. materialless (nameless & textureless) mesh-objects (without src and href)
          2. +
          3. materialless (nameless & textureless) mesh-objects (without href and >0 faces)
          optionally the viewer can offer thumbstick, mouse or joystick teleport-tools for non-roomscale VR/AR setups.
          - -
          UX spec -End-users should always have read/write access to: - -
            -
          1. the current (toplevel) <b>URL</b> (an URLbar etc)
          2. -
          3. URL-history (a <b>back/forward</b> button e.g.)
          4. -
          5. Clicking/Touching an href navigates (and updates the URL) to another scene/file (and coordinate e.g. in case the URL contains XR Fragments).
          6. -
          -
          Scaling instanced content -Sometimes embedded properties (like src) instance new objects.
          - -But what about their scale?
          - -How does the scale of the object (with the embedded properties) impact the scale of the referenced content?
          -
          -
          Rule of thumb: visible placeholder objects act as a '3D canvas' for the referenced scene (a plane acts like a 2D canvas for images e, a cube as a 3D canvas e.g.). -
          -
            -
          1. <b>IF</b> an embedded property (src e.g.) is set on an non-empty placeholder object (geometry of >2 vertices):
          2. -
          - -
            -
          • calculate the <b>bounding box</b> of the ''placeholder'' object (maxsize=1.4 e.g.)
          • -
          • hide the ''placeholder'' object (material e.g.)
          • -
          • instance the src scene as a child of the existing object
          • -
          • calculate the <b>bounding box</b> of the instanced scene, and scale it accordingly (to 1.4 e.g.)
          • -
          -
          REASON: non-empty placeholder object can act as a protective bounding-box (for remote content of which might grow over time e.g.) -
          -
            -
          1. ELSE multiply the scale-vector of the instanced scene with the scale-vector (a common property of a 3D node) of the <b>placeholder</b> object.
          2. -
          -
          TODO: needs intermediate visuals to make things more obvious -
          -
        - -
        XR Fragment: pos -[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]
        -
        -
        - -
        XR Fragment: rot -[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/pos.js]]
        -
        -
        - -
        XR Fragment: t -[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/t.js]]
        -
        -
        - -
        XR audio/video integration -To play global audio/video items: - -
          -
        1. add a src: foo.mp3 or src: bar.mp4 metadata to a 3D object (cube e.g.)
        2. -
        3. to enable auto-play and global timeline ([[#t=|t]]) control: hardcode a [[#t=|t]] XR Fragment: (src: bar.mp3#t=0&loop e.g.)
        4. -
        5. to play it, add href: #cube somewhere else
        6. -
        7. to enable enduser-triggered play, use a [[URI Template]] XR Fragment: (src: bar.mp3#{player} and play: t=0&loop and href: xrf://#player=play e.g.)
        8. -
        9. when the enduser clicks the href, #t=0&loop (play) will be applied to the src value
        10. -
        -
        NOTE: hardcoded framestart/framestop uses sampleRate/fps of embedded audio/video, otherwise the global fps applies. For more info see [[#t|t]]. -
        - -
        XR Fragment filters -Include, exclude, hide/shows objects using space-separated strings: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        exampleoutcome
        #-skyshow everything except object named sky
        #-language&englishhide everything with tag language, but show all tag english objects
        #-price&price=>10hide all objects with property price, then only show object with price above 10
        #-house*hide house object and everything inside (=*)
        It's simple but powerful syntax which allows filtering the scene using searchengine prompt-style feeling: - -
          -
        1. filters are a way to traverse a scene, and filter objects based on their name, tag- or property-values.
        2. -
        - -
          -
        • see an (outdated) example video here which used a dedicated q= variable (now deprecated and usable directly)
        • -
        - -
        including/excluding -By default, selectors work like photoshop-layers: they scan for matching layer(name/properties) within the scene-graph. -Each matched object (not their children) will be toggled (in)visible when selecting. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        operatorinfo
        -hides object(s) (#-myobject&-objects e.g.
        =indicates an object-embedded custom property key/value (#price=4&category=foo e.g.)
        => =<compare float or int number (#price=>4 e.g.)
        *deepselect: automatically select children of selected object, including local (nonremote) embedded objects (starting with #)
        NOTE 1: after an external embedded object has been instanced (src: https://y.com/bar.fbx#room e.g.), filters do not affect them anymore (reason: local tag/name collisions can be mitigated easily, but not in case of remote content). -NOTE 2: depending on the used 3D framework, toggling objects (in)visible should happen by enabling/disableing writing to the colorbuffer (to allow children being still visible while their parents are invisible). -
        » example implementation -» example 3D asset -» discussion -
        - -
        Filter Parser -Here's how to write a filter parser: - -
          -
        1. create an associative array/object to store filter-arguments as objects
        2. -
        3. detect object id's & properties foo=1 and foo (reference regex= ~/^.*=[><=]?/ )
        4. -
        5. detect excluders like -foo,-foo=1,-.foo,-/foo (reference regex= /^-/ )
        6. -
        7. detect root selectors like /foo (reference regex= /^[-]?\// )
        8. -
        9. detect number values like foo=1 (reference regex= /^[0-9\.]+$/ )
        10. -
        11. detect operators so you can easily strip keys (reference regex= /(^-|\*$)/ )
        12. -
        13. detect exclude keys like -foo (reference regex= /^-/ )
        14. -
        15. for every filter token split string on =
        16. -
        17. and we set root to true or false (true=/ root selector is present)
        18. -
        19. therefore we we set show to true or false (false=excluder -)
        20. -
        -
        An example filter-parser (which compiles to many languages) can be found here -
        -
        - -
        Visible links -When predefined views, XRWG fragments and ID fragments (#cube or #mytag e.g.) are triggered by the enduser (via toplevel URL or clicking href): - -
          -
        1. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) matching that ID (objectname)
        2. -
        3. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) matching that tag value
        4. -
        5. draw a wire from the enduser (preferabbly a bit below the camera, heartposition) to object(s) containing that in their src or href value
        6. -
        -The obvious approach for this, is to consult the XRWG (example), which basically has all these things already collected/organized for you during scene-load. -UX - -
          -
        1. do not update the wires when the enduser moves, leave them as is
        2. -
        3. offer a control near the back/forward button which allows the user to (turn off) control the correlation-intensity of the XRWG
        4. -
        -
        - -
        Text in XR (tagging,linking to spatial objects) -How does XR Fragments interlink text with objects? -
        The XR Fragments does this by collapsing space into a Word Graph (the XRWG example), augmented by Bib(s)Tex. -
        Instead of just throwing together all kinds media types into one experience (games), what about their tagged/semantical relationships?
        - -Perhaps the following question is related: why is HTML adopted less in games outside the browser?
        -Hence: - -
          -
        1. XR Fragments promotes (de)serializing a scene to a (lowercase) XRWG (example)
        2. -
        3. XR Fragments primes the XRWG, by collecting words from the tag and name-property of 3D objects.
        4. -
        5. XR Fragments primes the XRWG, by collecting words from optional metadata at the end of content of text (see default mimetype & Data URI)
        6. -
        7. XR Fragments primes the XRWG, by collecting tags/id's from linked hypermedia (URI fragments for HTML e.g.)
        8. -
        9. The XRWG should be recalculated when textvalues (in src) change
        10. -
        11. HTML/RDF/JSON is still great, but is beyond the XRWG-scope (they fit better in the application-layer, or as embedded src content)
        12. -
        13. Applications don't have to be able to access the XRWG programmatically, as they can easily generate one themselves by traversing the scene-nodes.
        14. -
        15. The XR Fragment focuses on fast and easy-to-generate end-user controllable word graphs (instead of complex implementations that try to defeat word ambiguity)
        16. -
        17. Instead of exact lowercase word-matching, levensteihn-distance-based matching is preferred
        18. -
        -Example of generating XRWG out of the XRWG and textdata with hashtags: - - - -This allows hasslefree authoring and copy-paste of associations for and by humans, but also makes these URLs possible: - - - - - - - - - - - - - - - - - - - - - - - - -
        URL exampleResult
        https://my.com/foo.gltf#baroquedraws lines between 3D mesh castle, and mydoc's text baroque
        https://my.com/foo.gltf#johndraws lines between mesh john, and the text John of mydoc
        https://my.com/foo.gltf#housedraws lines between mesh castle, and other objects with tag house or todo
        the URI fragment #john&mydoc&house would draw a connection between these 3 meshes. -
        The XRWG allows endusers to show/hide relationships in realtime in XR Browsers at various levels: - -
          -
        • wordmatch inside src text
        • -
        • wordmatch inside href text
        • -
        • wordmatch object-names
        • -
        • wordmatch object-tagnames
        • -
        -Spatial wires can be rendered between words/objects etc.
        - -Some pointers for good UX (but not necessary to be XR Fragment compatible):
        - -
          -
        1. The XR Browser needs to adjust tag-scope based on the endusers needs/focus (infinite tagging only makes sense when environment is scaled down significantly)
        2. -
        3. The XR Browser should always allow the human to view/edit the metadata, by clicking 'toggle metadata' on the 'back' (contextmenu e.g.) of any XR text, anywhere anytime.
        4. -
        5. respect multi-line BiBTeX metadata in text because of the core principle
        6. -
        7. Default font (unless specified otherwise) is a modern monospace font, for maximized tabular expressiveness (see the core principle).
        8. -
        9. anti-pattern: hardcoupling an XR Browser with a mandatory markup/scripting-language which departs from onubtrusive plain text (HTML/VRML/Javascript) (see the core principle)
        10. -
        11. anti-pattern: limiting human introspection, by abandoning plain text as first tag citizen.
        12. -
        - -
        Default Data URI mimetype -The src-values work as expected (respecting mime-types), however: -The XR Fragment specification advices to bump the traditional default browser-mimetype -text/plain;charset=US-ASCII -to a hashtag-friendly one: -text/plain;charset=utf-8;hashtag -This indicates that: - -
          -
        • utf-8 is supported by default
        • -
        • words beginning with # (hashtags) will prime the XRWG by adding the hashtag to the XRWG, linking to the current sentence/paragraph/alltext (depending on '.') to the XRWG
        • -
        -Advantages: - -
          -
        • out-of-the-box (de)multiplex human text and metadata in one go (see the core principle)
        • -
        • no network-overhead for metadata (see the core principle)
        • -
        • ensuring high FPS: realtime HTML/RDF historically is too 'requesty'/'parsy' for game studios
        • -
        • rich send/receive/copy-paste everywhere by default, metadata being retained (see the core principle)
        • -
        • netto result: less webservices, therefore less servers, and overall better FPS in XR
        • -
        -
        This significantly expands expressiveness and portability of human tagged text, by postponing machine-concerns to the end of the human text in contrast to literal interweaving of content and markupsymbols (or extra network requests, webservices e.g.). -
        For all other purposes, regular mimetypes can be used (but are not required by the spec).
        -
        -
        - -
        URL and Data URI - - - -The enduser will only see welcome human and Hello friends rendered verbatim (see mimetype). -The beauty is that text in Data URI automatically promotes rich copy-paste (retaining metadata). -In both cases, the text gets rendered immediately (onto a plane geometry, hence the name '_canvas'). -The XR Fragment-compatible browser can let the enduser access visual-meta(data)-fields after interacting with the object (contextmenu e.g.). -
        additional tagging using bibs: to tag spatial object note_canvas with 'todo', the enduser can type or speak #note_canvas@todo -
        -
        - -
        Importing/exporting -For usecases like importing/exporting/p2p casting a scene, the issue of external files comes into play. - -
          -
        1. export: if the 3D scene contains relative src/href values, rewrite them into absolute URL values.
        2. -
        -
        - -
        Reflection Mapping -Environment mapping is crucial for creating realistic reflections and lighting effects on 3D objects. -To apply environment mapping efficiently in a 3D scene, traverse the scene graph and assign each object's environment map based on the nearest ancestor's texture map. This ensures that objects inherit the correct environment mapping from their closest parent with a texture, enhancing the visual consistency and realism. - - - -Most 3D viewers apply one and the same environment map for various models, however this logic -allows a more natural & automatic strategy for reflection mapping: - -
          -
        1. traverse the scene graph depth-first
        2. -
        3. remember the most recent parentnode (P) with a texture material
        4. -
        5. for every non-root node with a texture material -3.1 clone that material (as materials might be shared across objects) -3.2 set the environmentmap to the last known parent texture (P)
        6. -
        -
        - -
        Transclusion (broken link) resolution -In spirit of Ted Nelson's 'transclusion resolution', there's a soft-mechanism to harden links & minimize broken links in various ways: - -
          -
        1. defining a different transport protocol (https vs ipfs or DAT) in src or href values can make a difference
        2. -
        3. mirroring files on another protocol using (HTTP) errorcode tags in src or href properties
        4. -
        5. in case of src: nesting a copy of the embedded object in the placeholder object (embeddedObject) will not be replaced when the request fails
        6. -
        -
        due to the popularity, maturity and extensiveness of HTTP codes for client/server communication, non-HTTP protocols easily map to HTTP codes (ipfs ERR_NOT_FOUND maps to 404 e.g.) -
        For example: - - - -
        - -
        Topic-based index-less Webrings -As hashtags in URLs map to the XWRG, href-values can be used to promote topic-based index-less webrings.
        - -Consider 3D scenes linking to eachother using these href values:
        +
        Virtual world rings +Consider 3D scenes linking to eachother using these href values, attached to 3D button-objects:
        • href: schoolA.edu/projects.gltf#math
        • href: schoolB.edu/projects.gltf#math
        • href: university.edu/projects.gltf#math
        -These links would all show visible links to math-tagged objects in the scene.
        +This would teleport users to the math-projects of those universities.
        -To filter out non-related objects one could take it a step further using filters:
        +Now consider adding a 'webring index'-button to each file, with this href-value:
          -
        • href: schoolA.edu/projects.gltf#math&-topics math
        • -
        • href: schoolB.edu/projects.gltf#math&-courses math
        • -
        • href: university.edu/projects.gltf#math&-theme math
        • +
        • href: workgroup.edu/webrings.glb#!webringmenu
        -
        This would hide all object tagged with topic, courses or theme (including math) so that later only objects tagged with math will be visible -
        This makes spatial content multi-purpose, without the need to separate content into separate files, or show/hide things using a complex logiclayer like javascript. +This would allow displaying the (remote 3D file) webring menu with various href-buttons inside, all centrally curated by the workgroup.
        -
        URI Templates (RFC6570) +
        Level5: URI Templates (RFC6570) XR Fragments adopts Level1 URI Fragment expansion to provide safe interactivity.
        -The following demonstrates a simple video player:
        - - - +This is non-normative, and the draft spec is available on request.
        Additional scene metadata @@ -1275,8 +749,10 @@ Instead, it encourages browsers to scan nodes for the following custom propertie
        • SPDX license information
        • ARIA attributes (aria-*: .....)
        • +
        • datapackage.json findability, accessibility, interoperability, and reusability of data
        -
        SPDX and ARIA's aria-description are normative, as they promote accessibility and scene transcripts: please start aria-description with a verb to aid transcripts. +ARIA's aria-description-metadata is normative, to aid accessibility and scene transcripts +
        NOTE: please always start aria-description with a verb to aid transcripts.
        The following metadata are non-normative but encouraged, since they are popular and cheap to parse:
          diff --git a/index.html b/index.html index d59916b..8d8f262 100644 --- a/index.html +++ b/index.html @@ -48,7 +48,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." /> XR Fragments — -A tiny specification for controlling any 3D model using URLs +A cute standard for (deep)linking 3D files via URI's. @@ -832,7 +832,7 @@ button.sidebar-toggle{ <li>Edit a 3D scene file</li> -<li>embed a 3D object (subtree)</li> +<li>embed a 3D object</li> <li>EU keeps/stops funding FOSS?</li> @@ -1005,7 +1005,7 @@ button.sidebar-toggle{ <script class="tiddlywiki-tiddler-store" type="application/json">[ {"created":"20240131104509452","text":"Create an empty mesh object (in Blender it's called an 'Empty') and add an [[src]] custom property with an OGG/MP3/WAV URL. For example:\n\u003Cbr>\u003Cbr>\n`src` : `https://foo.com/podcast.mp3`\n\u003Cbr>\u003Cbr>\n1. ''IF'' the empty is positioned at 0,0,0 the audio is nonpositional (like music e.g.)\u003Cbr>\u003Cbr>\n2. ''IF'' the empty is ''not'' positioned at 0,0,0, then it'll be positional audio\u003Cbr>\u003Cbr>\n3. the ''scale'' of the audio object will determine the amplitude/reach of the positional audio.\u003Cbr>\u003Cbr>\n\u003Cbr>\n\n> NOTE: audio does not play unless [[#t|`#t=1`]] triggers it. For auto-play try adding `#t=1` to the default fragment `#` on the scene ([[see this video|https://coderofsalvation.codeberg.page/xrfragment.media/gettingstarted2024.mp4#t=358]])","tags":"[[🧪 experimental]]","title":"(non)positional audio","modified":"20250910094156257"}, {"created":"20240208125917539","text":"`#` indicates a default fragment to execute during scene-load.\n\n| fragment | type | example value | info |\n|`#`| string (& separated) | `#-cube&t=0` | hide object with name `cube` and start 3D animations (implies `xrf://-cube&t=0`)|\n\n> NOTE: this only gets publish to the [[hashbus]] and does not update the top-Level URL\n\n[[» discussion|https://github.com/coderofsalvation/xrfragment/issues/12]]\u003Cbr>\n","tags":"[[🧪 levelX: non-normative metadata]]","title":"# aliases","modified":"20250910095330316","type":"text/vnd.tiddlywiki"}, -{"created":"20250910085517140","text":"# Object teleports\n\nPrefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.\u003Cbr>\n\n[img[objecteleport.png]]\n\nUsecases:\n* show/hide objects/buttons (menu e.g.)\n* instance an interactive object near the user regardless of location\n* instance HUD or semi-transparent-textured-sphere (LUT) around the user \n\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#!menu\u003C/span>\n\u003C/div>\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#whiteroom&!explainer&!exitmenu\u003C/span>\n\u003C/div>\n\u003Cbr>\n\nClicking the [[href]]-value above will:\n\n1. **reposition the referenced object** (menu) to the usercamera's-coordinates.\n2. **zoom** in case of mesh-object: rescale to 1 m³, and position 1m in front of the camera\n3. toggle behaviour: revert values if 1/2 were already applied\n4. `#+` is always implied (objects are always made visible)\n\nThis tiny but powerful symbol allows incredible interactive possibilities, by carefully positioning re-usable objects outside of a scene (below the floow e.g.).\n\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">https://foo.glb\u003C/span>\n\t\u003Cspan class=\"big hi2\">#roomB&!bar\u003C/span>\n\u003C/div>\n\u003Cbr>\n\nClicking the [[href]]-value above will:\n\n1. replace the current scene with `foo.glb` \n2. teleport the user to #roomB inside `foo.glb`\n3. **instance the referenced object** (bar inside foo.glb) in front of the user.\n4. it will update the top-Level URL (because `xrf:` was not used)\n5. hide the **instanced object** when clicked again (toggle visibility)\n\n> **NOTE**: [level2](#📜%20level2:%20explicit%20links) [teleportation](#teleport%20camera) links, as well as instancing mitigates the 'broken embedded image'-issue of HTML: **always** attaching the href-values to **a 3D (preview) object** (that way broken links will not break the design).\n\n**Example:** clicking a 3D button with title 'menu' and [href](#href)-value `xrf:menu.glb?instance#t=4,5` would instance a 3D menu (`menu.glb`) in front of the user, and loop its animation between from 4-5 seconds (`t=4,5`)\n\n> **NOTE**: combining instance-operators allows dynamic construction of 3D scenes (`#london&!welcomeMenu&!fadeBox` e.g.) \n","tags":"[[📜 level4: prefix operators]] level4","title":"#!","modified":"20250910100220304","type":"text/markdown"}, +{"created":"20250910085517140","text":"# Object teleports\n\nPrefixing an object with an exclamation-symbol, will teleport a (local or remote) referenced object from/to its original/usercamera location.\u003Cbr>\n\n[img[objecteleport.png]]\n\nUsecases:\n* show/hide objects/buttons (menu e.g.) in front of user\n* embed remote (object within) 3D file via remote URL\n* instance an interactive object near the user regardless of location\n* instance HUD or semi-transparent-textured-sphere (LUT) around the user \n\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#!menu\u003C/span>\n\u003C/div>\n\u003Cbr>\n\nClicking the [[href]]-value above will:\n\n1. **reposition the referenced object** (menu) to the usercamera's-coordinates.\n2. **zoom** in case of (non-empty) mesh-object: rescale to 1 m³, and position 1m in front of the camera\n3. toggle behaviour: revert values if 1/2 were already applied\n4. `#+` is always implied (objects are always made visible)\n\nThis tiny but powerful symbol allows incredible interactive possibilities, by carefully positioning re-usable objects outside of a scene (below the floow e.g.).\n\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#whiteroom&!explainer&!exitmenu\u003C/span>\n\u003C/div>\n\u003Cbr>\n\nThis will teleport the user to `whiteroom` and moves object `explainer` and `exitmenu` in front of the user.\n\u003Cbr>\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">https://my.org/foo.glb\u003C/span>\n\t\u003Cspan class=\"big hi2\">#!\u003C/span>\n\u003C/div>\n\u003Cbr>\n\nClicking the [[href]]-value above will:\n\n1. import `foo.glb` from `my.org`'s webserver\n2. show it in front of the user (because `#!` indicates object teleport)\n\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">https://foo.glb\u003C/span>\n\t\u003Cspan class=\"big hi2\">#roomB&!bar\u003C/span>\n\u003C/div>\n\nClicking the [[href]]-value above will:\n\n1. replace the current scene with `foo.glb` \n2. teleport the user to #roomB inside `foo.glb`\n3. **instance the referenced object** (bar inside foo.glb) in front of the user.\n4. it will update the top-Level URL (because `xrf:` was not used)\n5. hide the **instanced object** when clicked again (toggle visibility)\n\n> **NOTE**: [level2](#📜%20level2:%20explicit%20links) [teleportation](#teleport%20camera) links, as well as instancing mitigates the 'broken embedded image'-issue of HTML: **always** attaching the href-values to **a 3D (preview) object** (that way broken links will not break the design).\n\n**Example:** clicking a 3D button with title 'menu' and [href](#href)-value `xrf:menu.glb?instance#t=4,5` would instance a 3D menu (`menu.glb`) in front of the user, and loop its animation between from 4-5 seconds (`t=4,5`)\n\n> **NOTE**: combining instance-operators allows dynamic construction of 3D scenes (`#london&!welcomeMenu&!fadeBox` e.g.) \n","tags":"[[📜 level4: prefix operators]] level4","title":"#!","modified":"20250919160537225","type":"text/markdown"}, {"created":"20250910091840302","text":"# Object multipliers\n\nThe star-prefix will clone a (local or remote) referenced object to the usercamera's location, and make it grabbable.\u003Cbr>\nUsecases:\n* object-picker (build stuff with objects)\n\n> **NOTE**: this is basically the [#! operator](#%23%21) which infinitely **clones** the referenced object (instead of repositioning the object).","tags":"[[📜 level4: prefix operators]] level4","title":"#*","modified":"20250910100220324","type":"text/markdown"}, {"created":"20250910093946997","text":"## (De)selectors\n\nClicking href-value below will do:\n\n1. show/hide the target object (and children)\n\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#-welcome\u003C/span>\n\u003C/div>\n\u003Cbr>\n\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#+welcome\u003C/span>\n\u003C/div>\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">https://foo.glb\u003C/span>\n\t\u003Cspan class=\"big hi2\">#bar\u003C/span>\n\t\u003Cspan class=\"big hi1\">&\u003C/span>\n\t\u003Cspan class=\"big hi3\">-welcome\u003C/span>\n\u003C/div>\n\n> **NOTE:** the latter shows that (de)selectors can also be with regular [href](#href)-values \n","tags":"[[📜 level4: prefix operators]] level4","title":"#+-","modified":"20250910101236130","type":"text/markdown"}, {"created":"20250910093909237","text":"## Sharing object or file\n\nThe pipe-symbol (`|`) sends a (targeted) object to the OS.\nClicking the href-value below will:\n\n1. share the (targeted object in the) file to a another application\n\n> This URL can be fed straight into [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API) or [xdg-open](https://www.freedesktop.org/wiki/Software/xdg-utils/)\n\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi1\">#\u003C/span>\n\t\u003Cspan class=\"big hi2\">|bar\u003C/span>\n\u003C/div>\n\u003Cbr>\n\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big hi2\">https://foo.glb\u003C/span>\n\t\u003Cspan class=\"big hi1\">#|bar\u003C/span>\n\u003C/div>\n\u003Cbr>\n\n> **NOTE**: sharing is limited to `xrf:` scheme-only \n","tags":"[[📜 level4: prefix operators]] level4","title":"#|","modified":"20250910101321478","type":"text/markdown"}, @@ -1053,7 +1053,7 @@ button.sidebar-toggle{ {"created":"20230523124940866","title":"$:/config/DefaultSidebarTab","text":"Home","modified":"20250211170701446"}, {"created":"20230424093821723","text":"yes","tags":"","title":"$:/config/HtmlParser/DisableSandbox","modified":"20230424142930452"}, {"created":"20230424140117603","text":"allowvr allowfullscreen allow-scripts","tags":"","title":"$:/config/HtmlParser/SandboxTokens","modified":"20230424142737213"}, -{"created":"20230423174843715","text":"css","title":"$:/config/Manager/Filter","modified":"20250909120658847"}, +{"created":"20230423174843715","text":"controlling","title":"$:/config/Manager/Filter","modified":"20250919161605252"}, {"created":"20230423164137536","text":"","title":"$:/config/Manager/System","modified":"20240718185732477"}, {"created":"20240718202303000","title":"$:/config/Manager/Tag","text":"","modified":"20240719125709259"}, {"created":"20230425162854560","title":"$:/config/Navigation/UpdateAddressBar","text":"permalink","modified":"20230427180247389"}, @@ -1093,13 +1093,13 @@ button.sidebar-toggle{ {"title":"$:/plugins/tiddlywiki/codemirror-mode-javascript","name":"CodeMirror Mode JavaScript","description":"JavaScript highlighting mode for CodeMirror","parent-plugin":"$:/plugins/tiddlywiki/codemirror","list":"readme","version":"5.2.7","plugin-type":"plugin","dependents":"","type":"application/json","text":"{\"tiddlers\":{\"$:/plugins/tiddlywiki/codemirror/mode/javascript/javascript.js\":{\"text\":\"// CodeMirror, copyright (c) by Marijn Haverbeke and others\\n// Distributed under an MIT license: https://codemirror.net/LICENSE\\n!function(e){\\\"object\\\"==typeof exports&&\\\"object\\\"==typeof module?e(require(\\\"../../lib/codemirror\\\")):\\\"function\\\"==typeof define&&define.amd?define([\\\"../../lib/codemirror\\\"],e):e(CodeMirror)}(function(tt){\\\"use strict\\\";tt.defineMode(\\\"javascript\\\",function(e,l){var t,r,n,a,i,o,d=e.indentUnit,p=l.statementIndent,c=l.jsonld,s=l.json||c,u=l.typescript,f=l.wordCharacters||/[\\\\w$\\\\xa1-\\\\uffff]/,m=(t=v(\\\"keyword a\\\"),r=v(\\\"keyword b\\\"),n=v(\\\"keyword c\\\"),a=v(\\\"keyword d\\\"),i=v(\\\"operator\\\"),{if:v(\\\"if\\\"),while:t,with:t,else:r,do:r,try:r,finally:r,return:a,break:a,continue:a,new:v(\\\"new\\\"),delete:n,void:n,throw:n,debugger:v(\\\"debugger\\\"),var:v(\\\"var\\\"),const:v(\\\"var\\\"),let:v(\\\"var\\\"),function:v(\\\"function\\\"),catch:v(\\\"catch\\\"),for:v(\\\"for\\\"),switch:v(\\\"switch\\\"),case:v(\\\"case\\\"),default:v(\\\"default\\\"),in:i,typeof:i,instanceof:i,true:o={type:\\\"atom\\\",style:\\\"atom\\\"},false:o,null:o,undefined:o,NaN:o,Infinity:o,this:v(\\\"this\\\"),class:v(\\\"class\\\"),super:v(\\\"atom\\\"),yield:n,export:v(\\\"export\\\"),import:v(\\\"import\\\"),extends:n,await:n});function v(e){return{type:e,style:\\\"keyword\\\"}}var k,y,w=/[+\\\\-*&%=\u003C>!?|~^@]/,b=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)\\\"/;function x(e,t,r){return k=e,y=r,t}function h(e,t){var a,r=e.next();if('\\\"'==r||\\\"'\\\"==r)return t.tokenize=(a=r,function(e,t){var r,n=!1;if(c&&\\\"@\\\"==e.peek()&&e.match(b))return t.tokenize=h,x(\\\"jsonld-keyword\\\",\\\"meta\\\");for(;null!=(r=e.next())&&(r!=a||n);)n=!n&&\\\"\\\\\\\\\\\"==r;return n||(t.tokenize=h),x(\\\"string\\\",\\\"string\\\")}),t.tokenize(e,t);if(\\\".\\\"==r&&e.match(/^\\\\d[\\\\d_]*(?:[eE][+\\\\-]?[\\\\d_]+)?/))return x(\\\"number\\\",\\\"number\\\");if(\\\".\\\"==r&&e.match(\\\"..\\\"))return x(\\\"spread\\\",\\\"meta\\\");if(/[\\\\[\\\\]{}\\\\(\\\\),;\\\\:\\\\.]/.test(r))return x(r);if(\\\"=\\\"==r&&e.eat(\\\">\\\"))return x(\\\"=>\\\",\\\"operator\\\");if(\\\"0\\\"==r&&e.match(/^(?:x[\\\\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/))return x(\\\"number\\\",\\\"number\\\");if(/\\\\d/.test(r))return e.match(/^[\\\\d_]*(?:n|(?:\\\\.[\\\\d_]*)?(?:[eE][+\\\\-]?[\\\\d_]+)?)?/),x(\\\"number\\\",\\\"number\\\");if(\\\"/\\\"==r)return e.eat(\\\"*\\\")?(t.tokenize=g)(e,t):e.eat(\\\"/\\\")?(e.skipToEnd(),x(\\\"comment\\\",\\\"comment\\\")):et(e,t,1)?(function(e){for(var t,r=!1,n=!1;null!=(t=e.next());){if(!r){if(\\\"/\\\"==t&&!n)return;\\\"[\\\"==t?n=!0:n&&\\\"]\\\"==t&&(n=!1)}r=!r&&\\\"\\\\\\\\\\\"==t}}(e),e.match(/^\\\\b(([gimyus])(?![gimyus]*\\\\2))+\\\\b/),x(\\\"regexp\\\",\\\"string-2\\\")):(e.eat(\\\"=\\\"),x(\\\"operator\\\",\\\"operator\\\",e.current()));if(\\\"`\\\"==r)return(t.tokenize=j)(e,t);if(\\\"#\\\"==r&&\\\"!\\\"==e.peek())return e.skipToEnd(),x(\\\"meta\\\",\\\"meta\\\");if(\\\"#\\\"==r&&e.eatWhile(f))return x(\\\"variable\\\",\\\"property\\\");if(\\\"\u003C\\\"==r&&e.match(\\\"!--\\\")||\\\"-\\\"==r&&e.match(\\\"->\\\")&&!/\\\\S/.test(e.string.slice(0,e.start)))return e.skipToEnd(),x(\\\"comment\\\",\\\"comment\\\");if(w.test(r))return\\\">\\\"==r&&t.lexical&&\\\">\\\"==t.lexical.type||(e.eat(\\\"=\\\")?\\\"!\\\"!=r&&\\\"=\\\"!=r||e.eat(\\\"=\\\"):/[\u003C>*+\\\\-|&?]/.test(r)&&(e.eat(r),\\\">\\\"==r&&e.eat(r))),\\\"?\\\"==r&&e.eat(\\\".\\\")?x(\\\".\\\"):x(\\\"operator\\\",\\\"operator\\\",e.current());if(f.test(r)){e.eatWhile(f);var n=e.current();if(\\\".\\\"!=t.lastType){if(m.propertyIsEnumerable(n)){var i=m[n];return x(i.type,i.style,n)}if(\\\"async\\\"==n&&e.match(/^(\\\\s|\\\\/\\\\*([^*]|\\\\*(?!\\\\/))*?\\\\*\\\\/)*[\\\\[\\\\(\\\\w]/,!1))return x(\\\"async\\\",\\\"keyword\\\",n)}return x(\\\"variable\\\",\\\"variable\\\",n)}}function g(e,t){for(var r,n=!1;r=e.next();){if(\\\"/\\\"==r&&n){t.tokenize=h;break}n=\\\"*\\\"==r}return x(\\\"comment\\\",\\\"comment\\\")}function j(e,t){for(var r,n=!1;null!=(r=e.next());){if(!n&&(\\\"`\\\"==r||\\\"$\\\"==r&&e.eat(\\\"{\\\"))){t.tokenize=h;break}n=!n&&\\\"\\\\\\\\\\\"==r}return x(\\\"quasi\\\",\\\"string-2\\\",e.current())}var M=\\\"([{}])\\\";function A(e,t){t.fatArrowAt&&(t.fatArrowAt=null);var r,n=e.string.indexOf(\\\"=>\\\",e.start);if(!(n\u003C0)){!u||(r=/:\\\\s*(?:\\\\w+(?:\u003C[^>]*>|\\\\[\\\\])?|\\\\{[^}]*\\\\})\\\\s*$/.exec(e.string.slice(e.start,n)))&&(n=r.index);for(var a=0,i=!1,o=n-1;0\u003C=o;--o){var c=e.string.charAt(o),s=M.indexOf(c);if(0\u003C=s&&s\u003C3){if(!a){++o;break}if(0==--a){\\\"(\\\"==c&&(i=!0);break}}else if(3\u003C=s&&s\u003C6)++a;else if(f.test(c))i=!0;else if(/[\\\"'\\\\/`]/.test(c))for(;;--o){if(0==o)return;if(e.string.charAt(o-1)==c&&\\\"\\\\\\\\\\\"!=e.string.charAt(o-2)){o--;break}}else if(i&&!a){++o;break}}i&&!a&&(t.fatArrowAt=o)}}var V={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,this:!0,\\\"jsonld-keyword\\\":!0};function E(e,t,r,n,a,i){this.indented=e,this.column=t,this.type=r,this.prev=a,this.info=i,null!=n&&(this.align=n)}function z(e,t,r,n,a){var i=e.cc;for(I.state=e,I.stream=a,I.marked=null,I.cc=i,I.style=t,e.lexical.hasOwnProperty(\\\"align\\\")||(e.lexical.align=!0);;){if((i.length?i.pop():s?J:D)(r,n)){for(;i.length&&i[i.length-1].lex;)i.pop()();return I.marked?I.marked:\\\"variable\\\"==r&&function(e,t){for(var r=e.localVars;r;r=r.next)if(r.name==t)return 1;for(var n=e.context;n;n=n.prev)for(r=n.vars;r;r=r.next)if(r.name==t)return 1}(e,n)?\\\"variable-2\\\":t}}}var I={state:null,column:null,marked:null,cc:null};function T(){for(var e=arguments.length-1;0\u003C=e;e--)I.cc.push(arguments[e])}function $(){return T.apply(null,arguments),!0}function C(e,t){for(var r=t;r;r=r.next)if(r.name==e)return 1}function _(e){var t=I.state;if(I.marked=\\\"def\\\",t.context)if(\\\"var\\\"==t.lexical.info&&t.context&&t.context.block){var r=function e(t,r){{if(r){if(r.block){var n=e(t,r.prev);return n?n==r.prev?r:new q(n,r.vars,!0):null}return C(t,r.vars)?r:new q(r.prev,new S(t,r.vars),!1)}return null}}(e,t.context);if(null!=r)return void(t.context=r)}else if(!C(e,t.localVars))return void(t.localVars=new S(e,t.localVars));l.globalVars&&!C(e,t.globalVars)&&(t.globalVars=new S(e,t.globalVars))}function O(e){return\\\"public\\\"==e||\\\"private\\\"==e||\\\"protected\\\"==e||\\\"abstract\\\"==e||\\\"readonly\\\"==e}function q(e,t,r){this.prev=e,this.vars=t,this.block=r}function S(e,t){this.name=e,this.next=t}var P=new S(\\\"this\\\",new S(\\\"arguments\\\",null));function N(){I.state.context=new q(I.state.context,I.state.localVars,!1),I.state.localVars=P}function U(){I.state.context=new q(I.state.context,I.state.localVars,!0),I.state.localVars=null}function W(){I.state.localVars=I.state.context.vars,I.state.context=I.state.context.prev}function B(n,a){function e(){var e=I.state,t=e.indented;if(\\\"stat\\\"==e.lexical.type)t=e.lexical.indented;else for(var r=e.lexical;r&&\\\")\\\"==r.type&&r.align;r=r.prev)t=r.indented;e.lexical=new E(t,I.stream.column(),n,null,e.lexical,a)}return e.lex=!0,e}function F(){var e=I.state;e.lexical.prev&&(\\\")\\\"==e.lexical.type&&(e.indented=e.lexical.indented),e.lexical=e.lexical.prev)}function H(r){return function e(t){return t==r?$():\\\";\\\"==r||\\\"}\\\"==t||\\\")\\\"==t||\\\"]\\\"==t?T():$(e)}}function D(e,t){return\\\"var\\\"==e?$(B(\\\"vardef\\\",t),Ae,H(\\\";\\\"),F):\\\"keyword a\\\"==e?$(B(\\\"form\\\"),L,D,F):\\\"keyword b\\\"==e?$(B(\\\"form\\\"),D,F):\\\"keyword d\\\"==e?I.stream.match(/^\\\\s*$/,!1)?$():$(B(\\\"stat\\\"),R,H(\\\";\\\"),F):\\\"debugger\\\"==e?$(H(\\\";\\\")):\\\"{\\\"==e?$(B(\\\"}\\\"),U,de,F,W):\\\";\\\"==e?$():\\\"if\\\"==e?(\\\"else\\\"==I.state.lexical.info&&I.state.cc[I.state.cc.length-1]==F&&I.state.cc.pop()(),$(B(\\\"form\\\"),L,D,F,$e)):\\\"function\\\"==e?$(qe):\\\"for\\\"==e?$(B(\\\"form\\\"),Ce,D,F):\\\"class\\\"==e||u&&\\\"interface\\\"==t?(I.marked=\\\"keyword\\\",$(B(\\\"form\\\",\\\"class\\\"==e?e:t),We,F)):\\\"variable\\\"==e?u&&\\\"declare\\\"==t?(I.marked=\\\"keyword\\\",$(D)):u&&(\\\"module\\\"==t||\\\"enum\\\"==t||\\\"type\\\"==t)&&I.stream.match(/^\\\\s*\\\\w/,!1)?(I.marked=\\\"keyword\\\",\\\"enum\\\"==t?$(Ye):\\\"type\\\"==t?$(Pe,H(\\\"operator\\\"),ye,H(\\\";\\\")):$(B(\\\"form\\\"),Ve,H(\\\"{\\\"),B(\\\"}\\\"),de,F,F)):u&&\\\"namespace\\\"==t?(I.marked=\\\"keyword\\\",$(B(\\\"form\\\"),J,D,F)):u&&\\\"abstract\\\"==t?(I.marked=\\\"keyword\\\",$(D)):$(B(\\\"stat\\\"),ie):\\\"switch\\\"==e?$(B(\\\"form\\\"),L,H(\\\"{\\\"),B(\\\"}\\\",\\\"switch\\\"),U,de,F,F,W):\\\"case\\\"==e?$(J,H(\\\":\\\")):\\\"default\\\"==e?$(H(\\\":\\\")):\\\"catch\\\"==e?$(B(\\\"form\\\"),N,G,D,F,W):\\\"export\\\"==e?$(B(\\\"stat\\\"),De,F):\\\"import\\\"==e?$(B(\\\"stat\\\"),Je,F):\\\"async\\\"==e?$(D):\\\"@\\\"==t?$(J,D):T(B(\\\"stat\\\"),J,H(\\\";\\\"),F)}function G(e){if(\\\"(\\\"==e)return $(Ne,H(\\\")\\\"))}function J(e,t){return Q(e,t,!1)}function K(e,t){return Q(e,t,!0)}function L(e){return\\\"(\\\"!=e?T():$(B(\\\")\\\"),R,H(\\\")\\\"),F)}function Q(e,t,r){if(I.state.fatArrowAt==I.stream.start){var n=r?re:te;if(\\\"(\\\"==e)return $(N,B(\\\")\\\"),fe(Ne,\\\")\\\"),F,H(\\\"=>\\\"),n,W);if(\\\"variable\\\"==e)return T(N,Ve,H(\\\"=>\\\"),n,W)}var a,i=r?Y:X;return V.hasOwnProperty(e)?$(i):\\\"function\\\"==e?$(qe,i):\\\"class\\\"==e||u&&\\\"interface\\\"==t?(I.marked=\\\"keyword\\\",$(B(\\\"form\\\"),Ue,F)):\\\"keyword c\\\"==e||\\\"async\\\"==e?$(r?K:J):\\\"(\\\"==e?$(B(\\\")\\\"),R,H(\\\")\\\"),F,i):\\\"operator\\\"==e||\\\"spread\\\"==e?$(r?K:J):\\\"[\\\"==e?$(B(\\\"]\\\"),Xe,F,i):\\\"{\\\"==e?le(ce,\\\"}\\\",null,i):\\\"quasi\\\"==e?T(Z,i):\\\"new\\\"==e?$((a=r,function(e){return\\\".\\\"==e?$(a?ae:ne):\\\"variable\\\"==e&&u?$(ge,a?Y:X):T(a?K:J)})):\\\"import\\\"==e?$(J):$()}function R(e){return e.match(/[;\\\\}\\\\)\\\\],]/)?T():T(J)}function X(e,t){return\\\",\\\"==e?$(R):Y(e,t,!1)}function Y(e,t,r){var n=0==r?X:Y,a=0==r?J:K;return\\\"=>\\\"==e?$(N,r?re:te,W):\\\"operator\\\"==e?/\\\\+\\\\+|--/.test(t)||u&&\\\"!\\\"==t?$(n):u&&\\\"\u003C\\\"==t&&I.stream.match(/^([^\u003C>]|\u003C[^\u003C>]*>)*>\\\\s*\\\\(/,!1)?$(B(\\\">\\\"),fe(ye,\\\">\\\"),F,n):\\\"?\\\"==t?$(J,H(\\\":\\\"),a):$(a):\\\"quasi\\\"==e?T(Z,n):\\\";\\\"!=e?\\\"(\\\"==e?le(K,\\\")\\\",\\\"call\\\",n):\\\".\\\"==e?$(oe,n):\\\"[\\\"==e?$(B(\\\"]\\\"),R,H(\\\"]\\\"),F,n):u&&\\\"as\\\"==t?(I.marked=\\\"keyword\\\",$(ye,n)):\\\"regexp\\\"==e?(I.state.lastType=I.marked=\\\"operator\\\",I.stream.backUp(I.stream.pos-I.stream.start-1),$(a)):void 0:void 0}function Z(e,t){return\\\"quasi\\\"!=e?T():\\\"${\\\"!=t.slice(t.length-2)?$(Z):$(J,ee)}function ee(e){if(\\\"}\\\"==e)return I.marked=\\\"string-2\\\",I.state.tokenize=j,$(Z)}function te(e){return A(I.stream,I.state),T(\\\"{\\\"==e?D:J)}function re(e){return A(I.stream,I.state),T(\\\"{\\\"==e?D:K)}function ne(e,t){if(\\\"target\\\"==t)return I.marked=\\\"keyword\\\",$(X)}function ae(e,t){if(\\\"target\\\"==t)return I.marked=\\\"keyword\\\",$(Y)}function ie(e){return\\\":\\\"==e?$(F,D):T(X,H(\\\";\\\"),F)}function oe(e){if(\\\"variable\\\"==e)return I.marked=\\\"property\\\",$()}function ce(e,t){if(\\\"async\\\"==e)return I.marked=\\\"property\\\",$(ce);if(\\\"variable\\\"==e||\\\"keyword\\\"==I.style){return(I.marked=\\\"property\\\",\\\"get\\\"==t||\\\"set\\\"==t)?$(se):(u&&I.state.fatArrowAt==I.stream.start&&(r=I.stream.match(/^\\\\s*:\\\\s*/,!1))&&(I.state.fatArrowAt=I.stream.pos+r[0].length),$(ue));var r}else{if(\\\"number\\\"==e||\\\"string\\\"==e)return I.marked=c?\\\"property\\\":I.style+\\\" property\\\",$(ue);if(\\\"jsonld-keyword\\\"==e)return $(ue);if(u&&O(t))return I.marked=\\\"keyword\\\",$(ce);if(\\\"[\\\"==e)return $(J,pe,H(\\\"]\\\"),ue);if(\\\"spread\\\"==e)return $(K,ue);if(\\\"*\\\"==t)return I.marked=\\\"keyword\\\",$(ce);if(\\\":\\\"==e)return T(ue)}}function se(e){return\\\"variable\\\"!=e?T(ue):(I.marked=\\\"property\\\",$(qe))}function ue(e){return\\\":\\\"==e?$(K):\\\"(\\\"==e?T(qe):void 0}function fe(n,a,i){function o(e,t){if(i?-1\u003Ci.indexOf(e):\\\",\\\"==e){var r=I.state.lexical;return\\\"call\\\"==r.info&&(r.pos=(r.pos||0)+1),$(function(e,t){return e==a||t==a?T():T(n)},o)}return e==a||t==a?$():i&&-1\u003Ci.indexOf(\\\";\\\")?T(n):$(H(a))}return function(e,t){return e==a||t==a?$():T(n,o)}}function le(e,t,r){for(var n=3;n\u003Carguments.length;n++)I.cc.push(arguments[n]);return $(B(t,r),fe(e,t),F)}function de(e){return\\\"}\\\"==e?$():T(D,de)}function pe(e,t){if(u){if(\\\":\\\"==e)return $(ye);if(\\\"?\\\"==t)return $(pe)}}function me(e,t){if(u&&(\\\":\\\"==e||\\\"in\\\"==t))return $(ye)}function ve(e){if(u&&\\\":\\\"==e)return I.stream.match(/^\\\\s*\\\\w+\\\\s+is\\\\b/,!1)?$(J,ke,ye):$(ye)}function ke(e,t){if(\\\"is\\\"==t)return I.marked=\\\"keyword\\\",$()}function ye(e,t){return\\\"keyof\\\"==t||\\\"typeof\\\"==t||\\\"infer\\\"==t?(I.marked=\\\"keyword\\\",$(\\\"typeof\\\"==t?K:ye)):\\\"variable\\\"==e||\\\"void\\\"==t?(I.marked=\\\"type\\\",$(he)):\\\"|\\\"==t||\\\"&\\\"==t?$(ye):\\\"string\\\"==e||\\\"number\\\"==e||\\\"atom\\\"==e?$(he):\\\"[\\\"==e?$(B(\\\"]\\\"),fe(ye,\\\"]\\\",\\\",\\\"),F,he):\\\"{\\\"==e?$(B(\\\"}\\\"),fe(be,\\\"}\\\",\\\",;\\\"),F,he):\\\"(\\\"==e?$(fe(xe,\\\")\\\"),we,he):\\\"\u003C\\\"==e?$(fe(ye,\\\">\\\"),ye):void 0}function we(e){if(\\\"=>\\\"==e)return $(ye)}function be(e,t){return\\\"variable\\\"==e||\\\"keyword\\\"==I.style?(I.marked=\\\"property\\\",$(be)):\\\"?\\\"==t||\\\"number\\\"==e||\\\"string\\\"==e?$(be):\\\":\\\"==e?$(ye):\\\"[\\\"==e?$(H(\\\"variable\\\"),me,H(\\\"]\\\"),be):\\\"(\\\"==e?T(Se,be):void 0}function xe(e,t){return\\\"variable\\\"==e&&I.stream.match(/^\\\\s*[?:]/,!1)||\\\"?\\\"==t?$(xe):\\\":\\\"==e?$(ye):\\\"spread\\\"==e?$(xe):T(ye)}function he(e,t){return\\\"\u003C\\\"==t?$(B(\\\">\\\"),fe(ye,\\\">\\\"),F,he):\\\"|\\\"==t||\\\".\\\"==e||\\\"&\\\"==t?$(ye):\\\"[\\\"==e?$(ye,H(\\\"]\\\"),he):\\\"extends\\\"==t||\\\"implements\\\"==t?(I.marked=\\\"keyword\\\",$(ye)):\\\"?\\\"==t?$(ye,H(\\\":\\\"),ye):void 0}function ge(e,t){if(\\\"\u003C\\\"==t)return $(B(\\\">\\\"),fe(ye,\\\">\\\"),F,he)}function je(){return T(ye,Me)}function Me(e,t){if(\\\"=\\\"==t)return $(ye)}function Ae(e,t){return\\\"enum\\\"==t?(I.marked=\\\"keyword\\\",$(Ye)):T(Ve,pe,Ie,Te)}function Ve(e,t){return u&&O(t)?(I.marked=\\\"keyword\\\",$(Ve)):\\\"variable\\\"==e?(_(t),$()):\\\"spread\\\"==e?$(Ve):\\\"[\\\"==e?le(ze,\\\"]\\\"):\\\"{\\\"==e?le(Ee,\\\"}\\\"):void 0}function Ee(e,t){return\\\"variable\\\"!=e||I.stream.match(/^\\\\s*:/,!1)?(\\\"variable\\\"==e&&(I.marked=\\\"property\\\"),\\\"spread\\\"==e?$(Ve):\\\"}\\\"==e?T():\\\"[\\\"==e?$(J,H(\\\"]\\\"),H(\\\":\\\"),Ee):$(H(\\\":\\\"),Ve,Ie)):(_(t),$(Ie))}function ze(){return T(Ve,Ie)}function Ie(e,t){if(\\\"=\\\"==t)return $(K)}function Te(e){if(\\\",\\\"==e)return $(Ae)}function $e(e,t){if(\\\"keyword b\\\"==e&&\\\"else\\\"==t)return $(B(\\\"form\\\",\\\"else\\\"),D,F)}function Ce(e,t){return\\\"await\\\"==t?$(Ce):\\\"(\\\"==e?$(B(\\\")\\\"),_e,F):void 0}function _e(e){return\\\"var\\\"==e?$(Ae,Oe):(\\\"variable\\\"==e?$:T)(Oe)}function Oe(e,t){return\\\")\\\"==e?$():\\\";\\\"==e?$(Oe):\\\"in\\\"==t||\\\"of\\\"==t?(I.marked=\\\"keyword\\\",$(J,Oe)):T(J,Oe)}function qe(e,t){return\\\"*\\\"==t?(I.marked=\\\"keyword\\\",$(qe)):\\\"variable\\\"==e?(_(t),$(qe)):\\\"(\\\"==e?$(N,B(\\\")\\\"),fe(Ne,\\\")\\\"),F,ve,D,W):u&&\\\"\u003C\\\"==t?$(B(\\\">\\\"),fe(je,\\\">\\\"),F,qe):void 0}function Se(e,t){return\\\"*\\\"==t?(I.marked=\\\"keyword\\\",$(Se)):\\\"variable\\\"==e?(_(t),$(Se)):\\\"(\\\"==e?$(N,B(\\\")\\\"),fe(Ne,\\\")\\\"),F,ve,W):u&&\\\"\u003C\\\"==t?$(B(\\\">\\\"),fe(je,\\\">\\\"),F,Se):void 0}function Pe(e,t){return\\\"keyword\\\"==e||\\\"variable\\\"==e?(I.marked=\\\"type\\\",$(Pe)):\\\"\u003C\\\"==t?$(B(\\\">\\\"),fe(je,\\\">\\\"),F):void 0}function Ne(e,t){return\\\"@\\\"==t&&$(J,Ne),\\\"spread\\\"==e?$(Ne):u&&O(t)?(I.marked=\\\"keyword\\\",$(Ne)):u&&\\\"this\\\"==e?$(pe,Ie):T(Ve,pe,Ie)}function Ue(e,t){return(\\\"variable\\\"==e?We:Be)(e,t)}function We(e,t){if(\\\"variable\\\"==e)return _(t),$(Be)}function Be(e,t){return\\\"\u003C\\\"==t?$(B(\\\">\\\"),fe(je,\\\">\\\"),F,Be):\\\"extends\\\"==t||\\\"implements\\\"==t||u&&\\\",\\\"==e?(\\\"implements\\\"==t&&(I.marked=\\\"keyword\\\"),$(u?ye:J,Be)):\\\"{\\\"==e?$(B(\\\"}\\\"),Fe,F):void 0}function Fe(e,t){return\\\"async\\\"==e||\\\"variable\\\"==e&&(\\\"static\\\"==t||\\\"get\\\"==t||\\\"set\\\"==t||u&&O(t))&&I.stream.match(/^\\\\s+[\\\\w$\\\\xa1-\\\\uffff]/,!1)?(I.marked=\\\"keyword\\\",$(Fe)):\\\"variable\\\"==e||\\\"keyword\\\"==I.style?(I.marked=\\\"property\\\",$(He,Fe)):\\\"number\\\"==e||\\\"string\\\"==e?$(He,Fe):\\\"[\\\"==e?$(J,pe,H(\\\"]\\\"),He,Fe):\\\"*\\\"==t?(I.marked=\\\"keyword\\\",$(Fe)):u&&\\\"(\\\"==e?T(Se,Fe):\\\";\\\"==e||\\\",\\\"==e?$(Fe):\\\"}\\\"==e?$():\\\"@\\\"==t?$(J,Fe):void 0}function He(e,t){if(\\\"?\\\"==t)return $(He);if(\\\":\\\"==e)return $(ye,Ie);if(\\\"=\\\"==t)return $(K);var r=I.state.lexical.prev;return T(r&&\\\"interface\\\"==r.info?Se:qe)}function De(e,t){return\\\"*\\\"==t?(I.marked=\\\"keyword\\\",$(Re,H(\\\";\\\"))):\\\"default\\\"==t?(I.marked=\\\"keyword\\\",$(J,H(\\\";\\\"))):\\\"{\\\"==e?$(fe(Ge,\\\"}\\\"),Re,H(\\\";\\\")):T(D)}function Ge(e,t){return\\\"as\\\"==t?(I.marked=\\\"keyword\\\",$(H(\\\"variable\\\"))):\\\"variable\\\"==e?T(K,Ge):void 0}function Je(e){return\\\"string\\\"==e?$():\\\"(\\\"==e?T(J):T(Ke,Le,Re)}function Ke(e,t){return\\\"{\\\"==e?le(Ke,\\\"}\\\"):(\\\"variable\\\"==e&&_(t),\\\"*\\\"==t&&(I.marked=\\\"keyword\\\"),$(Qe))}function Le(e){if(\\\",\\\"==e)return $(Ke,Le)}function Qe(e,t){if(\\\"as\\\"==t)return I.marked=\\\"keyword\\\",$(Ke)}function Re(e,t){if(\\\"from\\\"==t)return I.marked=\\\"keyword\\\",$(J)}function Xe(e){return\\\"]\\\"==e?$():T(fe(K,\\\"]\\\"))}function Ye(){return T(B(\\\"form\\\"),Ve,H(\\\"{\\\"),B(\\\"}\\\"),fe(Ze,\\\"}\\\"),F,F)}function Ze(){return T(Ve,Ie)}function et(e,t,r){return t.tokenize==h&&/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\\\\[{}\\\\(,;:]|=>)$/.test(t.lastType)||\\\"quasi\\\"==t.lastType&&/\\\\{\\\\s*$/.test(e.string.slice(0,e.pos-(r||0)))}return F.lex=W.lex=!0,{startState:function(e){var t={tokenize:h,lastType:\\\"sof\\\",cc:[],lexical:new E((e||0)-d,0,\\\"block\\\",!1),localVars:l.localVars,context:l.localVars&&new q(null,null,!1),indented:e||0};return l.globalVars&&\\\"object\\\"==typeof l.globalVars&&(t.globalVars=l.globalVars),t},token:function(e,t){if(e.sol()&&(t.lexical.hasOwnProperty(\\\"align\\\")||(t.lexical.align=!1),t.indented=e.indentation(),A(e,t)),t.tokenize!=g&&e.eatSpace())return null;var r=t.tokenize(e,t);return\\\"comment\\\"==k?r:(t.lastType=\\\"operator\\\"!=k||\\\"++\\\"!=y&&\\\"--\\\"!=y?k:\\\"incdec\\\",z(t,r,k,y,e))},indent:function(e,t){if(e.tokenize==g||e.tokenize==j)return tt.Pass;if(e.tokenize!=h)return 0;var r,n=t&&t.charAt(0),a=e.lexical;if(!/^\\\\s*else\\\\b/.test(t))for(var i=e.cc.length-1;0\u003C=i;--i){var o=e.cc[i];if(o==F)a=a.prev;else if(o!=$e)break}for(;(\\\"stat\\\"==a.type||\\\"form\\\"==a.type)&&(\\\"}\\\"==n||(r=e.cc[e.cc.length-1])&&(r==X||r==Y)&&!/^[,\\\\.=+\\\\-*:?[\\\\(]/.test(t));)a=a.prev;p&&\\\")\\\"==a.type&&\\\"stat\\\"==a.prev.type&&(a=a.prev);var c,s,u=a.type,f=n==u;return\\\"vardef\\\"==u?a.indented+(\\\"operator\\\"==e.lastType||\\\",\\\"==e.lastType?a.info.length+1:0):\\\"form\\\"==u&&\\\"{\\\"==n?a.indented:\\\"form\\\"==u?a.indented+d:\\\"stat\\\"==u?a.indented+(s=t,\\\"operator\\\"==(c=e).lastType||\\\",\\\"==c.lastType||w.test(s.charAt(0))||/[,.]/.test(s.charAt(0))?p||d:0):\\\"switch\\\"!=a.info||f||0==l.doubleIndentSwitch?a.align?a.column+(f?0:1):a.indented+(f?0:d):a.indented+(/^(?:case|default)\\\\b/.test(t)?d:2*d)},electricInput:/^\\\\s*(?:case .*?:|default:|\\\\{|\\\\})$/,blockCommentStart:s?null:\\\"/*\\\",blockCommentEnd:s?null:\\\"*/\\\",blockCommentContinue:s?null:\\\" * \\\",lineComment:s?null:\\\"//\\\",fold:\\\"brace\\\",closeBrackets:\\\"()[]{}''\\\\\\\"\\\\\\\"``\\\",helperType:s?\\\"json\\\":\\\"javascript\\\",jsonldMode:c,jsonMode:s,expressionAllowed:et,skipExpression:function(e){var t=e.cc[e.cc.length-1];t!=J&&t!=K||e.cc.pop()}}}),tt.registerHelper(\\\"wordChars\\\",\\\"javascript\\\",/[\\\\w$]/),tt.defineMIME(\\\"text/javascript\\\",\\\"javascript\\\"),tt.defineMIME(\\\"text/ecmascript\\\",\\\"javascript\\\"),tt.defineMIME(\\\"application/javascript\\\",\\\"javascript\\\"),tt.defineMIME(\\\"application/x-javascript\\\",\\\"javascript\\\"),tt.defineMIME(\\\"application/ecmascript\\\",\\\"javascript\\\"),tt.defineMIME(\\\"application/json\\\",{name:\\\"javascript\\\",json:!0}),tt.defineMIME(\\\"application/x-json\\\",{name:\\\"javascript\\\",json:!0}),tt.defineMIME(\\\"application/ld+json\\\",{name:\\\"javascript\\\",jsonld:!0}),tt.defineMIME(\\\"text/typescript\\\",{name:\\\"javascript\\\",typescript:!0}),tt.defineMIME(\\\"application/typescript\\\",{name:\\\"javascript\\\",typescript:!0})});\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/codemirror/mode/javascript/javascript.js\",\"module-type\":\"codemirror\"},\"$:/plugins/tiddlywiki/codemirror-mode-javascript/readme\":{\"title\":\"$:/plugins/tiddlywiki/codemirror-mode-javascript/readme\",\"text\":\"This plugin adds Syntax Highlighting for Javascript tiddlers (application/javascript) to the [[CodeMirror|http://codemirror.net]] text editor. It needs the latest [[CodeMirror plugin|$:/plugins/tiddlywiki/codemirror]] to be installed\\n\\n\"}}}"}, {"title":"$:/plugins/tiddlywiki/codemirror-mode-xml","name":"CodeMirror Mode XML","description":"XML highlighting mode for CodeMirror","parent-plugin":"$:/plugins/tiddlywiki/codemirror","list":"readme","version":"5.2.7","plugin-type":"plugin","dependents":"","type":"application/json","text":"{\"tiddlers\":{\"$:/plugins/tiddlywiki/codemirror/mode/xml/xml.js\":{\"text\":\"// CodeMirror, copyright (c) by Marijn Haverbeke and others\\n// Distributed under an MIT license: https://codemirror.net/LICENSE\\n!function(t){\\\"object\\\"==typeof exports&&\\\"object\\\"==typeof module?t(require(\\\"../../lib/codemirror\\\")):\\\"function\\\"==typeof define&&define.amd?define([\\\"../../lib/codemirror\\\"],t):t(CodeMirror)}(function(N){\\\"use strict\\\";var y={autoSelfClosers:{area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,menuitem:!0},implicitlyClosed:{dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},contextGrabbers:{dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!0,caseFold:!0},z={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1,allowMissingTagName:!1,caseFold:!1};N.defineMode(\\\"xml\\\",function(t,e){var i,a,l=t.indentUnit,u={},n=e.htmlMode?y:z;for(var r in n)u[r]=n[r];for(var r in e)u[r]=e[r];function c(e,n){function t(t){return(n.tokenize=t)(e,n)}var r=e.next();if(\\\"\u003C\\\"==r)return e.eat(\\\"!\\\")?e.eat(\\\"[\\\")?e.match(\\\"CDATA[\\\")?t(s(\\\"atom\\\",\\\"]]>\\\")):null:e.match(\\\"--\\\")?t(s(\\\"comment\\\",\\\"--\\\\x3e\\\")):e.match(\\\"DOCTYPE\\\",!0,!0)?(e.eatWhile(/[\\\\w\\\\._\\\\-]/),t(function r(o){return function(t,e){for(var n;null!=(n=t.next());){if(\\\"\u003C\\\"==n)return e.tokenize=r(o+1),e.tokenize(t,e);if(\\\">\\\"==n){if(1!=o)return e.tokenize=r(o-1),e.tokenize(t,e);e.tokenize=c;break}}return\\\"meta\\\"}}(1))):null:e.eat(\\\"?\\\")?(e.eatWhile(/[\\\\w\\\\._\\\\-]/),n.tokenize=s(\\\"meta\\\",\\\"?>\\\"),\\\"meta\\\"):(i=e.eat(\\\"/\\\")?\\\"closeTag\\\":\\\"openTag\\\",n.tokenize=d,\\\"tag bracket\\\");if(\\\"&\\\"!=r)return e.eatWhile(/[^&\u003C]/),null;var o=e.eat(\\\"#\\\")?e.eat(\\\"x\\\")?e.eatWhile(/[a-fA-F\\\\d]/)&&e.eat(\\\";\\\"):e.eatWhile(/[\\\\d]/)&&e.eat(\\\";\\\"):e.eatWhile(/[\\\\w\\\\.\\\\-:]/)&&e.eat(\\\";\\\");return o?\\\"atom\\\":\\\"error\\\"}function d(t,e){var n=t.next();if(\\\">\\\"==n||\\\"/\\\"==n&&t.eat(\\\">\\\"))return e.tokenize=c,i=\\\">\\\"==n?\\\"endTag\\\":\\\"selfcloseTag\\\",\\\"tag bracket\\\";if(\\\"=\\\"==n)return i=\\\"equals\\\",null;if(\\\"\u003C\\\"!=n)return/[\\\\'\\\\\\\"]/.test(n)?(e.tokenize=(r=n,a.isInAttribute=!0,a),e.stringStartCol=t.column(),e.tokenize(t,e)):(t.match(/^[^\\\\s\\\\u00a0=\u003C>\\\\\\\"\\\\']*[^\\\\s\\\\u00a0=\u003C>\\\\\\\"\\\\'\\\\/]/),\\\"word\\\");e.tokenize=c,e.state=g,e.tagName=e.tagStart=null;var r,o=e.tokenize(t,e);return o?o+\\\" tag error\\\":\\\"tag error\\\";function a(t,e){for(;!t.eol();)if(t.next()==r){e.tokenize=d;break}return\\\"string\\\"}}function s(n,r){return function(t,e){for(;!t.eol();){if(t.match(r)){e.tokenize=c;break}t.next()}return n}}function f(t,e,n){this.prev=t.context,this.tagName=e||\\\"\\\",this.indent=t.indented,this.startOfLine=n,(u.doNotIndent.hasOwnProperty(e)||t.context&&t.context.noIndent)&&(this.noIndent=!0)}function o(t){t.context&&(t.context=t.context.prev)}function m(t,e){for(var n;;){if(!t.context)return;if(n=t.context.tagName,!u.contextGrabbers.hasOwnProperty(n)||!u.contextGrabbers[n].hasOwnProperty(e))return;o(t)}}function g(t,e,n){return\\\"openTag\\\"==t?(n.tagStart=e.column(),p):\\\"closeTag\\\"==t?h:g}function p(t,e,n){return\\\"word\\\"==t?(n.tagName=e.current(),a=\\\"tag\\\",k):u.allowMissingTagName&&\\\"endTag\\\"==t?(a=\\\"tag bracket\\\",k(t,0,n)):(a=\\\"error\\\",p)}function h(t,e,n){if(\\\"word\\\"!=t)return u.allowMissingTagName&&\\\"endTag\\\"==t?(a=\\\"tag bracket\\\",x(t,0,n)):(a=\\\"error\\\",b);var r=e.current();return n.context&&n.context.tagName!=r&&u.implicitlyClosed.hasOwnProperty(n.context.tagName)&&o(n),n.context&&n.context.tagName==r||!1===u.matchClosing?(a=\\\"tag\\\",x):(a=\\\"tag error\\\",b)}function x(t,e,n){return\\\"endTag\\\"!=t?(a=\\\"error\\\",x):(o(n),g)}function b(t,e,n){return a=\\\"error\\\",x(t,0,n)}function k(t,e,n){if(\\\"word\\\"==t)return a=\\\"attribute\\\",v;if(\\\"endTag\\\"!=t&&\\\"selfcloseTag\\\"!=t)return a=\\\"error\\\",k;var r=n.tagName,o=n.tagStart;return n.tagName=n.tagStart=null,\\\"selfcloseTag\\\"==t||u.autoSelfClosers.hasOwnProperty(r)?m(n,r):(m(n,r),n.context=new f(n,r,o==n.indented)),g}function v(t,e,n){return\\\"equals\\\"==t?w:(u.allowMissing||(a=\\\"error\\\"),k(t,0,n))}function w(t,e,n){return\\\"string\\\"==t?T:\\\"word\\\"==t&&u.allowUnquoted?(a=\\\"string\\\",k):(a=\\\"error\\\",k(t,0,n))}function T(t,e,n){return\\\"string\\\"==t?T:k(t,0,n)}return c.isInText=!0,{startState:function(t){var e={tokenize:c,state:g,indented:t||0,tagName:null,tagStart:null,context:null};return null!=t&&(e.baseIndent=t),e},token:function(t,e){if(!e.tagName&&t.sol()&&(e.indented=t.indentation()),t.eatSpace())return null;i=null;var n=e.tokenize(t,e);return(n||i)&&\\\"comment\\\"!=n&&(a=null,e.state=e.state(i||n,t,e),a&&(n=\\\"error\\\"==a?n+\\\" error\\\":a)),n},indent:function(t,e,n){var r=t.context;if(t.tokenize.isInAttribute)return t.tagStart==t.indented?t.stringStartCol+1:t.indented+l;if(r&&r.noIndent)return N.Pass;if(t.tokenize!=d&&t.tokenize!=c)return n?n.match(/^(\\\\s*)/)[0].length:0;if(t.tagName)return!1!==u.multilineTagIndentPastTag?t.tagStart+t.tagName.length+2:t.tagStart+l*(u.multilineTagIndentFactor||1);if(u.alignCDATA&&/\u003C!\\\\[CDATA\\\\[/.test(e))return 0;var o=e&&/^\u003C(\\\\/)?([\\\\w_:\\\\.-]*)/.exec(e);if(o&&o[1])for(;r;){if(r.tagName==o[2]){r=r.prev;break}if(!u.implicitlyClosed.hasOwnProperty(r.tagName))break;r=r.prev}else if(o)for(;r;){var a=u.contextGrabbers[r.tagName];if(!a||!a.hasOwnProperty(o[2]))break;r=r.prev}for(;r&&r.prev&&!r.startOfLine;)r=r.prev;return r?r.indent+l:t.baseIndent||0},electricInput:/\u003C\\\\/[\\\\s\\\\w:]+>$/,blockCommentStart:\\\"\\\\x3c!--\\\",blockCommentEnd:\\\"--\\\\x3e\\\",configuration:u.htmlMode?\\\"html\\\":\\\"xml\\\",helperType:u.htmlMode?\\\"html\\\":\\\"xml\\\",skipAttribute:function(t){t.state==w&&(t.state=k)},xmlCurrentTag:function(t){return t.tagName?{name:t.tagName,close:\\\"closeTag\\\"==t.type}:null},xmlCurrentContext:function(t){for(var e=[],n=t.context;n;n=n.prev)e.push(n.tagName);return e.reverse()}}}),N.defineMIME(\\\"text/xml\\\",\\\"xml\\\"),N.defineMIME(\\\"application/xml\\\",\\\"xml\\\"),N.mimeModes.hasOwnProperty(\\\"text/html\\\")||N.defineMIME(\\\"text/html\\\",{name:\\\"xml\\\",htmlMode:!0})});\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/codemirror/mode/xml/xml.js\",\"module-type\":\"codemirror\"},\"$:/plugins/tiddlywiki/codemirror-mode-xml/readme\":{\"title\":\"$:/plugins/tiddlywiki/codemirror-mode-xml/readme\",\"text\":\"This plugin is a requirement for other Syntax-highlighting plugins and adds Highlighting for XML tiddlers (application/xml) to the [[CodeMirror|http://codemirror.net]] text editor. It needs the latest [[CodeMirror plugin|$:/plugins/tiddlywiki/codemirror]] to be installed\\n\\n\"}}}"}, {"title":"$:/plugins/tiddlywiki/markdown","name":"Markdown","description":"Markdown parser based on markdown-it","list":"readme config syntax license","version":"5.2.7","plugin-type":"plugin","dependents":"","type":"application/json","text":"{\"tiddlers\":{\"$:/plugins/tiddlywiki/markdown/EditorToolbar/bold\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/bold\",\"list-after\":\"$:/core/ui/EditorToolbar/bold\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/bold\",\"caption\":\"{{$:/language/Buttons/Bold/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Bold/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((bold))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"wrap-selection\\\"\\n\\tprefix=\\\"**\\\"\\n\\tsuffix=\\\"**\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-1\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-1\",\"list-after\":\"$:/core/ui/EditorToolbar/heading-1\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/heading-1\",\"caption\":\"{{$:/language/Buttons/Heading1/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Heading1/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((heading-1))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"#\\\"\\n\\tcount=\\\"1\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-2\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-2\",\"list-after\":\"$:/core/ui/EditorToolbar/heading-2\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/heading-2\",\"caption\":\"{{$:/language/Buttons/Heading2/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Heading2/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((heading-2))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"#\\\"\\n\\tcount=\\\"2\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-3\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-3\",\"list-after\":\"$:/core/ui/EditorToolbar/heading-3\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/heading-3\",\"caption\":\"{{$:/language/Buttons/Heading3/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Heading3/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((heading-3))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"#\\\"\\n\\tcount=\\\"3\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-4\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-4\",\"list-after\":\"$:/core/ui/EditorToolbar/heading-4\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/heading-4\",\"caption\":\"{{$:/language/Buttons/Heading4/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Heading4/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((heading-4))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"#\\\"\\n\\tcount=\\\"4\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-5\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-5\",\"list-after\":\"$:/core/ui/EditorToolbar/heading-5\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/heading-5\",\"caption\":\"{{$:/language/Buttons/Heading5/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Heading5/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((heading-5))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"#\\\"\\n\\tcount=\\\"5\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-6\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/heading-6\",\"list-after\":\"$:/core/ui/EditorToolbar/heading-6\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/heading-6\",\"caption\":\"{{$:/language/Buttons/Heading6/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Heading6/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((heading-6))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"#\\\"\\n\\tcount=\\\"6\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/italic\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/italic\",\"list-after\":\"$:/core/ui/EditorToolbar/italic\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/italic\",\"caption\":\"{{$:/language/Buttons/Italic/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Italic/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((italic))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"wrap-selection\\\"\\n\\tprefix=\\\"*\\\"\\n\\tsuffix=\\\"*\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/link-dropdown\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/link-dropdown\",\"text\":\"\\\\define lingo-base() $:/language/Buttons/Link/\\n\\n\\\\define add-link-actions()\\n\\\\whitespace trim\\n\u003C$action-sendmessage $message=\\\"tm-edit-text-operation\\\" $param=\\\"make-markdown-link\\\" text={{$(linkTiddler)$}} />\\n\u003C$action-deletetiddler $filter=\\\"[\u003Cdropdown-state>] [\u003CsearchTiddler>] [\u003ClinkTiddler>] [\u003CstoreTitle>] [\u003CsearchListState>]\\\"/>\\n\\\\end\\n\\n\\\\define get-focus-selector() [data-tiddler-title=\\\"$(cssEscapedTitle)$\\\"] .tc-create-wikitext-link input\\n\\n\\\\define cancel-search-actions-inner()\\n\u003C$set name=\\\"userInput\\\" value={{{ [\u003CstoreTitle>get[text]] }}}>\u003C$list filter=\\\"[\u003CsearchTiddler>get[text]!match\u003CuserInput>]\\\" emptyMessage=\\\"\u003C$action-deletetiddler $filter='[\u003CsearchTiddler>] [\u003ClinkTiddler>] [\u003CstoreTitle>] [\u003CsearchListState>]'/>\\\">\u003C$action-setfield $tiddler=\u003C\u003CsearchTiddler>> text=\u003C\u003CuserInput>>/>\u003C$action-setfield $tiddler=\u003C\u003CrefreshTitle>> text=\\\"yes\\\"/>\u003C/$list>\u003C/$set>\\n\\\\end\\n\\n\\\\define cancel-search-actions() \u003C$list filter=\\\"[\u003CstoreTitle>!has[text]] +[\u003CsearchTiddler>!has[text]]\\\" emptyMessage=\\\"\u003C\u003Ccancel-search-actions-inner>>\\\">\u003C$action-sendmessage $message=\\\"tm-edit-text-operation\\\" $param=\\\"focus-editor\\\"/>\u003C/$list>\\n\\n\\\\define external-link()\\n\\\\whitespace trim\\n\u003C$button class=\\\"tc-btn-invisible\\\" style=\\\"width: auto; display: inline-block; background-colour: inherit;\\\" actions=\u003C\u003Cadd-link-actions>>>\\n{{$:/core/images/chevron-right}}\\n\u003C/$button>\\n\\\\end\\n\\n\\\\define set-next-input-tab(beforeafter:\\\"after\\\") \u003C$macrocall $name=\\\"change-input-tab\\\" stateTitle=\\\"$:/state/tab/search-results/sidebar\\\" tag=\\\"$:/tags/SearchResults\\\" beforeafter=\\\"$beforeafter$\\\" defaultState={{$:/config/SearchResults/Default}} actions=\\\"\u003C$action-setfield $tiddler='$:/state/search/currentTab' text=\u003C\u003CnextTab>>/>\\\"/>\\n\\n\\\\define body(config-title)\\n\\\\whitespace trim\\n''\u003C\u003Clingo Hint>>''\\n\\n\u003C$vars searchTiddler=\\\"\\\"\\\"$config-title$/search\\\"\\\"\\\" linkTiddler=\\\"\\\"\\\"$config-title$/link\\\"\\\"\\\" linktext=\\\"\\\" searchListState=\u003C\u003Cqualify \\\"$:/temp/link-search/selected-item\\\">> refreshTitle=\u003C\u003Cqualify \\\"$:/temp/link-search/refresh\\\">> storeTitle=\u003C\u003Cqualify \\\"$:/temp/link-search/input\\\">>>\\n\\n\u003C$vars linkTiddler=\u003C\u003CsearchTiddler>>>\\n\u003C$keyboard key=\\\"((input-tab-right))\\\" actions=\u003C\u003Cset-next-input-tab>>>\\n\u003C$keyboard key=\\\"((input-tab-left))\\\" actions=\u003C\u003Cset-next-input-tab \\\"before\\\">> class=\\\"tc-create-wikitext-link\\\">\\n\u003C$macrocall $name=\\\"keyboard-driven-input\\\" tiddler=\u003C\u003CsearchTiddler>> storeTitle=\u003C\u003CstoreTitle>>\\n\\t\\tselectionStateTitle=\u003C\u003CsearchListState>> refreshTitle=\u003C\u003CrefreshTitle>> type=\\\"search\\\" filterMinLength=\\\"1\\\"\\n\\t\\ttag=\\\"input\\\" focus=\\\"true\\\" class=\\\"tc-popup-handle\\\" inputCancelActions=\u003C\u003Ccancel-search-actions>>\\n\\t\\tinputAcceptActions=\u003C\u003Cadd-link-actions>> placeholder={{$:/language/Search/Search}} default=\\\"\\\"\\n\\t\\tconfigTiddlerFilter=\\\"[[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}]\\\" />\\n\u003C/$keyboard>\\n\u003C/$keyboard>\\n \\n\u003C$reveal tag=\\\"span\\\" state=\u003C\u003CstoreTitle>> type=\\\"nomatch\\\" text=\\\"\\\">\\n\u003C\u003Cexternal-link>>\\n \\n\u003C$button class=\\\"tc-btn-invisible\\\" style=\\\"width: auto; display: inline-block; background-colour: inherit;\\\">\\n\u003C\u003Ccancel-search-actions>>\u003C$set name=\\\"cssEscapedTitle\\\" value={{{ [\u003CstoryTiddler>escapecss[]] }}}>\u003C$action-sendmessage $message=\\\"tm-focus-selector\\\" $param=\u003C\u003Cget-focus-selector>>/>\u003C/$set>\\n{{$:/core/images/close-button}}\\n\u003C/$button>\\n\u003C/$reveal>\\n\u003C/$vars>\\n\\n\u003C$reveal tag=\\\"div\\\" state=\u003C\u003CstoreTitle>> type=\\\"nomatch\\\" text=\\\"\\\">\\n\\n\u003C$linkcatcher actions=\u003C\u003Cadd-link-actions>> to=\u003C\u003ClinkTiddler>>>\\n\\n\u003C$vars userInput={{{ [\u003CstoreTitle>get[text]] }}} configTiddler={{{ [[$:/state/search/currentTab]!is[missing]get[text]] ~[{$:/config/SearchResults/Default}] }}}>\\n\\n{{$:/core/ui/SearchResults}}\\n\\n\u003C/$vars>\\n\\n\u003C/$linkcatcher>\\n\\n\u003C/$reveal>\\n\\n\u003C/$vars>\\n\\n\\\\end\\n\\n\u003C$macrocall $name=\\\"body\\\" config-title=\u003C\u003Cqualify \\\"$:/state/Link/\\\">>/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/link\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/link\",\"list-after\":\"$:/core/ui/EditorToolbar/link\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/link\",\"caption\":\"{{$:/language/Buttons/Link/Caption}}\",\"description\":\"{{$:/language/Buttons/Link/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"button-classes\":\"tc-text-editor-toolbar-item-start-group\",\"shortcuts\":\"((link))\",\"dropdown\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/link-dropdown\",\"text\":\"\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/linkify\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/linkify\",\"caption\":\"{{$:/language/Buttons/Linkify/Caption}} (Markdown)\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"description\":\"{{$:/language/Buttons/Linkify/Hint}}\",\"icon\":\"$:/plugins/tiddlywiki/markdown/images/markdown-linkify\",\"list-after\":\"$:/core/ui/EditorToolbar/linkify\",\"shortcuts\":\"((linkify))\",\"tags\":\"$:/tags/EditorToolbar\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"wrap-selection\\\"\\n\\tprefix=\\\"[\\\"\\n\\tsuffix=\\\"]()\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/list-bullet\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/list-bullet\",\"list-after\":\"$:/core/ui/EditorToolbar/list-bullet\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/list-bullet\",\"caption\":\"{{$:/language/Buttons/ListBullet/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/ListBullet/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((list-bullet))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"*\\\"\\n\\tcount=\\\"1\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/list-number\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/list-number\",\"list-after\":\"$:/core/ui/EditorToolbar/list-number\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/list-number\",\"caption\":\"{{$:/language/Buttons/ListNumber/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/ListNumber/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((list-number))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\"1.\\\"\\n\\tcount=\\\"1\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/mono-block\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/mono-block\",\"list-after\":\"$:/core/ui/EditorToolbar/mono-block\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/mono-block\",\"caption\":\"{{$:/language/Buttons/MonoBlock/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/MonoBlock/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"button-classes\":\"tc-text-editor-toolbar-item-start-group\",\"shortcuts\":\"((mono-block))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"wrap-lines\\\"\\n\\tprefix=\\\"\\n```\\\"\\n\\tsuffix=\\\"```\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/mono-line\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/mono-line\",\"list-after\":\"$:/core/ui/EditorToolbar/mono-line\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/mono-line\",\"caption\":\"{{$:/language/Buttons/MonoLine/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/MonoLine/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((mono-line))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"wrap-selection\\\"\\n\\tprefix=\\\"`\\\"\\n\\tsuffix=\\\"`\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/EditorToolbar/quote\":{\"title\":\"$:/plugins/tiddlywiki/markdown/EditorToolbar/quote\",\"list-after\":\"$:/core/ui/EditorToolbar/quote\",\"tags\":\"$:/tags/EditorToolbar\",\"icon\":\"$:/core/images/quote\",\"caption\":\"{{$:/language/Buttons/Quote/Caption}} (Markdown)\",\"description\":\"{{$:/language/Buttons/Quote/Hint}}\",\"condition\":\"[\u003CtargetTiddler>type[text/x-markdown]] [\u003CtargetTiddler>type[text/markdown]]\",\"shortcuts\":\"((quote))\",\"text\":\"\u003C$action-sendmessage\\n\\t$message=\\\"tm-edit-text-operation\\\"\\n\\t$param=\\\"prefix-lines\\\"\\n\\tcharacter=\\\">\\\"\\n\\tcount=\\\"1\\\"\\n/>\\n\"},\"$:/plugins/tiddlywiki/markdown/KeyboardShortcuts/new-markdown-tiddler\":{\"title\":\"$:/plugins/tiddlywiki/markdown/KeyboardShortcuts/new-markdown-tiddler\",\"tags\":\"$:/tags/KeyboardShortcut\",\"key\":\"((new-markdown-tiddler))\",\"text\":\"\\\\whitespace trim\\n\u003C$navigator story=\\\"$:/StoryList\\\" history=\\\"$:/HistoryList\\\" openLinkFromInsideRiver={{$:/config/Navigation/openLinkFromInsideRiver}} openLinkFromOutsideRiver={{$:/config/Navigation/openLinkFromOutsideRiver}} relinkOnRename={{$:/config/RelinkOnRename}}>\\n\u003C$action-sendmessage $message=\\\"tm-new-tiddler\\\" type=\\\"text/markdown\\\"/>\\n\u003C/$navigator>\\n\"},\"$:/config/ShortcutInfo/new-markdown-tiddler\":{\"title\":\"$:/config/ShortcutInfo/new-markdown-tiddler\",\"text\":\"{{$:/language/Buttons/NewMarkdown/Hint}}\"},\"$:/config/shortcuts-mac/new-markdown-tiddler\":{\"title\":\"$:/config/shortcuts-mac/new-markdown-tiddler\",\"text\":\"ctrl-M\"},\"$:/config/shortcuts-not-mac/new-markdown-tiddler\":{\"title\":\"$:/config/shortcuts-not-mac/new-markdown-tiddler\",\"text\":\"alt-M\"},\"$:/config/markdown/breaks\":{\"title\":\"$:/config/markdown/breaks\",\"text\":\"false\"},\"$:/config/markdown/linkify\":{\"title\":\"$:/config/markdown/linkify\",\"text\":\"false\"},\"$:/config/markdown/quotes\":{\"title\":\"$:/config/markdown/quotes\",\"text\":\"“”‘’\"},\"$:/config/markdown/renderWikiText\":{\"title\":\"$:/config/markdown/renderWikiText\",\"text\":\"true\"},\"$:/config/markdown/renderWikiTextPragma\":{\"title\":\"$:/config/markdown/renderWikiTextPragma\",\"text\":\"\\\\rules only html entity syslink prettylink image prettyextlink wikilink commentblock commentinline macrocallblock macrocallinline transcludeblock transcludeinline filteredtranscludeblock filteredtranscludeinline\"},\"$:/config/markdown/typographer\":{\"title\":\"$:/config/markdown/typographer\",\"text\":\"false\"},\"$:/plugins/tiddlywiki/markdown/config\":{\"title\":\"$:/plugins/tiddlywiki/markdown/config\",\"text\":\"! Plugin Configuration\\n\\n|!Config |!Default |!Description |\\n|[[breaks|$:/config/markdown/breaks]]|`false`|markdown-it library config: Convert '\\\\n' in paragraphs into `\u003Cbr>` |\\n|[[linkify|$:/config/markdown/linkify]]|`false`|markdown-it library config: Autoconvert URL-like text to links |\\n|[[renderWikiText|$:/config/markdown/renderWikiText]]|`true`|After Markdown is parsed, should any text elements be handed off to the ~WikiText parser for further processing? |\\n|[[renderWikiTextPragma|$:/config/markdown/renderWikiTextPragma]]|\u003Ccode>\u003C$view tiddler=\\\"$:/plugins/tiddlywiki/markdown\\\" subtiddler=\\\"$:/config/markdown/renderWikiTextPragma\\\" mode=\\\"inline\\\"/>\u003C/code>|When handing off to the ~WikiText parser, what parser rules should it follow? |\\n|[[typographer|$:/config/markdown/typographer]]|`false`|markdown-it library config: Enable some language-neutral replacement + quotes beautification |\\n|[[quotes|$:/config/markdown/quotes]]|`“”‘’`|markdown-it library config: Double + single quotes replacement pairs, when `typographer` is enabled |\\n\\n''IMPORTANT:'' You must reload your wiki for changes to take effect.\\n\\n\u003Ch2 style=\\\"margin-top:1.5em\\\">~WikiText Pragma\u003C/h2>\\n\\nThe value of [[renderWikiTextPragma|$:/config/markdown/renderWikiTextPragma]] has been carefully tuned to properly integrate markdown with ~TiddlyWiki. Changing this setting may produce unexpected results, but the inclusion of the following parser rules should be fine:\\n\\n; image\\n: embed images using ~TiddlyWiki's image syntax:\\n\\n\u003Cp style=\\\"margin-left:1em\\\">\\n\\n```\\n[img[An explanatory tooltip|TiddlerTitle]]\\n\\n[img width=23 class=\\\"tc-image\\\" [https://tiddlywiki.com/fractalveg.jpg]]\\n```\\n\u003C/p>\\n\\n; prettylink\\n: create links the ~TiddlyWiki way:\\n\\n\u003Cp style=\\\"margin-left:1em\\\">\\n\\n```\\n[[TiddlerTitle]]\\n\\n[[Displayed Link Title|Tiddler Title]]\\n\\n[[TW5|https://tiddlywiki.com/]]\\n```\\n\u003C/p>\\n\\n; prettyextlink\\n: create external links using the following syntax:\\n\\n\u003Cp style=\\\"margin-left:1em\\\">\\n\\n```\\n[ext[Open file|index.html]]\\n\\n[ext[Open file|../README.md]]\\n```\\n\u003C/p>\\n\\n; wikilink\\n: auto-link ~CamelCase titles\\n\\n; syslink\\n: auto-link system tiddlers\\n\\n\u003Ch2 style=\\\"margin-top:1.5em\\\">Typographical Replacements\u003C/h2>\\n\\nWhen [[typographer|$:/config/markdown/typographer]] is enabled, markdown-it will provide these typographical replacements:\\n\\n```\\n(c) (C) → ©\\n(tm) (TM) → ™\\n(r) (R) → ®\\n+- → ±\\n... → …\\n?.... → ?..\\n!.... → !..\\n????? → ???\\n!!!!! → !!!\\n,, → ,\\n-- → –\\n--- → —\\n```\"},\"$:/language/Docs/Types/text/markdown\":{\"title\":\"$:/language/Docs/Types/text/markdown\",\"description\":\"Markdown\",\"name\":\"text/markdown\",\"group\":\"Text\"},\"$:/plugins/tiddlywiki/markdown/editor-operations/make-markdown-link.js\":{\"title\":\"$:/plugins/tiddlywiki/markdown/editor-operations/make-markdown-link.js\",\"text\":\"/*\\\\\\ntitle: $:/plugins/tiddlywiki/markdown/editor-operations/make-markdown-link.js\\ntype: application/javascript\\nmodule-type: texteditoroperation\\n\\nText editor operation to make a markdown link\\n\\n\\\\*/\\n(function(){\\n\\n/*jslint node: true, browser: true */\\n/*global $tw: false */\\n\\\"use strict\\\";\\n\\nexports[\\\"make-markdown-link\\\"] = function(event,operation) {\\n\\tvar rx = /[()\\\\\\\\]/g, rs = '\\\\\\\\$&';\\n\\n\\tif(operation.selection) {\\n\\t\\tvar desc = operation.selection.replace(/[\\\\[\\\\]\\\\\\\\]/g, rs);\\n\\n\\t\\tif(event.paramObject.text.indexOf(\\\"://\\\") !== -1) {\\n\\t\\t\\toperation.replacement = \\\"[\\\" + desc + \\\"](\\\" + event.paramObject.text.replace(rx, rs) + \\\")\\\";\\n\\t\\t} else {\\n\\t\\t\\toperation.replacement = \\\"[\\\" + desc + \\\"](#\\\" + encodeURIComponent(event.paramObject.text).replace(rx, rs) + \\\")\\\";\\n\\t\\t}\\n\\t\\toperation.cutStart = operation.selStart;\\n\\t\\toperation.cutEnd = operation.selEnd;\\n\\t} else {\\n\\t\\tif(event.paramObject.text.indexOf(\\\"://\\\") !== -1) {\\n\\t\\t\\toperation.replacement = \\\"\u003C\\\" + event.paramObject.text.replace(/[\u003C>]/g, function(m, offset, str) {\\n\\t\\t\\t\\treturn encodeURI(m);\\n\\t\\t\\t}) + \\\">\\\";\\n\\t\\t} else {\\n\\t\\t\\toperation.replacement = \\\"[](#\\\" + encodeURIComponent(event.paramObject.text).replace(rx, rs) + \\\")\\\";\\n\\t\\t}\\n\\t\\toperation.cutStart = operation.selStart;\\n\\t\\toperation.cutEnd = operation.selEnd;\\n\\t}\\n\\toperation.newSelStart = operation.selStart + operation.replacement.length;\\n\\toperation.newSelEnd = operation.newSelStart;\\n};\\n\\n})();\\n\",\"type\":\"application/javascript\",\"module-type\":\"texteditoroperation\"},\"$:/plugins/tiddlywiki/markdown/markdown-it.js\":{\"text\":\"/*! markdown-it 13.0.1 https://github.com/markdown-it/markdown-it @license MIT */\\n!function(e,r){\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module?module.exports=r():\\\"function\\\"==typeof define&&define.amd?define(r):(e=\\\"undefined\\\"!=typeof globalThis?globalThis:e||self).markdownit=r()}(this,(function(){\\\"use strict\\\";function e(e){if(e.__esModule)return e;var r=Object.defineProperty({},\\\"__esModule\\\",{value:!0});return Object.keys(e).forEach((function(t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})})),r}var r={Aacute:\\\"\\\\xc1\\\",aacute:\\\"\\\\xe1\\\",Abreve:\\\"\\\\u0102\\\",abreve:\\\"\\\\u0103\\\",ac:\\\"\\\\u223e\\\",acd:\\\"\\\\u223f\\\",acE:\\\"\\\\u223e\\\\u0333\\\",Acirc:\\\"\\\\xc2\\\",acirc:\\\"\\\\xe2\\\",acute:\\\"\\\\xb4\\\",Acy:\\\"\\\\u0410\\\",acy:\\\"\\\\u0430\\\",AElig:\\\"\\\\xc6\\\",aelig:\\\"\\\\xe6\\\",af:\\\"\\\\u2061\\\",Afr:\\\"\\\\ud835\\\\udd04\\\",afr:\\\"\\\\ud835\\\\udd1e\\\",Agrave:\\\"\\\\xc0\\\",agrave:\\\"\\\\xe0\\\",alefsym:\\\"\\\\u2135\\\",aleph:\\\"\\\\u2135\\\",Alpha:\\\"\\\\u0391\\\",alpha:\\\"\\\\u03b1\\\",Amacr:\\\"\\\\u0100\\\",amacr:\\\"\\\\u0101\\\",amalg:\\\"\\\\u2a3f\\\",amp:\\\"&\\\",AMP:\\\"&\\\",andand:\\\"\\\\u2a55\\\",And:\\\"\\\\u2a53\\\",and:\\\"\\\\u2227\\\",andd:\\\"\\\\u2a5c\\\",andslope:\\\"\\\\u2a58\\\",andv:\\\"\\\\u2a5a\\\",ang:\\\"\\\\u2220\\\",ange:\\\"\\\\u29a4\\\",angle:\\\"\\\\u2220\\\",angmsdaa:\\\"\\\\u29a8\\\",angmsdab:\\\"\\\\u29a9\\\",angmsdac:\\\"\\\\u29aa\\\",angmsdad:\\\"\\\\u29ab\\\",angmsdae:\\\"\\\\u29ac\\\",angmsdaf:\\\"\\\\u29ad\\\",angmsdag:\\\"\\\\u29ae\\\",angmsdah:\\\"\\\\u29af\\\",angmsd:\\\"\\\\u2221\\\",angrt:\\\"\\\\u221f\\\",angrtvb:\\\"\\\\u22be\\\",angrtvbd:\\\"\\\\u299d\\\",angsph:\\\"\\\\u2222\\\",angst:\\\"\\\\xc5\\\",angzarr:\\\"\\\\u237c\\\",Aogon:\\\"\\\\u0104\\\",aogon:\\\"\\\\u0105\\\",Aopf:\\\"\\\\ud835\\\\udd38\\\",aopf:\\\"\\\\ud835\\\\udd52\\\",apacir:\\\"\\\\u2a6f\\\",ap:\\\"\\\\u2248\\\",apE:\\\"\\\\u2a70\\\",ape:\\\"\\\\u224a\\\",apid:\\\"\\\\u224b\\\",apos:\\\"'\\\",ApplyFunction:\\\"\\\\u2061\\\",approx:\\\"\\\\u2248\\\",approxeq:\\\"\\\\u224a\\\",Aring:\\\"\\\\xc5\\\",aring:\\\"\\\\xe5\\\",Ascr:\\\"\\\\ud835\\\\udc9c\\\",ascr:\\\"\\\\ud835\\\\udcb6\\\",Assign:\\\"\\\\u2254\\\",ast:\\\"*\\\",asymp:\\\"\\\\u2248\\\",asympeq:\\\"\\\\u224d\\\",Atilde:\\\"\\\\xc3\\\",atilde:\\\"\\\\xe3\\\",Auml:\\\"\\\\xc4\\\",auml:\\\"\\\\xe4\\\",awconint:\\\"\\\\u2233\\\",awint:\\\"\\\\u2a11\\\",backcong:\\\"\\\\u224c\\\",backepsilon:\\\"\\\\u03f6\\\",backprime:\\\"\\\\u2035\\\",backsim:\\\"\\\\u223d\\\",backsimeq:\\\"\\\\u22cd\\\",Backslash:\\\"\\\\u2216\\\",Barv:\\\"\\\\u2ae7\\\",barvee:\\\"\\\\u22bd\\\",barwed:\\\"\\\\u2305\\\",Barwed:\\\"\\\\u2306\\\",barwedge:\\\"\\\\u2305\\\",bbrk:\\\"\\\\u23b5\\\",bbrktbrk:\\\"\\\\u23b6\\\",bcong:\\\"\\\\u224c\\\",Bcy:\\\"\\\\u0411\\\",bcy:\\\"\\\\u0431\\\",bdquo:\\\"\\\\u201e\\\",becaus:\\\"\\\\u2235\\\",because:\\\"\\\\u2235\\\",Because:\\\"\\\\u2235\\\",bemptyv:\\\"\\\\u29b0\\\",bepsi:\\\"\\\\u03f6\\\",bernou:\\\"\\\\u212c\\\",Bernoullis:\\\"\\\\u212c\\\",Beta:\\\"\\\\u0392\\\",beta:\\\"\\\\u03b2\\\",beth:\\\"\\\\u2136\\\",between:\\\"\\\\u226c\\\",Bfr:\\\"\\\\ud835\\\\udd05\\\",bfr:\\\"\\\\ud835\\\\udd1f\\\",bigcap:\\\"\\\\u22c2\\\",bigcirc:\\\"\\\\u25ef\\\",bigcup:\\\"\\\\u22c3\\\",bigodot:\\\"\\\\u2a00\\\",bigoplus:\\\"\\\\u2a01\\\",bigotimes:\\\"\\\\u2a02\\\",bigsqcup:\\\"\\\\u2a06\\\",bigstar:\\\"\\\\u2605\\\",bigtriangledown:\\\"\\\\u25bd\\\",bigtriangleup:\\\"\\\\u25b3\\\",biguplus:\\\"\\\\u2a04\\\",bigvee:\\\"\\\\u22c1\\\",bigwedge:\\\"\\\\u22c0\\\",bkarow:\\\"\\\\u290d\\\",blacklozenge:\\\"\\\\u29eb\\\",blacksquare:\\\"\\\\u25aa\\\",blacktriangle:\\\"\\\\u25b4\\\",blacktriangledown:\\\"\\\\u25be\\\",blacktriangleleft:\\\"\\\\u25c2\\\",blacktriangleright:\\\"\\\\u25b8\\\",blank:\\\"\\\\u2423\\\",blk12:\\\"\\\\u2592\\\",blk14:\\\"\\\\u2591\\\",blk34:\\\"\\\\u2593\\\",block:\\\"\\\\u2588\\\",bne:\\\"=\\\\u20e5\\\",bnequiv:\\\"\\\\u2261\\\\u20e5\\\",bNot:\\\"\\\\u2aed\\\",bnot:\\\"\\\\u2310\\\",Bopf:\\\"\\\\ud835\\\\udd39\\\",bopf:\\\"\\\\ud835\\\\udd53\\\",bot:\\\"\\\\u22a5\\\",bottom:\\\"\\\\u22a5\\\",bowtie:\\\"\\\\u22c8\\\",boxbox:\\\"\\\\u29c9\\\",boxdl:\\\"\\\\u2510\\\",boxdL:\\\"\\\\u2555\\\",boxDl:\\\"\\\\u2556\\\",boxDL:\\\"\\\\u2557\\\",boxdr:\\\"\\\\u250c\\\",boxdR:\\\"\\\\u2552\\\",boxDr:\\\"\\\\u2553\\\",boxDR:\\\"\\\\u2554\\\",boxh:\\\"\\\\u2500\\\",boxH:\\\"\\\\u2550\\\",boxhd:\\\"\\\\u252c\\\",boxHd:\\\"\\\\u2564\\\",boxhD:\\\"\\\\u2565\\\",boxHD:\\\"\\\\u2566\\\",boxhu:\\\"\\\\u2534\\\",boxHu:\\\"\\\\u2567\\\",boxhU:\\\"\\\\u2568\\\",boxHU:\\\"\\\\u2569\\\",boxminus:\\\"\\\\u229f\\\",boxplus:\\\"\\\\u229e\\\",boxtimes:\\\"\\\\u22a0\\\",boxul:\\\"\\\\u2518\\\",boxuL:\\\"\\\\u255b\\\",boxUl:\\\"\\\\u255c\\\",boxUL:\\\"\\\\u255d\\\",boxur:\\\"\\\\u2514\\\",boxuR:\\\"\\\\u2558\\\",boxUr:\\\"\\\\u2559\\\",boxUR:\\\"\\\\u255a\\\",boxv:\\\"\\\\u2502\\\",boxV:\\\"\\\\u2551\\\",boxvh:\\\"\\\\u253c\\\",boxvH:\\\"\\\\u256a\\\",boxVh:\\\"\\\\u256b\\\",boxVH:\\\"\\\\u256c\\\",boxvl:\\\"\\\\u2524\\\",boxvL:\\\"\\\\u2561\\\",boxVl:\\\"\\\\u2562\\\",boxVL:\\\"\\\\u2563\\\",boxvr:\\\"\\\\u251c\\\",boxvR:\\\"\\\\u255e\\\",boxVr:\\\"\\\\u255f\\\",boxVR:\\\"\\\\u2560\\\",bprime:\\\"\\\\u2035\\\",breve:\\\"\\\\u02d8\\\",Breve:\\\"\\\\u02d8\\\",brvbar:\\\"\\\\xa6\\\",bscr:\\\"\\\\ud835\\\\udcb7\\\",Bscr:\\\"\\\\u212c\\\",bsemi:\\\"\\\\u204f\\\",bsim:\\\"\\\\u223d\\\",bsime:\\\"\\\\u22cd\\\",bsolb:\\\"\\\\u29c5\\\",bsol:\\\"\\\\\\\\\\\",bsolhsub:\\\"\\\\u27c8\\\",bull:\\\"\\\\u2022\\\",bullet:\\\"\\\\u2022\\\",bump:\\\"\\\\u224e\\\",bumpE:\\\"\\\\u2aae\\\",bumpe:\\\"\\\\u224f\\\",Bumpeq:\\\"\\\\u224e\\\",bumpeq:\\\"\\\\u224f\\\",Cacute:\\\"\\\\u0106\\\",cacute:\\\"\\\\u0107\\\",capand:\\\"\\\\u2a44\\\",capbrcup:\\\"\\\\u2a49\\\",capcap:\\\"\\\\u2a4b\\\",cap:\\\"\\\\u2229\\\",Cap:\\\"\\\\u22d2\\\",capcup:\\\"\\\\u2a47\\\",capdot:\\\"\\\\u2a40\\\",CapitalDifferentialD:\\\"\\\\u2145\\\",caps:\\\"\\\\u2229\\\\ufe00\\\",caret:\\\"\\\\u2041\\\",caron:\\\"\\\\u02c7\\\",Cayleys:\\\"\\\\u212d\\\",ccaps:\\\"\\\\u2a4d\\\",Ccaron:\\\"\\\\u010c\\\",ccaron:\\\"\\\\u010d\\\",Ccedil:\\\"\\\\xc7\\\",ccedil:\\\"\\\\xe7\\\",Ccirc:\\\"\\\\u0108\\\",ccirc:\\\"\\\\u0109\\\",Cconint:\\\"\\\\u2230\\\",ccups:\\\"\\\\u2a4c\\\",ccupssm:\\\"\\\\u2a50\\\",Cdot:\\\"\\\\u010a\\\",cdot:\\\"\\\\u010b\\\",cedil:\\\"\\\\xb8\\\",Cedilla:\\\"\\\\xb8\\\",cemptyv:\\\"\\\\u29b2\\\",cent:\\\"\\\\xa2\\\",centerdot:\\\"\\\\xb7\\\",CenterDot:\\\"\\\\xb7\\\",cfr:\\\"\\\\ud835\\\\udd20\\\",Cfr:\\\"\\\\u212d\\\",CHcy:\\\"\\\\u0427\\\",chcy:\\\"\\\\u0447\\\",check:\\\"\\\\u2713\\\",checkmark:\\\"\\\\u2713\\\",Chi:\\\"\\\\u03a7\\\",chi:\\\"\\\\u03c7\\\",circ:\\\"\\\\u02c6\\\",circeq:\\\"\\\\u2257\\\",circlearrowleft:\\\"\\\\u21ba\\\",circlearrowright:\\\"\\\\u21bb\\\",circledast:\\\"\\\\u229b\\\",circledcirc:\\\"\\\\u229a\\\",circleddash:\\\"\\\\u229d\\\",CircleDot:\\\"\\\\u2299\\\",circledR:\\\"\\\\xae\\\",circledS:\\\"\\\\u24c8\\\",CircleMinus:\\\"\\\\u2296\\\",CirclePlus:\\\"\\\\u2295\\\",CircleTimes:\\\"\\\\u2297\\\",cir:\\\"\\\\u25cb\\\",cirE:\\\"\\\\u29c3\\\",cire:\\\"\\\\u2257\\\",cirfnint:\\\"\\\\u2a10\\\",cirmid:\\\"\\\\u2aef\\\",cirscir:\\\"\\\\u29c2\\\",ClockwiseContourIntegral:\\\"\\\\u2232\\\",CloseCurlyDoubleQuote:\\\"\\\\u201d\\\",CloseCurlyQuote:\\\"\\\\u2019\\\",clubs:\\\"\\\\u2663\\\",clubsuit:\\\"\\\\u2663\\\",colon:\\\":\\\",Colon:\\\"\\\\u2237\\\",Colone:\\\"\\\\u2a74\\\",colone:\\\"\\\\u2254\\\",coloneq:\\\"\\\\u2254\\\",comma:\\\",\\\",commat:\\\"@\\\",comp:\\\"\\\\u2201\\\",compfn:\\\"\\\\u2218\\\",complement:\\\"\\\\u2201\\\",complexes:\\\"\\\\u2102\\\",cong:\\\"\\\\u2245\\\",congdot:\\\"\\\\u2a6d\\\",Congruent:\\\"\\\\u2261\\\",conint:\\\"\\\\u222e\\\",Conint:\\\"\\\\u222f\\\",ContourIntegral:\\\"\\\\u222e\\\",copf:\\\"\\\\ud835\\\\udd54\\\",Copf:\\\"\\\\u2102\\\",coprod:\\\"\\\\u2210\\\",Coproduct:\\\"\\\\u2210\\\",copy:\\\"\\\\xa9\\\",COPY:\\\"\\\\xa9\\\",copysr:\\\"\\\\u2117\\\",CounterClockwiseContourIntegral:\\\"\\\\u2233\\\",crarr:\\\"\\\\u21b5\\\",cross:\\\"\\\\u2717\\\",Cross:\\\"\\\\u2a2f\\\",Cscr:\\\"\\\\ud835\\\\udc9e\\\",cscr:\\\"\\\\ud835\\\\udcb8\\\",csub:\\\"\\\\u2acf\\\",csube:\\\"\\\\u2ad1\\\",csup:\\\"\\\\u2ad0\\\",csupe:\\\"\\\\u2ad2\\\",ctdot:\\\"\\\\u22ef\\\",cudarrl:\\\"\\\\u2938\\\",cudarrr:\\\"\\\\u2935\\\",cuepr:\\\"\\\\u22de\\\",cuesc:\\\"\\\\u22df\\\",cularr:\\\"\\\\u21b6\\\",cularrp:\\\"\\\\u293d\\\",cupbrcap:\\\"\\\\u2a48\\\",cupcap:\\\"\\\\u2a46\\\",CupCap:\\\"\\\\u224d\\\",cup:\\\"\\\\u222a\\\",Cup:\\\"\\\\u22d3\\\",cupcup:\\\"\\\\u2a4a\\\",cupdot:\\\"\\\\u228d\\\",cupor:\\\"\\\\u2a45\\\",cups:\\\"\\\\u222a\\\\ufe00\\\",curarr:\\\"\\\\u21b7\\\",curarrm:\\\"\\\\u293c\\\",curlyeqprec:\\\"\\\\u22de\\\",curlyeqsucc:\\\"\\\\u22df\\\",curlyvee:\\\"\\\\u22ce\\\",curlywedge:\\\"\\\\u22cf\\\",curren:\\\"\\\\xa4\\\",curvearrowleft:\\\"\\\\u21b6\\\",curvearrowright:\\\"\\\\u21b7\\\",cuvee:\\\"\\\\u22ce\\\",cuwed:\\\"\\\\u22cf\\\",cwconint:\\\"\\\\u2232\\\",cwint:\\\"\\\\u2231\\\",cylcty:\\\"\\\\u232d\\\",dagger:\\\"\\\\u2020\\\",Dagger:\\\"\\\\u2021\\\",daleth:\\\"\\\\u2138\\\",darr:\\\"\\\\u2193\\\",Darr:\\\"\\\\u21a1\\\",dArr:\\\"\\\\u21d3\\\",dash:\\\"\\\\u2010\\\",Dashv:\\\"\\\\u2ae4\\\",dashv:\\\"\\\\u22a3\\\",dbkarow:\\\"\\\\u290f\\\",dblac:\\\"\\\\u02dd\\\",Dcaron:\\\"\\\\u010e\\\",dcaron:\\\"\\\\u010f\\\",Dcy:\\\"\\\\u0414\\\",dcy:\\\"\\\\u0434\\\",ddagger:\\\"\\\\u2021\\\",ddarr:\\\"\\\\u21ca\\\",DD:\\\"\\\\u2145\\\",dd:\\\"\\\\u2146\\\",DDotrahd:\\\"\\\\u2911\\\",ddotseq:\\\"\\\\u2a77\\\",deg:\\\"\\\\xb0\\\",Del:\\\"\\\\u2207\\\",Delta:\\\"\\\\u0394\\\",delta:\\\"\\\\u03b4\\\",demptyv:\\\"\\\\u29b1\\\",dfisht:\\\"\\\\u297f\\\",Dfr:\\\"\\\\ud835\\\\udd07\\\",dfr:\\\"\\\\ud835\\\\udd21\\\",dHar:\\\"\\\\u2965\\\",dharl:\\\"\\\\u21c3\\\",dharr:\\\"\\\\u21c2\\\",DiacriticalAcute:\\\"\\\\xb4\\\",DiacriticalDot:\\\"\\\\u02d9\\\",DiacriticalDoubleAcute:\\\"\\\\u02dd\\\",DiacriticalGrave:\\\"`\\\",DiacriticalTilde:\\\"\\\\u02dc\\\",diam:\\\"\\\\u22c4\\\",diamond:\\\"\\\\u22c4\\\",Diamond:\\\"\\\\u22c4\\\",diamondsuit:\\\"\\\\u2666\\\",diams:\\\"\\\\u2666\\\",die:\\\"\\\\xa8\\\",DifferentialD:\\\"\\\\u2146\\\",digamma:\\\"\\\\u03dd\\\",disin:\\\"\\\\u22f2\\\",div:\\\"\\\\xf7\\\",divide:\\\"\\\\xf7\\\",divideontimes:\\\"\\\\u22c7\\\",divonx:\\\"\\\\u22c7\\\",DJcy:\\\"\\\\u0402\\\",djcy:\\\"\\\\u0452\\\",dlcorn:\\\"\\\\u231e\\\",dlcrop:\\\"\\\\u230d\\\",dollar:\\\"$\\\",Dopf:\\\"\\\\ud835\\\\udd3b\\\",dopf:\\\"\\\\ud835\\\\udd55\\\",Dot:\\\"\\\\xa8\\\",dot:\\\"\\\\u02d9\\\",DotDot:\\\"\\\\u20dc\\\",doteq:\\\"\\\\u2250\\\",doteqdot:\\\"\\\\u2251\\\",DotEqual:\\\"\\\\u2250\\\",dotminus:\\\"\\\\u2238\\\",dotplus:\\\"\\\\u2214\\\",dotsquare:\\\"\\\\u22a1\\\",doublebarwedge:\\\"\\\\u2306\\\",DoubleContourIntegral:\\\"\\\\u222f\\\",DoubleDot:\\\"\\\\xa8\\\",DoubleDownArrow:\\\"\\\\u21d3\\\",DoubleLeftArrow:\\\"\\\\u21d0\\\",DoubleLeftRightArrow:\\\"\\\\u21d4\\\",DoubleLeftTee:\\\"\\\\u2ae4\\\",DoubleLongLeftArrow:\\\"\\\\u27f8\\\",DoubleLongLeftRightArrow:\\\"\\\\u27fa\\\",DoubleLongRightArrow:\\\"\\\\u27f9\\\",DoubleRightArrow:\\\"\\\\u21d2\\\",DoubleRightTee:\\\"\\\\u22a8\\\",DoubleUpArrow:\\\"\\\\u21d1\\\",DoubleUpDownArrow:\\\"\\\\u21d5\\\",DoubleVerticalBar:\\\"\\\\u2225\\\",DownArrowBar:\\\"\\\\u2913\\\",downarrow:\\\"\\\\u2193\\\",DownArrow:\\\"\\\\u2193\\\",Downarrow:\\\"\\\\u21d3\\\",DownArrowUpArrow:\\\"\\\\u21f5\\\",DownBreve:\\\"\\\\u0311\\\",downdownarrows:\\\"\\\\u21ca\\\",downharpoonleft:\\\"\\\\u21c3\\\",downharpoonright:\\\"\\\\u21c2\\\",DownLeftRightVector:\\\"\\\\u2950\\\",DownLeftTeeVector:\\\"\\\\u295e\\\",DownLeftVectorBar:\\\"\\\\u2956\\\",DownLeftVector:\\\"\\\\u21bd\\\",DownRightTeeVector:\\\"\\\\u295f\\\",DownRightVectorBar:\\\"\\\\u2957\\\",DownRightVector:\\\"\\\\u21c1\\\",DownTeeArrow:\\\"\\\\u21a7\\\",DownTee:\\\"\\\\u22a4\\\",drbkarow:\\\"\\\\u2910\\\",drcorn:\\\"\\\\u231f\\\",drcrop:\\\"\\\\u230c\\\",Dscr:\\\"\\\\ud835\\\\udc9f\\\",dscr:\\\"\\\\ud835\\\\udcb9\\\",DScy:\\\"\\\\u0405\\\",dscy:\\\"\\\\u0455\\\",dsol:\\\"\\\\u29f6\\\",Dstrok:\\\"\\\\u0110\\\",dstrok:\\\"\\\\u0111\\\",dtdot:\\\"\\\\u22f1\\\",dtri:\\\"\\\\u25bf\\\",dtrif:\\\"\\\\u25be\\\",duarr:\\\"\\\\u21f5\\\",duhar:\\\"\\\\u296f\\\",dwangle:\\\"\\\\u29a6\\\",DZcy:\\\"\\\\u040f\\\",dzcy:\\\"\\\\u045f\\\",dzigrarr:\\\"\\\\u27ff\\\",Eacute:\\\"\\\\xc9\\\",eacute:\\\"\\\\xe9\\\",easter:\\\"\\\\u2a6e\\\",Ecaron:\\\"\\\\u011a\\\",ecaron:\\\"\\\\u011b\\\",Ecirc:\\\"\\\\xca\\\",ecirc:\\\"\\\\xea\\\",ecir:\\\"\\\\u2256\\\",ecolon:\\\"\\\\u2255\\\",Ecy:\\\"\\\\u042d\\\",ecy:\\\"\\\\u044d\\\",eDDot:\\\"\\\\u2a77\\\",Edot:\\\"\\\\u0116\\\",edot:\\\"\\\\u0117\\\",eDot:\\\"\\\\u2251\\\",ee:\\\"\\\\u2147\\\",efDot:\\\"\\\\u2252\\\",Efr:\\\"\\\\ud835\\\\udd08\\\",efr:\\\"\\\\ud835\\\\udd22\\\",eg:\\\"\\\\u2a9a\\\",Egrave:\\\"\\\\xc8\\\",egrave:\\\"\\\\xe8\\\",egs:\\\"\\\\u2a96\\\",egsdot:\\\"\\\\u2a98\\\",el:\\\"\\\\u2a99\\\",Element:\\\"\\\\u2208\\\",elinters:\\\"\\\\u23e7\\\",ell:\\\"\\\\u2113\\\",els:\\\"\\\\u2a95\\\",elsdot:\\\"\\\\u2a97\\\",Emacr:\\\"\\\\u0112\\\",emacr:\\\"\\\\u0113\\\",empty:\\\"\\\\u2205\\\",emptyset:\\\"\\\\u2205\\\",EmptySmallSquare:\\\"\\\\u25fb\\\",emptyv:\\\"\\\\u2205\\\",EmptyVerySmallSquare:\\\"\\\\u25ab\\\",emsp13:\\\"\\\\u2004\\\",emsp14:\\\"\\\\u2005\\\",emsp:\\\"\\\\u2003\\\",ENG:\\\"\\\\u014a\\\",eng:\\\"\\\\u014b\\\",ensp:\\\"\\\\u2002\\\",Eogon:\\\"\\\\u0118\\\",eogon:\\\"\\\\u0119\\\",Eopf:\\\"\\\\ud835\\\\udd3c\\\",eopf:\\\"\\\\ud835\\\\udd56\\\",epar:\\\"\\\\u22d5\\\",eparsl:\\\"\\\\u29e3\\\",eplus:\\\"\\\\u2a71\\\",epsi:\\\"\\\\u03b5\\\",Epsilon:\\\"\\\\u0395\\\",epsilon:\\\"\\\\u03b5\\\",epsiv:\\\"\\\\u03f5\\\",eqcirc:\\\"\\\\u2256\\\",eqcolon:\\\"\\\\u2255\\\",eqsim:\\\"\\\\u2242\\\",eqslantgtr:\\\"\\\\u2a96\\\",eqslantless:\\\"\\\\u2a95\\\",Equal:\\\"\\\\u2a75\\\",equals:\\\"=\\\",EqualTilde:\\\"\\\\u2242\\\",equest:\\\"\\\\u225f\\\",Equilibrium:\\\"\\\\u21cc\\\",equiv:\\\"\\\\u2261\\\",equivDD:\\\"\\\\u2a78\\\",eqvparsl:\\\"\\\\u29e5\\\",erarr:\\\"\\\\u2971\\\",erDot:\\\"\\\\u2253\\\",escr:\\\"\\\\u212f\\\",Escr:\\\"\\\\u2130\\\",esdot:\\\"\\\\u2250\\\",Esim:\\\"\\\\u2a73\\\",esim:\\\"\\\\u2242\\\",Eta:\\\"\\\\u0397\\\",eta:\\\"\\\\u03b7\\\",ETH:\\\"\\\\xd0\\\",eth:\\\"\\\\xf0\\\",Euml:\\\"\\\\xcb\\\",euml:\\\"\\\\xeb\\\",euro:\\\"\\\\u20ac\\\",excl:\\\"!\\\",exist:\\\"\\\\u2203\\\",Exists:\\\"\\\\u2203\\\",expectation:\\\"\\\\u2130\\\",exponentiale:\\\"\\\\u2147\\\",ExponentialE:\\\"\\\\u2147\\\",fallingdotseq:\\\"\\\\u2252\\\",Fcy:\\\"\\\\u0424\\\",fcy:\\\"\\\\u0444\\\",female:\\\"\\\\u2640\\\",ffilig:\\\"\\\\ufb03\\\",fflig:\\\"\\\\ufb00\\\",ffllig:\\\"\\\\ufb04\\\",Ffr:\\\"\\\\ud835\\\\udd09\\\",ffr:\\\"\\\\ud835\\\\udd23\\\",filig:\\\"\\\\ufb01\\\",FilledSmallSquare:\\\"\\\\u25fc\\\",FilledVerySmallSquare:\\\"\\\\u25aa\\\",fjlig:\\\"fj\\\",flat:\\\"\\\\u266d\\\",fllig:\\\"\\\\ufb02\\\",fltns:\\\"\\\\u25b1\\\",fnof:\\\"\\\\u0192\\\",Fopf:\\\"\\\\ud835\\\\udd3d\\\",fopf:\\\"\\\\ud835\\\\udd57\\\",forall:\\\"\\\\u2200\\\",ForAll:\\\"\\\\u2200\\\",fork:\\\"\\\\u22d4\\\",forkv:\\\"\\\\u2ad9\\\",Fouriertrf:\\\"\\\\u2131\\\",fpartint:\\\"\\\\u2a0d\\\",frac12:\\\"\\\\xbd\\\",frac13:\\\"\\\\u2153\\\",frac14:\\\"\\\\xbc\\\",frac15:\\\"\\\\u2155\\\",frac16:\\\"\\\\u2159\\\",frac18:\\\"\\\\u215b\\\",frac23:\\\"\\\\u2154\\\",frac25:\\\"\\\\u2156\\\",frac34:\\\"\\\\xbe\\\",frac35:\\\"\\\\u2157\\\",frac38:\\\"\\\\u215c\\\",frac45:\\\"\\\\u2158\\\",frac56:\\\"\\\\u215a\\\",frac58:\\\"\\\\u215d\\\",frac78:\\\"\\\\u215e\\\",frasl:\\\"\\\\u2044\\\",frown:\\\"\\\\u2322\\\",fscr:\\\"\\\\ud835\\\\udcbb\\\",Fscr:\\\"\\\\u2131\\\",gacute:\\\"\\\\u01f5\\\",Gamma:\\\"\\\\u0393\\\",gamma:\\\"\\\\u03b3\\\",Gammad:\\\"\\\\u03dc\\\",gammad:\\\"\\\\u03dd\\\",gap:\\\"\\\\u2a86\\\",Gbreve:\\\"\\\\u011e\\\",gbreve:\\\"\\\\u011f\\\",Gcedil:\\\"\\\\u0122\\\",Gcirc:\\\"\\\\u011c\\\",gcirc:\\\"\\\\u011d\\\",Gcy:\\\"\\\\u0413\\\",gcy:\\\"\\\\u0433\\\",Gdot:\\\"\\\\u0120\\\",gdot:\\\"\\\\u0121\\\",ge:\\\"\\\\u2265\\\",gE:\\\"\\\\u2267\\\",gEl:\\\"\\\\u2a8c\\\",gel:\\\"\\\\u22db\\\",geq:\\\"\\\\u2265\\\",geqq:\\\"\\\\u2267\\\",geqslant:\\\"\\\\u2a7e\\\",gescc:\\\"\\\\u2aa9\\\",ges:\\\"\\\\u2a7e\\\",gesdot:\\\"\\\\u2a80\\\",gesdoto:\\\"\\\\u2a82\\\",gesdotol:\\\"\\\\u2a84\\\",gesl:\\\"\\\\u22db\\\\ufe00\\\",gesles:\\\"\\\\u2a94\\\",Gfr:\\\"\\\\ud835\\\\udd0a\\\",gfr:\\\"\\\\ud835\\\\udd24\\\",gg:\\\"\\\\u226b\\\",Gg:\\\"\\\\u22d9\\\",ggg:\\\"\\\\u22d9\\\",gimel:\\\"\\\\u2137\\\",GJcy:\\\"\\\\u0403\\\",gjcy:\\\"\\\\u0453\\\",gla:\\\"\\\\u2aa5\\\",gl:\\\"\\\\u2277\\\",glE:\\\"\\\\u2a92\\\",glj:\\\"\\\\u2aa4\\\",gnap:\\\"\\\\u2a8a\\\",gnapprox:\\\"\\\\u2a8a\\\",gne:\\\"\\\\u2a88\\\",gnE:\\\"\\\\u2269\\\",gneq:\\\"\\\\u2a88\\\",gneqq:\\\"\\\\u2269\\\",gnsim:\\\"\\\\u22e7\\\",Gopf:\\\"\\\\ud835\\\\udd3e\\\",gopf:\\\"\\\\ud835\\\\udd58\\\",grave:\\\"`\\\",GreaterEqual:\\\"\\\\u2265\\\",GreaterEqualLess:\\\"\\\\u22db\\\",GreaterFullEqual:\\\"\\\\u2267\\\",GreaterGreater:\\\"\\\\u2aa2\\\",GreaterLess:\\\"\\\\u2277\\\",GreaterSlantEqual:\\\"\\\\u2a7e\\\",GreaterTilde:\\\"\\\\u2273\\\",Gscr:\\\"\\\\ud835\\\\udca2\\\",gscr:\\\"\\\\u210a\\\",gsim:\\\"\\\\u2273\\\",gsime:\\\"\\\\u2a8e\\\",gsiml:\\\"\\\\u2a90\\\",gtcc:\\\"\\\\u2aa7\\\",gtcir:\\\"\\\\u2a7a\\\",gt:\\\">\\\",GT:\\\">\\\",Gt:\\\"\\\\u226b\\\",gtdot:\\\"\\\\u22d7\\\",gtlPar:\\\"\\\\u2995\\\",gtquest:\\\"\\\\u2a7c\\\",gtrapprox:\\\"\\\\u2a86\\\",gtrarr:\\\"\\\\u2978\\\",gtrdot:\\\"\\\\u22d7\\\",gtreqless:\\\"\\\\u22db\\\",gtreqqless:\\\"\\\\u2a8c\\\",gtrless:\\\"\\\\u2277\\\",gtrsim:\\\"\\\\u2273\\\",gvertneqq:\\\"\\\\u2269\\\\ufe00\\\",gvnE:\\\"\\\\u2269\\\\ufe00\\\",Hacek:\\\"\\\\u02c7\\\",hairsp:\\\"\\\\u200a\\\",half:\\\"\\\\xbd\\\",hamilt:\\\"\\\\u210b\\\",HARDcy:\\\"\\\\u042a\\\",hardcy:\\\"\\\\u044a\\\",harrcir:\\\"\\\\u2948\\\",harr:\\\"\\\\u2194\\\",hArr:\\\"\\\\u21d4\\\",harrw:\\\"\\\\u21ad\\\",Hat:\\\"^\\\",hbar:\\\"\\\\u210f\\\",Hcirc:\\\"\\\\u0124\\\",hcirc:\\\"\\\\u0125\\\",hearts:\\\"\\\\u2665\\\",heartsuit:\\\"\\\\u2665\\\",hellip:\\\"\\\\u2026\\\",hercon:\\\"\\\\u22b9\\\",hfr:\\\"\\\\ud835\\\\udd25\\\",Hfr:\\\"\\\\u210c\\\",HilbertSpace:\\\"\\\\u210b\\\",hksearow:\\\"\\\\u2925\\\",hkswarow:\\\"\\\\u2926\\\",hoarr:\\\"\\\\u21ff\\\",homtht:\\\"\\\\u223b\\\",hookleftarrow:\\\"\\\\u21a9\\\",hookrightarrow:\\\"\\\\u21aa\\\",hopf:\\\"\\\\ud835\\\\udd59\\\",Hopf:\\\"\\\\u210d\\\",horbar:\\\"\\\\u2015\\\",HorizontalLine:\\\"\\\\u2500\\\",hscr:\\\"\\\\ud835\\\\udcbd\\\",Hscr:\\\"\\\\u210b\\\",hslash:\\\"\\\\u210f\\\",Hstrok:\\\"\\\\u0126\\\",hstrok:\\\"\\\\u0127\\\",HumpDownHump:\\\"\\\\u224e\\\",HumpEqual:\\\"\\\\u224f\\\",hybull:\\\"\\\\u2043\\\",hyphen:\\\"\\\\u2010\\\",Iacute:\\\"\\\\xcd\\\",iacute:\\\"\\\\xed\\\",ic:\\\"\\\\u2063\\\",Icirc:\\\"\\\\xce\\\",icirc:\\\"\\\\xee\\\",Icy:\\\"\\\\u0418\\\",icy:\\\"\\\\u0438\\\",Idot:\\\"\\\\u0130\\\",IEcy:\\\"\\\\u0415\\\",iecy:\\\"\\\\u0435\\\",iexcl:\\\"\\\\xa1\\\",iff:\\\"\\\\u21d4\\\",ifr:\\\"\\\\ud835\\\\udd26\\\",Ifr:\\\"\\\\u2111\\\",Igrave:\\\"\\\\xcc\\\",igrave:\\\"\\\\xec\\\",ii:\\\"\\\\u2148\\\",iiiint:\\\"\\\\u2a0c\\\",iiint:\\\"\\\\u222d\\\",iinfin:\\\"\\\\u29dc\\\",iiota:\\\"\\\\u2129\\\",IJlig:\\\"\\\\u0132\\\",ijlig:\\\"\\\\u0133\\\",Imacr:\\\"\\\\u012a\\\",imacr:\\\"\\\\u012b\\\",image:\\\"\\\\u2111\\\",ImaginaryI:\\\"\\\\u2148\\\",imagline:\\\"\\\\u2110\\\",imagpart:\\\"\\\\u2111\\\",imath:\\\"\\\\u0131\\\",Im:\\\"\\\\u2111\\\",imof:\\\"\\\\u22b7\\\",imped:\\\"\\\\u01b5\\\",Implies:\\\"\\\\u21d2\\\",incare:\\\"\\\\u2105\\\",in:\\\"\\\\u2208\\\",infin:\\\"\\\\u221e\\\",infintie:\\\"\\\\u29dd\\\",inodot:\\\"\\\\u0131\\\",intcal:\\\"\\\\u22ba\\\",int:\\\"\\\\u222b\\\",Int:\\\"\\\\u222c\\\",integers:\\\"\\\\u2124\\\",Integral:\\\"\\\\u222b\\\",intercal:\\\"\\\\u22ba\\\",Intersection:\\\"\\\\u22c2\\\",intlarhk:\\\"\\\\u2a17\\\",intprod:\\\"\\\\u2a3c\\\",InvisibleComma:\\\"\\\\u2063\\\",InvisibleTimes:\\\"\\\\u2062\\\",IOcy:\\\"\\\\u0401\\\",iocy:\\\"\\\\u0451\\\",Iogon:\\\"\\\\u012e\\\",iogon:\\\"\\\\u012f\\\",Iopf:\\\"\\\\ud835\\\\udd40\\\",iopf:\\\"\\\\ud835\\\\udd5a\\\",Iota:\\\"\\\\u0399\\\",iota:\\\"\\\\u03b9\\\",iprod:\\\"\\\\u2a3c\\\",iquest:\\\"\\\\xbf\\\",iscr:\\\"\\\\ud835\\\\udcbe\\\",Iscr:\\\"\\\\u2110\\\",isin:\\\"\\\\u2208\\\",isindot:\\\"\\\\u22f5\\\",isinE:\\\"\\\\u22f9\\\",isins:\\\"\\\\u22f4\\\",isinsv:\\\"\\\\u22f3\\\",isinv:\\\"\\\\u2208\\\",it:\\\"\\\\u2062\\\",Itilde:\\\"\\\\u0128\\\",itilde:\\\"\\\\u0129\\\",Iukcy:\\\"\\\\u0406\\\",iukcy:\\\"\\\\u0456\\\",Iuml:\\\"\\\\xcf\\\",iuml:\\\"\\\\xef\\\",Jcirc:\\\"\\\\u0134\\\",jcirc:\\\"\\\\u0135\\\",Jcy:\\\"\\\\u0419\\\",jcy:\\\"\\\\u0439\\\",Jfr:\\\"\\\\ud835\\\\udd0d\\\",jfr:\\\"\\\\ud835\\\\udd27\\\",jmath:\\\"\\\\u0237\\\",Jopf:\\\"\\\\ud835\\\\udd41\\\",jopf:\\\"\\\\ud835\\\\udd5b\\\",Jscr:\\\"\\\\ud835\\\\udca5\\\",jscr:\\\"\\\\ud835\\\\udcbf\\\",Jsercy:\\\"\\\\u0408\\\",jsercy:\\\"\\\\u0458\\\",Jukcy:\\\"\\\\u0404\\\",jukcy:\\\"\\\\u0454\\\",Kappa:\\\"\\\\u039a\\\",kappa:\\\"\\\\u03ba\\\",kappav:\\\"\\\\u03f0\\\",Kcedil:\\\"\\\\u0136\\\",kcedil:\\\"\\\\u0137\\\",Kcy:\\\"\\\\u041a\\\",kcy:\\\"\\\\u043a\\\",Kfr:\\\"\\\\ud835\\\\udd0e\\\",kfr:\\\"\\\\ud835\\\\udd28\\\",kgreen:\\\"\\\\u0138\\\",KHcy:\\\"\\\\u0425\\\",khcy:\\\"\\\\u0445\\\",KJcy:\\\"\\\\u040c\\\",kjcy:\\\"\\\\u045c\\\",Kopf:\\\"\\\\ud835\\\\udd42\\\",kopf:\\\"\\\\ud835\\\\udd5c\\\",Kscr:\\\"\\\\ud835\\\\udca6\\\",kscr:\\\"\\\\ud835\\\\udcc0\\\",lAarr:\\\"\\\\u21da\\\",Lacute:\\\"\\\\u0139\\\",lacute:\\\"\\\\u013a\\\",laemptyv:\\\"\\\\u29b4\\\",lagran:\\\"\\\\u2112\\\",Lambda:\\\"\\\\u039b\\\",lambda:\\\"\\\\u03bb\\\",lang:\\\"\\\\u27e8\\\",Lang:\\\"\\\\u27ea\\\",langd:\\\"\\\\u2991\\\",langle:\\\"\\\\u27e8\\\",lap:\\\"\\\\u2a85\\\",Laplacetrf:\\\"\\\\u2112\\\",laquo:\\\"\\\\xab\\\",larrb:\\\"\\\\u21e4\\\",larrbfs:\\\"\\\\u291f\\\",larr:\\\"\\\\u2190\\\",Larr:\\\"\\\\u219e\\\",lArr:\\\"\\\\u21d0\\\",larrfs:\\\"\\\\u291d\\\",larrhk:\\\"\\\\u21a9\\\",larrlp:\\\"\\\\u21ab\\\",larrpl:\\\"\\\\u2939\\\",larrsim:\\\"\\\\u2973\\\",larrtl:\\\"\\\\u21a2\\\",latail:\\\"\\\\u2919\\\",lAtail:\\\"\\\\u291b\\\",lat:\\\"\\\\u2aab\\\",late:\\\"\\\\u2aad\\\",lates:\\\"\\\\u2aad\\\\ufe00\\\",lbarr:\\\"\\\\u290c\\\",lBarr:\\\"\\\\u290e\\\",lbbrk:\\\"\\\\u2772\\\",lbrace:\\\"{\\\",lbrack:\\\"[\\\",lbrke:\\\"\\\\u298b\\\",lbrksld:\\\"\\\\u298f\\\",lbrkslu:\\\"\\\\u298d\\\",Lcaron:\\\"\\\\u013d\\\",lcaron:\\\"\\\\u013e\\\",Lcedil:\\\"\\\\u013b\\\",lcedil:\\\"\\\\u013c\\\",lceil:\\\"\\\\u2308\\\",lcub:\\\"{\\\",Lcy:\\\"\\\\u041b\\\",lcy:\\\"\\\\u043b\\\",ldca:\\\"\\\\u2936\\\",ldquo:\\\"\\\\u201c\\\",ldquor:\\\"\\\\u201e\\\",ldrdhar:\\\"\\\\u2967\\\",ldrushar:\\\"\\\\u294b\\\",ldsh:\\\"\\\\u21b2\\\",le:\\\"\\\\u2264\\\",lE:\\\"\\\\u2266\\\",LeftAngleBracket:\\\"\\\\u27e8\\\",LeftArrowBar:\\\"\\\\u21e4\\\",leftarrow:\\\"\\\\u2190\\\",LeftArrow:\\\"\\\\u2190\\\",Leftarrow:\\\"\\\\u21d0\\\",LeftArrowRightArrow:\\\"\\\\u21c6\\\",leftarrowtail:\\\"\\\\u21a2\\\",LeftCeiling:\\\"\\\\u2308\\\",LeftDoubleBracket:\\\"\\\\u27e6\\\",LeftDownTeeVector:\\\"\\\\u2961\\\",LeftDownVectorBar:\\\"\\\\u2959\\\",LeftDownVector:\\\"\\\\u21c3\\\",LeftFloor:\\\"\\\\u230a\\\",leftharpoondown:\\\"\\\\u21bd\\\",leftharpoonup:\\\"\\\\u21bc\\\",leftleftarrows:\\\"\\\\u21c7\\\",leftrightarrow:\\\"\\\\u2194\\\",LeftRightArrow:\\\"\\\\u2194\\\",Leftrightarrow:\\\"\\\\u21d4\\\",leftrightarrows:\\\"\\\\u21c6\\\",leftrightharpoons:\\\"\\\\u21cb\\\",leftrightsquigarrow:\\\"\\\\u21ad\\\",LeftRightVector:\\\"\\\\u294e\\\",LeftTeeArrow:\\\"\\\\u21a4\\\",LeftTee:\\\"\\\\u22a3\\\",LeftTeeVector:\\\"\\\\u295a\\\",leftthreetimes:\\\"\\\\u22cb\\\",LeftTriangleBar:\\\"\\\\u29cf\\\",LeftTriangle:\\\"\\\\u22b2\\\",LeftTriangleEqual:\\\"\\\\u22b4\\\",LeftUpDownVector:\\\"\\\\u2951\\\",LeftUpTeeVector:\\\"\\\\u2960\\\",LeftUpVectorBar:\\\"\\\\u2958\\\",LeftUpVector:\\\"\\\\u21bf\\\",LeftVectorBar:\\\"\\\\u2952\\\",LeftVector:\\\"\\\\u21bc\\\",lEg:\\\"\\\\u2a8b\\\",leg:\\\"\\\\u22da\\\",leq:\\\"\\\\u2264\\\",leqq:\\\"\\\\u2266\\\",leqslant:\\\"\\\\u2a7d\\\",lescc:\\\"\\\\u2aa8\\\",les:\\\"\\\\u2a7d\\\",lesdot:\\\"\\\\u2a7f\\\",lesdoto:\\\"\\\\u2a81\\\",lesdotor:\\\"\\\\u2a83\\\",lesg:\\\"\\\\u22da\\\\ufe00\\\",lesges:\\\"\\\\u2a93\\\",lessapprox:\\\"\\\\u2a85\\\",lessdot:\\\"\\\\u22d6\\\",lesseqgtr:\\\"\\\\u22da\\\",lesseqqgtr:\\\"\\\\u2a8b\\\",LessEqualGreater:\\\"\\\\u22da\\\",LessFullEqual:\\\"\\\\u2266\\\",LessGreater:\\\"\\\\u2276\\\",lessgtr:\\\"\\\\u2276\\\",LessLess:\\\"\\\\u2aa1\\\",lesssim:\\\"\\\\u2272\\\",LessSlantEqual:\\\"\\\\u2a7d\\\",LessTilde:\\\"\\\\u2272\\\",lfisht:\\\"\\\\u297c\\\",lfloor:\\\"\\\\u230a\\\",Lfr:\\\"\\\\ud835\\\\udd0f\\\",lfr:\\\"\\\\ud835\\\\udd29\\\",lg:\\\"\\\\u2276\\\",lgE:\\\"\\\\u2a91\\\",lHar:\\\"\\\\u2962\\\",lhard:\\\"\\\\u21bd\\\",lharu:\\\"\\\\u21bc\\\",lharul:\\\"\\\\u296a\\\",lhblk:\\\"\\\\u2584\\\",LJcy:\\\"\\\\u0409\\\",ljcy:\\\"\\\\u0459\\\",llarr:\\\"\\\\u21c7\\\",ll:\\\"\\\\u226a\\\",Ll:\\\"\\\\u22d8\\\",llcorner:\\\"\\\\u231e\\\",Lleftarrow:\\\"\\\\u21da\\\",llhard:\\\"\\\\u296b\\\",lltri:\\\"\\\\u25fa\\\",Lmidot:\\\"\\\\u013f\\\",lmidot:\\\"\\\\u0140\\\",lmoustache:\\\"\\\\u23b0\\\",lmoust:\\\"\\\\u23b0\\\",lnap:\\\"\\\\u2a89\\\",lnapprox:\\\"\\\\u2a89\\\",lne:\\\"\\\\u2a87\\\",lnE:\\\"\\\\u2268\\\",lneq:\\\"\\\\u2a87\\\",lneqq:\\\"\\\\u2268\\\",lnsim:\\\"\\\\u22e6\\\",loang:\\\"\\\\u27ec\\\",loarr:\\\"\\\\u21fd\\\",lobrk:\\\"\\\\u27e6\\\",longleftarrow:\\\"\\\\u27f5\\\",LongLeftArrow:\\\"\\\\u27f5\\\",Longleftarrow:\\\"\\\\u27f8\\\",longleftrightarrow:\\\"\\\\u27f7\\\",LongLeftRightArrow:\\\"\\\\u27f7\\\",Longleftrightarrow:\\\"\\\\u27fa\\\",longmapsto:\\\"\\\\u27fc\\\",longrightarrow:\\\"\\\\u27f6\\\",LongRightArrow:\\\"\\\\u27f6\\\",Longrightarrow:\\\"\\\\u27f9\\\",looparrowleft:\\\"\\\\u21ab\\\",looparrowright:\\\"\\\\u21ac\\\",lopar:\\\"\\\\u2985\\\",Lopf:\\\"\\\\ud835\\\\udd43\\\",lopf:\\\"\\\\ud835\\\\udd5d\\\",loplus:\\\"\\\\u2a2d\\\",lotimes:\\\"\\\\u2a34\\\",lowast:\\\"\\\\u2217\\\",lowbar:\\\"_\\\",LowerLeftArrow:\\\"\\\\u2199\\\",LowerRightArrow:\\\"\\\\u2198\\\",loz:\\\"\\\\u25ca\\\",lozenge:\\\"\\\\u25ca\\\",lozf:\\\"\\\\u29eb\\\",lpar:\\\"(\\\",lparlt:\\\"\\\\u2993\\\",lrarr:\\\"\\\\u21c6\\\",lrcorner:\\\"\\\\u231f\\\",lrhar:\\\"\\\\u21cb\\\",lrhard:\\\"\\\\u296d\\\",lrm:\\\"\\\\u200e\\\",lrtri:\\\"\\\\u22bf\\\",lsaquo:\\\"\\\\u2039\\\",lscr:\\\"\\\\ud835\\\\udcc1\\\",Lscr:\\\"\\\\u2112\\\",lsh:\\\"\\\\u21b0\\\",Lsh:\\\"\\\\u21b0\\\",lsim:\\\"\\\\u2272\\\",lsime:\\\"\\\\u2a8d\\\",lsimg:\\\"\\\\u2a8f\\\",lsqb:\\\"[\\\",lsquo:\\\"\\\\u2018\\\",lsquor:\\\"\\\\u201a\\\",Lstrok:\\\"\\\\u0141\\\",lstrok:\\\"\\\\u0142\\\",ltcc:\\\"\\\\u2aa6\\\",ltcir:\\\"\\\\u2a79\\\",lt:\\\"\u003C\\\",LT:\\\"\u003C\\\",Lt:\\\"\\\\u226a\\\",ltdot:\\\"\\\\u22d6\\\",lthree:\\\"\\\\u22cb\\\",ltimes:\\\"\\\\u22c9\\\",ltlarr:\\\"\\\\u2976\\\",ltquest:\\\"\\\\u2a7b\\\",ltri:\\\"\\\\u25c3\\\",ltrie:\\\"\\\\u22b4\\\",ltrif:\\\"\\\\u25c2\\\",ltrPar:\\\"\\\\u2996\\\",lurdshar:\\\"\\\\u294a\\\",luruhar:\\\"\\\\u2966\\\",lvertneqq:\\\"\\\\u2268\\\\ufe00\\\",lvnE:\\\"\\\\u2268\\\\ufe00\\\",macr:\\\"\\\\xaf\\\",male:\\\"\\\\u2642\\\",malt:\\\"\\\\u2720\\\",maltese:\\\"\\\\u2720\\\",Map:\\\"\\\\u2905\\\",map:\\\"\\\\u21a6\\\",mapsto:\\\"\\\\u21a6\\\",mapstodown:\\\"\\\\u21a7\\\",mapstoleft:\\\"\\\\u21a4\\\",mapstoup:\\\"\\\\u21a5\\\",marker:\\\"\\\\u25ae\\\",mcomma:\\\"\\\\u2a29\\\",Mcy:\\\"\\\\u041c\\\",mcy:\\\"\\\\u043c\\\",mdash:\\\"\\\\u2014\\\",mDDot:\\\"\\\\u223a\\\",measuredangle:\\\"\\\\u2221\\\",MediumSpace:\\\"\\\\u205f\\\",Mellintrf:\\\"\\\\u2133\\\",Mfr:\\\"\\\\ud835\\\\udd10\\\",mfr:\\\"\\\\ud835\\\\udd2a\\\",mho:\\\"\\\\u2127\\\",micro:\\\"\\\\xb5\\\",midast:\\\"*\\\",midcir:\\\"\\\\u2af0\\\",mid:\\\"\\\\u2223\\\",middot:\\\"\\\\xb7\\\",minusb:\\\"\\\\u229f\\\",minus:\\\"\\\\u2212\\\",minusd:\\\"\\\\u2238\\\",minusdu:\\\"\\\\u2a2a\\\",MinusPlus:\\\"\\\\u2213\\\",mlcp:\\\"\\\\u2adb\\\",mldr:\\\"\\\\u2026\\\",mnplus:\\\"\\\\u2213\\\",models:\\\"\\\\u22a7\\\",Mopf:\\\"\\\\ud835\\\\udd44\\\",mopf:\\\"\\\\ud835\\\\udd5e\\\",mp:\\\"\\\\u2213\\\",mscr:\\\"\\\\ud835\\\\udcc2\\\",Mscr:\\\"\\\\u2133\\\",mstpos:\\\"\\\\u223e\\\",Mu:\\\"\\\\u039c\\\",mu:\\\"\\\\u03bc\\\",multimap:\\\"\\\\u22b8\\\",mumap:\\\"\\\\u22b8\\\",nabla:\\\"\\\\u2207\\\",Nacute:\\\"\\\\u0143\\\",nacute:\\\"\\\\u0144\\\",nang:\\\"\\\\u2220\\\\u20d2\\\",nap:\\\"\\\\u2249\\\",napE:\\\"\\\\u2a70\\\\u0338\\\",napid:\\\"\\\\u224b\\\\u0338\\\",napos:\\\"\\\\u0149\\\",napprox:\\\"\\\\u2249\\\",natural:\\\"\\\\u266e\\\",naturals:\\\"\\\\u2115\\\",natur:\\\"\\\\u266e\\\",nbsp:\\\"\\\\xa0\\\",nbump:\\\"\\\\u224e\\\\u0338\\\",nbumpe:\\\"\\\\u224f\\\\u0338\\\",ncap:\\\"\\\\u2a43\\\",Ncaron:\\\"\\\\u0147\\\",ncaron:\\\"\\\\u0148\\\",Ncedil:\\\"\\\\u0145\\\",ncedil:\\\"\\\\u0146\\\",ncong:\\\"\\\\u2247\\\",ncongdot:\\\"\\\\u2a6d\\\\u0338\\\",ncup:\\\"\\\\u2a42\\\",Ncy:\\\"\\\\u041d\\\",ncy:\\\"\\\\u043d\\\",ndash:\\\"\\\\u2013\\\",nearhk:\\\"\\\\u2924\\\",nearr:\\\"\\\\u2197\\\",neArr:\\\"\\\\u21d7\\\",nearrow:\\\"\\\\u2197\\\",ne:\\\"\\\\u2260\\\",nedot:\\\"\\\\u2250\\\\u0338\\\",NegativeMediumSpace:\\\"\\\\u200b\\\",NegativeThickSpace:\\\"\\\\u200b\\\",NegativeThinSpace:\\\"\\\\u200b\\\",NegativeVeryThinSpace:\\\"\\\\u200b\\\",nequiv:\\\"\\\\u2262\\\",nesear:\\\"\\\\u2928\\\",nesim:\\\"\\\\u2242\\\\u0338\\\",NestedGreaterGreater:\\\"\\\\u226b\\\",NestedLessLess:\\\"\\\\u226a\\\",NewLine:\\\"\\\\n\\\",nexist:\\\"\\\\u2204\\\",nexists:\\\"\\\\u2204\\\",Nfr:\\\"\\\\ud835\\\\udd11\\\",nfr:\\\"\\\\ud835\\\\udd2b\\\",ngE:\\\"\\\\u2267\\\\u0338\\\",nge:\\\"\\\\u2271\\\",ngeq:\\\"\\\\u2271\\\",ngeqq:\\\"\\\\u2267\\\\u0338\\\",ngeqslant:\\\"\\\\u2a7e\\\\u0338\\\",nges:\\\"\\\\u2a7e\\\\u0338\\\",nGg:\\\"\\\\u22d9\\\\u0338\\\",ngsim:\\\"\\\\u2275\\\",nGt:\\\"\\\\u226b\\\\u20d2\\\",ngt:\\\"\\\\u226f\\\",ngtr:\\\"\\\\u226f\\\",nGtv:\\\"\\\\u226b\\\\u0338\\\",nharr:\\\"\\\\u21ae\\\",nhArr:\\\"\\\\u21ce\\\",nhpar:\\\"\\\\u2af2\\\",ni:\\\"\\\\u220b\\\",nis:\\\"\\\\u22fc\\\",nisd:\\\"\\\\u22fa\\\",niv:\\\"\\\\u220b\\\",NJcy:\\\"\\\\u040a\\\",njcy:\\\"\\\\u045a\\\",nlarr:\\\"\\\\u219a\\\",nlArr:\\\"\\\\u21cd\\\",nldr:\\\"\\\\u2025\\\",nlE:\\\"\\\\u2266\\\\u0338\\\",nle:\\\"\\\\u2270\\\",nleftarrow:\\\"\\\\u219a\\\",nLeftarrow:\\\"\\\\u21cd\\\",nleftrightarrow:\\\"\\\\u21ae\\\",nLeftrightarrow:\\\"\\\\u21ce\\\",nleq:\\\"\\\\u2270\\\",nleqq:\\\"\\\\u2266\\\\u0338\\\",nleqslant:\\\"\\\\u2a7d\\\\u0338\\\",nles:\\\"\\\\u2a7d\\\\u0338\\\",nless:\\\"\\\\u226e\\\",nLl:\\\"\\\\u22d8\\\\u0338\\\",nlsim:\\\"\\\\u2274\\\",nLt:\\\"\\\\u226a\\\\u20d2\\\",nlt:\\\"\\\\u226e\\\",nltri:\\\"\\\\u22ea\\\",nltrie:\\\"\\\\u22ec\\\",nLtv:\\\"\\\\u226a\\\\u0338\\\",nmid:\\\"\\\\u2224\\\",NoBreak:\\\"\\\\u2060\\\",NonBreakingSpace:\\\"\\\\xa0\\\",nopf:\\\"\\\\ud835\\\\udd5f\\\",Nopf:\\\"\\\\u2115\\\",Not:\\\"\\\\u2aec\\\",not:\\\"\\\\xac\\\",NotCongruent:\\\"\\\\u2262\\\",NotCupCap:\\\"\\\\u226d\\\",NotDoubleVerticalBar:\\\"\\\\u2226\\\",NotElement:\\\"\\\\u2209\\\",NotEqual:\\\"\\\\u2260\\\",NotEqualTilde:\\\"\\\\u2242\\\\u0338\\\",NotExists:\\\"\\\\u2204\\\",NotGreater:\\\"\\\\u226f\\\",NotGreaterEqual:\\\"\\\\u2271\\\",NotGreaterFullEqual:\\\"\\\\u2267\\\\u0338\\\",NotGreaterGreater:\\\"\\\\u226b\\\\u0338\\\",NotGreaterLess:\\\"\\\\u2279\\\",NotGreaterSlantEqual:\\\"\\\\u2a7e\\\\u0338\\\",NotGreaterTilde:\\\"\\\\u2275\\\",NotHumpDownHump:\\\"\\\\u224e\\\\u0338\\\",NotHumpEqual:\\\"\\\\u224f\\\\u0338\\\",notin:\\\"\\\\u2209\\\",notindot:\\\"\\\\u22f5\\\\u0338\\\",notinE:\\\"\\\\u22f9\\\\u0338\\\",notinva:\\\"\\\\u2209\\\",notinvb:\\\"\\\\u22f7\\\",notinvc:\\\"\\\\u22f6\\\",NotLeftTriangleBar:\\\"\\\\u29cf\\\\u0338\\\",NotLeftTriangle:\\\"\\\\u22ea\\\",NotLeftTriangleEqual:\\\"\\\\u22ec\\\",NotLess:\\\"\\\\u226e\\\",NotLessEqual:\\\"\\\\u2270\\\",NotLessGreater:\\\"\\\\u2278\\\",NotLessLess:\\\"\\\\u226a\\\\u0338\\\",NotLessSlantEqual:\\\"\\\\u2a7d\\\\u0338\\\",NotLessTilde:\\\"\\\\u2274\\\",NotNestedGreaterGreater:\\\"\\\\u2aa2\\\\u0338\\\",NotNestedLessLess:\\\"\\\\u2aa1\\\\u0338\\\",notni:\\\"\\\\u220c\\\",notniva:\\\"\\\\u220c\\\",notnivb:\\\"\\\\u22fe\\\",notnivc:\\\"\\\\u22fd\\\",NotPrecedes:\\\"\\\\u2280\\\",NotPrecedesEqual:\\\"\\\\u2aaf\\\\u0338\\\",NotPrecedesSlantEqual:\\\"\\\\u22e0\\\",NotReverseElement:\\\"\\\\u220c\\\",NotRightTriangleBar:\\\"\\\\u29d0\\\\u0338\\\",NotRightTriangle:\\\"\\\\u22eb\\\",NotRightTriangleEqual:\\\"\\\\u22ed\\\",NotSquareSubset:\\\"\\\\u228f\\\\u0338\\\",NotSquareSubsetEqual:\\\"\\\\u22e2\\\",NotSquareSuperset:\\\"\\\\u2290\\\\u0338\\\",NotSquareSupersetEqual:\\\"\\\\u22e3\\\",NotSubset:\\\"\\\\u2282\\\\u20d2\\\",NotSubsetEqual:\\\"\\\\u2288\\\",NotSucceeds:\\\"\\\\u2281\\\",NotSucceedsEqual:\\\"\\\\u2ab0\\\\u0338\\\",NotSucceedsSlantEqual:\\\"\\\\u22e1\\\",NotSucceedsTilde:\\\"\\\\u227f\\\\u0338\\\",NotSuperset:\\\"\\\\u2283\\\\u20d2\\\",NotSupersetEqual:\\\"\\\\u2289\\\",NotTilde:\\\"\\\\u2241\\\",NotTildeEqual:\\\"\\\\u2244\\\",NotTildeFullEqual:\\\"\\\\u2247\\\",NotTildeTilde:\\\"\\\\u2249\\\",NotVerticalBar:\\\"\\\\u2224\\\",nparallel:\\\"\\\\u2226\\\",npar:\\\"\\\\u2226\\\",nparsl:\\\"\\\\u2afd\\\\u20e5\\\",npart:\\\"\\\\u2202\\\\u0338\\\",npolint:\\\"\\\\u2a14\\\",npr:\\\"\\\\u2280\\\",nprcue:\\\"\\\\u22e0\\\",nprec:\\\"\\\\u2280\\\",npreceq:\\\"\\\\u2aaf\\\\u0338\\\",npre:\\\"\\\\u2aaf\\\\u0338\\\",nrarrc:\\\"\\\\u2933\\\\u0338\\\",nrarr:\\\"\\\\u219b\\\",nrArr:\\\"\\\\u21cf\\\",nrarrw:\\\"\\\\u219d\\\\u0338\\\",nrightarrow:\\\"\\\\u219b\\\",nRightarrow:\\\"\\\\u21cf\\\",nrtri:\\\"\\\\u22eb\\\",nrtrie:\\\"\\\\u22ed\\\",nsc:\\\"\\\\u2281\\\",nsccue:\\\"\\\\u22e1\\\",nsce:\\\"\\\\u2ab0\\\\u0338\\\",Nscr:\\\"\\\\ud835\\\\udca9\\\",nscr:\\\"\\\\ud835\\\\udcc3\\\",nshortmid:\\\"\\\\u2224\\\",nshortparallel:\\\"\\\\u2226\\\",nsim:\\\"\\\\u2241\\\",nsime:\\\"\\\\u2244\\\",nsimeq:\\\"\\\\u2244\\\",nsmid:\\\"\\\\u2224\\\",nspar:\\\"\\\\u2226\\\",nsqsube:\\\"\\\\u22e2\\\",nsqsupe:\\\"\\\\u22e3\\\",nsub:\\\"\\\\u2284\\\",nsubE:\\\"\\\\u2ac5\\\\u0338\\\",nsube:\\\"\\\\u2288\\\",nsubset:\\\"\\\\u2282\\\\u20d2\\\",nsubseteq:\\\"\\\\u2288\\\",nsubseteqq:\\\"\\\\u2ac5\\\\u0338\\\",nsucc:\\\"\\\\u2281\\\",nsucceq:\\\"\\\\u2ab0\\\\u0338\\\",nsup:\\\"\\\\u2285\\\",nsupE:\\\"\\\\u2ac6\\\\u0338\\\",nsupe:\\\"\\\\u2289\\\",nsupset:\\\"\\\\u2283\\\\u20d2\\\",nsupseteq:\\\"\\\\u2289\\\",nsupseteqq:\\\"\\\\u2ac6\\\\u0338\\\",ntgl:\\\"\\\\u2279\\\",Ntilde:\\\"\\\\xd1\\\",ntilde:\\\"\\\\xf1\\\",ntlg:\\\"\\\\u2278\\\",ntriangleleft:\\\"\\\\u22ea\\\",ntrianglelefteq:\\\"\\\\u22ec\\\",ntriangleright:\\\"\\\\u22eb\\\",ntrianglerighteq:\\\"\\\\u22ed\\\",Nu:\\\"\\\\u039d\\\",nu:\\\"\\\\u03bd\\\",num:\\\"#\\\",numero:\\\"\\\\u2116\\\",numsp:\\\"\\\\u2007\\\",nvap:\\\"\\\\u224d\\\\u20d2\\\",nvdash:\\\"\\\\u22ac\\\",nvDash:\\\"\\\\u22ad\\\",nVdash:\\\"\\\\u22ae\\\",nVDash:\\\"\\\\u22af\\\",nvge:\\\"\\\\u2265\\\\u20d2\\\",nvgt:\\\">\\\\u20d2\\\",nvHarr:\\\"\\\\u2904\\\",nvinfin:\\\"\\\\u29de\\\",nvlArr:\\\"\\\\u2902\\\",nvle:\\\"\\\\u2264\\\\u20d2\\\",nvlt:\\\"\u003C\\\\u20d2\\\",nvltrie:\\\"\\\\u22b4\\\\u20d2\\\",nvrArr:\\\"\\\\u2903\\\",nvrtrie:\\\"\\\\u22b5\\\\u20d2\\\",nvsim:\\\"\\\\u223c\\\\u20d2\\\",nwarhk:\\\"\\\\u2923\\\",nwarr:\\\"\\\\u2196\\\",nwArr:\\\"\\\\u21d6\\\",nwarrow:\\\"\\\\u2196\\\",nwnear:\\\"\\\\u2927\\\",Oacute:\\\"\\\\xd3\\\",oacute:\\\"\\\\xf3\\\",oast:\\\"\\\\u229b\\\",Ocirc:\\\"\\\\xd4\\\",ocirc:\\\"\\\\xf4\\\",ocir:\\\"\\\\u229a\\\",Ocy:\\\"\\\\u041e\\\",ocy:\\\"\\\\u043e\\\",odash:\\\"\\\\u229d\\\",Odblac:\\\"\\\\u0150\\\",odblac:\\\"\\\\u0151\\\",odiv:\\\"\\\\u2a38\\\",odot:\\\"\\\\u2299\\\",odsold:\\\"\\\\u29bc\\\",OElig:\\\"\\\\u0152\\\",oelig:\\\"\\\\u0153\\\",ofcir:\\\"\\\\u29bf\\\",Ofr:\\\"\\\\ud835\\\\udd12\\\",ofr:\\\"\\\\ud835\\\\udd2c\\\",ogon:\\\"\\\\u02db\\\",Ograve:\\\"\\\\xd2\\\",ograve:\\\"\\\\xf2\\\",ogt:\\\"\\\\u29c1\\\",ohbar:\\\"\\\\u29b5\\\",ohm:\\\"\\\\u03a9\\\",oint:\\\"\\\\u222e\\\",olarr:\\\"\\\\u21ba\\\",olcir:\\\"\\\\u29be\\\",olcross:\\\"\\\\u29bb\\\",oline:\\\"\\\\u203e\\\",olt:\\\"\\\\u29c0\\\",Omacr:\\\"\\\\u014c\\\",omacr:\\\"\\\\u014d\\\",Omega:\\\"\\\\u03a9\\\",omega:\\\"\\\\u03c9\\\",Omicron:\\\"\\\\u039f\\\",omicron:\\\"\\\\u03bf\\\",omid:\\\"\\\\u29b6\\\",ominus:\\\"\\\\u2296\\\",Oopf:\\\"\\\\ud835\\\\udd46\\\",oopf:\\\"\\\\ud835\\\\udd60\\\",opar:\\\"\\\\u29b7\\\",OpenCurlyDoubleQuote:\\\"\\\\u201c\\\",OpenCurlyQuote:\\\"\\\\u2018\\\",operp:\\\"\\\\u29b9\\\",oplus:\\\"\\\\u2295\\\",orarr:\\\"\\\\u21bb\\\",Or:\\\"\\\\u2a54\\\",or:\\\"\\\\u2228\\\",ord:\\\"\\\\u2a5d\\\",order:\\\"\\\\u2134\\\",orderof:\\\"\\\\u2134\\\",ordf:\\\"\\\\xaa\\\",ordm:\\\"\\\\xba\\\",origof:\\\"\\\\u22b6\\\",oror:\\\"\\\\u2a56\\\",orslope:\\\"\\\\u2a57\\\",orv:\\\"\\\\u2a5b\\\",oS:\\\"\\\\u24c8\\\",Oscr:\\\"\\\\ud835\\\\udcaa\\\",oscr:\\\"\\\\u2134\\\",Oslash:\\\"\\\\xd8\\\",oslash:\\\"\\\\xf8\\\",osol:\\\"\\\\u2298\\\",Otilde:\\\"\\\\xd5\\\",otilde:\\\"\\\\xf5\\\",otimesas:\\\"\\\\u2a36\\\",Otimes:\\\"\\\\u2a37\\\",otimes:\\\"\\\\u2297\\\",Ouml:\\\"\\\\xd6\\\",ouml:\\\"\\\\xf6\\\",ovbar:\\\"\\\\u233d\\\",OverBar:\\\"\\\\u203e\\\",OverBrace:\\\"\\\\u23de\\\",OverBracket:\\\"\\\\u23b4\\\",OverParenthesis:\\\"\\\\u23dc\\\",para:\\\"\\\\xb6\\\",parallel:\\\"\\\\u2225\\\",par:\\\"\\\\u2225\\\",parsim:\\\"\\\\u2af3\\\",parsl:\\\"\\\\u2afd\\\",part:\\\"\\\\u2202\\\",PartialD:\\\"\\\\u2202\\\",Pcy:\\\"\\\\u041f\\\",pcy:\\\"\\\\u043f\\\",percnt:\\\"%\\\",period:\\\".\\\",permil:\\\"\\\\u2030\\\",perp:\\\"\\\\u22a5\\\",pertenk:\\\"\\\\u2031\\\",Pfr:\\\"\\\\ud835\\\\udd13\\\",pfr:\\\"\\\\ud835\\\\udd2d\\\",Phi:\\\"\\\\u03a6\\\",phi:\\\"\\\\u03c6\\\",phiv:\\\"\\\\u03d5\\\",phmmat:\\\"\\\\u2133\\\",phone:\\\"\\\\u260e\\\",Pi:\\\"\\\\u03a0\\\",pi:\\\"\\\\u03c0\\\",pitchfork:\\\"\\\\u22d4\\\",piv:\\\"\\\\u03d6\\\",planck:\\\"\\\\u210f\\\",planckh:\\\"\\\\u210e\\\",plankv:\\\"\\\\u210f\\\",plusacir:\\\"\\\\u2a23\\\",plusb:\\\"\\\\u229e\\\",pluscir:\\\"\\\\u2a22\\\",plus:\\\"+\\\",plusdo:\\\"\\\\u2214\\\",plusdu:\\\"\\\\u2a25\\\",pluse:\\\"\\\\u2a72\\\",PlusMinus:\\\"\\\\xb1\\\",plusmn:\\\"\\\\xb1\\\",plussim:\\\"\\\\u2a26\\\",plustwo:\\\"\\\\u2a27\\\",pm:\\\"\\\\xb1\\\",Poincareplane:\\\"\\\\u210c\\\",pointint:\\\"\\\\u2a15\\\",popf:\\\"\\\\ud835\\\\udd61\\\",Popf:\\\"\\\\u2119\\\",pound:\\\"\\\\xa3\\\",prap:\\\"\\\\u2ab7\\\",Pr:\\\"\\\\u2abb\\\",pr:\\\"\\\\u227a\\\",prcue:\\\"\\\\u227c\\\",precapprox:\\\"\\\\u2ab7\\\",prec:\\\"\\\\u227a\\\",preccurlyeq:\\\"\\\\u227c\\\",Precedes:\\\"\\\\u227a\\\",PrecedesEqual:\\\"\\\\u2aaf\\\",PrecedesSlantEqual:\\\"\\\\u227c\\\",PrecedesTilde:\\\"\\\\u227e\\\",preceq:\\\"\\\\u2aaf\\\",precnapprox:\\\"\\\\u2ab9\\\",precneqq:\\\"\\\\u2ab5\\\",precnsim:\\\"\\\\u22e8\\\",pre:\\\"\\\\u2aaf\\\",prE:\\\"\\\\u2ab3\\\",precsim:\\\"\\\\u227e\\\",prime:\\\"\\\\u2032\\\",Prime:\\\"\\\\u2033\\\",primes:\\\"\\\\u2119\\\",prnap:\\\"\\\\u2ab9\\\",prnE:\\\"\\\\u2ab5\\\",prnsim:\\\"\\\\u22e8\\\",prod:\\\"\\\\u220f\\\",Product:\\\"\\\\u220f\\\",profalar:\\\"\\\\u232e\\\",profline:\\\"\\\\u2312\\\",profsurf:\\\"\\\\u2313\\\",prop:\\\"\\\\u221d\\\",Proportional:\\\"\\\\u221d\\\",Proportion:\\\"\\\\u2237\\\",propto:\\\"\\\\u221d\\\",prsim:\\\"\\\\u227e\\\",prurel:\\\"\\\\u22b0\\\",Pscr:\\\"\\\\ud835\\\\udcab\\\",pscr:\\\"\\\\ud835\\\\udcc5\\\",Psi:\\\"\\\\u03a8\\\",psi:\\\"\\\\u03c8\\\",puncsp:\\\"\\\\u2008\\\",Qfr:\\\"\\\\ud835\\\\udd14\\\",qfr:\\\"\\\\ud835\\\\udd2e\\\",qint:\\\"\\\\u2a0c\\\",qopf:\\\"\\\\ud835\\\\udd62\\\",Qopf:\\\"\\\\u211a\\\",qprime:\\\"\\\\u2057\\\",Qscr:\\\"\\\\ud835\\\\udcac\\\",qscr:\\\"\\\\ud835\\\\udcc6\\\",quaternions:\\\"\\\\u210d\\\",quatint:\\\"\\\\u2a16\\\",quest:\\\"?\\\",questeq:\\\"\\\\u225f\\\",quot:'\\\"',QUOT:'\\\"',rAarr:\\\"\\\\u21db\\\",race:\\\"\\\\u223d\\\\u0331\\\",Racute:\\\"\\\\u0154\\\",racute:\\\"\\\\u0155\\\",radic:\\\"\\\\u221a\\\",raemptyv:\\\"\\\\u29b3\\\",rang:\\\"\\\\u27e9\\\",Rang:\\\"\\\\u27eb\\\",rangd:\\\"\\\\u2992\\\",range:\\\"\\\\u29a5\\\",rangle:\\\"\\\\u27e9\\\",raquo:\\\"\\\\xbb\\\",rarrap:\\\"\\\\u2975\\\",rarrb:\\\"\\\\u21e5\\\",rarrbfs:\\\"\\\\u2920\\\",rarrc:\\\"\\\\u2933\\\",rarr:\\\"\\\\u2192\\\",Rarr:\\\"\\\\u21a0\\\",rArr:\\\"\\\\u21d2\\\",rarrfs:\\\"\\\\u291e\\\",rarrhk:\\\"\\\\u21aa\\\",rarrlp:\\\"\\\\u21ac\\\",rarrpl:\\\"\\\\u2945\\\",rarrsim:\\\"\\\\u2974\\\",Rarrtl:\\\"\\\\u2916\\\",rarrtl:\\\"\\\\u21a3\\\",rarrw:\\\"\\\\u219d\\\",ratail:\\\"\\\\u291a\\\",rAtail:\\\"\\\\u291c\\\",ratio:\\\"\\\\u2236\\\",rationals:\\\"\\\\u211a\\\",rbarr:\\\"\\\\u290d\\\",rBarr:\\\"\\\\u290f\\\",RBarr:\\\"\\\\u2910\\\",rbbrk:\\\"\\\\u2773\\\",rbrace:\\\"}\\\",rbrack:\\\"]\\\",rbrke:\\\"\\\\u298c\\\",rbrksld:\\\"\\\\u298e\\\",rbrkslu:\\\"\\\\u2990\\\",Rcaron:\\\"\\\\u0158\\\",rcaron:\\\"\\\\u0159\\\",Rcedil:\\\"\\\\u0156\\\",rcedil:\\\"\\\\u0157\\\",rceil:\\\"\\\\u2309\\\",rcub:\\\"}\\\",Rcy:\\\"\\\\u0420\\\",rcy:\\\"\\\\u0440\\\",rdca:\\\"\\\\u2937\\\",rdldhar:\\\"\\\\u2969\\\",rdquo:\\\"\\\\u201d\\\",rdquor:\\\"\\\\u201d\\\",rdsh:\\\"\\\\u21b3\\\",real:\\\"\\\\u211c\\\",realine:\\\"\\\\u211b\\\",realpart:\\\"\\\\u211c\\\",reals:\\\"\\\\u211d\\\",Re:\\\"\\\\u211c\\\",rect:\\\"\\\\u25ad\\\",reg:\\\"\\\\xae\\\",REG:\\\"\\\\xae\\\",ReverseElement:\\\"\\\\u220b\\\",ReverseEquilibrium:\\\"\\\\u21cb\\\",ReverseUpEquilibrium:\\\"\\\\u296f\\\",rfisht:\\\"\\\\u297d\\\",rfloor:\\\"\\\\u230b\\\",rfr:\\\"\\\\ud835\\\\udd2f\\\",Rfr:\\\"\\\\u211c\\\",rHar:\\\"\\\\u2964\\\",rhard:\\\"\\\\u21c1\\\",rharu:\\\"\\\\u21c0\\\",rharul:\\\"\\\\u296c\\\",Rho:\\\"\\\\u03a1\\\",rho:\\\"\\\\u03c1\\\",rhov:\\\"\\\\u03f1\\\",RightAngleBracket:\\\"\\\\u27e9\\\",RightArrowBar:\\\"\\\\u21e5\\\",rightarrow:\\\"\\\\u2192\\\",RightArrow:\\\"\\\\u2192\\\",Rightarrow:\\\"\\\\u21d2\\\",RightArrowLeftArrow:\\\"\\\\u21c4\\\",rightarrowtail:\\\"\\\\u21a3\\\",RightCeiling:\\\"\\\\u2309\\\",RightDoubleBracket:\\\"\\\\u27e7\\\",RightDownTeeVector:\\\"\\\\u295d\\\",RightDownVectorBar:\\\"\\\\u2955\\\",RightDownVector:\\\"\\\\u21c2\\\",RightFloor:\\\"\\\\u230b\\\",rightharpoondown:\\\"\\\\u21c1\\\",rightharpoonup:\\\"\\\\u21c0\\\",rightleftarrows:\\\"\\\\u21c4\\\",rightleftharpoons:\\\"\\\\u21cc\\\",rightrightarrows:\\\"\\\\u21c9\\\",rightsquigarrow:\\\"\\\\u219d\\\",RightTeeArrow:\\\"\\\\u21a6\\\",RightTee:\\\"\\\\u22a2\\\",RightTeeVector:\\\"\\\\u295b\\\",rightthreetimes:\\\"\\\\u22cc\\\",RightTriangleBar:\\\"\\\\u29d0\\\",RightTriangle:\\\"\\\\u22b3\\\",RightTriangleEqual:\\\"\\\\u22b5\\\",RightUpDownVector:\\\"\\\\u294f\\\",RightUpTeeVector:\\\"\\\\u295c\\\",RightUpVectorBar:\\\"\\\\u2954\\\",RightUpVector:\\\"\\\\u21be\\\",RightVectorBar:\\\"\\\\u2953\\\",RightVector:\\\"\\\\u21c0\\\",ring:\\\"\\\\u02da\\\",risingdotseq:\\\"\\\\u2253\\\",rlarr:\\\"\\\\u21c4\\\",rlhar:\\\"\\\\u21cc\\\",rlm:\\\"\\\\u200f\\\",rmoustache:\\\"\\\\u23b1\\\",rmoust:\\\"\\\\u23b1\\\",rnmid:\\\"\\\\u2aee\\\",roang:\\\"\\\\u27ed\\\",roarr:\\\"\\\\u21fe\\\",robrk:\\\"\\\\u27e7\\\",ropar:\\\"\\\\u2986\\\",ropf:\\\"\\\\ud835\\\\udd63\\\",Ropf:\\\"\\\\u211d\\\",roplus:\\\"\\\\u2a2e\\\",rotimes:\\\"\\\\u2a35\\\",RoundImplies:\\\"\\\\u2970\\\",rpar:\\\")\\\",rpargt:\\\"\\\\u2994\\\",rppolint:\\\"\\\\u2a12\\\",rrarr:\\\"\\\\u21c9\\\",Rrightarrow:\\\"\\\\u21db\\\",rsaquo:\\\"\\\\u203a\\\",rscr:\\\"\\\\ud835\\\\udcc7\\\",Rscr:\\\"\\\\u211b\\\",rsh:\\\"\\\\u21b1\\\",Rsh:\\\"\\\\u21b1\\\",rsqb:\\\"]\\\",rsquo:\\\"\\\\u2019\\\",rsquor:\\\"\\\\u2019\\\",rthree:\\\"\\\\u22cc\\\",rtimes:\\\"\\\\u22ca\\\",rtri:\\\"\\\\u25b9\\\",rtrie:\\\"\\\\u22b5\\\",rtrif:\\\"\\\\u25b8\\\",rtriltri:\\\"\\\\u29ce\\\",RuleDelayed:\\\"\\\\u29f4\\\",ruluhar:\\\"\\\\u2968\\\",rx:\\\"\\\\u211e\\\",Sacute:\\\"\\\\u015a\\\",sacute:\\\"\\\\u015b\\\",sbquo:\\\"\\\\u201a\\\",scap:\\\"\\\\u2ab8\\\",Scaron:\\\"\\\\u0160\\\",scaron:\\\"\\\\u0161\\\",Sc:\\\"\\\\u2abc\\\",sc:\\\"\\\\u227b\\\",sccue:\\\"\\\\u227d\\\",sce:\\\"\\\\u2ab0\\\",scE:\\\"\\\\u2ab4\\\",Scedil:\\\"\\\\u015e\\\",scedil:\\\"\\\\u015f\\\",Scirc:\\\"\\\\u015c\\\",scirc:\\\"\\\\u015d\\\",scnap:\\\"\\\\u2aba\\\",scnE:\\\"\\\\u2ab6\\\",scnsim:\\\"\\\\u22e9\\\",scpolint:\\\"\\\\u2a13\\\",scsim:\\\"\\\\u227f\\\",Scy:\\\"\\\\u0421\\\",scy:\\\"\\\\u0441\\\",sdotb:\\\"\\\\u22a1\\\",sdot:\\\"\\\\u22c5\\\",sdote:\\\"\\\\u2a66\\\",searhk:\\\"\\\\u2925\\\",searr:\\\"\\\\u2198\\\",seArr:\\\"\\\\u21d8\\\",searrow:\\\"\\\\u2198\\\",sect:\\\"\\\\xa7\\\",semi:\\\";\\\",seswar:\\\"\\\\u2929\\\",setminus:\\\"\\\\u2216\\\",setmn:\\\"\\\\u2216\\\",sext:\\\"\\\\u2736\\\",Sfr:\\\"\\\\ud835\\\\udd16\\\",sfr:\\\"\\\\ud835\\\\udd30\\\",sfrown:\\\"\\\\u2322\\\",sharp:\\\"\\\\u266f\\\",SHCHcy:\\\"\\\\u0429\\\",shchcy:\\\"\\\\u0449\\\",SHcy:\\\"\\\\u0428\\\",shcy:\\\"\\\\u0448\\\",ShortDownArrow:\\\"\\\\u2193\\\",ShortLeftArrow:\\\"\\\\u2190\\\",shortmid:\\\"\\\\u2223\\\",shortparallel:\\\"\\\\u2225\\\",ShortRightArrow:\\\"\\\\u2192\\\",ShortUpArrow:\\\"\\\\u2191\\\",shy:\\\"\\\\xad\\\",Sigma:\\\"\\\\u03a3\\\",sigma:\\\"\\\\u03c3\\\",sigmaf:\\\"\\\\u03c2\\\",sigmav:\\\"\\\\u03c2\\\",sim:\\\"\\\\u223c\\\",simdot:\\\"\\\\u2a6a\\\",sime:\\\"\\\\u2243\\\",simeq:\\\"\\\\u2243\\\",simg:\\\"\\\\u2a9e\\\",simgE:\\\"\\\\u2aa0\\\",siml:\\\"\\\\u2a9d\\\",simlE:\\\"\\\\u2a9f\\\",simne:\\\"\\\\u2246\\\",simplus:\\\"\\\\u2a24\\\",simrarr:\\\"\\\\u2972\\\",slarr:\\\"\\\\u2190\\\",SmallCircle:\\\"\\\\u2218\\\",smallsetminus:\\\"\\\\u2216\\\",smashp:\\\"\\\\u2a33\\\",smeparsl:\\\"\\\\u29e4\\\",smid:\\\"\\\\u2223\\\",smile:\\\"\\\\u2323\\\",smt:\\\"\\\\u2aaa\\\",smte:\\\"\\\\u2aac\\\",smtes:\\\"\\\\u2aac\\\\ufe00\\\",SOFTcy:\\\"\\\\u042c\\\",softcy:\\\"\\\\u044c\\\",solbar:\\\"\\\\u233f\\\",solb:\\\"\\\\u29c4\\\",sol:\\\"/\\\",Sopf:\\\"\\\\ud835\\\\udd4a\\\",sopf:\\\"\\\\ud835\\\\udd64\\\",spades:\\\"\\\\u2660\\\",spadesuit:\\\"\\\\u2660\\\",spar:\\\"\\\\u2225\\\",sqcap:\\\"\\\\u2293\\\",sqcaps:\\\"\\\\u2293\\\\ufe00\\\",sqcup:\\\"\\\\u2294\\\",sqcups:\\\"\\\\u2294\\\\ufe00\\\",Sqrt:\\\"\\\\u221a\\\",sqsub:\\\"\\\\u228f\\\",sqsube:\\\"\\\\u2291\\\",sqsubset:\\\"\\\\u228f\\\",sqsubseteq:\\\"\\\\u2291\\\",sqsup:\\\"\\\\u2290\\\",sqsupe:\\\"\\\\u2292\\\",sqsupset:\\\"\\\\u2290\\\",sqsupseteq:\\\"\\\\u2292\\\",square:\\\"\\\\u25a1\\\",Square:\\\"\\\\u25a1\\\",SquareIntersection:\\\"\\\\u2293\\\",SquareSubset:\\\"\\\\u228f\\\",SquareSubsetEqual:\\\"\\\\u2291\\\",SquareSuperset:\\\"\\\\u2290\\\",SquareSupersetEqual:\\\"\\\\u2292\\\",SquareUnion:\\\"\\\\u2294\\\",squarf:\\\"\\\\u25aa\\\",squ:\\\"\\\\u25a1\\\",squf:\\\"\\\\u25aa\\\",srarr:\\\"\\\\u2192\\\",Sscr:\\\"\\\\ud835\\\\udcae\\\",sscr:\\\"\\\\ud835\\\\udcc8\\\",ssetmn:\\\"\\\\u2216\\\",ssmile:\\\"\\\\u2323\\\",sstarf:\\\"\\\\u22c6\\\",Star:\\\"\\\\u22c6\\\",star:\\\"\\\\u2606\\\",starf:\\\"\\\\u2605\\\",straightepsilon:\\\"\\\\u03f5\\\",straightphi:\\\"\\\\u03d5\\\",strns:\\\"\\\\xaf\\\",sub:\\\"\\\\u2282\\\",Sub:\\\"\\\\u22d0\\\",subdot:\\\"\\\\u2abd\\\",subE:\\\"\\\\u2ac5\\\",sube:\\\"\\\\u2286\\\",subedot:\\\"\\\\u2ac3\\\",submult:\\\"\\\\u2ac1\\\",subnE:\\\"\\\\u2acb\\\",subne:\\\"\\\\u228a\\\",subplus:\\\"\\\\u2abf\\\",subrarr:\\\"\\\\u2979\\\",subset:\\\"\\\\u2282\\\",Subset:\\\"\\\\u22d0\\\",subseteq:\\\"\\\\u2286\\\",subseteqq:\\\"\\\\u2ac5\\\",SubsetEqual:\\\"\\\\u2286\\\",subsetneq:\\\"\\\\u228a\\\",subsetneqq:\\\"\\\\u2acb\\\",subsim:\\\"\\\\u2ac7\\\",subsub:\\\"\\\\u2ad5\\\",subsup:\\\"\\\\u2ad3\\\",succapprox:\\\"\\\\u2ab8\\\",succ:\\\"\\\\u227b\\\",succcurlyeq:\\\"\\\\u227d\\\",Succeeds:\\\"\\\\u227b\\\",SucceedsEqual:\\\"\\\\u2ab0\\\",SucceedsSlantEqual:\\\"\\\\u227d\\\",SucceedsTilde:\\\"\\\\u227f\\\",succeq:\\\"\\\\u2ab0\\\",succnapprox:\\\"\\\\u2aba\\\",succneqq:\\\"\\\\u2ab6\\\",succnsim:\\\"\\\\u22e9\\\",succsim:\\\"\\\\u227f\\\",SuchThat:\\\"\\\\u220b\\\",sum:\\\"\\\\u2211\\\",Sum:\\\"\\\\u2211\\\",sung:\\\"\\\\u266a\\\",sup1:\\\"\\\\xb9\\\",sup2:\\\"\\\\xb2\\\",sup3:\\\"\\\\xb3\\\",sup:\\\"\\\\u2283\\\",Sup:\\\"\\\\u22d1\\\",supdot:\\\"\\\\u2abe\\\",supdsub:\\\"\\\\u2ad8\\\",supE:\\\"\\\\u2ac6\\\",supe:\\\"\\\\u2287\\\",supedot:\\\"\\\\u2ac4\\\",Superset:\\\"\\\\u2283\\\",SupersetEqual:\\\"\\\\u2287\\\",suphsol:\\\"\\\\u27c9\\\",suphsub:\\\"\\\\u2ad7\\\",suplarr:\\\"\\\\u297b\\\",supmult:\\\"\\\\u2ac2\\\",supnE:\\\"\\\\u2acc\\\",supne:\\\"\\\\u228b\\\",supplus:\\\"\\\\u2ac0\\\",supset:\\\"\\\\u2283\\\",Supset:\\\"\\\\u22d1\\\",supseteq:\\\"\\\\u2287\\\",supseteqq:\\\"\\\\u2ac6\\\",supsetneq:\\\"\\\\u228b\\\",supsetneqq:\\\"\\\\u2acc\\\",supsim:\\\"\\\\u2ac8\\\",supsub:\\\"\\\\u2ad4\\\",supsup:\\\"\\\\u2ad6\\\",swarhk:\\\"\\\\u2926\\\",swarr:\\\"\\\\u2199\\\",swArr:\\\"\\\\u21d9\\\",swarrow:\\\"\\\\u2199\\\",swnwar:\\\"\\\\u292a\\\",szlig:\\\"\\\\xdf\\\",Tab:\\\"\\\\t\\\",target:\\\"\\\\u2316\\\",Tau:\\\"\\\\u03a4\\\",tau:\\\"\\\\u03c4\\\",tbrk:\\\"\\\\u23b4\\\",Tcaron:\\\"\\\\u0164\\\",tcaron:\\\"\\\\u0165\\\",Tcedil:\\\"\\\\u0162\\\",tcedil:\\\"\\\\u0163\\\",Tcy:\\\"\\\\u0422\\\",tcy:\\\"\\\\u0442\\\",tdot:\\\"\\\\u20db\\\",telrec:\\\"\\\\u2315\\\",Tfr:\\\"\\\\ud835\\\\udd17\\\",tfr:\\\"\\\\ud835\\\\udd31\\\",there4:\\\"\\\\u2234\\\",therefore:\\\"\\\\u2234\\\",Therefore:\\\"\\\\u2234\\\",Theta:\\\"\\\\u0398\\\",theta:\\\"\\\\u03b8\\\",thetasym:\\\"\\\\u03d1\\\",thetav:\\\"\\\\u03d1\\\",thickapprox:\\\"\\\\u2248\\\",thicksim:\\\"\\\\u223c\\\",ThickSpace:\\\"\\\\u205f\\\\u200a\\\",ThinSpace:\\\"\\\\u2009\\\",thinsp:\\\"\\\\u2009\\\",thkap:\\\"\\\\u2248\\\",thksim:\\\"\\\\u223c\\\",THORN:\\\"\\\\xde\\\",thorn:\\\"\\\\xfe\\\",tilde:\\\"\\\\u02dc\\\",Tilde:\\\"\\\\u223c\\\",TildeEqual:\\\"\\\\u2243\\\",TildeFullEqual:\\\"\\\\u2245\\\",TildeTilde:\\\"\\\\u2248\\\",timesbar:\\\"\\\\u2a31\\\",timesb:\\\"\\\\u22a0\\\",times:\\\"\\\\xd7\\\",timesd:\\\"\\\\u2a30\\\",tint:\\\"\\\\u222d\\\",toea:\\\"\\\\u2928\\\",topbot:\\\"\\\\u2336\\\",topcir:\\\"\\\\u2af1\\\",top:\\\"\\\\u22a4\\\",Topf:\\\"\\\\ud835\\\\udd4b\\\",topf:\\\"\\\\ud835\\\\udd65\\\",topfork:\\\"\\\\u2ada\\\",tosa:\\\"\\\\u2929\\\",tprime:\\\"\\\\u2034\\\",trade:\\\"\\\\u2122\\\",TRADE:\\\"\\\\u2122\\\",triangle:\\\"\\\\u25b5\\\",triangledown:\\\"\\\\u25bf\\\",triangleleft:\\\"\\\\u25c3\\\",trianglelefteq:\\\"\\\\u22b4\\\",triangleq:\\\"\\\\u225c\\\",triangleright:\\\"\\\\u25b9\\\",trianglerighteq:\\\"\\\\u22b5\\\",tridot:\\\"\\\\u25ec\\\",trie:\\\"\\\\u225c\\\",triminus:\\\"\\\\u2a3a\\\",TripleDot:\\\"\\\\u20db\\\",triplus:\\\"\\\\u2a39\\\",trisb:\\\"\\\\u29cd\\\",tritime:\\\"\\\\u2a3b\\\",trpezium:\\\"\\\\u23e2\\\",Tscr:\\\"\\\\ud835\\\\udcaf\\\",tscr:\\\"\\\\ud835\\\\udcc9\\\",TScy:\\\"\\\\u0426\\\",tscy:\\\"\\\\u0446\\\",TSHcy:\\\"\\\\u040b\\\",tshcy:\\\"\\\\u045b\\\",Tstrok:\\\"\\\\u0166\\\",tstrok:\\\"\\\\u0167\\\",twixt:\\\"\\\\u226c\\\",twoheadleftarrow:\\\"\\\\u219e\\\",twoheadrightarrow:\\\"\\\\u21a0\\\",Uacute:\\\"\\\\xda\\\",uacute:\\\"\\\\xfa\\\",uarr:\\\"\\\\u2191\\\",Uarr:\\\"\\\\u219f\\\",uArr:\\\"\\\\u21d1\\\",Uarrocir:\\\"\\\\u2949\\\",Ubrcy:\\\"\\\\u040e\\\",ubrcy:\\\"\\\\u045e\\\",Ubreve:\\\"\\\\u016c\\\",ubreve:\\\"\\\\u016d\\\",Ucirc:\\\"\\\\xdb\\\",ucirc:\\\"\\\\xfb\\\",Ucy:\\\"\\\\u0423\\\",ucy:\\\"\\\\u0443\\\",udarr:\\\"\\\\u21c5\\\",Udblac:\\\"\\\\u0170\\\",udblac:\\\"\\\\u0171\\\",udhar:\\\"\\\\u296e\\\",ufisht:\\\"\\\\u297e\\\",Ufr:\\\"\\\\ud835\\\\udd18\\\",ufr:\\\"\\\\ud835\\\\udd32\\\",Ugrave:\\\"\\\\xd9\\\",ugrave:\\\"\\\\xf9\\\",uHar:\\\"\\\\u2963\\\",uharl:\\\"\\\\u21bf\\\",uharr:\\\"\\\\u21be\\\",uhblk:\\\"\\\\u2580\\\",ulcorn:\\\"\\\\u231c\\\",ulcorner:\\\"\\\\u231c\\\",ulcrop:\\\"\\\\u230f\\\",ultri:\\\"\\\\u25f8\\\",Umacr:\\\"\\\\u016a\\\",umacr:\\\"\\\\u016b\\\",uml:\\\"\\\\xa8\\\",UnderBar:\\\"_\\\",UnderBrace:\\\"\\\\u23df\\\",UnderBracket:\\\"\\\\u23b5\\\",UnderParenthesis:\\\"\\\\u23dd\\\",Union:\\\"\\\\u22c3\\\",UnionPlus:\\\"\\\\u228e\\\",Uogon:\\\"\\\\u0172\\\",uogon:\\\"\\\\u0173\\\",Uopf:\\\"\\\\ud835\\\\udd4c\\\",uopf:\\\"\\\\ud835\\\\udd66\\\",UpArrowBar:\\\"\\\\u2912\\\",uparrow:\\\"\\\\u2191\\\",UpArrow:\\\"\\\\u2191\\\",Uparrow:\\\"\\\\u21d1\\\",UpArrowDownArrow:\\\"\\\\u21c5\\\",updownarrow:\\\"\\\\u2195\\\",UpDownArrow:\\\"\\\\u2195\\\",Updownarrow:\\\"\\\\u21d5\\\",UpEquilibrium:\\\"\\\\u296e\\\",upharpoonleft:\\\"\\\\u21bf\\\",upharpoonright:\\\"\\\\u21be\\\",uplus:\\\"\\\\u228e\\\",UpperLeftArrow:\\\"\\\\u2196\\\",UpperRightArrow:\\\"\\\\u2197\\\",upsi:\\\"\\\\u03c5\\\",Upsi:\\\"\\\\u03d2\\\",upsih:\\\"\\\\u03d2\\\",Upsilon:\\\"\\\\u03a5\\\",upsilon:\\\"\\\\u03c5\\\",UpTeeArrow:\\\"\\\\u21a5\\\",UpTee:\\\"\\\\u22a5\\\",upuparrows:\\\"\\\\u21c8\\\",urcorn:\\\"\\\\u231d\\\",urcorner:\\\"\\\\u231d\\\",urcrop:\\\"\\\\u230e\\\",Uring:\\\"\\\\u016e\\\",uring:\\\"\\\\u016f\\\",urtri:\\\"\\\\u25f9\\\",Uscr:\\\"\\\\ud835\\\\udcb0\\\",uscr:\\\"\\\\ud835\\\\udcca\\\",utdot:\\\"\\\\u22f0\\\",Utilde:\\\"\\\\u0168\\\",utilde:\\\"\\\\u0169\\\",utri:\\\"\\\\u25b5\\\",utrif:\\\"\\\\u25b4\\\",uuarr:\\\"\\\\u21c8\\\",Uuml:\\\"\\\\xdc\\\",uuml:\\\"\\\\xfc\\\",uwangle:\\\"\\\\u29a7\\\",vangrt:\\\"\\\\u299c\\\",varepsilon:\\\"\\\\u03f5\\\",varkappa:\\\"\\\\u03f0\\\",varnothing:\\\"\\\\u2205\\\",varphi:\\\"\\\\u03d5\\\",varpi:\\\"\\\\u03d6\\\",varpropto:\\\"\\\\u221d\\\",varr:\\\"\\\\u2195\\\",vArr:\\\"\\\\u21d5\\\",varrho:\\\"\\\\u03f1\\\",varsigma:\\\"\\\\u03c2\\\",varsubsetneq:\\\"\\\\u228a\\\\ufe00\\\",varsubsetneqq:\\\"\\\\u2acb\\\\ufe00\\\",varsupsetneq:\\\"\\\\u228b\\\\ufe00\\\",varsupsetneqq:\\\"\\\\u2acc\\\\ufe00\\\",vartheta:\\\"\\\\u03d1\\\",vartriangleleft:\\\"\\\\u22b2\\\",vartriangleright:\\\"\\\\u22b3\\\",vBar:\\\"\\\\u2ae8\\\",Vbar:\\\"\\\\u2aeb\\\",vBarv:\\\"\\\\u2ae9\\\",Vcy:\\\"\\\\u0412\\\",vcy:\\\"\\\\u0432\\\",vdash:\\\"\\\\u22a2\\\",vDash:\\\"\\\\u22a8\\\",Vdash:\\\"\\\\u22a9\\\",VDash:\\\"\\\\u22ab\\\",Vdashl:\\\"\\\\u2ae6\\\",veebar:\\\"\\\\u22bb\\\",vee:\\\"\\\\u2228\\\",Vee:\\\"\\\\u22c1\\\",veeeq:\\\"\\\\u225a\\\",vellip:\\\"\\\\u22ee\\\",verbar:\\\"|\\\",Verbar:\\\"\\\\u2016\\\",vert:\\\"|\\\",Vert:\\\"\\\\u2016\\\",VerticalBar:\\\"\\\\u2223\\\",VerticalLine:\\\"|\\\",VerticalSeparator:\\\"\\\\u2758\\\",VerticalTilde:\\\"\\\\u2240\\\",VeryThinSpace:\\\"\\\\u200a\\\",Vfr:\\\"\\\\ud835\\\\udd19\\\",vfr:\\\"\\\\ud835\\\\udd33\\\",vltri:\\\"\\\\u22b2\\\",vnsub:\\\"\\\\u2282\\\\u20d2\\\",vnsup:\\\"\\\\u2283\\\\u20d2\\\",Vopf:\\\"\\\\ud835\\\\udd4d\\\",vopf:\\\"\\\\ud835\\\\udd67\\\",vprop:\\\"\\\\u221d\\\",vrtri:\\\"\\\\u22b3\\\",Vscr:\\\"\\\\ud835\\\\udcb1\\\",vscr:\\\"\\\\ud835\\\\udccb\\\",vsubnE:\\\"\\\\u2acb\\\\ufe00\\\",vsubne:\\\"\\\\u228a\\\\ufe00\\\",vsupnE:\\\"\\\\u2acc\\\\ufe00\\\",vsupne:\\\"\\\\u228b\\\\ufe00\\\",Vvdash:\\\"\\\\u22aa\\\",vzigzag:\\\"\\\\u299a\\\",Wcirc:\\\"\\\\u0174\\\",wcirc:\\\"\\\\u0175\\\",wedbar:\\\"\\\\u2a5f\\\",wedge:\\\"\\\\u2227\\\",Wedge:\\\"\\\\u22c0\\\",wedgeq:\\\"\\\\u2259\\\",weierp:\\\"\\\\u2118\\\",Wfr:\\\"\\\\ud835\\\\udd1a\\\",wfr:\\\"\\\\ud835\\\\udd34\\\",Wopf:\\\"\\\\ud835\\\\udd4e\\\",wopf:\\\"\\\\ud835\\\\udd68\\\",wp:\\\"\\\\u2118\\\",wr:\\\"\\\\u2240\\\",wreath:\\\"\\\\u2240\\\",Wscr:\\\"\\\\ud835\\\\udcb2\\\",wscr:\\\"\\\\ud835\\\\udccc\\\",xcap:\\\"\\\\u22c2\\\",xcirc:\\\"\\\\u25ef\\\",xcup:\\\"\\\\u22c3\\\",xdtri:\\\"\\\\u25bd\\\",Xfr:\\\"\\\\ud835\\\\udd1b\\\",xfr:\\\"\\\\ud835\\\\udd35\\\",xharr:\\\"\\\\u27f7\\\",xhArr:\\\"\\\\u27fa\\\",Xi:\\\"\\\\u039e\\\",xi:\\\"\\\\u03be\\\",xlarr:\\\"\\\\u27f5\\\",xlArr:\\\"\\\\u27f8\\\",xmap:\\\"\\\\u27fc\\\",xnis:\\\"\\\\u22fb\\\",xodot:\\\"\\\\u2a00\\\",Xopf:\\\"\\\\ud835\\\\udd4f\\\",xopf:\\\"\\\\ud835\\\\udd69\\\",xoplus:\\\"\\\\u2a01\\\",xotime:\\\"\\\\u2a02\\\",xrarr:\\\"\\\\u27f6\\\",xrArr:\\\"\\\\u27f9\\\",Xscr:\\\"\\\\ud835\\\\udcb3\\\",xscr:\\\"\\\\ud835\\\\udccd\\\",xsqcup:\\\"\\\\u2a06\\\",xuplus:\\\"\\\\u2a04\\\",xutri:\\\"\\\\u25b3\\\",xvee:\\\"\\\\u22c1\\\",xwedge:\\\"\\\\u22c0\\\",Yacute:\\\"\\\\xdd\\\",yacute:\\\"\\\\xfd\\\",YAcy:\\\"\\\\u042f\\\",yacy:\\\"\\\\u044f\\\",Ycirc:\\\"\\\\u0176\\\",ycirc:\\\"\\\\u0177\\\",Ycy:\\\"\\\\u042b\\\",ycy:\\\"\\\\u044b\\\",yen:\\\"\\\\xa5\\\",Yfr:\\\"\\\\ud835\\\\udd1c\\\",yfr:\\\"\\\\ud835\\\\udd36\\\",YIcy:\\\"\\\\u0407\\\",yicy:\\\"\\\\u0457\\\",Yopf:\\\"\\\\ud835\\\\udd50\\\",yopf:\\\"\\\\ud835\\\\udd6a\\\",Yscr:\\\"\\\\ud835\\\\udcb4\\\",yscr:\\\"\\\\ud835\\\\udcce\\\",YUcy:\\\"\\\\u042e\\\",yucy:\\\"\\\\u044e\\\",yuml:\\\"\\\\xff\\\",Yuml:\\\"\\\\u0178\\\",Zacute:\\\"\\\\u0179\\\",zacute:\\\"\\\\u017a\\\",Zcaron:\\\"\\\\u017d\\\",zcaron:\\\"\\\\u017e\\\",Zcy:\\\"\\\\u0417\\\",zcy:\\\"\\\\u0437\\\",Zdot:\\\"\\\\u017b\\\",zdot:\\\"\\\\u017c\\\",zeetrf:\\\"\\\\u2128\\\",ZeroWidthSpace:\\\"\\\\u200b\\\",Zeta:\\\"\\\\u0396\\\",zeta:\\\"\\\\u03b6\\\",zfr:\\\"\\\\ud835\\\\udd37\\\",Zfr:\\\"\\\\u2128\\\",ZHcy:\\\"\\\\u0416\\\",zhcy:\\\"\\\\u0436\\\",zigrarr:\\\"\\\\u21dd\\\",zopf:\\\"\\\\ud835\\\\udd6b\\\",Zopf:\\\"\\\\u2124\\\",Zscr:\\\"\\\\ud835\\\\udcb5\\\",zscr:\\\"\\\\ud835\\\\udccf\\\",zwj:\\\"\\\\u200d\\\",zwnj:\\\"\\\\u200c\\\"},t=/[!-#%-\\\\*,-\\\\/:;\\\\?@\\\\[-\\\\]_\\\\{\\\\}\\\\xA1\\\\xA7\\\\xAB\\\\xB6\\\\xB7\\\\xBB\\\\xBF\\\\u037E\\\\u0387\\\\u055A-\\\\u055F\\\\u0589\\\\u058A\\\\u05BE\\\\u05C0\\\\u05C3\\\\u05C6\\\\u05F3\\\\u05F4\\\\u0609\\\\u060A\\\\u060C\\\\u060D\\\\u061B\\\\u061E\\\\u061F\\\\u066A-\\\\u066D\\\\u06D4\\\\u0700-\\\\u070D\\\\u07F7-\\\\u07F9\\\\u0830-\\\\u083E\\\\u085E\\\\u0964\\\\u0965\\\\u0970\\\\u09FD\\\\u0A76\\\\u0AF0\\\\u0C84\\\\u0DF4\\\\u0E4F\\\\u0E5A\\\\u0E5B\\\\u0F04-\\\\u0F12\\\\u0F14\\\\u0F3A-\\\\u0F3D\\\\u0F85\\\\u0FD0-\\\\u0FD4\\\\u0FD9\\\\u0FDA\\\\u104A-\\\\u104F\\\\u10FB\\\\u1360-\\\\u1368\\\\u1400\\\\u166D\\\\u166E\\\\u169B\\\\u169C\\\\u16EB-\\\\u16ED\\\\u1735\\\\u1736\\\\u17D4-\\\\u17D6\\\\u17D8-\\\\u17DA\\\\u1800-\\\\u180A\\\\u1944\\\\u1945\\\\u1A1E\\\\u1A1F\\\\u1AA0-\\\\u1AA6\\\\u1AA8-\\\\u1AAD\\\\u1B5A-\\\\u1B60\\\\u1BFC-\\\\u1BFF\\\\u1C3B-\\\\u1C3F\\\\u1C7E\\\\u1C7F\\\\u1CC0-\\\\u1CC7\\\\u1CD3\\\\u2010-\\\\u2027\\\\u2030-\\\\u2043\\\\u2045-\\\\u2051\\\\u2053-\\\\u205E\\\\u207D\\\\u207E\\\\u208D\\\\u208E\\\\u2308-\\\\u230B\\\\u2329\\\\u232A\\\\u2768-\\\\u2775\\\\u27C5\\\\u27C6\\\\u27E6-\\\\u27EF\\\\u2983-\\\\u2998\\\\u29D8-\\\\u29DB\\\\u29FC\\\\u29FD\\\\u2CF9-\\\\u2CFC\\\\u2CFE\\\\u2CFF\\\\u2D70\\\\u2E00-\\\\u2E2E\\\\u2E30-\\\\u2E4E\\\\u3001-\\\\u3003\\\\u3008-\\\\u3011\\\\u3014-\\\\u301F\\\\u3030\\\\u303D\\\\u30A0\\\\u30FB\\\\uA4FE\\\\uA4FF\\\\uA60D-\\\\uA60F\\\\uA673\\\\uA67E\\\\uA6F2-\\\\uA6F7\\\\uA874-\\\\uA877\\\\uA8CE\\\\uA8CF\\\\uA8F8-\\\\uA8FA\\\\uA8FC\\\\uA92E\\\\uA92F\\\\uA95F\\\\uA9C1-\\\\uA9CD\\\\uA9DE\\\\uA9DF\\\\uAA5C-\\\\uAA5F\\\\uAADE\\\\uAADF\\\\uAAF0\\\\uAAF1\\\\uABEB\\\\uFD3E\\\\uFD3F\\\\uFE10-\\\\uFE19\\\\uFE30-\\\\uFE52\\\\uFE54-\\\\uFE61\\\\uFE63\\\\uFE68\\\\uFE6A\\\\uFE6B\\\\uFF01-\\\\uFF03\\\\uFF05-\\\\uFF0A\\\\uFF0C-\\\\uFF0F\\\\uFF1A\\\\uFF1B\\\\uFF1F\\\\uFF20\\\\uFF3B-\\\\uFF3D\\\\uFF3F\\\\uFF5B\\\\uFF5D\\\\uFF5F-\\\\uFF65]|\\\\uD800[\\\\uDD00-\\\\uDD02\\\\uDF9F\\\\uDFD0]|\\\\uD801\\\\uDD6F|\\\\uD802[\\\\uDC57\\\\uDD1F\\\\uDD3F\\\\uDE50-\\\\uDE58\\\\uDE7F\\\\uDEF0-\\\\uDEF6\\\\uDF39-\\\\uDF3F\\\\uDF99-\\\\uDF9C]|\\\\uD803[\\\\uDF55-\\\\uDF59]|\\\\uD804[\\\\uDC47-\\\\uDC4D\\\\uDCBB\\\\uDCBC\\\\uDCBE-\\\\uDCC1\\\\uDD40-\\\\uDD43\\\\uDD74\\\\uDD75\\\\uDDC5-\\\\uDDC8\\\\uDDCD\\\\uDDDB\\\\uDDDD-\\\\uDDDF\\\\uDE38-\\\\uDE3D\\\\uDEA9]|\\\\uD805[\\\\uDC4B-\\\\uDC4F\\\\uDC5B\\\\uDC5D\\\\uDCC6\\\\uDDC1-\\\\uDDD7\\\\uDE41-\\\\uDE43\\\\uDE60-\\\\uDE6C\\\\uDF3C-\\\\uDF3E]|\\\\uD806[\\\\uDC3B\\\\uDE3F-\\\\uDE46\\\\uDE9A-\\\\uDE9C\\\\uDE9E-\\\\uDEA2]|\\\\uD807[\\\\uDC41-\\\\uDC45\\\\uDC70\\\\uDC71\\\\uDEF7\\\\uDEF8]|\\\\uD809[\\\\uDC70-\\\\uDC74]|\\\\uD81A[\\\\uDE6E\\\\uDE6F\\\\uDEF5\\\\uDF37-\\\\uDF3B\\\\uDF44]|\\\\uD81B[\\\\uDE97-\\\\uDE9A]|\\\\uD82F\\\\uDC9F|\\\\uD836[\\\\uDE87-\\\\uDE8B]|\\\\uD83A[\\\\uDD5E\\\\uDD5F]/,n={};function s(e,r,t){var o,i,a,c,l,u=\\\"\\\";for(\\\"string\\\"!=typeof r&&(t=r,r=s.defaultChars),void 0===t&&(t=!0),l=function(e){var r,t,s=n[e];if(s)return s;for(s=n[e]=[],r=0;r\u003C128;r++)t=String.fromCharCode(r),/^[0-9a-z]$/i.test(t)?s.push(t):s.push(\\\"%\\\"+(\\\"0\\\"+r.toString(16).toUpperCase()).slice(-2));for(r=0;r\u003Ce.length;r++)s[e.charCodeAt(r)]=e[r];return s}(r),o=0,i=e.length;o\u003Ci;o++)if(a=e.charCodeAt(o),t&&37===a&&o+2\u003Ci&&/^[0-9a-f]{2}$/i.test(e.slice(o+1,o+3)))u+=e.slice(o,o+3),o+=2;else if(a\u003C128)u+=l[a];else if(a>=55296&&a\u003C=57343){if(a>=55296&&a\u003C=56319&&o+1\u003Ci&&(c=e.charCodeAt(o+1))>=56320&&c\u003C=57343){u+=encodeURIComponent(e[o]+e[o+1]),o++;continue}u+=\\\"%EF%BF%BD\\\"}else u+=encodeURIComponent(e[o]);return u}s.defaultChars=\\\";/?:@&=+$,-_.!~*'()#\\\",s.componentChars=\\\"-_.!~*'()\\\";var o=s,i={};function a(e,r){var t;return\\\"string\\\"!=typeof r&&(r=a.defaultChars),t=function(e){var r,t,n=i[e];if(n)return n;for(n=i[e]=[],r=0;r\u003C128;r++)t=String.fromCharCode(r),n.push(t);for(r=0;r\u003Ce.length;r++)n[t=e.charCodeAt(r)]=\\\"%\\\"+(\\\"0\\\"+t.toString(16).toUpperCase()).slice(-2);return n}(r),e.replace(/(%[a-f0-9]{2})+/gi,(function(e){var r,n,s,o,i,a,c,l=\\\"\\\";for(r=0,n=e.length;r\u003Cn;r+=3)(s=parseInt(e.slice(r+1,r+3),16))\u003C128?l+=t[s]:192==(224&s)&&r+3\u003Cn&&128==(192&(o=parseInt(e.slice(r+4,r+6),16)))?(l+=(c=s\u003C\u003C6&1984|63&o)\u003C128?\\\"\\\\ufffd\\\\ufffd\\\":String.fromCharCode(c),r+=3):224==(240&s)&&r+6\u003Cn&&(o=parseInt(e.slice(r+4,r+6),16),i=parseInt(e.slice(r+7,r+9),16),128==(192&o)&&128==(192&i))?(l+=(c=s\u003C\u003C12&61440|o\u003C\u003C6&4032|63&i)\u003C2048||c>=55296&&c\u003C=57343?\\\"\\\\ufffd\\\\ufffd\\\\ufffd\\\":String.fromCharCode(c),r+=6):240==(248&s)&&r+9\u003Cn&&(o=parseInt(e.slice(r+4,r+6),16),i=parseInt(e.slice(r+7,r+9),16),a=parseInt(e.slice(r+10,r+12),16),128==(192&o)&&128==(192&i)&&128==(192&a))?((c=s\u003C\u003C18&1835008|o\u003C\u003C12&258048|i\u003C\u003C6&4032|63&a)\u003C65536||c>1114111?l+=\\\"\\\\ufffd\\\\ufffd\\\\ufffd\\\\ufffd\\\":(c-=65536,l+=String.fromCharCode(55296+(c>>10),56320+(1023&c))),r+=9):l+=\\\"\\\\ufffd\\\";return l}))}a.defaultChars=\\\";/?:@&=+$,#\\\",a.componentChars=\\\"\\\";var c=a;function l(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}var u=/^([a-z0-9.+-]+:)/i,p=/:[0-9]*$/,h=/^(\\\\/\\\\/?(?!\\\\/)[^\\\\?\\\\s]*)(\\\\?[^\\\\s]*)?$/,f=[\\\"{\\\",\\\"}\\\",\\\"|\\\",\\\"\\\\\\\\\\\",\\\"^\\\",\\\"`\\\"].concat([\\\"\u003C\\\",\\\">\\\",'\\\"',\\\"`\\\",\\\" \\\",\\\"\\\\r\\\",\\\"\\\\n\\\",\\\"\\\\t\\\"]),d=[\\\"'\\\"].concat(f),m=[\\\"%\\\",\\\"/\\\",\\\"?\\\",\\\";\\\",\\\"#\\\"].concat(d),g=[\\\"/\\\",\\\"?\\\",\\\"#\\\"],_=/^[+a-z0-9A-Z_-]{0,63}$/,k=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,b={javascript:!0,\\\"javascript:\\\":!0},v={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,\\\"http:\\\":!0,\\\"https:\\\":!0,\\\"ftp:\\\":!0,\\\"gopher:\\\":!0,\\\"file:\\\":!0};l.prototype.parse=function(e,r){var t,n,s,o,i,a=e;if(a=a.trim(),!r&&1===e.split(\\\"#\\\").length){var c=h.exec(a);if(c)return this.pathname=c[1],c[2]&&(this.search=c[2]),this}var l=u.exec(a);if(l&&(s=(l=l[0]).toLowerCase(),this.protocol=l,a=a.substr(l.length)),(r||l||a.match(/^\\\\/\\\\/[^@\\\\/]+@[^@\\\\/]+/))&&(!(i=\\\"//\\\"===a.substr(0,2))||l&&b[l]||(a=a.substr(2),this.slashes=!0)),!b[l]&&(i||l&&!v[l])){var p,f,d=-1;for(t=0;t\u003Cg.length;t++)-1!==(o=a.indexOf(g[t]))&&(-1===d||o\u003Cd)&&(d=o);for(-1!==(f=-1===d?a.lastIndexOf(\\\"@\\\"):a.lastIndexOf(\\\"@\\\",d))&&(p=a.slice(0,f),a=a.slice(f+1),this.auth=p),d=-1,t=0;t\u003Cm.length;t++)-1!==(o=a.indexOf(m[t]))&&(-1===d||o\u003Cd)&&(d=o);-1===d&&(d=a.length),\\\":\\\"===a[d-1]&&d--;var C=a.slice(0,d);a=a.slice(d),this.parseHost(C),this.hostname=this.hostname||\\\"\\\";var y=\\\"[\\\"===this.hostname[0]&&\\\"]\\\"===this.hostname[this.hostname.length-1];if(!y){var A=this.hostname.split(/\\\\./);for(t=0,n=A.length;t\u003Cn;t++){var x=A[t];if(x&&!x.match(_)){for(var D=\\\"\\\",w=0,E=x.length;w\u003CE;w++)x.charCodeAt(w)>127?D+=\\\"x\\\":D+=x[w];if(!D.match(_)){var q=A.slice(0,t),S=A.slice(t+1),F=x.match(k);F&&(q.push(F[1]),S.unshift(F[2])),S.length&&(a=S.join(\\\".\\\")+a),this.hostname=q.join(\\\".\\\");break}}}}this.hostname.length>255&&(this.hostname=\\\"\\\"),y&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}var L=a.indexOf(\\\"#\\\");-1!==L&&(this.hash=a.substr(L),a=a.slice(0,L));var z=a.indexOf(\\\"?\\\");return-1!==z&&(this.search=a.substr(z),a=a.slice(0,z)),a&&(this.pathname=a),v[s]&&this.hostname&&!this.pathname&&(this.pathname=\\\"\\\"),this},l.prototype.parseHost=function(e){var r=p.exec(e);r&&(\\\":\\\"!==(r=r[0])&&(this.port=r.substr(1)),e=e.substr(0,e.length-r.length)),e&&(this.hostname=e)};var C={encode:o,decode:c,format:function(e){var r=\\\"\\\";return r+=e.protocol||\\\"\\\",r+=e.slashes?\\\"//\\\":\\\"\\\",r+=e.auth?e.auth+\\\"@\\\":\\\"\\\",e.hostname&&-1!==e.hostname.indexOf(\\\":\\\")?r+=\\\"[\\\"+e.hostname+\\\"]\\\":r+=e.hostname||\\\"\\\",r+=e.port?\\\":\\\"+e.port:\\\"\\\",r+=e.pathname||\\\"\\\",r+=e.search||\\\"\\\",r+=e.hash||\\\"\\\"},parse:function(e,r){if(e&&e instanceof l)return e;var t=new l;return t.parse(e,r),t}},y=/[\\\\0-\\\\uD7FF\\\\uE000-\\\\uFFFF]|[\\\\uD800-\\\\uDBFF][\\\\uDC00-\\\\uDFFF]|[\\\\uD800-\\\\uDBFF](?![\\\\uDC00-\\\\uDFFF])|(?:[^\\\\uD800-\\\\uDBFF]|^)[\\\\uDC00-\\\\uDFFF]/,A=/[\\\\0-\\\\x1F\\\\x7F-\\\\x9F]/,x=/[ \\\\xA0\\\\u1680\\\\u2000-\\\\u200A\\\\u2028\\\\u2029\\\\u202F\\\\u205F\\\\u3000]/,D={Any:y,Cc:A,Cf:/[\\\\xAD\\\\u0600-\\\\u0605\\\\u061C\\\\u06DD\\\\u070F\\\\u08E2\\\\u180E\\\\u200B-\\\\u200F\\\\u202A-\\\\u202E\\\\u2060-\\\\u2064\\\\u2066-\\\\u206F\\\\uFEFF\\\\uFFF9-\\\\uFFFB]|\\\\uD804[\\\\uDCBD\\\\uDCCD]|\\\\uD82F[\\\\uDCA0-\\\\uDCA3]|\\\\uD834[\\\\uDD73-\\\\uDD7A]|\\\\uDB40[\\\\uDC01\\\\uDC20-\\\\uDC7F]/,P:t,Z:x},w=function(e,r,t){return t={path:r,exports:{},require:function(e,r){return function(){throw new Error(\\\"Dynamic requires are not currently supported by @rollup/plugin-commonjs\\\")}(null==r&&t.path)}},e(t,t.exports),t.exports}((function(e,n){var s=Object.prototype.hasOwnProperty;function o(e,r){return s.call(e,r)}function i(e){return!(e>=55296&&e\u003C=57343)&&(!(e>=64976&&e\u003C=65007)&&(65535!=(65535&e)&&65534!=(65535&e)&&(!(e>=0&&e\u003C=8)&&(11!==e&&(!(e>=14&&e\u003C=31)&&(!(e>=127&&e\u003C=159)&&!(e>1114111)))))))}function a(e){if(e>65535){var r=55296+((e-=65536)>>10),t=56320+(1023&e);return String.fromCharCode(r,t)}return String.fromCharCode(e)}var c=/\\\\\\\\([!\\\"#$%&'()*+,\\\\-.\\\\/:;\u003C=>?@[\\\\\\\\\\\\]^_`{|}~])/g,l=new RegExp(c.source+\\\"|\\\"+/&([a-z#][a-z0-9]{1,31});/gi.source,\\\"gi\\\"),u=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i;var p=/[&\u003C>\\\"]/,h=/[&\u003C>\\\"]/g,f={\\\"&\\\":\\\"&\\\",\\\"\u003C\\\":\\\"<\\\",\\\">\\\":\\\">\\\",'\\\"':\\\""\\\"};function d(e){return f[e]}var m=/[.?*+^$[\\\\]\\\\\\\\(){}|-]/g;n.lib={},n.lib.mdurl=C,n.lib.ucmicro=D,n.assign=function(e){var r=Array.prototype.slice.call(arguments,1);return r.forEach((function(r){if(r){if(\\\"object\\\"!=typeof r)throw new TypeError(r+\\\"must be object\\\");Object.keys(r).forEach((function(t){e[t]=r[t]}))}})),e},n.isString=function(e){return\\\"[object String]\\\"===function(e){return Object.prototype.toString.call(e)}(e)},n.has=o,n.unescapeMd=function(e){return e.indexOf(\\\"\\\\\\\\\\\")\u003C0?e:e.replace(c,\\\"$1\\\")},n.unescapeAll=function(e){return e.indexOf(\\\"\\\\\\\\\\\")\u003C0&&e.indexOf(\\\"&\\\")\u003C0?e:e.replace(l,(function(e,t,n){return t||function(e,t){var n=0;return o(r,t)?r[t]:35===t.charCodeAt(0)&&u.test(t)&&i(n=\\\"x\\\"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10))?a(n):e}(e,n)}))},n.isValidEntityCode=i,n.fromCodePoint=a,n.escapeHtml=function(e){return p.test(e)?e.replace(h,d):e},n.arrayReplaceAt=function(e,r,t){return[].concat(e.slice(0,r),t,e.slice(r+1))},n.isSpace=function(e){switch(e){case 9:case 32:return!0}return!1},n.isWhiteSpace=function(e){if(e>=8192&&e\u003C=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1},n.isMdAsciiPunct=function(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}},n.isPunctChar=function(e){return t.test(e)},n.escapeRE=function(e){return e.replace(m,\\\"\\\\\\\\$&\\\")},n.normalizeReference=function(e){return e=e.trim().replace(/\\\\s+/g,\\\" \\\"),\\\"\\\\u1e7e\\\"===\\\"\\\\u1e9e\\\".toLowerCase()&&(e=e.replace(/\\\\u1e9e/g,\\\"\\\\xdf\\\")),e.toLowerCase().toUpperCase()}})),E=w.unescapeAll,q=w.unescapeAll,S=function(e,r,t){var n,s,o=r,i={ok:!1,pos:0,lines:0,str:\\\"\\\"};if(60===e.charCodeAt(r)){for(r++;r\u003Ct;){if(10===(n=e.charCodeAt(r)))return i;if(60===n)return i;if(62===n)return i.pos=r+1,i.str=E(e.slice(o+1,r)),i.ok=!0,i;92===n&&r+1\u003Ct?r+=2:r++}return i}for(s=0;r\u003Ct&&32!==(n=e.charCodeAt(r))&&!(n\u003C32||127===n);)if(92===n&&r+1\u003Ct){if(32===e.charCodeAt(r+1))break;r+=2}else{if(40===n&&++s>32)return i;if(41===n){if(0===s)break;s--}r++}return o===r||0!==s||(i.str=E(e.slice(o,r)),i.lines=0,i.pos=r,i.ok=!0),i},F=function(e,r,t){var n,s,o=0,i=r,a={ok:!1,pos:0,lines:0,str:\\\"\\\"};if(r>=t)return a;if(34!==(s=e.charCodeAt(r))&&39!==s&&40!==s)return a;for(r++,40===s&&(s=41);r\u003Ct;){if((n=e.charCodeAt(r))===s)return a.pos=r+1,a.lines=o,a.str=q(e.slice(i+1,r)),a.ok=!0,a;if(40===n&&41===s)return a;10===n?o++:92===n&&r+1\u003Ct&&(r++,10===e.charCodeAt(r)&&o++),r++}return a},L={parseLinkLabel:function(e,r,t){var n,s,o,i,a=-1,c=e.posMax,l=e.pos;for(e.pos=r+1,n=1;e.pos\u003Cc;){if(93===(o=e.src.charCodeAt(e.pos))&&0===--n){s=!0;break}if(i=e.pos,e.md.inline.skipToken(e),91===o)if(i===e.pos-1)n++;else if(t)return e.pos=l,-1}return s&&(a=e.pos),e.pos=l,a},parseLinkDestination:S,parseLinkTitle:F},z=w.assign,T=w.unescapeAll,I=w.escapeHtml,M={};function R(){this.rules=z({},M)}M.code_inline=function(e,r,t,n,s){var o=e[r];return\\\"\u003Ccode\\\"+s.renderAttrs(o)+\\\">\\\"+I(e[r].content)+\\\"\u003C/code>\\\"},M.code_block=function(e,r,t,n,s){var o=e[r];return\\\"\u003Cpre\\\"+s.renderAttrs(o)+\\\">\u003Ccode>\\\"+I(e[r].content)+\\\"\u003C/code>\u003C/pre>\\\\n\\\"},M.fence=function(e,r,t,n,s){var o,i,a,c,l,u=e[r],p=u.info?T(u.info).trim():\\\"\\\",h=\\\"\\\",f=\\\"\\\";return p&&(h=(a=p.split(/(\\\\s+)/g))[0],f=a.slice(2).join(\\\"\\\")),0===(o=t.highlight&&t.highlight(u.content,h,f)||I(u.content)).indexOf(\\\"\u003Cpre\\\")?o+\\\"\\\\n\\\":p?(i=u.attrIndex(\\\"class\\\"),c=u.attrs?u.attrs.slice():[],i\u003C0?c.push([\\\"class\\\",t.langPrefix+h]):(c[i]=c[i].slice(),c[i][1]+=\\\" \\\"+t.langPrefix+h),l={attrs:c},\\\"\u003Cpre>\u003Ccode\\\"+s.renderAttrs(l)+\\\">\\\"+o+\\\"\u003C/code>\u003C/pre>\\\\n\\\"):\\\"\u003Cpre>\u003Ccode\\\"+s.renderAttrs(u)+\\\">\\\"+o+\\\"\u003C/code>\u003C/pre>\\\\n\\\"},M.image=function(e,r,t,n,s){var o=e[r];return o.attrs[o.attrIndex(\\\"alt\\\")][1]=s.renderInlineAsText(o.children,t,n),s.renderToken(e,r,t)},M.hardbreak=function(e,r,t){return t.xhtmlOut?\\\"\u003Cbr />\\\\n\\\":\\\"\u003Cbr>\\\\n\\\"},M.softbreak=function(e,r,t){return t.breaks?t.xhtmlOut?\\\"\u003Cbr />\\\\n\\\":\\\"\u003Cbr>\\\\n\\\":\\\"\\\\n\\\"},M.text=function(e,r){return I(e[r].content)},M.html_block=function(e,r){return e[r].content},M.html_inline=function(e,r){return e[r].content},R.prototype.renderAttrs=function(e){var r,t,n;if(!e.attrs)return\\\"\\\";for(n=\\\"\\\",r=0,t=e.attrs.length;r\u003Ct;r++)n+=\\\" \\\"+I(e.attrs[r][0])+'=\\\"'+I(e.attrs[r][1])+'\\\"';return n},R.prototype.renderToken=function(e,r,t){var n,s=\\\"\\\",o=!1,i=e[r];return i.hidden?\\\"\\\":(i.block&&-1!==i.nesting&&r&&e[r-1].hidden&&(s+=\\\"\\\\n\\\"),s+=(-1===i.nesting?\\\"\u003C/\\\":\\\"\u003C\\\")+i.tag,s+=this.renderAttrs(i),0===i.nesting&&t.xhtmlOut&&(s+=\\\" /\\\"),i.block&&(o=!0,1===i.nesting&&r+1\u003Ce.length&&(\\\"inline\\\"===(n=e[r+1]).type||n.hidden||-1===n.nesting&&n.tag===i.tag)&&(o=!1)),s+=o?\\\">\\\\n\\\":\\\">\\\")},R.prototype.renderInline=function(e,r,t){for(var n,s=\\\"\\\",o=this.rules,i=0,a=e.length;i\u003Ca;i++)void 0!==o[n=e[i].type]?s+=o[n](e,i,r,t,this):s+=this.renderToken(e,i,r);return s},R.prototype.renderInlineAsText=function(e,r,t){for(var n=\\\"\\\",s=0,o=e.length;s\u003Co;s++)\\\"text\\\"===e[s].type?n+=e[s].content:\\\"image\\\"===e[s].type?n+=this.renderInlineAsText(e[s].children,r,t):\\\"softbreak\\\"===e[s].type&&(n+=\\\"\\\\n\\\");return n},R.prototype.render=function(e,r,t){var n,s,o,i=\\\"\\\",a=this.rules;for(n=0,s=e.length;n\u003Cs;n++)\\\"inline\\\"===(o=e[n].type)?i+=this.renderInline(e[n].children,r,t):void 0!==a[o]?i+=a[e[n].type](e,n,r,t,this):i+=this.renderToken(e,n,r,t);return i};var B=R;function N(){this.__rules__=[],this.__cache__=null}N.prototype.__find__=function(e){for(var r=0;r\u003Cthis.__rules__.length;r++)if(this.__rules__[r].name===e)return r;return-1},N.prototype.__compile__=function(){var e=this,r=[\\\"\\\"];e.__rules__.forEach((function(e){e.enabled&&e.alt.forEach((function(e){r.indexOf(e)\u003C0&&r.push(e)}))})),e.__cache__={},r.forEach((function(r){e.__cache__[r]=[],e.__rules__.forEach((function(t){t.enabled&&(r&&t.alt.indexOf(r)\u003C0||e.__cache__[r].push(t.fn))}))}))},N.prototype.at=function(e,r,t){var n=this.__find__(e),s=t||{};if(-1===n)throw new Error(\\\"Parser rule not found: \\\"+e);this.__rules__[n].fn=r,this.__rules__[n].alt=s.alt||[],this.__cache__=null},N.prototype.before=function(e,r,t,n){var s=this.__find__(e),o=n||{};if(-1===s)throw new Error(\\\"Parser rule not found: \\\"+e);this.__rules__.splice(s,0,{name:r,enabled:!0,fn:t,alt:o.alt||[]}),this.__cache__=null},N.prototype.after=function(e,r,t,n){var s=this.__find__(e),o=n||{};if(-1===s)throw new Error(\\\"Parser rule not found: \\\"+e);this.__rules__.splice(s+1,0,{name:r,enabled:!0,fn:t,alt:o.alt||[]}),this.__cache__=null},N.prototype.push=function(e,r,t){var n=t||{};this.__rules__.push({name:e,enabled:!0,fn:r,alt:n.alt||[]}),this.__cache__=null},N.prototype.enable=function(e,r){Array.isArray(e)||(e=[e]);var t=[];return e.forEach((function(e){var n=this.__find__(e);if(n\u003C0){if(r)return;throw new Error(\\\"Rules manager: invalid rule name \\\"+e)}this.__rules__[n].enabled=!0,t.push(e)}),this),this.__cache__=null,t},N.prototype.enableOnly=function(e,r){Array.isArray(e)||(e=[e]),this.__rules__.forEach((function(e){e.enabled=!1})),this.enable(e,r)},N.prototype.disable=function(e,r){Array.isArray(e)||(e=[e]);var t=[];return e.forEach((function(e){var n=this.__find__(e);if(n\u003C0){if(r)return;throw new Error(\\\"Rules manager: invalid rule name \\\"+e)}this.__rules__[n].enabled=!1,t.push(e)}),this),this.__cache__=null,t},N.prototype.getRules=function(e){return null===this.__cache__&&this.__compile__(),this.__cache__[e]||[]};var O=N,P=/\\\\r\\\\n?|\\\\n/g,j=/\\\\0/g,U=w.arrayReplaceAt;function V(e){return/^\u003C\\\\/a\\\\s*>/i.test(e)}var Z=/\\\\+-|\\\\.\\\\.|\\\\?\\\\?\\\\?\\\\?|!!!!|,,|--/,$=/\\\\((c|tm|r)\\\\)/i,G=/\\\\((c|tm|r)\\\\)/gi,H={c:\\\"\\\\xa9\\\",r:\\\"\\\\xae\\\",tm:\\\"\\\\u2122\\\"};function J(e,r){return H[r.toLowerCase()]}function W(e){var r,t,n=0;for(r=e.length-1;r>=0;r--)\\\"text\\\"!==(t=e[r]).type||n||(t.content=t.content.replace(G,J)),\\\"link_open\\\"===t.type&&\\\"auto\\\"===t.info&&n--,\\\"link_close\\\"===t.type&&\\\"auto\\\"===t.info&&n++}function Y(e){var r,t,n=0;for(r=e.length-1;r>=0;r--)\\\"text\\\"!==(t=e[r]).type||n||Z.test(t.content)&&(t.content=t.content.replace(/\\\\+-/g,\\\"\\\\xb1\\\").replace(/\\\\.{2,}/g,\\\"\\\\u2026\\\").replace(/([?!])\\\\u2026/g,\\\"$1..\\\").replace(/([?!]){4,}/g,\\\"$1$1$1\\\").replace(/,{2,}/g,\\\",\\\").replace(/(^|[^-])---(?=[^-]|$)/gm,\\\"$1\\\\u2014\\\").replace(/(^|\\\\s)--(?=\\\\s|$)/gm,\\\"$1\\\\u2013\\\").replace(/(^|[^-\\\\s])--(?=[^-\\\\s]|$)/gm,\\\"$1\\\\u2013\\\")),\\\"link_open\\\"===t.type&&\\\"auto\\\"===t.info&&n--,\\\"link_close\\\"===t.type&&\\\"auto\\\"===t.info&&n++}var K=w.isWhiteSpace,Q=w.isPunctChar,X=w.isMdAsciiPunct,ee=/['\\\"]/,re=/['\\\"]/g;function te(e,r,t){return e.slice(0,r)+t+e.slice(r+1)}function ne(e,r){var t,n,s,o,i,a,c,l,u,p,h,f,d,m,g,_,k,b,v,C,y;for(v=[],t=0;t\u003Ce.length;t++){for(n=e[t],c=e[t].level,k=v.length-1;k>=0&&!(v[k].level\u003C=c);k--);if(v.length=k+1,\\\"text\\\"===n.type){i=0,a=(s=n.content).length;e:for(;i\u003Ca&&(re.lastIndex=i,o=re.exec(s));){if(g=_=!0,i=o.index+1,b=\\\"'\\\"===o[0],u=32,o.index-1>=0)u=s.charCodeAt(o.index-1);else for(k=t-1;k>=0&&(\\\"softbreak\\\"!==e[k].type&&\\\"hardbreak\\\"!==e[k].type);k--)if(e[k].content){u=e[k].content.charCodeAt(e[k].content.length-1);break}if(p=32,i\u003Ca)p=s.charCodeAt(i);else for(k=t+1;k\u003Ce.length&&(\\\"softbreak\\\"!==e[k].type&&\\\"hardbreak\\\"!==e[k].type);k++)if(e[k].content){p=e[k].content.charCodeAt(0);break}if(h=X(u)||Q(String.fromCharCode(u)),f=X(p)||Q(String.fromCharCode(p)),d=K(u),(m=K(p))?g=!1:f&&(d||h||(g=!1)),d?_=!1:h&&(m||f||(_=!1)),34===p&&'\\\"'===o[0]&&u>=48&&u\u003C=57&&(_=g=!1),g&&_&&(g=h,_=f),g||_){if(_)for(k=v.length-1;k>=0&&(l=v[k],!(v[k].level\u003Cc));k--)if(l.single===b&&v[k].level===c){l=v[k],b?(C=r.md.options.quotes[2],y=r.md.options.quotes[3]):(C=r.md.options.quotes[0],y=r.md.options.quotes[1]),n.content=te(n.content,o.index,y),e[l.token].content=te(e[l.token].content,l.pos,C),i+=y.length-1,l.token===t&&(i+=C.length-1),a=(s=n.content).length,v.length=k;continue e}g?v.push({token:t,pos:o.index,single:b,level:c}):_&&b&&(n.content=te(n.content,o.index,\\\"\\\\u2019\\\"))}else b&&(n.content=te(n.content,o.index,\\\"\\\\u2019\\\"))}}}}function se(e,r,t){this.type=e,this.tag=r,this.attrs=null,this.map=null,this.nesting=t,this.level=0,this.children=null,this.content=\\\"\\\",this.markup=\\\"\\\",this.info=\\\"\\\",this.meta=null,this.block=!1,this.hidden=!1}se.prototype.attrIndex=function(e){var r,t,n;if(!this.attrs)return-1;for(t=0,n=(r=this.attrs).length;t\u003Cn;t++)if(r[t][0]===e)return t;return-1},se.prototype.attrPush=function(e){this.attrs?this.attrs.push(e):this.attrs=[e]},se.prototype.attrSet=function(e,r){var t=this.attrIndex(e),n=[e,r];t\u003C0?this.attrPush(n):this.attrs[t]=n},se.prototype.attrGet=function(e){var r=this.attrIndex(e),t=null;return r>=0&&(t=this.attrs[r][1]),t},se.prototype.attrJoin=function(e,r){var t=this.attrIndex(e);t\u003C0?this.attrPush([e,r]):this.attrs[t][1]=this.attrs[t][1]+\\\" \\\"+r};var oe=se;function ie(e,r,t){this.src=e,this.env=t,this.tokens=[],this.inlineMode=!1,this.md=r}ie.prototype.Token=oe;var ae=ie,ce=[[\\\"normalize\\\",function(e){var r;r=(r=e.src.replace(P,\\\"\\\\n\\\")).replace(j,\\\"\\\\ufffd\\\"),e.src=r}],[\\\"block\\\",function(e){var r;e.inlineMode?((r=new e.Token(\\\"inline\\\",\\\"\\\",0)).content=e.src,r.map=[0,1],r.children=[],e.tokens.push(r)):e.md.block.parse(e.src,e.md,e.env,e.tokens)}],[\\\"inline\\\",function(e){var r,t,n,s=e.tokens;for(t=0,n=s.length;t\u003Cn;t++)\\\"inline\\\"===(r=s[t]).type&&e.md.inline.parse(r.content,e.md,e.env,r.children)}],[\\\"linkify\\\",function(e){var r,t,n,s,o,i,a,c,l,u,p,h,f,d,m,g,_,k,b=e.tokens;if(e.md.options.linkify)for(t=0,n=b.length;t\u003Cn;t++)if(\\\"inline\\\"===b[t].type&&e.md.linkify.pretest(b[t].content))for(f=0,r=(s=b[t].children).length-1;r>=0;r--)if(\\\"link_close\\\"!==(i=s[r]).type){if(\\\"html_inline\\\"===i.type&&(k=i.content,/^\u003Ca[>\\\\s]/i.test(k)&&f>0&&f--,V(i.content)&&f++),!(f>0)&&\\\"text\\\"===i.type&&e.md.linkify.test(i.content)){for(l=i.content,_=e.md.linkify.match(l),a=[],h=i.level,p=0,_.length>0&&0===_[0].index&&r>0&&\\\"text_special\\\"===s[r-1].type&&(_=_.slice(1)),c=0;c\u003C_.length;c++)d=_[c].url,m=e.md.normalizeLink(d),e.md.validateLink(m)&&(g=_[c].text,g=_[c].schema?\\\"mailto:\\\"!==_[c].schema||/^mailto:/i.test(g)?e.md.normalizeLinkText(g):e.md.normalizeLinkText(\\\"mailto:\\\"+g).replace(/^mailto:/,\\\"\\\"):e.md.normalizeLinkText(\\\"http://\\\"+g).replace(/^http:\\\\/\\\\//,\\\"\\\"),(u=_[c].index)>p&&((o=new e.Token(\\\"text\\\",\\\"\\\",0)).content=l.slice(p,u),o.level=h,a.push(o)),(o=new e.Token(\\\"link_open\\\",\\\"a\\\",1)).attrs=[[\\\"href\\\",m]],o.level=h++,o.markup=\\\"linkify\\\",o.info=\\\"auto\\\",a.push(o),(o=new e.Token(\\\"text\\\",\\\"\\\",0)).content=g,o.level=h,a.push(o),(o=new e.Token(\\\"link_close\\\",\\\"a\\\",-1)).level=--h,o.markup=\\\"linkify\\\",o.info=\\\"auto\\\",a.push(o),p=_[c].lastIndex);p\u003Cl.length&&((o=new e.Token(\\\"text\\\",\\\"\\\",0)).content=l.slice(p),o.level=h,a.push(o)),b[t].children=s=U(s,r,a)}}else for(r--;s[r].level!==i.level&&\\\"link_open\\\"!==s[r].type;)r--}],[\\\"replacements\\\",function(e){var r;if(e.md.options.typographer)for(r=e.tokens.length-1;r>=0;r--)\\\"inline\\\"===e.tokens[r].type&&($.test(e.tokens[r].content)&&W(e.tokens[r].children),Z.test(e.tokens[r].content)&&Y(e.tokens[r].children))}],[\\\"smartquotes\\\",function(e){var r;if(e.md.options.typographer)for(r=e.tokens.length-1;r>=0;r--)\\\"inline\\\"===e.tokens[r].type&&ee.test(e.tokens[r].content)&&ne(e.tokens[r].children,e)}],[\\\"text_join\\\",function(e){var r,t,n,s,o,i,a=e.tokens;for(r=0,t=a.length;r\u003Ct;r++)if(\\\"inline\\\"===a[r].type){for(o=(n=a[r].children).length,s=0;s\u003Co;s++)\\\"text_special\\\"===n[s].type&&(n[s].type=\\\"text\\\");for(s=i=0;s\u003Co;s++)\\\"text\\\"===n[s].type&&s+1\u003Co&&\\\"text\\\"===n[s+1].type?n[s+1].content=n[s].content+n[s+1].content:(s!==i&&(n[i]=n[s]),i++);s!==i&&(n.length=i)}}]];function le(){this.ruler=new O;for(var e=0;e\u003Cce.length;e++)this.ruler.push(ce[e][0],ce[e][1])}le.prototype.process=function(e){var r,t,n;for(r=0,t=(n=this.ruler.getRules(\\\"\\\")).length;r\u003Ct;r++)n[r](e)},le.prototype.State=ae;var ue=le,pe=w.isSpace;function he(e,r){var t=e.bMarks[r]+e.tShift[r],n=e.eMarks[r];return e.src.slice(t,n)}function fe(e){var r,t=[],n=0,s=e.length,o=!1,i=0,a=\\\"\\\";for(r=e.charCodeAt(n);n\u003Cs;)124===r&&(o?(a+=e.substring(i,n-1),i=n):(t.push(a+e.substring(i,n)),a=\\\"\\\",i=n+1)),o=92===r,n++,r=e.charCodeAt(n);return t.push(a+e.substring(i)),t}var de=w.isSpace,me=w.isSpace,ge=w.isSpace;function _e(e,r){var t,n,s,o;return n=e.bMarks[r]+e.tShift[r],s=e.eMarks[r],42!==(t=e.src.charCodeAt(n++))&&45!==t&&43!==t||n\u003Cs&&(o=e.src.charCodeAt(n),!ge(o))?-1:n}function ke(e,r){var t,n=e.bMarks[r]+e.tShift[r],s=n,o=e.eMarks[r];if(s+1>=o)return-1;if((t=e.src.charCodeAt(s++))\u003C48||t>57)return-1;for(;;){if(s>=o)return-1;if(!((t=e.src.charCodeAt(s++))>=48&&t\u003C=57)){if(41===t||46===t)break;return-1}if(s-n>=10)return-1}return s\u003Co&&(t=e.src.charCodeAt(s),!ge(t))?-1:s}var be=w.normalizeReference,ve=w.isSpace,Ce=\\\"\u003C[A-Za-z][A-Za-z0-9\\\\\\\\-]*(?:\\\\\\\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\\\\\\\s*=\\\\\\\\s*(?:[^\\\\\\\"'=\u003C>`\\\\\\\\x00-\\\\\\\\x20]+|'[^']*'|\\\\\\\"[^\\\\\\\"]*\\\\\\\"))?)*\\\\\\\\s*\\\\\\\\/?>\\\",ye=\\\"\u003C\\\\\\\\/[A-Za-z][A-Za-z0-9\\\\\\\\-]*\\\\\\\\s*>\\\",Ae={HTML_TAG_RE:new RegExp(\\\"^(?:\\\"+Ce+\\\"|\\\"+ye+\\\"|\\\\x3c!----\\\\x3e|\\\\x3c!--(?:-?[^>-])(?:-?[^-])*--\\\\x3e|\u003C[?][\\\\\\\\s\\\\\\\\S]*?[?]>|\u003C![A-Z]+\\\\\\\\s+[^>]*>|\u003C!\\\\\\\\[CDATA\\\\\\\\[[\\\\\\\\s\\\\\\\\S]*?\\\\\\\\]\\\\\\\\]>)\\\"),HTML_OPEN_CLOSE_TAG_RE:new RegExp(\\\"^(?:\\\"+Ce+\\\"|\\\"+ye+\\\")\\\")},xe=Ae.HTML_OPEN_CLOSE_TAG_RE,De=[[/^\u003C(script|pre|style|textarea)(?=(\\\\s|>|$))/i,/\u003C\\\\/(script|pre|style|textarea)>/i,!0],[/^\u003C!--/,/-->/,!0],[/^\u003C\\\\?/,/\\\\?>/,!0],[/^\u003C![A-Z]/,/>/,!0],[/^\u003C!\\\\[CDATA\\\\[/,/\\\\]\\\\]>/,!0],[new RegExp(\\\"^\u003C/?(\\\"+[\\\"address\\\",\\\"article\\\",\\\"aside\\\",\\\"base\\\",\\\"basefont\\\",\\\"blockquote\\\",\\\"body\\\",\\\"caption\\\",\\\"center\\\",\\\"col\\\",\\\"colgroup\\\",\\\"dd\\\",\\\"details\\\",\\\"dialog\\\",\\\"dir\\\",\\\"div\\\",\\\"dl\\\",\\\"dt\\\",\\\"fieldset\\\",\\\"figcaption\\\",\\\"figure\\\",\\\"footer\\\",\\\"form\\\",\\\"frame\\\",\\\"frameset\\\",\\\"h1\\\",\\\"h2\\\",\\\"h3\\\",\\\"h4\\\",\\\"h5\\\",\\\"h6\\\",\\\"head\\\",\\\"header\\\",\\\"hr\\\",\\\"html\\\",\\\"iframe\\\",\\\"legend\\\",\\\"li\\\",\\\"link\\\",\\\"main\\\",\\\"menu\\\",\\\"menuitem\\\",\\\"nav\\\",\\\"noframes\\\",\\\"ol\\\",\\\"optgroup\\\",\\\"option\\\",\\\"p\\\",\\\"param\\\",\\\"section\\\",\\\"source\\\",\\\"summary\\\",\\\"table\\\",\\\"tbody\\\",\\\"td\\\",\\\"tfoot\\\",\\\"th\\\",\\\"thead\\\",\\\"title\\\",\\\"tr\\\",\\\"track\\\",\\\"ul\\\"].join(\\\"|\\\")+\\\")(?=(\\\\\\\\s|/?>|$))\\\",\\\"i\\\"),/^$/,!0],[new RegExp(xe.source+\\\"\\\\\\\\s*$\\\"),/^$/,!1]],we=w.isSpace,Ee=w.isSpace;function qe(e,r,t,n){var s,o,i,a,c,l,u,p;for(this.src=e,this.md=r,this.env=t,this.tokens=n,this.bMarks=[],this.eMarks=[],this.tShift=[],this.sCount=[],this.bsCount=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.ddIndent=-1,this.listIndent=-1,this.parentType=\\\"root\\\",this.level=0,this.result=\\\"\\\",p=!1,i=a=l=u=0,c=(o=this.src).length;a\u003Cc;a++){if(s=o.charCodeAt(a),!p){if(Ee(s)){l++,9===s?u+=4-u%4:u++;continue}p=!0}10!==s&&a!==c-1||(10!==s&&a++,this.bMarks.push(i),this.eMarks.push(a),this.tShift.push(l),this.sCount.push(u),this.bsCount.push(0),p=!1,l=0,u=0,i=a+1)}this.bMarks.push(o.length),this.eMarks.push(o.length),this.tShift.push(0),this.sCount.push(0),this.bsCount.push(0),this.lineMax=this.bMarks.length-1}qe.prototype.push=function(e,r,t){var n=new oe(e,r,t);return n.block=!0,t\u003C0&&this.level--,n.level=this.level,t>0&&this.level++,this.tokens.push(n),n},qe.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},qe.prototype.skipEmptyLines=function(e){for(var r=this.lineMax;e\u003Cr&&!(this.bMarks[e]+this.tShift[e]\u003Cthis.eMarks[e]);e++);return e},qe.prototype.skipSpaces=function(e){for(var r,t=this.src.length;e\u003Ct&&(r=this.src.charCodeAt(e),Ee(r));e++);return e},qe.prototype.skipSpacesBack=function(e,r){if(e\u003C=r)return e;for(;e>r;)if(!Ee(this.src.charCodeAt(--e)))return e+1;return e},qe.prototype.skipChars=function(e,r){for(var t=this.src.length;e\u003Ct&&this.src.charCodeAt(e)===r;e++);return e},qe.prototype.skipCharsBack=function(e,r,t){if(e\u003C=t)return e;for(;e>t;)if(r!==this.src.charCodeAt(--e))return e+1;return e},qe.prototype.getLines=function(e,r,t,n){var s,o,i,a,c,l,u,p=e;if(e>=r)return\\\"\\\";for(l=new Array(r-e),s=0;p\u003Cr;p++,s++){for(o=0,u=a=this.bMarks[p],c=p+1\u003Cr||n?this.eMarks[p]+1:this.eMarks[p];a\u003Cc&&o\u003Ct;){if(i=this.src.charCodeAt(a),Ee(i))9===i?o+=4-(o+this.bsCount[p])%4:o++;else{if(!(a-u\u003Cthis.tShift[p]))break;o++}a++}l[s]=o>t?new Array(o-t+1).join(\\\" \\\")+this.src.slice(a,c):this.src.slice(a,c)}return l.join(\\\"\\\")},qe.prototype.Token=oe;var Se=qe,Fe=[[\\\"table\\\",function(e,r,t,n){var s,o,i,a,c,l,u,p,h,f,d,m,g,_,k,b,v,C;if(r+2>t)return!1;if(l=r+1,e.sCount[l]\u003Ce.blkIndent)return!1;if(e.sCount[l]-e.blkIndent>=4)return!1;if((i=e.bMarks[l]+e.tShift[l])>=e.eMarks[l])return!1;if(124!==(v=e.src.charCodeAt(i++))&&45!==v&&58!==v)return!1;if(i>=e.eMarks[l])return!1;if(124!==(C=e.src.charCodeAt(i++))&&45!==C&&58!==C&&!pe(C))return!1;if(45===v&&pe(C))return!1;for(;i\u003Ce.eMarks[l];){if(124!==(s=e.src.charCodeAt(i))&&45!==s&&58!==s&&!pe(s))return!1;i++}for(u=(o=he(e,r+1)).split(\\\"|\\\"),f=[],a=0;a\u003Cu.length;a++){if(!(d=u[a].trim())){if(0===a||a===u.length-1)continue;return!1}if(!/^:?-+:?$/.test(d))return!1;58===d.charCodeAt(d.length-1)?f.push(58===d.charCodeAt(0)?\\\"center\\\":\\\"right\\\"):58===d.charCodeAt(0)?f.push(\\\"left\\\"):f.push(\\\"\\\")}if(-1===(o=he(e,r).trim()).indexOf(\\\"|\\\"))return!1;if(e.sCount[r]-e.blkIndent>=4)return!1;if((u=fe(o)).length&&\\\"\\\"===u[0]&&u.shift(),u.length&&\\\"\\\"===u[u.length-1]&&u.pop(),0===(p=u.length)||p!==f.length)return!1;if(n)return!0;for(_=e.parentType,e.parentType=\\\"table\\\",b=e.md.block.ruler.getRules(\\\"blockquote\\\"),(h=e.push(\\\"table_open\\\",\\\"table\\\",1)).map=m=[r,0],(h=e.push(\\\"thead_open\\\",\\\"thead\\\",1)).map=[r,r+1],(h=e.push(\\\"tr_open\\\",\\\"tr\\\",1)).map=[r,r+1],a=0;a\u003Cu.length;a++)h=e.push(\\\"th_open\\\",\\\"th\\\",1),f[a]&&(h.attrs=[[\\\"style\\\",\\\"text-align:\\\"+f[a]]]),(h=e.push(\\\"inline\\\",\\\"\\\",0)).content=u[a].trim(),h.children=[],h=e.push(\\\"th_close\\\",\\\"th\\\",-1);for(h=e.push(\\\"tr_close\\\",\\\"tr\\\",-1),h=e.push(\\\"thead_close\\\",\\\"thead\\\",-1),l=r+2;l\u003Ct&&!(e.sCount[l]\u003Ce.blkIndent);l++){for(k=!1,a=0,c=b.length;a\u003Cc;a++)if(b[a](e,l,t,!0)){k=!0;break}if(k)break;if(!(o=he(e,l).trim()))break;if(e.sCount[l]-e.blkIndent>=4)break;for((u=fe(o)).length&&\\\"\\\"===u[0]&&u.shift(),u.length&&\\\"\\\"===u[u.length-1]&&u.pop(),l===r+2&&((h=e.push(\\\"tbody_open\\\",\\\"tbody\\\",1)).map=g=[r+2,0]),(h=e.push(\\\"tr_open\\\",\\\"tr\\\",1)).map=[l,l+1],a=0;a\u003Cp;a++)h=e.push(\\\"td_open\\\",\\\"td\\\",1),f[a]&&(h.attrs=[[\\\"style\\\",\\\"text-align:\\\"+f[a]]]),(h=e.push(\\\"inline\\\",\\\"\\\",0)).content=u[a]?u[a].trim():\\\"\\\",h.children=[],h=e.push(\\\"td_close\\\",\\\"td\\\",-1);h=e.push(\\\"tr_close\\\",\\\"tr\\\",-1)}return g&&(h=e.push(\\\"tbody_close\\\",\\\"tbody\\\",-1),g[1]=l),h=e.push(\\\"table_close\\\",\\\"table\\\",-1),m[1]=l,e.parentType=_,e.line=l,!0},[\\\"paragraph\\\",\\\"reference\\\"]],[\\\"code\\\",function(e,r,t){var n,s,o;if(e.sCount[r]-e.blkIndent\u003C4)return!1;for(s=n=r+1;n\u003Ct;)if(e.isEmpty(n))n++;else{if(!(e.sCount[n]-e.blkIndent>=4))break;s=++n}return e.line=s,(o=e.push(\\\"code_block\\\",\\\"code\\\",0)).content=e.getLines(r,s,4+e.blkIndent,!1)+\\\"\\\\n\\\",o.map=[r,e.line],!0}],[\\\"fence\\\",function(e,r,t,n){var s,o,i,a,c,l,u,p=!1,h=e.bMarks[r]+e.tShift[r],f=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(h+3>f)return!1;if(126!==(s=e.src.charCodeAt(h))&&96!==s)return!1;if(c=h,(o=(h=e.skipChars(h,s))-c)\u003C3)return!1;if(u=e.src.slice(c,h),i=e.src.slice(h,f),96===s&&i.indexOf(String.fromCharCode(s))>=0)return!1;if(n)return!0;for(a=r;!(++a>=t)&&!((h=c=e.bMarks[a]+e.tShift[a])\u003C(f=e.eMarks[a])&&e.sCount[a]\u003Ce.blkIndent);)if(e.src.charCodeAt(h)===s&&!(e.sCount[a]-e.blkIndent>=4||(h=e.skipChars(h,s))-c\u003Co||(h=e.skipSpaces(h))\u003Cf)){p=!0;break}return o=e.sCount[r],e.line=a+(p?1:0),(l=e.push(\\\"fence\\\",\\\"code\\\",0)).info=i,l.content=e.getLines(r+1,a,o,!0),l.markup=u,l.map=[r,e.line],!0},[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\",\\\"list\\\"]],[\\\"blockquote\\\",function(e,r,t,n){var s,o,i,a,c,l,u,p,h,f,d,m,g,_,k,b,v,C,y,A,x=e.lineMax,D=e.bMarks[r]+e.tShift[r],w=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(62!==e.src.charCodeAt(D++))return!1;if(n)return!0;for(a=h=e.sCount[r]+1,32===e.src.charCodeAt(D)?(D++,a++,h++,s=!1,b=!0):9===e.src.charCodeAt(D)?(b=!0,(e.bsCount[r]+h)%4==3?(D++,a++,h++,s=!1):s=!0):b=!1,f=[e.bMarks[r]],e.bMarks[r]=D;D\u003Cw&&(o=e.src.charCodeAt(D),de(o));)9===o?h+=4-(h+e.bsCount[r]+(s?1:0))%4:h++,D++;for(d=[e.bsCount[r]],e.bsCount[r]=e.sCount[r]+1+(b?1:0),l=D>=w,_=[e.sCount[r]],e.sCount[r]=h-a,k=[e.tShift[r]],e.tShift[r]=D-e.bMarks[r],C=e.md.block.ruler.getRules(\\\"blockquote\\\"),g=e.parentType,e.parentType=\\\"blockquote\\\",p=r+1;p\u003Ct&&(A=e.sCount[p]\u003Ce.blkIndent,!((D=e.bMarks[p]+e.tShift[p])>=(w=e.eMarks[p])));p++)if(62!==e.src.charCodeAt(D++)||A){if(l)break;for(v=!1,i=0,c=C.length;i\u003Cc;i++)if(C[i](e,p,t,!0)){v=!0;break}if(v){e.lineMax=p,0!==e.blkIndent&&(f.push(e.bMarks[p]),d.push(e.bsCount[p]),k.push(e.tShift[p]),_.push(e.sCount[p]),e.sCount[p]-=e.blkIndent);break}f.push(e.bMarks[p]),d.push(e.bsCount[p]),k.push(e.tShift[p]),_.push(e.sCount[p]),e.sCount[p]=-1}else{for(a=h=e.sCount[p]+1,32===e.src.charCodeAt(D)?(D++,a++,h++,s=!1,b=!0):9===e.src.charCodeAt(D)?(b=!0,(e.bsCount[p]+h)%4==3?(D++,a++,h++,s=!1):s=!0):b=!1,f.push(e.bMarks[p]),e.bMarks[p]=D;D\u003Cw&&(o=e.src.charCodeAt(D),de(o));)9===o?h+=4-(h+e.bsCount[p]+(s?1:0))%4:h++,D++;l=D>=w,d.push(e.bsCount[p]),e.bsCount[p]=e.sCount[p]+1+(b?1:0),_.push(e.sCount[p]),e.sCount[p]=h-a,k.push(e.tShift[p]),e.tShift[p]=D-e.bMarks[p]}for(m=e.blkIndent,e.blkIndent=0,(y=e.push(\\\"blockquote_open\\\",\\\"blockquote\\\",1)).markup=\\\">\\\",y.map=u=[r,0],e.md.block.tokenize(e,r,p),(y=e.push(\\\"blockquote_close\\\",\\\"blockquote\\\",-1)).markup=\\\">\\\",e.lineMax=x,e.parentType=g,u[1]=e.line,i=0;i\u003Ck.length;i++)e.bMarks[i+r]=f[i],e.tShift[i+r]=k[i],e.sCount[i+r]=_[i],e.bsCount[i+r]=d[i];return e.blkIndent=m,!0},[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\",\\\"list\\\"]],[\\\"hr\\\",function(e,r,t,n){var s,o,i,a,c=e.bMarks[r]+e.tShift[r],l=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(42!==(s=e.src.charCodeAt(c++))&&45!==s&&95!==s)return!1;for(o=1;c\u003Cl;){if((i=e.src.charCodeAt(c++))!==s&&!me(i))return!1;i===s&&o++}return!(o\u003C3)&&(n||(e.line=r+1,(a=e.push(\\\"hr\\\",\\\"hr\\\",0)).map=[r,e.line],a.markup=Array(o+1).join(String.fromCharCode(s))),!0)},[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\",\\\"list\\\"]],[\\\"list\\\",function(e,r,t,n){var s,o,i,a,c,l,u,p,h,f,d,m,g,_,k,b,v,C,y,A,x,D,w,E,q,S,F,L,z=!1,T=!0;if(e.sCount[r]-e.blkIndent>=4)return!1;if(e.listIndent>=0&&e.sCount[r]-e.listIndent>=4&&e.sCount[r]\u003Ce.blkIndent)return!1;if(n&&\\\"paragraph\\\"===e.parentType&&e.sCount[r]>=e.blkIndent&&(z=!0),(w=ke(e,r))>=0){if(u=!0,q=e.bMarks[r]+e.tShift[r],g=Number(e.src.slice(q,w-1)),z&&1!==g)return!1}else{if(!((w=_e(e,r))>=0))return!1;u=!1}if(z&&e.skipSpaces(w)>=e.eMarks[r])return!1;if(m=e.src.charCodeAt(w-1),n)return!0;for(d=e.tokens.length,u?(L=e.push(\\\"ordered_list_open\\\",\\\"ol\\\",1),1!==g&&(L.attrs=[[\\\"start\\\",g]])):L=e.push(\\\"bullet_list_open\\\",\\\"ul\\\",1),L.map=f=[r,0],L.markup=String.fromCharCode(m),k=r,E=!1,F=e.md.block.ruler.getRules(\\\"list\\\"),C=e.parentType,e.parentType=\\\"list\\\";k\u003Ct;){for(D=w,_=e.eMarks[k],l=b=e.sCount[k]+w-(e.bMarks[r]+e.tShift[r]);D\u003C_;){if(9===(s=e.src.charCodeAt(D)))b+=4-(b+e.bsCount[k])%4;else{if(32!==s)break;b++}D++}if((c=(o=D)>=_?1:b-l)>4&&(c=1),a=l+c,(L=e.push(\\\"list_item_open\\\",\\\"li\\\",1)).markup=String.fromCharCode(m),L.map=p=[r,0],u&&(L.info=e.src.slice(q,w-1)),x=e.tight,A=e.tShift[r],y=e.sCount[r],v=e.listIndent,e.listIndent=e.blkIndent,e.blkIndent=a,e.tight=!0,e.tShift[r]=o-e.bMarks[r],e.sCount[r]=b,o>=_&&e.isEmpty(r+1)?e.line=Math.min(e.line+2,t):e.md.block.tokenize(e,r,t,!0),e.tight&&!E||(T=!1),E=e.line-r>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=v,e.tShift[r]=A,e.sCount[r]=y,e.tight=x,(L=e.push(\\\"list_item_close\\\",\\\"li\\\",-1)).markup=String.fromCharCode(m),k=r=e.line,p[1]=k,o=e.bMarks[r],k>=t)break;if(e.sCount[k]\u003Ce.blkIndent)break;if(e.sCount[r]-e.blkIndent>=4)break;for(S=!1,i=0,h=F.length;i\u003Ch;i++)if(F[i](e,k,t,!0)){S=!0;break}if(S)break;if(u){if((w=ke(e,k))\u003C0)break;q=e.bMarks[k]+e.tShift[k]}else if((w=_e(e,k))\u003C0)break;if(m!==e.src.charCodeAt(w-1))break}return(L=u?e.push(\\\"ordered_list_close\\\",\\\"ol\\\",-1):e.push(\\\"bullet_list_close\\\",\\\"ul\\\",-1)).markup=String.fromCharCode(m),f[1]=k,e.line=k,e.parentType=C,T&&function(e,r){var t,n,s=e.level+2;for(t=r+2,n=e.tokens.length-2;t\u003Cn;t++)e.tokens[t].level===s&&\\\"paragraph_open\\\"===e.tokens[t].type&&(e.tokens[t+2].hidden=!0,e.tokens[t].hidden=!0,t+=2)}(e,d),!0},[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\"]],[\\\"reference\\\",function(e,r,t,n){var s,o,i,a,c,l,u,p,h,f,d,m,g,_,k,b,v=0,C=e.bMarks[r]+e.tShift[r],y=e.eMarks[r],A=r+1;if(e.sCount[r]-e.blkIndent>=4)return!1;if(91!==e.src.charCodeAt(C))return!1;for(;++C\u003Cy;)if(93===e.src.charCodeAt(C)&&92!==e.src.charCodeAt(C-1)){if(C+1===y)return!1;if(58!==e.src.charCodeAt(C+1))return!1;break}for(a=e.lineMax,k=e.md.block.ruler.getRules(\\\"reference\\\"),f=e.parentType,e.parentType=\\\"reference\\\";A\u003Ca&&!e.isEmpty(A);A++)if(!(e.sCount[A]-e.blkIndent>3||e.sCount[A]\u003C0)){for(_=!1,l=0,u=k.length;l\u003Cu;l++)if(k[l](e,A,a,!0)){_=!0;break}if(_)break}for(y=(g=e.getLines(r,A,e.blkIndent,!1).trim()).length,C=1;C\u003Cy;C++){if(91===(s=g.charCodeAt(C)))return!1;if(93===s){h=C;break}(10===s||92===s&&++C\u003Cy&&10===g.charCodeAt(C))&&v++}if(h\u003C0||58!==g.charCodeAt(h+1))return!1;for(C=h+2;C\u003Cy;C++)if(10===(s=g.charCodeAt(C)))v++;else if(!ve(s))break;if(!(d=e.md.helpers.parseLinkDestination(g,C,y)).ok)return!1;if(c=e.md.normalizeLink(d.str),!e.md.validateLink(c))return!1;for(o=C=d.pos,i=v+=d.lines,m=C;C\u003Cy;C++)if(10===(s=g.charCodeAt(C)))v++;else if(!ve(s))break;for(d=e.md.helpers.parseLinkTitle(g,C,y),C\u003Cy&&m!==C&&d.ok?(b=d.str,C=d.pos,v+=d.lines):(b=\\\"\\\",C=o,v=i);C\u003Cy&&(s=g.charCodeAt(C),ve(s));)C++;if(C\u003Cy&&10!==g.charCodeAt(C)&&b)for(b=\\\"\\\",C=o,v=i;C\u003Cy&&(s=g.charCodeAt(C),ve(s));)C++;return!(C\u003Cy&&10!==g.charCodeAt(C))&&(!!(p=be(g.slice(1,h)))&&(n||(void 0===e.env.references&&(e.env.references={}),void 0===e.env.references[p]&&(e.env.references[p]={title:b,href:c}),e.parentType=f,e.line=r+v+1),!0))}],[\\\"html_block\\\",function(e,r,t,n){var s,o,i,a,c=e.bMarks[r]+e.tShift[r],l=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(!e.md.options.html)return!1;if(60!==e.src.charCodeAt(c))return!1;for(a=e.src.slice(c,l),s=0;s\u003CDe.length&&!De[s][0].test(a);s++);if(s===De.length)return!1;if(n)return De[s][2];if(o=r+1,!De[s][1].test(a))for(;o\u003Ct&&!(e.sCount[o]\u003Ce.blkIndent);o++)if(c=e.bMarks[o]+e.tShift[o],l=e.eMarks[o],a=e.src.slice(c,l),De[s][1].test(a)){0!==a.length&&o++;break}return e.line=o,(i=e.push(\\\"html_block\\\",\\\"\\\",0)).map=[r,o],i.content=e.getLines(r,o,e.blkIndent,!0),!0},[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\"]],[\\\"heading\\\",function(e,r,t,n){var s,o,i,a,c=e.bMarks[r]+e.tShift[r],l=e.eMarks[r];if(e.sCount[r]-e.blkIndent>=4)return!1;if(35!==(s=e.src.charCodeAt(c))||c>=l)return!1;for(o=1,s=e.src.charCodeAt(++c);35===s&&c\u003Cl&&o\u003C=6;)o++,s=e.src.charCodeAt(++c);return!(o>6||c\u003Cl&&!we(s))&&(n||(l=e.skipSpacesBack(l,c),(i=e.skipCharsBack(l,35,c))>c&&we(e.src.charCodeAt(i-1))&&(l=i),e.line=r+1,(a=e.push(\\\"heading_open\\\",\\\"h\\\"+String(o),1)).markup=\\\"########\\\".slice(0,o),a.map=[r,e.line],(a=e.push(\\\"inline\\\",\\\"\\\",0)).content=e.src.slice(c,l).trim(),a.map=[r,e.line],a.children=[],(a=e.push(\\\"heading_close\\\",\\\"h\\\"+String(o),-1)).markup=\\\"########\\\".slice(0,o)),!0)},[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\"]],[\\\"lheading\\\",function(e,r,t){var n,s,o,i,a,c,l,u,p,h,f=r+1,d=e.md.block.ruler.getRules(\\\"paragraph\\\");if(e.sCount[r]-e.blkIndent>=4)return!1;for(h=e.parentType,e.parentType=\\\"paragraph\\\";f\u003Ct&&!e.isEmpty(f);f++)if(!(e.sCount[f]-e.blkIndent>3)){if(e.sCount[f]>=e.blkIndent&&(c=e.bMarks[f]+e.tShift[f])\u003C(l=e.eMarks[f])&&(45===(p=e.src.charCodeAt(c))||61===p)&&(c=e.skipChars(c,p),(c=e.skipSpaces(c))>=l)){u=61===p?1:2;break}if(!(e.sCount[f]\u003C0)){for(s=!1,o=0,i=d.length;o\u003Ci;o++)if(d[o](e,f,t,!0)){s=!0;break}if(s)break}}return!!u&&(n=e.getLines(r,f,e.blkIndent,!1).trim(),e.line=f+1,(a=e.push(\\\"heading_open\\\",\\\"h\\\"+String(u),1)).markup=String.fromCharCode(p),a.map=[r,e.line],(a=e.push(\\\"inline\\\",\\\"\\\",0)).content=n,a.map=[r,e.line-1],a.children=[],(a=e.push(\\\"heading_close\\\",\\\"h\\\"+String(u),-1)).markup=String.fromCharCode(p),e.parentType=h,!0)}],[\\\"paragraph\\\",function(e,r){var t,n,s,o,i,a,c=r+1,l=e.md.block.ruler.getRules(\\\"paragraph\\\"),u=e.lineMax;for(a=e.parentType,e.parentType=\\\"paragraph\\\";c\u003Cu&&!e.isEmpty(c);c++)if(!(e.sCount[c]-e.blkIndent>3||e.sCount[c]\u003C0)){for(n=!1,s=0,o=l.length;s\u003Co;s++)if(l[s](e,c,u,!0)){n=!0;break}if(n)break}return t=e.getLines(r,c,e.blkIndent,!1).trim(),e.line=c,(i=e.push(\\\"paragraph_open\\\",\\\"p\\\",1)).map=[r,e.line],(i=e.push(\\\"inline\\\",\\\"\\\",0)).content=t,i.map=[r,e.line],i.children=[],i=e.push(\\\"paragraph_close\\\",\\\"p\\\",-1),e.parentType=a,!0}]];function Le(){this.ruler=new O;for(var e=0;e\u003CFe.length;e++)this.ruler.push(Fe[e][0],Fe[e][1],{alt:(Fe[e][2]||[]).slice()})}Le.prototype.tokenize=function(e,r,t){for(var n,s=this.ruler.getRules(\\\"\\\"),o=s.length,i=r,a=!1,c=e.md.options.maxNesting;i\u003Ct&&(e.line=i=e.skipEmptyLines(i),!(i>=t))&&!(e.sCount[i]\u003Ce.blkIndent);){if(e.level>=c){e.line=t;break}for(n=0;n\u003Co&&!s[n](e,i,t,!1);n++);e.tight=!a,e.isEmpty(e.line-1)&&(a=!0),(i=e.line)\u003Ct&&e.isEmpty(i)&&(a=!0,i++,e.line=i)}},Le.prototype.parse=function(e,r,t,n){var s;e&&(s=new this.State(e,r,t,n),this.tokenize(s,s.line,s.lineMax))},Le.prototype.State=Se;var ze=Le;function Te(e){switch(e){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!0;default:return!1}}for(var Ie=/(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$/i,Me=w.isSpace,Re=w.isSpace,Be=[],Ne=0;Ne\u003C256;Ne++)Be.push(0);\\\"\\\\\\\\!\\\\\\\"#$%&'()*+,./:;\u003C=>?@[]^_`{|}~-\\\".split(\\\"\\\").forEach((function(e){Be[e.charCodeAt(0)]=1}));function Oe(e,r){var t,n,s,o,i,a=[],c=r.length;for(t=0;t\u003Cc;t++)126===(s=r[t]).marker&&-1!==s.end&&(o=r[s.end],(i=e.tokens[s.token]).type=\\\"s_open\\\",i.tag=\\\"s\\\",i.nesting=1,i.markup=\\\"~~\\\",i.content=\\\"\\\",(i=e.tokens[o.token]).type=\\\"s_close\\\",i.tag=\\\"s\\\",i.nesting=-1,i.markup=\\\"~~\\\",i.content=\\\"\\\",\\\"text\\\"===e.tokens[o.token-1].type&&\\\"~\\\"===e.tokens[o.token-1].content&&a.push(o.token-1));for(;a.length;){for(n=(t=a.pop())+1;n\u003Ce.tokens.length&&\\\"s_close\\\"===e.tokens[n].type;)n++;t!==--n&&(i=e.tokens[n],e.tokens[n]=e.tokens[t],e.tokens[t]=i)}}var Pe={tokenize:function(e,r){var t,n,s,o,i=e.pos,a=e.src.charCodeAt(i);if(r)return!1;if(126!==a)return!1;if(s=(n=e.scanDelims(e.pos,!0)).length,o=String.fromCharCode(a),s\u003C2)return!1;for(s%2&&(e.push(\\\"text\\\",\\\"\\\",0).content=o,s--),t=0;t\u003Cs;t+=2)e.push(\\\"text\\\",\\\"\\\",0).content=o+o,e.delimiters.push({marker:a,length:0,token:e.tokens.length-1,end:-1,open:n.can_open,close:n.can_close});return e.pos+=n.length,!0},postProcess:function(e){var r,t=e.tokens_meta,n=e.tokens_meta.length;for(Oe(e,e.delimiters),r=0;r\u003Cn;r++)t[r]&&t[r].delimiters&&Oe(e,t[r].delimiters)}};function je(e,r){var t,n,s,o,i,a;for(t=r.length-1;t>=0;t--)95!==(n=r[t]).marker&&42!==n.marker||-1!==n.end&&(s=r[n.end],a=t>0&&r[t-1].end===n.end+1&&r[t-1].marker===n.marker&&r[t-1].token===n.token-1&&r[n.end+1].token===s.token+1,i=String.fromCharCode(n.marker),(o=e.tokens[n.token]).type=a?\\\"strong_open\\\":\\\"em_open\\\",o.tag=a?\\\"strong\\\":\\\"em\\\",o.nesting=1,o.markup=a?i+i:i,o.content=\\\"\\\",(o=e.tokens[s.token]).type=a?\\\"strong_close\\\":\\\"em_close\\\",o.tag=a?\\\"strong\\\":\\\"em\\\",o.nesting=-1,o.markup=a?i+i:i,o.content=\\\"\\\",a&&(e.tokens[r[t-1].token].content=\\\"\\\",e.tokens[r[n.end+1].token].content=\\\"\\\",t--))}var Ue={tokenize:function(e,r){var t,n,s=e.pos,o=e.src.charCodeAt(s);if(r)return!1;if(95!==o&&42!==o)return!1;for(n=e.scanDelims(e.pos,42===o),t=0;t\u003Cn.length;t++)e.push(\\\"text\\\",\\\"\\\",0).content=String.fromCharCode(o),e.delimiters.push({marker:o,length:n.length,token:e.tokens.length-1,end:-1,open:n.can_open,close:n.can_close});return e.pos+=n.length,!0},postProcess:function(e){var r,t=e.tokens_meta,n=e.tokens_meta.length;for(je(e,e.delimiters),r=0;r\u003Cn;r++)t[r]&&t[r].delimiters&&je(e,t[r].delimiters)}},Ve=w.normalizeReference,Ze=w.isSpace,$e=w.normalizeReference,Ge=w.isSpace,He=/^([a-zA-Z0-9.!#$%&'*+\\\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,Je=/^([a-zA-Z][a-zA-Z0-9+.\\\\-]{1,31}):([^\u003C>\\\\x00-\\\\x20]*)$/,We=Ae.HTML_TAG_RE;var Ye=w.has,Ke=w.isValidEntityCode,Qe=w.fromCodePoint,Xe=/^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));/i,er=/^&([a-z][a-z0-9]{1,31});/i;function rr(e,r){var t,n,s,o,i,a,c,l,u={},p=r.length;if(p){var h=0,f=-2,d=[];for(t=0;t\u003Cp;t++)if(s=r[t],d.push(0),r[h].marker===s.marker&&f===s.token-1||(h=t),f=s.token,s.length=s.length||0,s.close){for(u.hasOwnProperty(s.marker)||(u[s.marker]=[-1,-1,-1,-1,-1,-1]),i=u[s.marker][(s.open?3:0)+s.length%3],a=n=h-d[h]-1;n>i;n-=d[n]+1)if((o=r[n]).marker===s.marker&&o.open&&o.end\u003C0&&(c=!1,(o.close||s.open)&&(o.length+s.length)%3==0&&(o.length%3==0&&s.length%3==0||(c=!0)),!c)){l=n>0&&!r[n-1].open?d[n-1]+1:0,d[t]=t-n+l,d[n]=l,s.open=!1,o.end=t,o.close=!1,a=-1,f=-2;break}-1!==a&&(u[s.marker][(s.open?3:0)+(s.length||0)%3]=a)}}}var tr=w.isWhiteSpace,nr=w.isPunctChar,sr=w.isMdAsciiPunct;function or(e,r,t,n){this.src=e,this.env=t,this.md=r,this.tokens=n,this.tokens_meta=Array(n.length),this.pos=0,this.posMax=this.src.length,this.level=0,this.pending=\\\"\\\",this.pendingLevel=0,this.cache={},this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0}or.prototype.pushPending=function(){var e=new oe(\\\"text\\\",\\\"\\\",0);return e.content=this.pending,e.level=this.pendingLevel,this.tokens.push(e),this.pending=\\\"\\\",e},or.prototype.push=function(e,r,t){this.pending&&this.pushPending();var n=new oe(e,r,t),s=null;return t\u003C0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),n.level=this.level,t>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],s={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(n),this.tokens_meta.push(s),n},or.prototype.scanDelims=function(e,r){var t,n,s,o,i,a,c,l,u,p=e,h=!0,f=!0,d=this.posMax,m=this.src.charCodeAt(e);for(t=e>0?this.src.charCodeAt(e-1):32;p\u003Cd&&this.src.charCodeAt(p)===m;)p++;return s=p-e,n=p\u003Cd?this.src.charCodeAt(p):32,c=sr(t)||nr(String.fromCharCode(t)),u=sr(n)||nr(String.fromCharCode(n)),a=tr(t),(l=tr(n))?h=!1:u&&(a||c||(h=!1)),a?f=!1:c&&(l||u||(f=!1)),r?(o=h,i=f):(o=h&&(!f||c),i=f&&(!h||u)),{can_open:o,can_close:i,length:s}},or.prototype.Token=oe;var ir=or,ar=[[\\\"text\\\",function(e,r){for(var t=e.pos;t\u003Ce.posMax&&!Te(e.src.charCodeAt(t));)t++;return t!==e.pos&&(r||(e.pending+=e.src.slice(e.pos,t)),e.pos=t,!0)}],[\\\"linkify\\\",function(e,r){var t,n,s,o,i,a,c;return!!e.md.options.linkify&&(!(e.linkLevel>0)&&(!((t=e.pos)+3>e.posMax)&&(58===e.src.charCodeAt(t)&&(47===e.src.charCodeAt(t+1)&&(47===e.src.charCodeAt(t+2)&&(!!(n=e.pending.match(Ie))&&(s=n[1],!!(o=e.md.linkify.matchAtStart(e.src.slice(t-s.length)))&&(i=(i=o.url).replace(/\\\\*+$/,\\\"\\\"),a=e.md.normalizeLink(i),!!e.md.validateLink(a)&&(r||(e.pending=e.pending.slice(0,-s.length),(c=e.push(\\\"link_open\\\",\\\"a\\\",1)).attrs=[[\\\"href\\\",a]],c.markup=\\\"linkify\\\",c.info=\\\"auto\\\",(c=e.push(\\\"text\\\",\\\"\\\",0)).content=e.md.normalizeLinkText(i),(c=e.push(\\\"link_close\\\",\\\"a\\\",-1)).markup=\\\"linkify\\\",c.info=\\\"auto\\\"),e.pos+=i.length-s.length,!0)))))))))}],[\\\"newline\\\",function(e,r){var t,n,s,o=e.pos;if(10!==e.src.charCodeAt(o))return!1;if(t=e.pending.length-1,n=e.posMax,!r)if(t>=0&&32===e.pending.charCodeAt(t))if(t>=1&&32===e.pending.charCodeAt(t-1)){for(s=t-1;s>=1&&32===e.pending.charCodeAt(s-1);)s--;e.pending=e.pending.slice(0,s),e.push(\\\"hardbreak\\\",\\\"br\\\",0)}else e.pending=e.pending.slice(0,-1),e.push(\\\"softbreak\\\",\\\"br\\\",0);else e.push(\\\"softbreak\\\",\\\"br\\\",0);for(o++;o\u003Cn&&Me(e.src.charCodeAt(o));)o++;return e.pos=o,!0}],[\\\"escape\\\",function(e,r){var t,n,s,o,i,a=e.pos,c=e.posMax;if(92!==e.src.charCodeAt(a))return!1;if(++a>=c)return!1;if(10===(t=e.src.charCodeAt(a))){for(r||e.push(\\\"hardbreak\\\",\\\"br\\\",0),a++;a\u003Cc&&(t=e.src.charCodeAt(a),Re(t));)a++;return e.pos=a,!0}return o=e.src[a],t>=55296&&t\u003C=56319&&a+1\u003Cc&&(n=e.src.charCodeAt(a+1))>=56320&&n\u003C=57343&&(o+=e.src[a+1],a++),s=\\\"\\\\\\\\\\\"+o,r||(i=e.push(\\\"text_special\\\",\\\"\\\",0),t\u003C256&&0!==Be[t]?i.content=o:i.content=s,i.markup=s,i.info=\\\"escape\\\"),e.pos=a+1,!0}],[\\\"backticks\\\",function(e,r){var t,n,s,o,i,a,c,l,u=e.pos;if(96!==e.src.charCodeAt(u))return!1;for(t=u,u++,n=e.posMax;u\u003Cn&&96===e.src.charCodeAt(u);)u++;if(c=(s=e.src.slice(t,u)).length,e.backticksScanned&&(e.backticks[c]||0)\u003C=t)return r||(e.pending+=s),e.pos+=c,!0;for(i=a=u;-1!==(i=e.src.indexOf(\\\"`\\\",a));){for(a=i+1;a\u003Cn&&96===e.src.charCodeAt(a);)a++;if((l=a-i)===c)return r||((o=e.push(\\\"code_inline\\\",\\\"code\\\",0)).markup=s,o.content=e.src.slice(u,i).replace(/\\\\n/g,\\\" \\\").replace(/^ (.+) $/,\\\"$1\\\")),e.pos=a,!0;e.backticks[l]=i}return e.backticksScanned=!0,r||(e.pending+=s),e.pos+=c,!0}],[\\\"strikethrough\\\",Pe.tokenize],[\\\"emphasis\\\",Ue.tokenize],[\\\"link\\\",function(e,r){var t,n,s,o,i,a,c,l,u=\\\"\\\",p=\\\"\\\",h=e.pos,f=e.posMax,d=e.pos,m=!0;if(91!==e.src.charCodeAt(e.pos))return!1;if(i=e.pos+1,(o=e.md.helpers.parseLinkLabel(e,e.pos,!0))\u003C0)return!1;if((a=o+1)\u003Cf&&40===e.src.charCodeAt(a)){for(m=!1,a++;a\u003Cf&&(n=e.src.charCodeAt(a),Ze(n)||10===n);a++);if(a>=f)return!1;if(d=a,(c=e.md.helpers.parseLinkDestination(e.src,a,e.posMax)).ok){for(u=e.md.normalizeLink(c.str),e.md.validateLink(u)?a=c.pos:u=\\\"\\\",d=a;a\u003Cf&&(n=e.src.charCodeAt(a),Ze(n)||10===n);a++);if(c=e.md.helpers.parseLinkTitle(e.src,a,e.posMax),a\u003Cf&&d!==a&&c.ok)for(p=c.str,a=c.pos;a\u003Cf&&(n=e.src.charCodeAt(a),Ze(n)||10===n);a++);}(a>=f||41!==e.src.charCodeAt(a))&&(m=!0),a++}if(m){if(void 0===e.env.references)return!1;if(a\u003Cf&&91===e.src.charCodeAt(a)?(d=a+1,(a=e.md.helpers.parseLinkLabel(e,a))>=0?s=e.src.slice(d,a++):a=o+1):a=o+1,s||(s=e.src.slice(i,o)),!(l=e.env.references[Ve(s)]))return e.pos=h,!1;u=l.href,p=l.title}return r||(e.pos=i,e.posMax=o,e.push(\\\"link_open\\\",\\\"a\\\",1).attrs=t=[[\\\"href\\\",u]],p&&t.push([\\\"title\\\",p]),e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push(\\\"link_close\\\",\\\"a\\\",-1)),e.pos=a,e.posMax=f,!0}],[\\\"image\\\",function(e,r){var t,n,s,o,i,a,c,l,u,p,h,f,d,m=\\\"\\\",g=e.pos,_=e.posMax;if(33!==e.src.charCodeAt(e.pos))return!1;if(91!==e.src.charCodeAt(e.pos+1))return!1;if(a=e.pos+2,(i=e.md.helpers.parseLinkLabel(e,e.pos+1,!1))\u003C0)return!1;if((c=i+1)\u003C_&&40===e.src.charCodeAt(c)){for(c++;c\u003C_&&(n=e.src.charCodeAt(c),Ge(n)||10===n);c++);if(c>=_)return!1;for(d=c,(u=e.md.helpers.parseLinkDestination(e.src,c,e.posMax)).ok&&(m=e.md.normalizeLink(u.str),e.md.validateLink(m)?c=u.pos:m=\\\"\\\"),d=c;c\u003C_&&(n=e.src.charCodeAt(c),Ge(n)||10===n);c++);if(u=e.md.helpers.parseLinkTitle(e.src,c,e.posMax),c\u003C_&&d!==c&&u.ok)for(p=u.str,c=u.pos;c\u003C_&&(n=e.src.charCodeAt(c),Ge(n)||10===n);c++);else p=\\\"\\\";if(c>=_||41!==e.src.charCodeAt(c))return e.pos=g,!1;c++}else{if(void 0===e.env.references)return!1;if(c\u003C_&&91===e.src.charCodeAt(c)?(d=c+1,(c=e.md.helpers.parseLinkLabel(e,c))>=0?o=e.src.slice(d,c++):c=i+1):c=i+1,o||(o=e.src.slice(a,i)),!(l=e.env.references[$e(o)]))return e.pos=g,!1;m=l.href,p=l.title}return r||(s=e.src.slice(a,i),e.md.inline.parse(s,e.md,e.env,f=[]),(h=e.push(\\\"image\\\",\\\"img\\\",0)).attrs=t=[[\\\"src\\\",m],[\\\"alt\\\",\\\"\\\"]],h.children=f,h.content=s,p&&t.push([\\\"title\\\",p])),e.pos=c,e.posMax=_,!0}],[\\\"autolink\\\",function(e,r){var t,n,s,o,i,a,c=e.pos;if(60!==e.src.charCodeAt(c))return!1;for(i=e.pos,a=e.posMax;;){if(++c>=a)return!1;if(60===(o=e.src.charCodeAt(c)))return!1;if(62===o)break}return t=e.src.slice(i+1,c),Je.test(t)?(n=e.md.normalizeLink(t),!!e.md.validateLink(n)&&(r||((s=e.push(\\\"link_open\\\",\\\"a\\\",1)).attrs=[[\\\"href\\\",n]],s.markup=\\\"autolink\\\",s.info=\\\"auto\\\",(s=e.push(\\\"text\\\",\\\"\\\",0)).content=e.md.normalizeLinkText(t),(s=e.push(\\\"link_close\\\",\\\"a\\\",-1)).markup=\\\"autolink\\\",s.info=\\\"auto\\\"),e.pos+=t.length+2,!0)):!!He.test(t)&&(n=e.md.normalizeLink(\\\"mailto:\\\"+t),!!e.md.validateLink(n)&&(r||((s=e.push(\\\"link_open\\\",\\\"a\\\",1)).attrs=[[\\\"href\\\",n]],s.markup=\\\"autolink\\\",s.info=\\\"auto\\\",(s=e.push(\\\"text\\\",\\\"\\\",0)).content=e.md.normalizeLinkText(t),(s=e.push(\\\"link_close\\\",\\\"a\\\",-1)).markup=\\\"autolink\\\",s.info=\\\"auto\\\"),e.pos+=t.length+2,!0))}],[\\\"html_inline\\\",function(e,r){var t,n,s,o,i,a=e.pos;return!!e.md.options.html&&(s=e.posMax,!(60!==e.src.charCodeAt(a)||a+2>=s)&&(!(33!==(t=e.src.charCodeAt(a+1))&&63!==t&&47!==t&&!function(e){var r=32|e;return r>=97&&r\u003C=122}(t))&&(!!(n=e.src.slice(a).match(We))&&(r||((o=e.push(\\\"html_inline\\\",\\\"\\\",0)).content=e.src.slice(a,a+n[0].length),i=o.content,/^\u003Ca[>\\\\s]/i.test(i)&&e.linkLevel++,function(e){return/^\u003C\\\\/a\\\\s*>/i.test(e)}(o.content)&&e.linkLevel--),e.pos+=n[0].length,!0))))}],[\\\"entity\\\",function(e,t){var n,s,o,i=e.pos,a=e.posMax;if(38!==e.src.charCodeAt(i))return!1;if(i+1>=a)return!1;if(35===e.src.charCodeAt(i+1)){if(s=e.src.slice(i).match(Xe))return t||(n=\\\"x\\\"===s[1][0].toLowerCase()?parseInt(s[1].slice(1),16):parseInt(s[1],10),(o=e.push(\\\"text_special\\\",\\\"\\\",0)).content=Ke(n)?Qe(n):Qe(65533),o.markup=s[0],o.info=\\\"entity\\\"),e.pos+=s[0].length,!0}else if((s=e.src.slice(i).match(er))&&Ye(r,s[1]))return t||((o=e.push(\\\"text_special\\\",\\\"\\\",0)).content=r[s[1]],o.markup=s[0],o.info=\\\"entity\\\"),e.pos+=s[0].length,!0;return!1}]],cr=[[\\\"balance_pairs\\\",function(e){var r,t=e.tokens_meta,n=e.tokens_meta.length;for(rr(0,e.delimiters),r=0;r\u003Cn;r++)t[r]&&t[r].delimiters&&rr(0,t[r].delimiters)}],[\\\"strikethrough\\\",Pe.postProcess],[\\\"emphasis\\\",Ue.postProcess],[\\\"fragments_join\\\",function(e){var r,t,n=0,s=e.tokens,o=e.tokens.length;for(r=t=0;r\u003Co;r++)s[r].nesting\u003C0&&n--,s[r].level=n,s[r].nesting>0&&n++,\\\"text\\\"===s[r].type&&r+1\u003Co&&\\\"text\\\"===s[r+1].type?s[r+1].content=s[r].content+s[r+1].content:(r!==t&&(s[t]=s[r]),t++);r!==t&&(s.length=t)}]];function lr(){var e;for(this.ruler=new O,e=0;e\u003Car.length;e++)this.ruler.push(ar[e][0],ar[e][1]);for(this.ruler2=new O,e=0;e\u003Ccr.length;e++)this.ruler2.push(cr[e][0],cr[e][1])}lr.prototype.skipToken=function(e){var r,t,n=e.pos,s=this.ruler.getRules(\\\"\\\"),o=s.length,i=e.md.options.maxNesting,a=e.cache;if(void 0===a[n]){if(e.level\u003Ci)for(t=0;t\u003Co&&(e.level++,r=s[t](e,!0),e.level--,!r);t++);else e.pos=e.posMax;r||e.pos++,a[n]=e.pos}else e.pos=a[n]},lr.prototype.tokenize=function(e){for(var r,t,n=this.ruler.getRules(\\\"\\\"),s=n.length,o=e.posMax,i=e.md.options.maxNesting;e.pos\u003Co;){if(e.level\u003Ci)for(t=0;t\u003Cs&&!(r=n[t](e,!1));t++);if(r){if(e.pos>=o)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},lr.prototype.parse=function(e,r,t,n){var s,o,i,a=new this.State(e,r,t,n);for(this.tokenize(a),i=(o=this.ruler2.getRules(\\\"\\\")).length,s=0;s\u003Ci;s++)o[s](a)},lr.prototype.State=ir;var ur=lr;function pr(e){var r=Array.prototype.slice.call(arguments,1);return r.forEach((function(r){r&&Object.keys(r).forEach((function(t){e[t]=r[t]}))})),e}function hr(e){return Object.prototype.toString.call(e)}function fr(e){return\\\"[object Function]\\\"===hr(e)}function dr(e){return e.replace(/[.?*+^$[\\\\]\\\\\\\\(){}|-]/g,\\\"\\\\\\\\$&\\\")}var mr={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1};var gr={\\\"http:\\\":{validate:function(e,r,t){var n=e.slice(r);return t.re.http||(t.re.http=new RegExp(\\\"^\\\\\\\\/\\\\\\\\/\\\"+t.re.src_auth+t.re.src_host_port_strict+t.re.src_path,\\\"i\\\")),t.re.http.test(n)?n.match(t.re.http)[0].length:0}},\\\"https:\\\":\\\"http:\\\",\\\"ftp:\\\":\\\"http:\\\",\\\"//\\\":{validate:function(e,r,t){var n=e.slice(r);return t.re.no_http||(t.re.no_http=new RegExp(\\\"^\\\"+t.re.src_auth+\\\"(?:localhost|(?:(?:\\\"+t.re.src_domain+\\\")\\\\\\\\.)+\\\"+t.re.src_domain_root+\\\")\\\"+t.re.src_port+t.re.src_host_terminator+t.re.src_path,\\\"i\\\")),t.re.no_http.test(n)?r>=3&&\\\":\\\"===e[r-3]||r>=3&&\\\"/\\\"===e[r-3]?0:n.match(t.re.no_http)[0].length:0}},\\\"mailto:\\\":{validate:function(e,r,t){var n=e.slice(r);return t.re.mailto||(t.re.mailto=new RegExp(\\\"^\\\"+t.re.src_email_name+\\\"@\\\"+t.re.src_host_strict,\\\"i\\\")),t.re.mailto.test(n)?n.match(t.re.mailto)[0].length:0}}},_r=\\\"biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\\\\u0440\\\\u0444\\\".split(\\\"|\\\");function kr(e){var r=e.re=function(e){var r={};return e=e||{},r.src_Any=y.source,r.src_Cc=A.source,r.src_Z=x.source,r.src_P=t.source,r.src_ZPCc=[r.src_Z,r.src_P,r.src_Cc].join(\\\"|\\\"),r.src_ZCc=[r.src_Z,r.src_Cc].join(\\\"|\\\"),r.src_pseudo_letter=\\\"(?:(?![>\u003C\\\\uff5c]|\\\"+r.src_ZPCc+\\\")\\\"+r.src_Any+\\\")\\\",r.src_ip4=\\\"(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\\\\\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\\",r.src_auth=\\\"(?:(?:(?!\\\"+r.src_ZCc+\\\"|[@/\\\\\\\\[\\\\\\\\]()]).)+@)?\\\",r.src_port=\\\"(?::(?:6(?:[0-4]\\\\\\\\d{3}|5(?:[0-4]\\\\\\\\d{2}|5(?:[0-2]\\\\\\\\d|3[0-5])))|[1-5]?\\\\\\\\d{1,4}))?\\\",r.src_host_terminator=\\\"(?=$|[>\u003C\\\\uff5c]|\\\"+r.src_ZPCc+\\\")(?!\\\"+(e[\\\"---\\\"]?\\\"-(?!--)|\\\":\\\"-|\\\")+\\\"_|:\\\\\\\\d|\\\\\\\\.-|\\\\\\\\.(?!$|\\\"+r.src_ZPCc+\\\"))\\\",r.src_path=\\\"(?:[/?#](?:(?!\\\"+r.src_ZCc+\\\"|[>\u003C\\\\uff5c]|[()[\\\\\\\\]{}.,\\\\\\\"'?!\\\\\\\\-;]).|\\\\\\\\[(?:(?!\\\"+r.src_ZCc+\\\"|\\\\\\\\]).)*\\\\\\\\]|\\\\\\\\((?:(?!\\\"+r.src_ZCc+\\\"|[)]).)*\\\\\\\\)|\\\\\\\\{(?:(?!\\\"+r.src_ZCc+'|[}]).)*\\\\\\\\}|\\\\\\\\\\\"(?:(?!'+r.src_ZCc+'|[\\\"]).)+\\\\\\\\\\\"|\\\\\\\\\\\\'(?:(?!'+r.src_ZCc+\\\"|[']).)+\\\\\\\\'|\\\\\\\\'(?=\\\"+r.src_pseudo_letter+\\\"|[-])|\\\\\\\\.{2,}[a-zA-Z0-9%/&]|\\\\\\\\.(?!\\\"+r.src_ZCc+\\\"|[.]|$)|\\\"+(e[\\\"---\\\"]?\\\"\\\\\\\\-(?!--(?:[^-]|$))(?:-*)|\\\":\\\"\\\\\\\\-+|\\\")+\\\",(?!\\\"+r.src_ZCc+\\\"|$)|;(?!\\\"+r.src_ZCc+\\\"|$)|\\\\\\\\!+(?!\\\"+r.src_ZCc+\\\"|[!]|$)|\\\\\\\\?(?!\\\"+r.src_ZCc+\\\"|[?]|$))+|\\\\\\\\/)?\\\",r.src_email_name='[\\\\\\\\-;:&=\\\\\\\\+\\\\\\\\$,\\\\\\\\.a-zA-Z0-9_][\\\\\\\\-;:&=\\\\\\\\+\\\\\\\\$,\\\\\\\\\\\"\\\\\\\\.a-zA-Z0-9_]*',r.src_xn=\\\"xn--[a-z0-9\\\\\\\\-]{1,59}\\\",r.src_domain_root=\\\"(?:\\\"+r.src_xn+\\\"|\\\"+r.src_pseudo_letter+\\\"{1,63})\\\",r.src_domain=\\\"(?:\\\"+r.src_xn+\\\"|(?:\\\"+r.src_pseudo_letter+\\\")|(?:\\\"+r.src_pseudo_letter+\\\"(?:-|\\\"+r.src_pseudo_letter+\\\"){0,61}\\\"+r.src_pseudo_letter+\\\"))\\\",r.src_host=\\\"(?:(?:(?:(?:\\\"+r.src_domain+\\\")\\\\\\\\.)*\\\"+r.src_domain+\\\"))\\\",r.tpl_host_fuzzy=\\\"(?:\\\"+r.src_ip4+\\\"|(?:(?:(?:\\\"+r.src_domain+\\\")\\\\\\\\.)+(?:%TLDS%)))\\\",r.tpl_host_no_ip_fuzzy=\\\"(?:(?:(?:\\\"+r.src_domain+\\\")\\\\\\\\.)+(?:%TLDS%))\\\",r.src_host_strict=r.src_host+r.src_host_terminator,r.tpl_host_fuzzy_strict=r.tpl_host_fuzzy+r.src_host_terminator,r.src_host_port_strict=r.src_host+r.src_port+r.src_host_terminator,r.tpl_host_port_fuzzy_strict=r.tpl_host_fuzzy+r.src_port+r.src_host_terminator,r.tpl_host_port_no_ip_fuzzy_strict=r.tpl_host_no_ip_fuzzy+r.src_port+r.src_host_terminator,r.tpl_host_fuzzy_test=\\\"localhost|www\\\\\\\\.|\\\\\\\\.\\\\\\\\d{1,3}\\\\\\\\.|(?:\\\\\\\\.(?:%TLDS%)(?:\\\"+r.src_ZPCc+\\\"|>|$))\\\",r.tpl_email_fuzzy='(^|[>\u003C\\\\uff5c]|\\\"|\\\\\\\\(|'+r.src_ZCc+\\\")(\\\"+r.src_email_name+\\\"@\\\"+r.tpl_host_fuzzy_strict+\\\")\\\",r.tpl_link_fuzzy=\\\"(^|(?![.:/\\\\\\\\-_@])(?:[$+\u003C=>^`|\\\\uff5c]|\\\"+r.src_ZPCc+\\\"))((?![$+\u003C=>^`|\\\\uff5c])\\\"+r.tpl_host_port_fuzzy_strict+r.src_path+\\\")\\\",r.tpl_link_no_ip_fuzzy=\\\"(^|(?![.:/\\\\\\\\-_@])(?:[$+\u003C=>^`|\\\\uff5c]|\\\"+r.src_ZPCc+\\\"))((?![$+\u003C=>^`|\\\\uff5c])\\\"+r.tpl_host_port_no_ip_fuzzy_strict+r.src_path+\\\")\\\",r}(e.__opts__),n=e.__tlds__.slice();function s(e){return e.replace(\\\"%TLDS%\\\",r.src_tlds)}e.onCompile(),e.__tlds_replaced__||n.push(\\\"a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]\\\"),n.push(r.src_xn),r.src_tlds=n.join(\\\"|\\\"),r.email_fuzzy=RegExp(s(r.tpl_email_fuzzy),\\\"i\\\"),r.link_fuzzy=RegExp(s(r.tpl_link_fuzzy),\\\"i\\\"),r.link_no_ip_fuzzy=RegExp(s(r.tpl_link_no_ip_fuzzy),\\\"i\\\"),r.host_fuzzy_test=RegExp(s(r.tpl_host_fuzzy_test),\\\"i\\\");var o=[];function i(e,r){throw new Error('(LinkifyIt) Invalid schema \\\"'+e+'\\\": '+r)}e.__compiled__={},Object.keys(e.__schemas__).forEach((function(r){var t=e.__schemas__[r];if(null!==t){var n={validate:null,link:null};if(e.__compiled__[r]=n,\\\"[object Object]\\\"===hr(t))return!function(e){return\\\"[object RegExp]\\\"===hr(e)}(t.validate)?fr(t.validate)?n.validate=t.validate:i(r,t):n.validate=function(e){return function(r,t){var n=r.slice(t);return e.test(n)?n.match(e)[0].length:0}}(t.validate),void(fr(t.normalize)?n.normalize=t.normalize:t.normalize?i(r,t):n.normalize=function(e,r){r.normalize(e)});!function(e){return\\\"[object String]\\\"===hr(e)}(t)?i(r,t):o.push(r)}})),o.forEach((function(r){e.__compiled__[e.__schemas__[r]]&&(e.__compiled__[r].validate=e.__compiled__[e.__schemas__[r]].validate,e.__compiled__[r].normalize=e.__compiled__[e.__schemas__[r]].normalize)})),e.__compiled__[\\\"\\\"]={validate:null,normalize:function(e,r){r.normalize(e)}};var a=Object.keys(e.__compiled__).filter((function(r){return r.length>0&&e.__compiled__[r]})).map(dr).join(\\\"|\\\");e.re.schema_test=RegExp(\\\"(^|(?!_)(?:[>\u003C\\\\uff5c]|\\\"+r.src_ZPCc+\\\"))(\\\"+a+\\\")\\\",\\\"i\\\"),e.re.schema_search=RegExp(\\\"(^|(?!_)(?:[>\u003C\\\\uff5c]|\\\"+r.src_ZPCc+\\\"))(\\\"+a+\\\")\\\",\\\"ig\\\"),e.re.schema_at_start=RegExp(\\\"^\\\"+e.re.schema_search.source,\\\"i\\\"),e.re.pretest=RegExp(\\\"(\\\"+e.re.schema_test.source+\\\")|(\\\"+e.re.host_fuzzy_test.source+\\\")|@\\\",\\\"i\\\"),function(e){e.__index__=-1,e.__text_cache__=\\\"\\\"}(e)}function br(e,r){var t=e.__index__,n=e.__last_index__,s=e.__text_cache__.slice(t,n);this.schema=e.__schema__.toLowerCase(),this.index=t+r,this.lastIndex=n+r,this.raw=s,this.text=s,this.url=s}function vr(e,r){var t=new br(e,r);return e.__compiled__[t.schema].normalize(t,e),t}function Cr(e,r){if(!(this instanceof Cr))return new Cr(e,r);var t;r||(t=e,Object.keys(t||{}).reduce((function(e,r){return e||mr.hasOwnProperty(r)}),!1)&&(r=e,e={})),this.__opts__=pr({},mr,r),this.__index__=-1,this.__last_index__=-1,this.__schema__=\\\"\\\",this.__text_cache__=\\\"\\\",this.__schemas__=pr({},gr,e),this.__compiled__={},this.__tlds__=_r,this.__tlds_replaced__=!1,this.re={},kr(this)}Cr.prototype.add=function(e,r){return this.__schemas__[e]=r,kr(this),this},Cr.prototype.set=function(e){return this.__opts__=pr(this.__opts__,e),this},Cr.prototype.test=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return!1;var r,t,n,s,o,i,a,c;if(this.re.schema_test.test(e))for((a=this.re.schema_search).lastIndex=0;null!==(r=a.exec(e));)if(s=this.testSchemaAt(e,r[2],a.lastIndex)){this.__schema__=r[2],this.__index__=r.index+r[1].length,this.__last_index__=r.index+r[0].length+s;break}return this.__opts__.fuzzyLink&&this.__compiled__[\\\"http:\\\"]&&(c=e.search(this.re.host_fuzzy_test))>=0&&(this.__index__\u003C0||c\u003Cthis.__index__)&&null!==(t=e.match(this.__opts__.fuzzyIP?this.re.link_fuzzy:this.re.link_no_ip_fuzzy))&&(o=t.index+t[1].length,(this.__index__\u003C0||o\u003Cthis.__index__)&&(this.__schema__=\\\"\\\",this.__index__=o,this.__last_index__=t.index+t[0].length)),this.__opts__.fuzzyEmail&&this.__compiled__[\\\"mailto:\\\"]&&e.indexOf(\\\"@\\\")>=0&&null!==(n=e.match(this.re.email_fuzzy))&&(o=n.index+n[1].length,i=n.index+n[0].length,(this.__index__\u003C0||o\u003Cthis.__index__||o===this.__index__&&i>this.__last_index__)&&(this.__schema__=\\\"mailto:\\\",this.__index__=o,this.__last_index__=i)),this.__index__>=0},Cr.prototype.pretest=function(e){return this.re.pretest.test(e)},Cr.prototype.testSchemaAt=function(e,r,t){return this.__compiled__[r.toLowerCase()]?this.__compiled__[r.toLowerCase()].validate(e,t,this):0},Cr.prototype.match=function(e){var r=0,t=[];this.__index__>=0&&this.__text_cache__===e&&(t.push(vr(this,r)),r=this.__last_index__);for(var n=r?e.slice(r):e;this.test(n);)t.push(vr(this,r)),n=n.slice(this.__last_index__),r+=this.__last_index__;return t.length?t:null},Cr.prototype.matchAtStart=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return null;var r=this.re.schema_at_start.exec(e);if(!r)return null;var t=this.testSchemaAt(e,r[2],r[0].length);return t?(this.__schema__=r[2],this.__index__=r.index+r[1].length,this.__last_index__=r.index+r[0].length+t,vr(this,0)):null},Cr.prototype.tlds=function(e,r){return e=Array.isArray(e)?e:[e],r?(this.__tlds__=this.__tlds__.concat(e).sort().filter((function(e,r,t){return e!==t[r-1]})).reverse(),kr(this),this):(this.__tlds__=e.slice(),this.__tlds_replaced__=!0,kr(this),this)},Cr.prototype.normalize=function(e){e.schema||(e.url=\\\"http://\\\"+e.url),\\\"mailto:\\\"!==e.schema||/^mailto:/i.test(e.url)||(e.url=\\\"mailto:\\\"+e.url)},Cr.prototype.onCompile=function(){};var yr=Cr,Ar=2147483647,xr=36,Dr=/^xn--/,wr=/[^\\\\x20-\\\\x7E]/,Er=/[\\\\x2E\\\\u3002\\\\uFF0E\\\\uFF61]/g,qr={overflow:\\\"Overflow: input needs wider integers to process\\\",\\\"not-basic\\\":\\\"Illegal input >= 0x80 (not a basic code point)\\\",\\\"invalid-input\\\":\\\"Invalid input\\\"},Sr=Math.floor,Fr=String.fromCharCode;\\n/*! https://mths.be/punycode v1.4.1 by @mathias */function Lr(e){throw new RangeError(qr[e])}function zr(e,r){for(var t=e.length,n=[];t--;)n[t]=r(e[t]);return n}function Tr(e,r){var t=e.split(\\\"@\\\"),n=\\\"\\\";return t.length>1&&(n=t[0]+\\\"@\\\",e=t[1]),n+zr((e=e.replace(Er,\\\".\\\")).split(\\\".\\\"),r).join(\\\".\\\")}function Ir(e){for(var r,t,n=[],s=0,o=e.length;s\u003Co;)(r=e.charCodeAt(s++))>=55296&&r\u003C=56319&&s\u003Co?56320==(64512&(t=e.charCodeAt(s++)))?n.push(((1023&r)\u003C\u003C10)+(1023&t)+65536):(n.push(r),s--):n.push(r);return n}function Mr(e){return zr(e,(function(e){var r=\\\"\\\";return e>65535&&(r+=Fr((e-=65536)>>>10&1023|55296),e=56320|1023&e),r+=Fr(e)})).join(\\\"\\\")}function Rr(e,r){return e+22+75*(e\u003C26)-((0!=r)\u003C\u003C5)}function Br(e,r,t){var n=0;for(e=t?Sr(e/700):e>>1,e+=Sr(e/r);e>455;n+=xr)e=Sr(e/35);return Sr(n+36*e/(e+38))}function Nr(e){var r,t,n,s,o,i,a,c,l,u,p,h=[],f=e.length,d=0,m=128,g=72;for((t=e.lastIndexOf(\\\"-\\\"))\u003C0&&(t=0),n=0;n\u003Ct;++n)e.charCodeAt(n)>=128&&Lr(\\\"not-basic\\\"),h.push(e.charCodeAt(n));for(s=t>0?t+1:0;s\u003Cf;){for(o=d,i=1,a=xr;s>=f&&Lr(\\\"invalid-input\\\"),((c=(p=e.charCodeAt(s++))-48\u003C10?p-22:p-65\u003C26?p-65:p-97\u003C26?p-97:xr)>=xr||c>Sr((Ar-d)/i))&&Lr(\\\"overflow\\\"),d+=c*i,!(c\u003C(l=a\u003C=g?1:a>=g+26?26:a-g));a+=xr)i>Sr(Ar/(u=xr-l))&&Lr(\\\"overflow\\\"),i*=u;g=Br(d-o,r=h.length+1,0==o),Sr(d/r)>Ar-m&&Lr(\\\"overflow\\\"),m+=Sr(d/r),d%=r,h.splice(d++,0,m)}return Mr(h)}function Or(e){var r,t,n,s,o,i,a,c,l,u,p,h,f,d,m,g=[];for(h=(e=Ir(e)).length,r=128,t=0,o=72,i=0;i\u003Ch;++i)(p=e[i])\u003C128&&g.push(Fr(p));for(n=s=g.length,s&&g.push(\\\"-\\\");n\u003Ch;){for(a=Ar,i=0;i\u003Ch;++i)(p=e[i])>=r&&p\u003Ca&&(a=p);for(a-r>Sr((Ar-t)/(f=n+1))&&Lr(\\\"overflow\\\"),t+=(a-r)*f,r=a,i=0;i\u003Ch;++i)if((p=e[i])\u003Cr&&++t>Ar&&Lr(\\\"overflow\\\"),p==r){for(c=t,l=xr;!(c\u003C(u=l\u003C=o?1:l>=o+26?26:l-o));l+=xr)m=c-u,d=xr-u,g.push(Fr(Rr(u+m%d,0))),c=Sr(m/d);g.push(Fr(Rr(c,0))),o=Br(t,f,n==s),t=0,++n}++t,++r}return g.join(\\\"\\\")}function Pr(e){return Tr(e,(function(e){return Dr.test(e)?Nr(e.slice(4).toLowerCase()):e}))}function jr(e){return Tr(e,(function(e){return wr.test(e)?\\\"xn--\\\"+Or(e):e}))}var Ur=\\\"1.4.1\\\",Vr={decode:Ir,encode:Mr},Zr={version:Ur,ucs2:Vr,toASCII:jr,toUnicode:Pr,encode:Or,decode:Nr},$r=e(Object.freeze({__proto__:null,decode:Nr,encode:Or,toUnicode:Pr,toASCII:jr,version:Ur,ucs2:Vr,default:Zr})),Gr={default:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:\\\"language-\\\",linkify:!1,typographer:!1,quotes:\\\"\\\\u201c\\\\u201d\\\\u2018\\\\u2019\\\",highlight:null,maxNesting:100},components:{core:{},block:{},inline:{}}},zero:{options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:\\\"language-\\\",linkify:!1,typographer:!1,quotes:\\\"\\\\u201c\\\\u201d\\\\u2018\\\\u2019\\\",highlight:null,maxNesting:20},components:{core:{rules:[\\\"normalize\\\",\\\"block\\\",\\\"inline\\\",\\\"text_join\\\"]},block:{rules:[\\\"paragraph\\\"]},inline:{rules:[\\\"text\\\"],rules2:[\\\"balance_pairs\\\",\\\"fragments_join\\\"]}}},commonmark:{options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:\\\"language-\\\",linkify:!1,typographer:!1,quotes:\\\"\\\\u201c\\\\u201d\\\\u2018\\\\u2019\\\",highlight:null,maxNesting:20},components:{core:{rules:[\\\"normalize\\\",\\\"block\\\",\\\"inline\\\",\\\"text_join\\\"]},block:{rules:[\\\"blockquote\\\",\\\"code\\\",\\\"fence\\\",\\\"heading\\\",\\\"hr\\\",\\\"html_block\\\",\\\"lheading\\\",\\\"list\\\",\\\"reference\\\",\\\"paragraph\\\"]},inline:{rules:[\\\"autolink\\\",\\\"backticks\\\",\\\"emphasis\\\",\\\"entity\\\",\\\"escape\\\",\\\"html_inline\\\",\\\"image\\\",\\\"link\\\",\\\"newline\\\",\\\"text\\\"],rules2:[\\\"balance_pairs\\\",\\\"emphasis\\\",\\\"fragments_join\\\"]}}}},Hr=/^(vbscript|javascript|file|data):/,Jr=/^data:image\\\\/(gif|png|jpeg|webp);/;function Wr(e){var r=e.trim().toLowerCase();return!Hr.test(r)||!!Jr.test(r)}var Yr=[\\\"http:\\\",\\\"https:\\\",\\\"mailto:\\\"];function Kr(e){var r=C.parse(e,!0);if(r.hostname&&(!r.protocol||Yr.indexOf(r.protocol)>=0))try{r.hostname=$r.toASCII(r.hostname)}catch(e){}return C.encode(C.format(r))}function Qr(e){var r=C.parse(e,!0);if(r.hostname&&(!r.protocol||Yr.indexOf(r.protocol)>=0))try{r.hostname=$r.toUnicode(r.hostname)}catch(e){}return C.decode(C.format(r),C.decode.defaultChars+\\\"%\\\")}function Xr(e,r){if(!(this instanceof Xr))return new Xr(e,r);r||w.isString(e)||(r=e||{},e=\\\"default\\\"),this.inline=new ur,this.block=new ze,this.core=new ue,this.renderer=new B,this.linkify=new yr,this.validateLink=Wr,this.normalizeLink=Kr,this.normalizeLinkText=Qr,this.utils=w,this.helpers=w.assign({},L),this.options={},this.configure(e),r&&this.set(r)}return Xr.prototype.set=function(e){return w.assign(this.options,e),this},Xr.prototype.configure=function(e){var r,t=this;if(w.isString(e)&&!(e=Gr[r=e]))throw new Error('Wrong `markdown-it` preset \\\"'+r+'\\\", check name');if(!e)throw new Error(\\\"Wrong `markdown-it` preset, can't be empty\\\");return e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach((function(r){e.components[r].rules&&t[r].ruler.enableOnly(e.components[r].rules),e.components[r].rules2&&t[r].ruler2.enableOnly(e.components[r].rules2)})),this},Xr.prototype.enable=function(e,r){var t=[];Array.isArray(e)||(e=[e]),[\\\"core\\\",\\\"block\\\",\\\"inline\\\"].forEach((function(r){t=t.concat(this[r].ruler.enable(e,!0))}),this),t=t.concat(this.inline.ruler2.enable(e,!0));var n=e.filter((function(e){return t.indexOf(e)\u003C0}));if(n.length&&!r)throw new Error(\\\"MarkdownIt. Failed to enable unknown rule(s): \\\"+n);return this},Xr.prototype.disable=function(e,r){var t=[];Array.isArray(e)||(e=[e]),[\\\"core\\\",\\\"block\\\",\\\"inline\\\"].forEach((function(r){t=t.concat(this[r].ruler.disable(e,!0))}),this),t=t.concat(this.inline.ruler2.disable(e,!0));var n=e.filter((function(e){return t.indexOf(e)\u003C0}));if(n.length&&!r)throw new Error(\\\"MarkdownIt. Failed to disable unknown rule(s): \\\"+n);return this},Xr.prototype.use=function(e){var r=[this].concat(Array.prototype.slice.call(arguments,1));return e.apply(e,r),this},Xr.prototype.parse=function(e,r){if(\\\"string\\\"!=typeof e)throw new Error(\\\"Input data should be a String\\\");var t=new this.core.State(e,this,r);return this.core.process(t),t.tokens},Xr.prototype.render=function(e,r){return r=r||{},this.renderer.render(this.parse(e,r),this.options,r)},Xr.prototype.parseInline=function(e,r){var t=new this.core.State(e,this,r);return t.inlineMode=!0,this.core.process(t),t.tokens},Xr.prototype.renderInline=function(e,r){return r=r||{},this.renderer.render(this.parseInline(e,r),this.options,r)},Xr}));\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-deflist.js\":{\"text\":\"/*!\\n\\nmarkdown-it-deflist\\nhttps://github.com/markdown-it/markdown-it-deflist\\n\\n*/\\n!function(e){if(\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module)module.exports=e();else if(\\\"function\\\"==typeof define&&define.amd)define([],e);else{(\\\"undefined\\\"!=typeof window?window:\\\"undefined\\\"!=typeof global?global:\\\"undefined\\\"!=typeof self?self:this).markdownitDeflist=e()}}((function(){return function e(t,n,r){function i(f,d){if(!n[f]){if(!t[f]){var s=\\\"function\\\"==typeof require&&require;if(!d&&s)return s(f,!0);if(o)return o(f,!0);var u=new Error(\\\"Cannot find module '\\\"+f+\\\"'\\\");throw u.code=\\\"MODULE_NOT_FOUND\\\",u}var a=n[f]={exports:{}};t[f][0].call(a.exports,(function(e){return i(t[f][1][e]||e)}),a,a.exports,e,t,n,r)}return n[f].exports}for(var o=\\\"function\\\"==typeof require&&require,f=0;f\u003Cr.length;f++)i(r[f]);return i}({\\\"/\\\":[function(e,t,n){\\\"use strict\\\";t.exports=function(e){var t=e.utils.isSpace;function n(e,t){var n,r,i=e.bMarks[t]+e.tShift[t],o=e.eMarks[t];return i>=o||126!==(r=e.src.charCodeAt(i++))&&58!==r||i===(n=e.skipSpaces(i))||n>=o?-1:i}e.block.ruler.before(\\\"paragraph\\\",\\\"deflist\\\",(function(e,r,i,o){var f,d,s,u,a,l,p,k,c,h,b,y,m,g,C,I,v,_,w,x;if(o)return!(e.ddIndent\u003C0)&&n(e,r)>=0;if((c=r+1)>=i)return!1;if(e.isEmpty(c)&&++c>=i)return!1;if(e.sCount[c]\u003Ce.blkIndent)return!1;if((d=n(e,c))\u003C0)return!1;p=e.tokens.length,w=!0,(x=e.push(\\\"dl_open\\\",\\\"dl\\\",1)).map=l=[r,0],u=r,s=c;e:for(;;){for(_=!1,(x=e.push(\\\"dt_open\\\",\\\"dt\\\",1)).map=[u,u],(x=e.push(\\\"inline\\\",\\\"\\\",0)).map=[u,u],x.content=e.getLines(u,u+1,e.blkIndent,!1).trim(),x.children=[],x=e.push(\\\"dt_close\\\",\\\"dt\\\",-1);;){for((x=e.push(\\\"dd_open\\\",\\\"dd\\\",1)).map=a=[c,0],v=d,k=e.eMarks[s],h=e.sCount[s]+d-(e.bMarks[s]+e.tShift[s]);v\u003Ck&&(f=e.src.charCodeAt(v),t(f));)9===f?h+=4-h%4:h++,v++;if(d=v,I=e.tight,b=e.ddIndent,y=e.blkIndent,C=e.tShift[s],g=e.sCount[s],m=e.parentType,e.blkIndent=e.ddIndent=e.sCount[s]+2,e.tShift[s]=d-e.bMarks[s],e.sCount[s]=h,e.tight=!0,e.parentType=\\\"deflist\\\",e.md.block.tokenize(e,s,i,!0),e.tight&&!_||(w=!1),_=e.line-s>1&&e.isEmpty(e.line-1),e.tShift[s]=C,e.sCount[s]=g,e.tight=I,e.parentType=m,e.blkIndent=y,e.ddIndent=b,x=e.push(\\\"dd_close\\\",\\\"dd\\\",-1),a[1]=c=e.line,c>=i)break e;if(e.sCount[c]\u003Ce.blkIndent)break e;if((d=n(e,c))\u003C0)break;s=c}if(c>=i)break;if(u=c,e.isEmpty(u))break;if(e.sCount[u]\u003Ce.blkIndent)break;if((s=u+1)>=i)break;if(e.isEmpty(s)&&s++,s>=i)break;if(e.sCount[s]\u003Ce.blkIndent)break;if((d=n(e,s))\u003C0)break}return x=e.push(\\\"dl_close\\\",\\\"dl\\\",-1),l[1]=c,e.line=c,w&&function(e,t){var n,r,i=e.level+2;for(n=t+2,r=e.tokens.length-2;n\u003Cr;n++)e.tokens[n].level===i&&\\\"paragraph_open\\\"===e.tokens[n].type&&(e.tokens[n+2].hidden=!0,e.tokens[n].hidden=!0,n+=2)}(e,p),!0}),{alt:[\\\"paragraph\\\",\\\"reference\\\",\\\"blockquote\\\"]})}},{}]},{},[])(\\\"/\\\")}));\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-deflist.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-footnote.js\":{\"text\":\"!function(e){if(\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module)module.exports=e();else if(\\\"function\\\"==typeof define&&define.amd)define([],e);else{(\\\"undefined\\\"!=typeof window?window:\\\"undefined\\\"!=typeof global?global:\\\"undefined\\\"!=typeof self?self:this).markdownitFootnote=e()}}(function(){return function(){return function e(o,t,n){function r(f,l){if(!t[f]){if(!o[f]){var i=\\\"function\\\"==typeof require&&require;if(!l&&i)return i(f,!0);if(s)return s(f,!0);var u=new Error(\\\"Cannot find module '\\\"+f+\\\"'\\\");throw u.code=\\\"MODULE_NOT_FOUND\\\",u}var a=t[f]={exports:{}};o[f][0].call(a.exports,function(e){return r(o[f][1][e]||e)},a,a.exports,e,o,t,n)}return t[f].exports}for(var s=\\\"function\\\"==typeof require&&require,f=0;f\u003Cn.length;f++)r(n[f]);return r}}()({1:[function(e,o,t){\\\"use strict\\\";function n(e,o,t,n){var r=Number(e[o].meta.id+1).toString(),s=\\\"\\\";return\\\"string\\\"==typeof n.docId&&(s=\\\"-\\\"+n.docId+\\\"-\\\"),s+r}function r(e,o){var t=Number(e[o].meta.id+1).toString();return e[o].meta.subId>0&&(t+=\\\":\\\"+e[o].meta.subId),\\\"[\\\"+t+\\\"]\\\"}function s(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r),f=r.rules.footnote_caption(e,o,t,n,r),l=s;return e[o].meta.subId>0&&(l+=\\\":\\\"+e[o].meta.subId),'\u003Csup class=\\\"footnote-ref\\\">\u003Ca href=\\\"#fn'+s+'\\\" id=\\\"fnref'+l+'\\\">'+f+\\\"\u003C/a>\u003C/sup>\\\"}function f(e,o,t){return(t.xhtmlOut?'\u003Chr class=\\\"footnotes-sep\\\" />\\\\n':'\u003Chr class=\\\"footnotes-sep\\\">\\\\n')+'\u003Csection class=\\\"footnotes\\\">\\\\n\u003Col class=\\\"footnotes-list\\\">\\\\n'}function l(){return\\\"\u003C/ol>\\\\n\u003C/section>\\\\n\\\"}function i(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r);return e[o].meta.subId>0&&(s+=\\\":\\\"+e[o].meta.subId),'\u003Cli id=\\\"fn'+s+'\\\" class=\\\"footnote-item\\\">'}function u(){return\\\"\u003C/li>\\\\n\\\"}function a(e,o,t,n,r){var s=r.rules.footnote_anchor_name(e,o,t,n,r);return e[o].meta.subId>0&&(s+=\\\":\\\"+e[o].meta.subId),' \u003Ca href=\\\"#fnref'+s+'\\\" class=\\\"footnote-backref\\\">\\\\u21a9\\\\ufe0e\u003C/a>'}o.exports=function(e){var o=e.helpers.parseLinkLabel,t=e.utils.isSpace;e.renderer.rules.footnote_ref=s,e.renderer.rules.footnote_block_open=f,e.renderer.rules.footnote_block_close=l,e.renderer.rules.footnote_open=i,e.renderer.rules.footnote_close=u,e.renderer.rules.footnote_anchor=a,e.renderer.rules.footnote_caption=r,e.renderer.rules.footnote_anchor_name=n,e.block.ruler.before(\\\"reference\\\",\\\"footnote_def\\\",function(e,o,n,r){var s,f,l,i,u,a,c,p,d,h,k,b=e.bMarks[o]+e.tShift[o],v=e.eMarks[o];if(b+4>v)return!1;if(91!==e.src.charCodeAt(b))return!1;if(94!==e.src.charCodeAt(b+1))return!1;for(u=b+2;u\u003Cv;u++){if(32===e.src.charCodeAt(u))return!1;if(93===e.src.charCodeAt(u))break}if(u===b+2)return!1;if(u+1>=v||58!==e.src.charCodeAt(++u))return!1;if(r)return!0;for(u++,e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.refs||(e.env.footnotes.refs={}),a=e.src.slice(b+2,u-2),e.env.footnotes.refs[\\\":\\\"+a]=-1,(c=new e.Token(\\\"footnote_reference_open\\\",\\\"\\\",1)).meta={label:a},c.level=e.level++,e.tokens.push(c),s=e.bMarks[o],f=e.tShift[o],l=e.sCount[o],i=e.parentType,k=u,p=d=e.sCount[o]+u-(e.bMarks[o]+e.tShift[o]);u\u003Cv&&(h=e.src.charCodeAt(u),t(h));)9===h?d+=4-d%4:d++,u++;return e.tShift[o]=u-k,e.sCount[o]=d-p,e.bMarks[o]=k,e.blkIndent+=4,e.parentType=\\\"footnote\\\",e.sCount[o]\u003Ce.blkIndent&&(e.sCount[o]+=e.blkIndent),e.md.block.tokenize(e,o,n,!0),e.parentType=i,e.blkIndent-=4,e.tShift[o]=f,e.sCount[o]=l,e.bMarks[o]=s,(c=new e.Token(\\\"footnote_reference_close\\\",\\\"\\\",-1)).level=--e.level,e.tokens.push(c),!0},{alt:[\\\"paragraph\\\",\\\"reference\\\"]}),e.inline.ruler.after(\\\"image\\\",\\\"footnote_inline\\\",function(e,t){var n,r,s,f,l=e.posMax,i=e.pos;return!(i+2>=l||94!==e.src.charCodeAt(i)||91!==e.src.charCodeAt(i+1)||(n=i+2,(r=o(e,i+1))\u003C0||(t||(e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.list||(e.env.footnotes.list=[]),s=e.env.footnotes.list.length,e.md.inline.parse(e.src.slice(n,r),e.md,e.env,f=[]),e.push(\\\"footnote_ref\\\",\\\"\\\",0).meta={id:s},e.env.footnotes.list[s]={content:e.src.slice(n,r),tokens:f}),e.pos=r+1,e.posMax=l,0)))}),e.inline.ruler.after(\\\"footnote_inline\\\",\\\"footnote_ref\\\",function(e,o){var t,n,r,s,f=e.posMax,l=e.pos;if(l+3>f)return!1;if(!e.env.footnotes||!e.env.footnotes.refs)return!1;if(91!==e.src.charCodeAt(l))return!1;if(94!==e.src.charCodeAt(l+1))return!1;for(n=l+2;n\u003Cf;n++){if(32===e.src.charCodeAt(n))return!1;if(10===e.src.charCodeAt(n))return!1;if(93===e.src.charCodeAt(n))break}return!(n===l+2||n>=f||(n++,t=e.src.slice(l+2,n-1),void 0===e.env.footnotes.refs[\\\":\\\"+t]||(o||(e.env.footnotes.list||(e.env.footnotes.list=[]),e.env.footnotes.refs[\\\":\\\"+t]\u003C0?(r=e.env.footnotes.list.length,e.env.footnotes.list[r]={label:t,count:0},e.env.footnotes.refs[\\\":\\\"+t]=r):r=e.env.footnotes.refs[\\\":\\\"+t],s=e.env.footnotes.list[r].count,e.env.footnotes.list[r].count++,e.push(\\\"footnote_ref\\\",\\\"\\\",0).meta={id:r,subId:s,label:t}),e.pos=n,e.posMax=f,0)))}),e.core.ruler.after(\\\"inline\\\",\\\"footnote_tail\\\",function(e){var o,t,n,r,s,f,l,i,u,a,c=!1,p={};if(e.env.footnotes&&(e.tokens=e.tokens.filter(function(e){return\\\"footnote_reference_open\\\"===e.type?(c=!0,u=[],a=e.meta.label,!1):\\\"footnote_reference_close\\\"===e.type?(c=!1,p[\\\":\\\"+a]=u,!1):(c&&u.push(e),!c)}),e.env.footnotes.list)){for(f=e.env.footnotes.list,l=new e.Token(\\\"footnote_block_open\\\",\\\"\\\",1),e.tokens.push(l),o=0,t=f.length;o\u003Ct;o++){for((l=new e.Token(\\\"footnote_open\\\",\\\"\\\",1)).meta={id:o,label:f[o].label},e.tokens.push(l),f[o].tokens?(i=[],(l=new e.Token(\\\"paragraph_open\\\",\\\"p\\\",1)).block=!0,i.push(l),(l=new e.Token(\\\"inline\\\",\\\"\\\",0)).children=f[o].tokens,l.content=f[o].content,i.push(l),(l=new e.Token(\\\"paragraph_close\\\",\\\"p\\\",-1)).block=!0,i.push(l)):f[o].label&&(i=p[\\\":\\\"+f[o].label]),i&&(e.tokens=e.tokens.concat(i)),s=\\\"paragraph_close\\\"===e.tokens[e.tokens.length-1].type?e.tokens.pop():null,r=f[o].count>0?f[o].count:1,n=0;n\u003Cr;n++)(l=new e.Token(\\\"footnote_anchor\\\",\\\"\\\",0)).meta={id:o,subId:n,label:f[o].label},e.tokens.push(l);s&&e.tokens.push(s),l=new e.Token(\\\"footnote_close\\\",\\\"\\\",-1),e.tokens.push(l)}l=new e.Token(\\\"footnote_block_close\\\",\\\"\\\",-1),e.tokens.push(l)}})}},{}]},{},[1])(1)});\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-footnote.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-ins.js\":{\"text\":\"/*! markdown-it-ins 3.0.1 https://github.com/markdown-it/markdown-it-mark @license MIT */\\n!function(e,n){\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module?module.exports=n():\\\"function\\\"==typeof define&&define.amd?define(n):(e=\\\"undefined\\\"!=typeof globalThis?globalThis:e||self).markdownitIns=n()}(this,(function(){\\\"use strict\\\";return function(e){function n(e,n){var t,o,s,i,r,l=[],f=n.length;for(t=0;t\u003Cf;t++)43===(s=n[t]).marker&&-1!==s.end&&(i=n[s.end],(r=e.tokens[s.token]).type=\\\"ins_open\\\",r.tag=\\\"ins\\\",r.nesting=1,r.markup=\\\"++\\\",r.content=\\\"\\\",(r=e.tokens[i.token]).type=\\\"ins_close\\\",r.tag=\\\"ins\\\",r.nesting=-1,r.markup=\\\"++\\\",r.content=\\\"\\\",\\\"text\\\"===e.tokens[i.token-1].type&&\\\"+\\\"===e.tokens[i.token-1].content&&l.push(i.token-1));for(;l.length;){for(o=(t=l.pop())+1;o\u003Ce.tokens.length&&\\\"ins_close\\\"===e.tokens[o].type;)o++;t!==--o&&(r=e.tokens[o],e.tokens[o]=e.tokens[t],e.tokens[t]=r)}}e.inline.ruler.before(\\\"emphasis\\\",\\\"ins\\\",(function(e,n){var t,o,s,i,r=e.pos,l=e.src.charCodeAt(r);if(n)return!1;if(43!==l)return!1;if(s=(o=e.scanDelims(e.pos,!0)).length,i=String.fromCharCode(l),s\u003C2)return!1;for(s%2&&(e.push(\\\"text\\\",\\\"\\\",0).content=i,s--),t=0;t\u003Cs;t+=2)e.push(\\\"text\\\",\\\"\\\",0).content=i+i,(o.can_open||o.can_close)&&e.delimiters.push({marker:l,length:0,jump:t/2,token:e.tokens.length-1,end:-1,open:o.can_open,close:o.can_close});return e.pos+=o.length,!0})),e.inline.ruler2.before(\\\"emphasis\\\",\\\"ins\\\",(function(e){var t,o=e.tokens_meta,s=(e.tokens_meta||[]).length;for(n(e,e.delimiters),t=0;t\u003Cs;t++)o[t]&&o[t].delimiters&&n(e,o[t].delimiters)}))}}));\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-ins.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-mark.js\":{\"text\":\"/*! markdown-it-mark 3.0.1 https://github.com/markdown-it/markdown-it-mark @license MIT */\\n!function(e,n){\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module?module.exports=n():\\\"function\\\"==typeof define&&define.amd?define(n):(e=\\\"undefined\\\"!=typeof globalThis?globalThis:e||self).markdownitMark=n()}(this,(function(){\\\"use strict\\\";return function(e){function n(e,n){var t,o,r,s,i,a=[],k=n.length;for(t=0;t\u003Ck;t++)61===(r=n[t]).marker&&-1!==r.end&&(s=n[r.end],(i=e.tokens[r.token]).type=\\\"mark_open\\\",i.tag=\\\"mark\\\",i.nesting=1,i.markup=\\\"==\\\",i.content=\\\"\\\",(i=e.tokens[s.token]).type=\\\"mark_close\\\",i.tag=\\\"mark\\\",i.nesting=-1,i.markup=\\\"==\\\",i.content=\\\"\\\",\\\"text\\\"===e.tokens[s.token-1].type&&\\\"=\\\"===e.tokens[s.token-1].content&&a.push(s.token-1));for(;a.length;){for(o=(t=a.pop())+1;o\u003Ce.tokens.length&&\\\"mark_close\\\"===e.tokens[o].type;)o++;t!==--o&&(i=e.tokens[o],e.tokens[o]=e.tokens[t],e.tokens[t]=i)}}e.inline.ruler.before(\\\"emphasis\\\",\\\"mark\\\",(function(e,n){var t,o,r,s,i=e.pos,a=e.src.charCodeAt(i);if(n)return!1;if(61!==a)return!1;if(r=(o=e.scanDelims(e.pos,!0)).length,s=String.fromCharCode(a),r\u003C2)return!1;for(r%2&&(e.push(\\\"text\\\",\\\"\\\",0).content=s,r--),t=0;t\u003Cr;t+=2)e.push(\\\"text\\\",\\\"\\\",0).content=s+s,(o.can_open||o.can_close)&&e.delimiters.push({marker:a,length:0,jump:t/2,token:e.tokens.length-1,end:-1,open:o.can_open,close:o.can_close});return e.pos+=o.length,!0})),e.inline.ruler2.before(\\\"emphasis\\\",\\\"mark\\\",(function(e){var t,o=e.tokens_meta,r=(e.tokens_meta||[]).length;for(n(e,e.delimiters),t=0;t\u003Cr;t++)o[t]&&o[t].delimiters&&n(e,o[t].delimiters)}))}}));\\n\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-mark.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-sub.js\":{\"text\":\"/*! markdown-it-sub 1.0.0 https://github.com//markdown-it/markdown-it-sub @license MIT */\\n!function(e){if(\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module)module.exports=e();else if(\\\"function\\\"==typeof define&&define.amd)define([],e);else{var r;r=\\\"undefined\\\"!=typeof window?window:\\\"undefined\\\"!=typeof global?global:\\\"undefined\\\"!=typeof self?self:this,r.markdownitSub=e()}}(function(){return function e(r,o,n){function t(i,u){if(!o[i]){if(!r[i]){var f=\\\"function\\\"==typeof require&&require;if(!u&&f)return f(i,!0);if(s)return s(i,!0);var p=new Error(\\\"Cannot find module '\\\"+i+\\\"'\\\");throw p.code=\\\"MODULE_NOT_FOUND\\\",p}var a=o[i]={exports:{}};r[i][0].call(a.exports,function(e){var o=r[i][1][e];return t(o?o:e)},a,a.exports,e,r,o,n)}return o[i].exports}for(var s=\\\"function\\\"==typeof require&&require,i=0;i\u003Cn.length;i++)t(n[i]);return t}({1:[function(e,r){\\\"use strict\\\";function o(e,r){var o,t,s,i=e.posMax,u=e.pos;if(126!==e.src.charCodeAt(u))return!1;if(r)return!1;if(u+2>=i)return!1;for(e.pos=u+1;e.pos\u003Ci;){if(126===e.src.charCodeAt(e.pos)){o=!0;break}e.md.inline.skipToken(e)}return o&&u+1!==e.pos?(t=e.src.slice(u+1,e.pos),t.match(/(^|[^\\\\\\\\])(\\\\\\\\\\\\\\\\)*\\\\s/)?(e.pos=u,!1):(e.posMax=e.pos,e.pos=u+1,s=e.push(\\\"sub_open\\\",\\\"sub\\\",1),s.markup=\\\"~\\\",s=e.push(\\\"text\\\",\\\"\\\",0),s.content=t.replace(n,\\\"$1\\\"),s=e.push(\\\"sub_close\\\",\\\"sub\\\",-1),s.markup=\\\"~\\\",e.pos=e.posMax+1,e.posMax=i,!0)):(e.pos=u,!1)}var n=/\\\\\\\\([ \\\\\\\\!\\\"#$%&'()*+,.\\\\/:;\u003C=>?@[\\\\]^_`{|}~-])/g;r.exports=function(e){e.inline.ruler.after(\\\"emphasis\\\",\\\"sub\\\",o)}},{}]},{},[1])(1)});\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-sub.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-sup.js\":{\"text\":\"/*! markdown-it-sup 1.0.0 https://github.com//markdown-it/markdown-it-sup @license MIT */\\n!function(e){if(\\\"object\\\"==typeof exports&&\\\"undefined\\\"!=typeof module)module.exports=e();else if(\\\"function\\\"==typeof define&&define.amd)define([],e);else{var r;r=\\\"undefined\\\"!=typeof window?window:\\\"undefined\\\"!=typeof global?global:\\\"undefined\\\"!=typeof self?self:this,r.markdownitSup=e()}}(function(){return function e(r,o,n){function t(i,p){if(!o[i]){if(!r[i]){var u=\\\"function\\\"==typeof require&&require;if(!p&&u)return u(i,!0);if(s)return s(i,!0);var f=new Error(\\\"Cannot find module '\\\"+i+\\\"'\\\");throw f.code=\\\"MODULE_NOT_FOUND\\\",f}var a=o[i]={exports:{}};r[i][0].call(a.exports,function(e){var o=r[i][1][e];return t(o?o:e)},a,a.exports,e,r,o,n)}return o[i].exports}for(var s=\\\"function\\\"==typeof require&&require,i=0;i\u003Cn.length;i++)t(n[i]);return t}({1:[function(e,r){\\\"use strict\\\";function o(e,r){var o,t,s,i=e.posMax,p=e.pos;if(94!==e.src.charCodeAt(p))return!1;if(r)return!1;if(p+2>=i)return!1;for(e.pos=p+1;e.pos\u003Ci;){if(94===e.src.charCodeAt(e.pos)){o=!0;break}e.md.inline.skipToken(e)}return o&&p+1!==e.pos?(t=e.src.slice(p+1,e.pos),t.match(/(^|[^\\\\\\\\])(\\\\\\\\\\\\\\\\)*\\\\s/)?(e.pos=p,!1):(e.posMax=e.pos,e.pos=p+1,s=e.push(\\\"sup_open\\\",\\\"sup\\\",1),s.markup=\\\"^\\\",s=e.push(\\\"text\\\",\\\"\\\",0),s.content=t.replace(n,\\\"$1\\\"),s=e.push(\\\"sup_close\\\",\\\"sup\\\",-1),s.markup=\\\"^\\\",e.pos=e.posMax+1,e.posMax=i,!0)):(e.pos=p,!1)}var n=/\\\\\\\\([ \\\\\\\\!\\\"#$%&'()*+,.\\\\/:;\u003C=>?@[\\\\]^_`{|}~-])/g;r.exports=function(e){e.inline.ruler.after(\\\"emphasis\\\",\\\"sup\\\",o)}},{}]},{},[1])(1)});\",\"type\":\"application/javascript\",\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-sup.js\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/license\":{\"text\":\"Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin.\\n\\nPermission is hereby granted, free of charge, to any person\\nobtaining a copy of this software and associated documentation\\nfiles (the \\\"Software\\\"), to deal in the Software without\\nrestriction, including without limitation the rights to use,\\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\\ncopies of the Software, and to permit persons to whom the\\nSoftware is furnished to do so, subject to the following\\nconditions:\\n\\nThe above copyright notice and this permission notice shall be\\nincluded in all copies or substantial portions of the Software.\\n\\nTHE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND,\\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\\nOTHER DEALINGS IN THE SOFTWARE.\\n\",\"type\":\"text/plain\",\"title\":\"$:/plugins/tiddlywiki/markdown/license\"},\"$:/plugins/tiddlywiki/markdown/images/markdown-linkify\":{\"title\":\"$:/plugins/tiddlywiki/markdown/images/markdown-linkify\",\"tags\":\"$:/tags/Image\",\"text\":\"\u003Csvg width=\\\"22pt\\\" height=\\\"22pt\\\" class=\\\"tc-markdown-linkify-button tc-image-button\\\" viewBox=\\\"0 0 128 128\\\">\\n\u003Cpath d=\\\"M17.031185,32.1989189 L9.04781705,32.1989189 L9.04781705,97.1303119 L17.031185,97.1303119 L17.031185,104.049231 L0,104.049231 L0,25.28 L17.031185,25.28 L17.031185,32.1989189 Z M93.6716009,24.75 C90.4007675,30.8326023 88.0193713,37.1590826 86.5274123,43.7294408 C85.0354532,50.299799 84.2894737,56.9705775 84.2894737,63.7417763 C84.2894737,70.6277412 85.0211075,77.3702485 86.484375,83.9692982 C87.9476425,90.568348 90.314693,96.9952485 93.5855263,103.25 L93.5855263,103.25 L83.4287281,103.25 C79.8135965,97.3395468 77.0161732,91.1134868 75.0364583,84.5718202 C73.0567434,78.0301535 72.066886,71.3737208 72.066886,64.6025219 C72.066886,61.3890716 72.3107639,58.017818 72.7985197,54.488761 C73.2862756,50.9597039 74.0035636,47.4449927 74.9503838,43.9446272 C75.8972039,40.4442617 77.0735563,37.0586623 78.4794408,33.7878289 C79.8853253,30.5169956 81.5350877,27.504386 83.4287281,24.75 L83.4287281,24.75 Z M116.638158,24.75 C120.253289,30.6604532 123.050713,36.9152047 125.030428,43.5142544 C127.010143,50.1133041 128,56.7984284 128,63.5696272 C128,66.7830775 127.770468,70.1543311 127.311404,73.6833882 C126.852339,77.2124452 126.149397,80.7128107 125.202577,84.1844846 C124.255757,87.6561586 123.065058,91.0274123 121.630482,94.2982456 C120.195906,97.5690789 118.531798,100.552997 116.638158,103.25 L116.638158,103.25 L106.48136,103.25 C109.637427,97.1673977 111.975786,90.8696089 113.496436,84.3566338 C115.017087,77.8436586 115.777412,71.2015716 115.777412,64.4303728 C115.777412,57.5444079 115.031433,50.7732091 113.539474,44.1167763 C112.047515,37.4603436 109.723501,31.0047515 106.567434,24.75 L106.567434,24.75 Z M37.1101871,44.1061384 L37.1101871,56.702119 L49.0852391,52.799139 L51.3915454,59.8954661 L39.3277893,63.798446 L46.956341,74.1768244 L40.8357588,78.6120289 L33.2072072,68.1449464 L25.7560638,78.3459166 L19.8128898,73.8220081 L27.4414414,63.798446 L15.2889813,59.6293539 L17.5952876,52.5330268 L29.6590437,56.702119 L29.6590437,44.1061384 L37.1101871,44.1061384 Z M49.6493416,97.1303119 L57.6327096,97.1303119 L57.6327096,32.1989189 L49.6493416,32.1989189 L49.6493416,25.28 L66.6805267,25.28 L66.6805267,104.049231 L49.6493416,104.049231 L49.6493416,97.1303119 Z\\\">\u003C/path>\\n\u003C/svg>\\n\"},\"$:/plugins/tiddlywiki/markdown/images/new-markdown-button\":{\"title\":\"$:/plugins/tiddlywiki/markdown/images/new-markdown-button\",\"tags\":\"$:/tags/Image\",\"text\":\"\u003Csvg class=\\\"tc-image-new-markdown-button tc-image-button\\\" viewBox=\\\"0 0 128 128\\\" width=\\\"22pt\\\" height=\\\"22pt\\\">\\n \u003Cg fill-rule=\\\"evenodd\\\">\\n \u003Crect x=\\\"80\\\" y=\\\"96\\\" width=\\\"48\\\" height=\\\"16\\\" rx=\\\"8\\\">\u003C/rect>\\n \u003Crect x=\\\"96\\\" y=\\\"80\\\" width=\\\"16\\\" height=\\\"48\\\" rx=\\\"8\\\">\u003C/rect>\\n \u003Cpath d=\\\"M3.23876972,39.5396716 C3.23876972,35.9653274 6.13586353,33.0691646 9.7141757,33.0691646 L98.1283744,33.0691646 C101.706101,33.0691646 104.60378,35.9646626 104.60378,39.5396716 L104.60378,84.8296213 C104.60378,88.4039654 101.706687,91.3001282 98.1283744,91.3001282 L9.7141757,91.3001282 C6.13644944,91.3001282 3.23876972,88.4046302 3.23876972,84.8296213 L3.23876972,39.5396716 L3.23876972,39.5396716 Z M-2.15298617,39.5396716 L-2.15298617,84.8296213 C-2.15298617,91.3833243 3.15957363,96.6918841 9.7141757,96.6918841 L98.1283744,96.6918841 C104.684083,96.6918841 109.995536,91.382138 109.995536,84.8296213 L109.995536,39.5396716 C109.995536,32.9859686 104.682977,27.6774087 98.1283744,27.6774087 L9.7141757,27.6774087 C3.15846686,27.6774087 -2.15298617,32.9871549 -2.15298617,39.5396716 Z M14.0222815,80.5166164 L14.0222815,43.8526764 L24.8057933,43.8526764 L35.589305,57.3320661 L46.3728168,43.8526764 L57.1563286,43.8526764 L57.1563286,80.5166164 L46.3728168,80.5166164 L46.3728168,59.4887685 L35.589305,72.9681582 L24.8057933,59.4887685 L24.8057933,80.5166164 L14.0222815,80.5166164 Z M81.4192301,80.5166164 L65.2439624,62.723822 L76.0274742,62.723822 L76.0274742,43.8526764 L86.810986,43.8526764 L86.810986,62.723822 L97.5944978,62.723822 L81.4192301,80.5166164 Z\\\"transform=\\\"translate(53.921275, 62.184646) rotate(-60.000000) translate(-53.921275, -62.184646) \\\">\u003C/path>\\n \u003C/g>\\n\u003C/svg>\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-katex.js\":{\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-katex.js\",\"text\":\"/*\\\\\\ntitle: $:/plugins/tiddlywiki/markdown/markdown-it-katex.js\\ntype: application/javascript\\nmodule-type: library\\n\\nBased on markdown-it-katex v2.0.0 by @waylonflinn https://github.com/waylonflinn/markdown-it-katex | MIT License\\n\\\\*/\\n(function(){\\n/* Process inline math */\\n/*\\nLike markdown-it-simplemath, this is a stripped down, simplified version of:\\nhttps://github.com/runarberg/markdown-it-math\\n\\nIt differs in that it takes (a subset of) LaTeX as input and relies on KaTeX\\nfor rendering output.\\n*/\\n\\n/*jslint node: true */\\n'use strict';\\n\\n// Test if potential opening or closing delimieter\\n// Assumes that there is a \\\"$\\\" at state.src[pos]\\nfunction isValidDelim(state, pos) {\\n var prevChar, nextChar,\\n max = state.posMax,\\n can_open = true,\\n can_close = true;\\n\\n prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;\\n nextChar = pos + 1 \u003C= max ? state.src.charCodeAt(pos + 1) : -1;\\n\\n // Check non-whitespace conditions for opening and closing, and\\n // check that closing delimeter isn't followed by a number\\n if (prevChar === 0x20/* \\\" \\\" */ || prevChar === 0x09/* \\\\t */ ||\\n prevChar === 0x0d/* \\\"\\\\r\\\" */ || prevChar === 0x0a/* \\\\n */ ||\\n (nextChar >= 0x30/* \\\"0\\\" */ && nextChar \u003C= 0x39/* \\\"9\\\" */)) {\\n can_close = false;\\n }\\n if (nextChar === 0x20/* \\\" \\\" */ || nextChar === 0x09/* \\\\t */ ||\\n nextChar === 0x0d/* \\\"\\\\r\\\" */ || nextChar === 0x0a/* \\\\ns */) {\\n can_open = false;\\n }\\n\\n if (state.src.substring(pos,pos+3) === \\\"$:/\\\") {\\n can_open = false;\\n can_close = false;\\n }\\n\\n return {\\n can_open: can_open,\\n can_close: can_close\\n };\\n}\\n\\nfunction math_inline(state, silent) {\\n var start, match, token, res, pos, esc_count;\\n\\n if (state.src[state.pos] !== \\\"$\\\") { return false; }\\n\\n res = isValidDelim(state, state.pos);\\n if (!res.can_open) {\\n if (!silent) { state.pending += \\\"$\\\"; }\\n state.pos += 1;\\n return true;\\n }\\n\\n // First check for and bypass all properly escaped delimieters\\n // This loop will assume that the first leading backtick can not\\n // be the first character in state.src, which is known since\\n // we have found an opening delimieter already.\\n start = state.pos + 1;\\n match = start;\\n while ( (match = state.src.indexOf(\\\"$\\\", match)) !== -1) {\\n // Found potential $, look for escapes, pos will point to\\n // first non escape when complete\\n pos = match - 1;\\n while (state.src[pos] === \\\"\\\\\\\\\\\") { pos -= 1; }\\n\\n // Even number of escapes, potential closing delimiter found\\n if ( ((match - pos) % 2) == 1 ) { break; }\\n match += 1;\\n }\\n\\n // No closing delimter found. Consume $ and continue.\\n if (match === -1) {\\n if (!silent) { state.pending += \\\"$\\\"; }\\n state.pos = start;\\n return true;\\n }\\n\\n // Check if we have empty content, ie: $$. Do not parse.\\n if (match - start === 0) {\\n if (!silent) { state.pending += \\\"$$\\\"; }\\n state.pos = start + 1;\\n return true;\\n }\\n\\n // Check for valid closing delimiter\\n res = isValidDelim(state, match);\\n if (!res.can_close) {\\n if (!silent) { state.pending += \\\"$\\\"; }\\n state.pos = start;\\n return true;\\n }\\n\\n if (!silent) {\\n token = state.push('math_inline', '$latex', 0);\\n token.markup = \\\"$\\\";\\n token.content = state.src.slice(start, match);\\n token.attrs = [[\\\"displayMode\\\", \\\"false\\\"], [\\\"text\\\", token.content]];\\n }\\n\\n state.pos = match + 1;\\n return true;\\n}\\n\\n/*! https://github.com/iktakahiro/markdown-it-katex/pull/2 by @shinhermit */\\nfunction math_inline_block(state, silent) {\\n var start, match, token, res, pos, esc_count;\\n\\n if(state.src.slice(state.pos, state.pos+2) !== \\\"$$\\\") { return false; }\\n\\n // First check for and bypass all properly escaped delimieters\\n // This loop will assume that the first leading backtick can not\\n // be the first character in state.src, which is known since\\n // we have found an opening delimieter already.\\n start = state.pos + 2;\\n match = start;\\n while ( (match = state.src.indexOf(\\\"$$\\\", match)) !== -1) {\\n // Found potential $$, look for escapes, pos will point to\\n // first non escape when complete\\n pos = match - 1;\\n while (state.src[pos] === \\\"\\\\\\\\\\\") { pos -= 1; }\\n\\n // Even number of escapes, potential closing delimiter found\\n if ( ((match - pos) % 2) == 1 ) { break; }\\n match += 2;\\n }\\n\\n // No closing delimter found. Consume $$ and continue.\\n if (match === -1) {\\n if (!silent) { state.pending += \\\"$$\\\"; }\\n state.pos = start;\\n return true;\\n }\\n\\n // Check if we have empty content, ie: $$$$. Do not parse.\\n if (match - start === 0) {\\n if (!silent) { state.pending += \\\"$$$$\\\"; }\\n state.pos = start + 2;\\n return true;\\n }\\n\\n if (!silent) {\\n token = state.push('math_inline_block', '$latex', 0);\\n token.block = true;\\n token.markup = \\\"$$\\\";\\n token.content = state.src.slice(start, match);\\n token.attrs = [[\\\"displayMode\\\", \\\"true\\\"], [\\\"text\\\", token.content]];\\n }\\n\\n state.pos = match + 2;\\n return true;\\n}\\n\\nmodule.exports = function math_plugin(md, options) {\\n md.inline.ruler.after('escape', 'math_inline', math_inline);\\n md.inline.ruler.after('escape', 'math_inline_block', math_inline_block);\\n};\\n})();\",\"type\":\"application/javascript\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/markdown-it-tiddlywiki.js\":{\"title\":\"$:/plugins/tiddlywiki/markdown/markdown-it-tiddlywiki.js\",\"text\":\"/*\\\\\\ntitle: $:/plugins/tiddlywiki/markdown/markdown-it-tiddlywiki.js\\ntype: application/javascript\\nmodule-type: library\\n\\nWraps up the markdown-it parser for use as a Parser in TiddlyWiki\\n\\n\\\\*/\\n(function(){\\n\\n/*jslint node: true, browser: true */\\n/*global $tw: false */\\n\\\"use strict\\\";\\n\\nvar md;\\nvar pluginOpts;\\n\\nvar TWMarkReplacements = {\\n\\t\\\"{\\\" : \\\"{\\\",\\n\\t\\\"[\\\" : \\\"[\\\",\\n\\t\\\"$\\\" : \\\"$\\\"\\n};\\n\\nvar TWMarkRegEx = /[{[$]/g;\\nfunction encodeTWMark(match) {\\n\\treturn TWMarkReplacements[match];\\n}\\n\\n// escpae {, [ and $ in string s\\nfunction escapeTWMarks(s) {\\n\\ts = String(s);\\n\\tTWMarkRegEx.lastIndex = 0;\\n\\treturn s.replace(TWMarkRegEx,encodeTWMark);\\n}\\n\\n// escape anything that could be interpreted as transclusion or syslink\\nfunction render_code_inline(tokens,idx,options,env,slf) {\\n\\ttokens[idx].attrJoin('class','_codified_');\\n\\treturn '\u003Ccode' + slf.renderAttrs(tokens[idx]) + '>'\\n\\t\\t+ escapeTWMarks(md.utils.escapeHtml(tokens[idx].content))\\n\\t\\t+ '\u003C/code>';\\n}\\n\\nfunction render_code_block(tokens,idx) {\\n\\treturn '\u003C$codeblock code=e\\\"' + md.utils.escapeHtml(tokens[idx].content) + '\\\" language=\\\"\\\"/>\\\\n';\\n}\\n\\nfunction render_fence(tokens,idx) {\\n\\tvar info = tokens[idx].info ? md.utils.unescapeAll(tokens[idx].info).trim() : '';\\n\\treturn '\u003C$codeblock code=e\\\"' + md.utils.escapeHtml(tokens[idx].content) + '\\\" language=\\\"' + info.split(/(\\\\s+)/g)[0] + '\\\"/>\\\\n';\\n}\\n\\n// add a blank line after opening tag to activate TW block parsing\\nfunction render_paragraph_open(tokens,idx) {\\n\\treturn tokens[idx].hidden ? '' : '\u003Cp>\\\\n\\\\n';\\n}\\n\\nfunction render_paragraph_close(tokens,idx) {\\n\\treturn tokens[idx].hidden ? '' : '\\\\n\u003C/p>\\\\n';\\n}\\n\\n// Replace footnote links with \\\"qualified\\\" internal links\\nfunction render_footnote_ref(tokens,idx,options,env,slf) {\\n\\tvar id = slf.rules.footnote_anchor_name(tokens,idx,options,env,slf);\\n\\tvar caption = slf.rules.footnote_caption(tokens,idx,options,env,slf);\\n\\tvar refid = id;\\n\\n\\tif(tokens[idx].meta.subId > 0) {\\n\\t\\trefid += ':' + tokens[idx].meta.subId;\\n\\t}\\n\\treturn '\u003Ca class=\\\"footnote-ref\\\" href=\u003C\u003Cqualify \\\"##fn' + id + '\\\">> id=\u003C\u003Cqualify \\\"#fnref' + refid + '\\\">>>' + caption + '\u003C/a>';\\n}\\n\\nfunction render_footnote_open(tokens,idx,options,env,slf) {\\n\\tvar id = slf.rules.footnote_anchor_name(tokens,idx,options,env,slf);\\n\\n\\tif(tokens[idx].meta.subId > 0) {\\n\\t\\tid += ':' + tokens[idx].meta.subId;\\n\\t}\\n\\treturn '\u003Cli id=\u003C\u003Cqualify \\\"#fn' + id + '\\\">> class=\\\"footnote-item\\\">';\\n}\\n\\nfunction render_footnote_anchor(tokens,idx,options,env,slf) {\\n\\tvar id = slf.rules.footnote_anchor_name(tokens,idx,options,env,slf);\\n\\n\\tif(tokens[idx].meta.subId > 0) {\\n\\t\\tid += ':' + tokens[idx].meta.subId;\\n\\t}\\n\\n\\t// append variation selector to prevent display as Apple Emoji on iOS\\n\\treturn '\u003Ca href=\u003C\u003Cqualify \\\"##fnref' + id + '\\\">> class=\\\"footnote-backref\\\">\\\\u21A5\\\\uFE0E\u003C/a>';\\n}\\n\\n// do not un-escape html entities and escape characters\\nfunction render_text_special(tokens,idx) {\\n\\tif(tokens[idx].info === 'entity') {\\n\\t\\treturn tokens[idx].markup;\\n\\t}\\n\\treturn escapeTWMarks(md.utils.escapeHtml(tokens[idx].content));\\n}\\n\\nfunction render_tw_expr(tokens,idx) {\\n\\treturn tokens[idx].content;\\n}\\n\\n// Overwrite default: attribute values can be either a string or {type;, value:}.\\n// 1) string attr val: render in e\\\"...\\\" format so HTML entities can be decoded.\\n// 2) object attr val: render value as is.\\nfunction render_token_attrs(token) {\\n\\tvar i, l, result;\\n\\n\\tif(!token.attrs) { return ''; }\\n\\n\\tresult = '';\\n\\n\\tfor(i=0, l=token.attrs.length; i\u003Cl; i++) {\\n\\t\\tif(typeof token.attrs[i][1] === \\\"object\\\" && token.attrs[i][1] !== null) {\\n\\t\\t\\tresult += ' ' + md.utils.escapeHtml(token.attrs[i][0]) + '=' + token.attrs[i][1].value;\\n\\t\\t} else {\\n\\t\\t\\tresult += ' ' + md.utils.escapeHtml(token.attrs[i][0]) + '=e\\\"' + md.utils.escapeHtml(token.attrs[i][1]) + '\\\"';\\n\\t\\t}\\n\\t}\\n\\n\\treturn result;\\n}\\n\\n// given tw parsing rule and starting pos, returns match index or undefined\\n// assumes pos >= 0\\nfunction findNextMatch(ruleinfo,pos) {\\n\\t// ruleinfo.matchIndex needs to be -1 at the start of inline state\\n\\tif(ruleinfo.matchIndex \u003C pos) {\\n\\t\\truleinfo.matchIndex = ruleinfo.rule.findNextMatch(pos);\\n\\t}\\n\\n\\treturn ruleinfo.matchIndex;\\n}\\n\\n// Add inline rule \\\"macrocall\\\" to parse \u003C\u003Cmacroname ...>>\\nvar MacroCallRegEx = /\u003C\u003C([^\\\\s>\\\"'=]+)[^>]*>>/g;\\nfunction tw_macrocallinline(state,silent) {\\n\\tvar match, max, pos = state.pos;\\n\\n\\t// Check start\\n\\tmax = state.posMax;\\n\\tif(state.src.charCodeAt(pos) !== 0x3C || state.src.charCodeAt(pos+1) !== 0x3C /* \u003C\u003C */|| pos + 3 >= max) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tMacroCallRegEx.lastIndex = pos;\\n\\tmatch = MacroCallRegEx.exec(state.src);\\n\\tif(!match || match.index !== pos) { return false; }\\n\\n\\tif(!silent) {\\n\\t\\tvar token = state.push('tw_expr','',0);\\n\\t\\ttoken.content = state.src.slice(pos,pos+match[0].length);\\n\\t}\\n\\tstate.pos = MacroCallRegEx.lastIndex;\\n\\treturn true;\\n}\\n\\n// parse transclusion elements\\nfunction tw_transcludeinline(state,silent) {\\n\\tvar ruleinfo = pluginOpts.inlineRules.transcludeinline;\\n\\n\\tvar pos = state.pos;\\n\\tvar matchIndex = findNextMatch(ruleinfo,pos);\\n\\tif(matchIndex === undefined || matchIndex !== pos) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tif(!silent) {\\n\\t\\tvar token = state.push('tw_expr','',0);\\n\\t\\ttoken.content = state.src.slice(pos,pos+ruleinfo.rule.match[0].length);\\n\\t}\\n\\tstate.pos += ruleinfo.rule.match[0].length;\\n\\treturn true;\\n}\\n\\n// parse filtered transclusion elements\\nfunction tw_filteredtranscludeinline(state,silent) {\\n\\tvar ruleinfo = pluginOpts.inlineRules.filteredtranscludeinline;\\n\\n\\tvar pos = state.pos;\\n\\tvar matchIndex = findNextMatch(ruleinfo,pos);\\n\\tif(matchIndex === undefined || matchIndex !== pos) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tif(!silent) {\\n\\t\\tvar token = state.push('tw_expr','',0);\\n\\t\\tif(state.linkLevel > 0) {\\n\\t\\t\\tvar filter = ruleinfo.rule.match[1];\\n\\t\\t\\ttoken.content = '\u003C$text text={{{' + filter + '}}}/>';\\n\\t\\t} else {\\n\\t\\t\\ttoken.content = state.src.slice(pos,pos+ruleinfo.rule.match[0].length);\\n\\t\\t}\\n\\t}\\n\\tstate.pos += ruleinfo.rule.match[0].length;\\n\\treturn true;\\n}\\n\\n// based on markdown-it html_block()\\nvar WidgetTagRegEx = [/^\u003C\\\\/?\\\\$[a-zA-Z0-9\\\\-\\\\$]+(?=(\\\\s|\\\\/?>|$))/, /^$/];\\nfunction tw_block(state,startLine,endLine,silent) {\\n\\tvar i, nextLine, token, lineText,\\n\\t\\tpos = state.bMarks[startLine] + state.tShift[startLine],\\n\\t\\tmax = state.eMarks[startLine];\\n\\n\\t// if it's indented more than 3 spaces, it should be a code block\\n\\tif(state.sCount[startLine] - state.blkIndent >= 4) { return false; }\\n\\n\\tif(!state.md.options.html) { return false; }\\n\\n\\tif(state.src.charCodeAt(pos) !== 0x3C/* \u003C */) { return false; }\\n\\n\\tlineText = state.src.slice(pos,max);\\n\\n\\tif(!WidgetTagRegEx[0].test(lineText)) { return false; }\\n\\n\\tif(silent) {\\n\\t\\t// don't let widgets interrupt a paragrpah\\n\\t\\treturn false;\\n\\t}\\n\\n\\tnextLine = startLine + 1;\\n\\n\\t// If we are here - we detected HTML block.\\n\\t// Let's roll down till block end.\\n\\tif(!WidgetTagRegEx[1].test(lineText)) {\\n\\t\\tfor(; nextLine \u003C endLine; nextLine++) {\\n\\t\\t\\tif(state.sCount[nextLine] \u003C state.blkIndent) { break; }\\n\\n\\t\\t\\tpos = state.bMarks[nextLine] + state.tShift[nextLine];\\n\\t\\t\\tmax = state.eMarks[nextLine];\\n\\t\\t\\tlineText = state.src.slice(pos,max);\\n\\n\\t\\t\\tif(WidgetTagRegEx[1].test(lineText)) {\\n\\t\\t\\t\\tif(lineText.length !== 0) { nextLine++; }\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\tstate.line = nextLine;\\n\\n\\ttoken = state.push('html_block','',0);\\n\\ttoken.map = [ startLine, nextLine ];\\n\\ttoken.content = state.getLines(startLine,nextLine,state.blkIndent,true);\\n\\n\\treturn true;\\n}\\n\\n// parse [img[...]] elements\\nfunction tw_image(state,silent) {\\n\\tvar ruleinfo = pluginOpts.inlineRules.image;\\n\\n\\t// ignore at parseLinkLabel stage; will be recognized in tokenize()\\n\\tif(state.parsingLinkLabel > 0) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tvar pos = state.pos;\\n\\tvar matchIndex = findNextMatch(ruleinfo,pos);\\n\\tif(matchIndex === undefined || matchIndex !== pos) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tif(!silent) {\\n\\t\\tvar twNode = ruleinfo.rule.parse()[0];\\n\\t\\tvar token = state.push('$image','$image',0);\\n\\t\\t$tw.utils.each(twNode.attributes,function(attr,id) {\\n\\t\\t\\tswitch(attr.type) {\\n\\t\\t\\t\\tcase \\\"filtered\\\":\\n\\t\\t\\t\\t\\ttoken.attrSet(id,{ type: \\\"filtered\\\", value: \\\"{{{\\\" + attr.filter + \\\"}}}\\\" });\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\tcase \\\"indirect\\\":\\n\\t\\t\\t\\t\\ttoken.attrSet(id,{ type: \\\"indirect\\\", value: \\\"{{\\\" + attr.textReference + \\\"}}\\\" });\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\tcase \\\"macro\\\":\\n\\t\\t\\t\\t\\ttoken.attrSet(id,{ type: \\\"macro\\\", value: ruleinfo.rule.parser.source.substring(attr.value.start,attr.value.end) });\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\tdefault:\\n\\t\\t\\t\\t\\ttoken.attrSet(id,attr.value);\\n\\t\\t\\t}\\n\\t\\t});\\n\\t\\ttoken.markup = 'tw_image';\\n\\t}\\n\\tstate.pos = ruleinfo.rule.parser.pos;\\n\\treturn true;\\n}\\n\\n// parse [[link]] elements\\nfunction tw_prettylink(state,silent) {\\n\\tvar ruleinfo = pluginOpts.inlineRules.prettylink;\\n\\n\\t// skip if in link label\\n\\tif(state.linkLevel > 0 || state.parsingLinkLabel > 0) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tvar pos = state.pos;\\n\\tvar matchIndex = findNextMatch(ruleinfo,pos);\\n\\tif(matchIndex === undefined || matchIndex !== pos) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tif(!silent) {\\n\\t\\tvar twNode = ruleinfo.rule.parse()[0];\\n\\t\\tvar tag = (twNode.type==='link' ? '$link' : 'a');\\n\\t\\t// push a link_open token so markdown's core.linkify will ignore\\n\\t\\tvar token = state.push('link_open',tag,1);\\n\\n\\t\\t$tw.utils.each(twNode.attributes,function(attr,id) {\\n\\t\\t\\ttoken.attrSet(id,attr.value);\\n\\t\\t});\\n\\t\\ttoken.attrJoin('class','_codified_');\\n\\t\\ttoken.markup = 'tw_prettylink';\\n\\n\\t\\tstate.linkLevel++;\\n\\t\\ttoken = state.push('text','',0);\\n\\t\\ttoken.content = twNode.children[0].text;\\n\\t\\tstate.linkLevel--;\\n\\n\\t\\ttoken = state.push('link_close',tag,-1);\\n\\t\\ttoken.markup = 'tw_prettylink';\\n\\t}\\n\\tstate.pos = ruleinfo.rule.parser.pos;\\n\\treturn true;\\n}\\n\\nfunction tw_prettyextlink(state,silent) {\\n\\tvar ruleinfo = pluginOpts.inlineRules.prettyextlink;\\n\\n\\t// skip if in link label\\n\\tif(state.linkLevel > 0 || state.parsingLinkLabel > 0) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tvar pos = state.pos;\\n\\tvar matchIndex = findNextMatch(ruleinfo,pos);\\n\\tif(matchIndex === undefined || matchIndex !== pos) {\\n\\t\\treturn false;\\n\\t}\\n\\n\\tif(!silent) {\\n\\t\\tvar twNode = ruleinfo.rule.parse()[0];\\n\\t\\tvar token = state.push('link_open','a',1);\\n\\n\\t\\t$tw.utils.each(twNode.attributes,function(attr,id) {\\n\\t\\t\\ttoken.attrSet(id,attr.value);\\n\\t\\t});\\n\\t\\ttoken.attrJoin('class','_codified_');\\n\\t\\ttoken.markup = 'tw_prettyextlink';\\n\\n\\t\\tstate.linkLevel++;\\n\\t\\ttoken = state.push('text','',0);\\n\\t\\ttoken.content = twNode.children[0].text;\\n\\t\\tstate.linkLevel--;\\n\\n\\t\\ttoken = state.push('link_close','a',-1);\\n\\t\\ttoken.markup = 'tw_prettyextlink';\\n\\t}\\n\\tstate.pos = ruleinfo.rule.parser.pos;\\n\\treturn true;\\n}\\n\\nvar TWCloseTagRegEx = /\u003C\\\\/\\\\$[A-Za-z0-9\\\\-\\\\$]+\\\\s*>/gm;\\nfunction extendHtmlInline(origRule) {\\n\\treturn function(state,silent) {\\n\\t\\tif(origRule(state,silent)) {\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\n\\t\\tvar token, pos = state.pos;\\n\\t\\tvar parseTag = $tw.Wiki.parsers['text/vnd.tiddlywiki'].prototype.inlineRuleClasses.html.prototype.parseTag;\\n\\t\\tvar tag = parseTag(state.src,pos,{});\\n\\t\\tif(tag) {\\n\\t\\t\\tif(!silent) {\\n\\t\\t\\t\\ttoken = state.push('html_inline','',0);\\n\\t\\t\\t\\ttoken.content = state.src.slice(pos,tag.end);\\n\\t\\t\\t}\\n\\t\\t\\tstate.pos = tag.end;\\n\\t\\t\\treturn true;\\n\\t\\t}\\n\\n\\t\\tTWCloseTagRegEx.lastIndex = pos;\\n\\t\\tvar match = TWCloseTagRegEx.exec(state.src);\\n\\t\\tif(!match || match.index !== pos) {\\n\\t\\t\\treturn false;\\n\\t\\t}\\n\\n\\t\\tif(!silent) {\\n\\t\\t\\ttoken = state.push('html_inline','',0);\\n\\t\\t\\ttoken.content = state.src.slice(pos,pos + match[0].length);\\n\\t\\t}\\n\\t\\tstate.pos = TWCloseTagRegEx.lastIndex;\\n\\t\\treturn true;\\n\\t};\\n}\\n\\nfunction extendParseLinkLabel(origFunc) {\\n\\treturn function(state,start,disableNested) {\\n\\t\\tif(state.parsingLinkLabel === undefined) {\\n\\t\\t\\tstate.parsingLinkLabel = 0;\\n\\t\\t}\\n\\t\\tstate.parsingLinkLabel++;\\n\\t\\tvar labelEnd = origFunc(state,start,disableNested);\\n\\t\\tstate.parsingLinkLabel--;\\n\\t\\treturn labelEnd;\\n\\t};\\n}\\n\\n// reset each tw inline rule to initial inline state\\nfunction extendInlineParse(thisArg,origFunc,twInlineRules) {\\n\\treturn function(str,md,env,outTokens) {\\n\\t\\tvar i, ruleinfo, key;\\n\\t\\tfor(key in twInlineRules) {\\n\\t\\t\\truleinfo = twInlineRules[key];\\n\\t\\t\\truleinfo.rule.parser.source = str;\\n\\t\\t\\truleinfo.rule.parser.sourceLength = str.length;\\n\\t\\t\\truleinfo.rule.parser.pos = 0; // not used\\n\\t\\t\\truleinfo.matchIndex = -1;\\n\\t\\t}\\n\\t\\torigFunc.call(thisArg,str,md,env,outTokens);\\n\\t}\\n}\\n\\n/// post processing ///\\n\\nfunction wikify(state) {\\n\\tvar href, title, src, alt;\\n\\tvar tagStack = [];\\n\\n\\tstate.tokens.forEach(function(blockToken) {\\n\\t\\tif(blockToken.type === 'inline' && blockToken.children) {\\n\\t\\t\\tblockToken.children.forEach(function(token) {\\n\\t\\t\\t\\tswitch(token.type) {\\n\\t\\t\\t\\tcase 'link_open':\\n\\t\\t\\t\\t\\tif(token.markup === 'tw_prettylink' || token.markup === 'tw_prettyextlink') {\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\thref = token.attrGet('href');\\n\\t\\t\\t\\t\\tif(href[0] === '#') {\\n\\t\\t\\t\\t\\t\\ttoken.tag = '$link';\\n\\t\\t\\t\\t\\t\\thref = $tw.utils.decodeURIComponentSafe(href.substring(1));\\n\\t\\t\\t\\t\\t\\ttitle = token.attrGet('title');\\n\\t\\t\\t\\t\\t\\ttoken.attrs = [['to', href], ['class', '_codified_']];\\n\\t\\t\\t\\t\\t\\tif(title) {\\n\\t\\t\\t\\t\\t\\t\\ttoken.attrSet('tooltip',title);\\n\\t\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\t} else {\\n\\t\\t\\t\\t\\t\\ttoken.attrSet('target','_blank');\\n\\t\\t\\t\\t\\t\\ttoken.attrJoin('class','tc-tiddlylink-external');\\n\\t\\t\\t\\t\\t\\ttoken.attrJoin('class','_codified_');\\n\\t\\t\\t\\t\\t\\ttoken.attrSet('rel','noopener noreferrer');\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\ttagStack.push(token.tag);\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\tcase 'link_close':\\n\\t\\t\\t\\t\\tif(token.markup === 'tw_prettylink' || token.markup === 'tw_prettyextlink') {\\n\\t\\t\\t\\t\\t\\treturn;\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\ttoken.tag = tagStack.pop();\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\tcase 'image':\\n\\t\\t\\t\\t\\ttoken.tag = '$image';\\n\\t\\t\\t\\t\\tsrc = token.attrGet('src');\\n\\t\\t\\t\\t\\talt = token.attrGet('alt');\\n\\t\\t\\t\\t\\ttitle = token.attrGet('title');\\n\\n\\t\\t\\t\\t\\ttoken.attrs[token.attrIndex('src')][0] = 'source';\\n\\t\\t\\t\\t\\tif(src[0] === '#') {\\n\\t\\t\\t\\t\\t\\tsrc = $tw.utils.decodeURIComponentSafe(src.substring(1));\\n\\t\\t\\t\\t\\t\\ttoken.attrSet('source',src);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\tif(title) {\\n\\t\\t\\t\\t\\t\\ttoken.attrs[token.attrIndex('title')][0] = 'tooltip';\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t\\tbreak;\\n\\t\\t\\t\\t}\\n\\t\\t\\t});\\n\\t\\t}\\n\\t});\\n}\\n\\nmodule.exports = function tiddlyWikiPlugin(markdown,options) {\\n\\tvar defaults = {\\n\\t\\trenderWikiText: false,\\n\\t\\tblockRules: {},\\n\\t\\tinlineRules: {}\\n\\t};\\n\\n\\tmd = markdown;\\n\\tpluginOpts = md.utils.assign({},defaults,options||{});\\n\\n\\tmd.renderer.rules.code_inline = render_code_inline;\\n\\tmd.renderer.rules.code_block = render_code_block;\\n\\tmd.renderer.rules.fence = render_fence;\\n\\tmd.renderer.rules.paragraph_open = render_paragraph_open;\\n\\tmd.renderer.rules.paragraph_close = render_paragraph_close;\\n\\tmd.renderer.rules.footnote_ref = render_footnote_ref;\\n\\tmd.renderer.rules.footnote_open = render_footnote_open;\\n\\tmd.renderer.rules.footnote_anchor = render_footnote_anchor;\\n\\tmd.renderer.rules.text_special = render_text_special;\\n\\tmd.renderer.rules.tw_expr = render_tw_expr;\\n\\tmd.renderer.renderAttrs = render_token_attrs;\\n\\n\\tif(pluginOpts.renderWikiText) {\\n\\t\\tmd.helpers.parseLinkLabel = extendParseLinkLabel(md.helpers.parseLinkLabel);\\n\\n\\t\\tif(pluginOpts.inlineRules.image) {\\n\\t\\t\\tmd.inline.ruler.after('link','tw_image',tw_image);\\n\\t\\t}\\n\\t\\tif(pluginOpts.inlineRules.prettyextlink) {\\n\\t\\t\\tmd.inline.ruler.after('link','tw_prettyextlink',tw_prettyextlink);\\n\\t\\t}\\n\\t\\tif(pluginOpts.inlineRules.prettylink) {\\n\\t\\t\\tmd.inline.ruler.after('link','tw_prettylink',tw_prettylink);\\n\\t\\t}\\n\\t\\tif(pluginOpts.inlineRules.filteredtranscludeinline) {\\n\\t\\t\\tmd.inline.ruler.before('html_inline','tw_filteredtranscludeinline',tw_filteredtranscludeinline);\\n\\t\\t}\\n\\t\\tif(pluginOpts.inlineRules.transcludeinline) {\\n\\t\\t\\tmd.inline.ruler.before('html_inline','tw_transcludeinline',tw_transcludeinline);\\n\\t\\t}\\n\\n\\t\\tmd.inline.ruler.before('html_inline','tw_macrocallinline',tw_macrocallinline);\\n\\t\\tmd.inline.ruler.at('html_inline',extendHtmlInline(md.inline.ruler.__rules__[md.inline.ruler.__find__('html_inline')].fn));\\n\\t\\tmd.block.ruler.after('html_block','tw_block',tw_block,{\\n\\t\\t\\talt: [ 'paragraph', 'reference', 'blockquote' ]\\n\\t\\t});\\n\\t\\tmd.inline.parse = extendInlineParse(md.inline,md.inline.parse,options.inlineRules);\\n\\t}\\n\\n\\tmd.core.ruler.disable('text_join');\\n\\tmd.core.ruler.push('wikify',wikify);\\n};\\n\\n})();\\n\",\"type\":\"application/javascript\",\"module-type\":\"library\"},\"$:/plugins/tiddlywiki/markdown/new-markdown-button\":{\"title\":\"$:/plugins/tiddlywiki/markdown/new-markdown-button\",\"tags\":\"$:/tags/PageControls\",\"caption\":\"{{$:/plugins/tiddlywiki/markdown/images/new-markdown-button}} {{$:/language/Buttons/NewMarkdown/Caption}}\",\"description\":\"{{$:/language/Buttons/NewMarkdown/Hint}}\",\"list-after\":\"$:/core/ui/Buttons/new-tiddler\",\"text\":\"\\\\whitespace trim\\n\u003C$button tooltip={{$:/language/Buttons/NewMarkdown/Hint}} aria-label={{$:/language/Buttons/NewMarkdown/Caption}} class=\u003C\u003Ctv-config-toolbar-class>>>\\n\u003C$action-sendmessage $message=\\\"tm-new-tiddler\\\" type=\\\"text/markdown\\\"/>\\n\u003C$list filter=\\\"[\u003Ctv-config-toolbar-icons>match[yes]]\\\">\\n{{$:/plugins/tiddlywiki/markdown/images/new-markdown-button}}\\n\u003C/$list>\\n\u003C$list filter=\\\"[\u003Ctv-config-toolbar-text>match[yes]]\\\">\\n\u003Cspan class=\\\"tc-btn-text\\\">\u003C$text text={{$:/language/Buttons/NewMarkdown/Caption}}/>\u003C/span>\\n\u003C/$list>\\n\u003C/$button>\\n\"},\"$:/plugins/tiddlywiki/markdown/readme\":{\"title\":\"$:/plugins/tiddlywiki/markdown/readme\",\"text\":\"This plugin provides Markdown support via the [[markdown-it|https://github.com/markdown-it/markdown-it]] parser and its associated plugins:\\n\\n* markdown-it-deflist\\n* markdown-it-footnote\\n* markdown-it-ins\\n* markdown-it-mark\\n* markdown-it-sub\\n* markdown-it-sup\\n\\n!! Compatibility Notes\\n\\n* \u003Cp>A tab character in Markdown has a size of four spaces. Configure the tab size of your code editor accordingly. For example, if you use \u003C$text text=\\\"CodeMirror\\\"/>, it is recommended that you set $:/config/codemirror/indentUnit and $:/config/codemirror/tabSize to `4` to avoid inconsistent indentations.\u003C/p>\\n* \u003Cp>HTML blocks are ultimately parsed by the \u003C$text text=WikiText/> parser: //an opening tag followed by a blank line will activate block-level parsing for its content//. When working with tags designed to contain literal content, such as `\u003Cpre>` and `\u003Cstyle>` tags, refrain from adding blank lines after the opening tags.\u003C/p>\\n* \u003Cp>You must terminate a table with either a blank line or another block-level structure.\u003C/p>\\n* \u003Cp>`latex-parser` in $:/config/markdown/renderWikiTextPragma is no longer required and will be ignored.\u003C/p>\\n* \u003Cp>Config option `linkNewWindow` is removed.\u003C/p>\\n\\n!! Extending the Parser\\n\\nYou can extend the parser by loading additional markdown-it plugins this way:\\n\\n```js\\nvar plugin1 = require(...);\\nvar plugin2 = require(...);\\n\\nvar md = $tw.Wiki.parsers[\\\"text/markdown\\\"].prototype.md;\\n\\nmd.use(plugin1)\\n .use(plugin2, opts, ...);\\n```\"},\"$:/plugins/tiddlywiki/markdown/styles\":{\"title\":\"$:/plugins/tiddlywiki/markdown/styles\",\"tags\":\"[[$:/tags/Stylesheet]]\",\"code-body\":\"yes\",\"text\":\".markdown {\\n\\tdisplay: block;\\n\\tmargin: 0px;\\n}\\n.markdown hr {\\n margin-top: 20px;\\n margin-bottom: 20px;\\n border: 0;\\n border-top: 1px solid \u003C\u003Ccolour muted-foreground>>;\\n}\\n.markdown .footnotes {\\n\\tfont-size: 0.9em;\\n\\tline-height: 1.32;\\n}\\n.markdown a.footnote-ref {\\n\\tcolor: \u003C\u003Ccolour tiddler-link-foreground>>;\\n\\tfont-size: 0.75em;\\n\\ttext-decoration: none;\\n\\tvertical-align: super;\\n\\tpadding:0px 1px;\\n}\\n.markdown ol.footnotes-list {\\n\\tpadding-left: 2em;\\n}\\n.markdown .footnote-item p {\\n\\tmargin: 0.7em 0px;\\n}\\n.markdown a.footnote-backref {\\n\\tcolor: \u003C\u003Ccolour tiddler-link-foreground>>;\\n\\tfont-size: 0.8em;\\n\\ttext-decoration: none;\\n\\tmargin-left: 0.25em;\\n}\\n.markdown a.footnote-ref:target, .markdown .footnote-item:target {\\n\\tbackground-color: \u003C\u003Ccolour message-background>>;\\n\\tscroll-margin-top: {{{ [{$:/themes/tiddlywiki/vanilla/options/stickytitles}match[yes]then[120px]else[60px]] }}};\\n}\\n.markdown li > p:first-child {\\n\\tmargin-top: 0px;\\n}\\n.markdown li + li {\\n\\tmargin-top: 2px;\\n}\\n.markdown mark {\\n\\tpadding: 1px 3px;\\n}\\n\"},\"$:/plugins/tiddlywiki/markdown/syntax\":{\"title\":\"$:/plugins/tiddlywiki/markdown/syntax\",\"text\":\"To review standard Markdown syntax, see: [ext[CommonMark quick reference|https://commonmark.org/help/]]. For formal specification, consult the [ext[CommonMark Spec|https://spec.commonmark.org/current/]].\\n\\n! Linking to Tiddlers\\n\\nPrepend `#` to tiddler titles to form link addresses. If a tiddler title contains spaces or other special characters, you must either (1) URI-encode the title, or (2) surround the #title with `\u003C` `>` and backslash-escape any `\u003C` or `>` in the title.\\n\\n!! Links\\n\\n\u003Cpre>\u003Ccode>[link text](\u003Cstrong>#\u003C/strong>\u003C$text text=\\\"TiddlerTitle\\\"/> \\\"optional tooltip\\\")\\n\\n[link text](\u003Cstrong>#\u003C/strong>New\u003Cstrong>%20\u003C/strong>Tiddler)\\n\\n[link text](\u003Cstrong><#\u003C/strong>New Tiddler\u003Cstrong>>\u003C/strong>)\\n\\n[](\u003Cstrong><#\u003C/strong>How to use \u003Cstrong>\\\\\u003C/strong><$list\u003Cstrong>\\\\\u003C/strong>> widget?\u003Cstrong>>\u003C/strong>)\\n\u003C/code>\u003C/pre>\\n\\nYou can also use the `\u003C$link>` widget to generate links to tiddlers:\\n\\n```\\n\u003C$link to=\\\"Tiddler Title\\\">Displayed Link Title\u003C/$link>\\n```\\n\\n!! Reference Style Links\\n\\n```\\n[link text][1]\\n[link text][2]\\n\\n[1]: #New%20Tiddler \\\"optional tooltip\\\"\\n\\n[2]: \u003C#Another Tiddler>\\n```\\n\\n!! Images\\n\\n```\\n![alt text](#Motovun%20Jack.jpg \\\"optional tooltip\\\")\\n\\n![alt text](\u003C#Motovun Jack.jpg>)\\n```\\n\\n! Escaping Special Characters\\n\\nMarkdown allows you to escape ASCII punctuation characters with `\\\\`.\\n\\n! HTML Blocks\\n\\nAn [[HTML block|https://spec.commonmark.org/0.30/#html-blocks]] is a group of lines that starts with an HTML tag and is treated as raw HTML. Block-level tags such as `\u003Cdiv>` and `\u003Cp>` can interrupt a paragraph. Inline elements such as `\u003Cstrong>` and `\u003Cem>` can start an HTML block if the //complete// tag begins on a new paragraph by itself. In most cases, an HTML block continues until a blank line is reached.\\n\\nA widget tag that begins on a new paragraph will also be treated as an HTML block. Markdown elements are not recognized inside the HTML block. For example:\\n\\n```\\nsee\\n\\n\u003C$link to=\\\"New Tiddler\\\">\\n_New_ Tiddler\\n\u003C/$link>\\n```\\n\\nrendered as:\\n\\n```\\n\u003Cp>see\u003C/p>\\n\u003C$link to=\\\"New Tiddler\\\">\\n_New_ Tiddler\\n\u003C/$link>\\n```\\n\\nA widget tag not preceded by a blank line is an inline element.\\n\\n```\\nsee\\n\u003C$link to=\\\"New Tiddler\\\">\\n_New_ Tiddler\\n\u003C/$link>\\n```\\n\\nrendered as:\\n\\n```\\n\u003Cp>see \u003C$link to=\\\"New Tiddler\\\">\u003Cem>New\u003C/em> Tiddler\u003C/$link>\u003C/p>\\n```\\n\\n! Syntax Extensions\\n\\n!! \u003C$text text=KaTeX/>\\n\\nYou need to install the \u003C$text text=KaTeX/> plugin to activate this syntax extension.\\n\\nSurround your math expression with `$` for inline rendering. Whitespace characters cannot immediately follow the opening `$` or precede the closing `$`, and the closing delimiter must not immediately precede a digit. Furthermore, `$` followed by `:/` will not be recognized as a valid opening or closing delimiter either.\\n\\nHere's an example of an inline math expression:\\n\\n```\\n$c = \\\\pm\\\\sqrt{a^2 + b^2}$\\n```\\n\\nUse `$$` to center the math in display mode:\\n\\n```\\n$$c = \\\\pm\\\\sqrt{a^2 + b^2}$$\\n```\\n\\n!! Superscript and Subscript\\n\\n```\\nX^2^\\n```\\nx\u003Csup>2\u003C/sup>\\n\\n```\\nH~2~O\\n```\\nH\u003Csub>2\u003C/sub>O\\n\\n!! Marked Text\\n\\n```\\n==marked text==\\n```\\n\\n\u003Cmark>marked text\u003C/mark>\\n\\n!! Strikethrough\\n\\n```\\n~~striked through text~~\\n```\\n\\n\u003Cs>striked through text\u003C/s>\\n\\n!! Inserted Text\\n\\n```\\n++inserted text++\\n```\\n\\n\u003Cins>inserted text\u003C/ins>\\n\\n!! Tables\\n\\nmarkdown-it supports \u003C$text text=\\\"GitHub Flavored Markdown\\\"/> (GFM) [ext[table syntax|https://github.github.com/gfm/#tables-extension-]].\\n\\n```\\n|Left Aligned |Centered |Right Aligned |\\n|:--- | :---: | ---:|\\n|apple |bat |candle |\\n```\\n\\n\u003Ctable>\\n\u003Cthead>\\n\u003Ctr>\u003Cth style=\\\"text-align:left\\\">Left Aligned\u003C/th>\u003Cth style=\\\"text-align:center\\\">Centered\u003C/th>\u003Cth style=\\\"text-align:right\\\">Right Aligned\u003C/th>\u003C/tr>\\n\u003C/thead>\\n\u003Ctbody>\\n\u003Ctr>\u003Ctd style=\\\"text-align:left\\\">apple\u003C/td>\u003Ctd style=\\\"text-align:center\\\">bat\u003C/td>\u003Ctd style=\\\"text-align:right\\\">candle\u003C/td>\u003C/tr>\\n\u003C/tbody>\\n\u003C/table>\\n\\n!! Definition Lists\\n\\n```\\nTerm One\\n: Definition with\\nlazy continuation.\\n\\nTerm Two\\n: Here is the first defintion.\\n\\n: Here is the second definition.\\n\\n As you can see. A definition can have\\n more than one paragrpah. It can also have\\n\\n And indended code block...\\n```\\n\\n\u003Cdl>\\n\u003Cdt>Term One\u003C/dt>\\n\u003Cdd>\u003Cp>Definition with\\nlazy continuation.\\n\u003C/p>\u003C/dd>\\n\u003Cdt>Term Two\u003C/dt>\\n\u003Cdd>\u003Cp>Here is the first defintion.\\n\u003C/p>\u003C/dd>\\n\u003Cdd>\u003Cp>Here is the second definition.\u003C/p>\u003Cp>As you can see. A definition can have\\nmore than one paragrpah. It can also have\\n\u003Cpre>\u003Ccode>And indended code block...\\n\u003C/code>\u003C/pre>\\n\u003C/p>\u003C/dd>\\n\u003C/dl>\\n\\n!! Footnotes\\n\\nFor detailed explanation, see [[Creating Footnotes|https://www.markdownguide.org/extended-syntax/#footnotes]].\\n\\n```\\nHere's a simple footnote,[^1] and here's a longer one.[^bignote]\\n\\n[^1]: This is the first footnote.\\n\\n[^bignote]: Here's one with multiple paragraphs and code.\\n\\n Indent paragraphs to include them in the footnote.\\n\\n `{ my code }`\\n\\n Add as many paragraphs as you like.\\n```\\n\\n\u003Cdiv class=\\\"markdown\\\">\u003Cp>Here’s a simple footnote,\u003Ca class=\\\"footnote-ref\\\" href=\\\"##fn1--doc639182\\\" id=\\\"#fnref1--doc639182\\\">[1]\u003C/a> and here’s a longer one.\u003Ca class=\\\"footnote-ref\\\" href=\\\"##fn2--doc639182\\\" id=\\\"#fnref2--doc639182\\\">[2]\u003C/a>\\n\u003Chr class=\\\"footnotes-sep\\\">\\n\u003Csection class=\\\"footnotes\\\">\\n\u003Col class=\\\"footnotes-list\\\">\\n\u003Cli id=\\\"#fn1--doc639182\\\" class=\\\"footnote-item\\\">\u003Cp>This is the first footnote. \u003Ca href=\\\"##fnref1--doc639182\\\" class=\\\"footnote-backref\\\">↥︎\u003C/a>\\n\u003C/p>\u003C/li>\\n\u003Cli id=\\\"#fn2--doc639182\\\" class=\\\"footnote-item\\\">\u003Cp>Here’s one with multiple paragraphs and code.\u003C/p>\u003Cp>Indent paragraphs to include them in the footnote.\u003C/p>\u003Cp>\u003Ccode class=\\\"codified\\\">{ my code }\u003C/code>\u003C/p>\u003Cp>Add as many paragraphs as you like. \u003Ca href=\\\"##fnref2--doc639182\\\" class=\\\"footnote-backref\\\">↥︎\u003C/a>\\n\u003C/p>\u003C/li>\\n\u003C/ol>\\n\u003C/section>\\n\u003C/p>\u003C/div>\"},\"$:/plugins/tiddlywiki/markdown/wrapper.js\":{\"title\":\"$:/plugins/tiddlywiki/markdown/wrapper.js\",\"text\":\"/*\\\\\\ntitle: $:/plugins/tiddlywiki/markdown/wrapper.js\\ntype: application/javascript\\nmodule-type: parser\\n\\nWraps up the markdown-it parser for use as a Parser in TiddlyWiki\\n\\n\\\\*/\\n(function(){\\n\\n/*jslint node: true, browser: true */\\n/*global $tw: false */\\n\\\"use strict\\\";\\n\\nvar MarkdownIt = require(\\\"./markdown-it\\\");\\n\\nfunction parseAsBoolean(tiddlerName) {\\n\\treturn $tw.wiki.getTiddlerText(tiddlerName,\\\"false\\\").trim().toLowerCase() === \\\"true\\\";\\n}\\n\\nvar pluginOpts = {\\n\\trenderWikiText: parseAsBoolean(\\\"$:/config/markdown/renderWikiText\\\"),\\n\\trenderWikiTextPragma: $tw.wiki.getTiddlerText(\\\"$:/config/markdown/renderWikiTextPragma\\\").trim()\\n};\\n\\nvar markdownOpts = {\\n\\thtml: true,\\n\\txhtmlOut: true,\\n\\tbreaks: parseAsBoolean(\\\"$:/config/markdown/breaks\\\"),\\n\\tquotes: $tw.wiki.getTiddlerText(\\\"$:/config/markdown/quotes\\\").trim(),\\n\\ttypographer: parseAsBoolean(\\\"$:/config/markdown/typographer\\\"),\\n\\tlinkify: parseAsBoolean(\\\"$:/config/markdown/linkify\\\")\\n};\\n\\n// Retrieve needed TW rule classes and instantiated rules\\nfunction setupWikiRules(pluginOptions) {\\n\\tvar results = {};\\n\\n\\tfunction collectAllRules(classes,type) {\\n\\t\\tvar rulesInfo = [], key,\\n\\t\\t\\tself = wikiParser;\\n\\t\\tfor(key in classes) {\\n\\t\\t\\t// instantiate the rule\\n\\t\\t\\tvar RuleClass = classes[key];\\n\\t\\t\\tvar rule = new RuleClass(self);\\n\\t\\t\\trule.name = key;\\n\\t\\t\\trule.class = RuleClass;\\n\\t\\t\\trule.is = {};\\n\\t\\t\\trule.is[type] = true;\\n\\t\\t\\trule.init(self);\\n\\n\\t\\t\\trulesInfo.push({\\n\\t\\t\\t\\trule: rule,\\n\\t\\t\\t\\tmatchIndex: -1\\n\\t\\t\\t});\\n\\t\\t};\\n\\t\\treturn rulesInfo;\\n\\t}\\n\\n\\tvar WikiParser = require(\\\"$:/core/modules/parsers/wikiparser/wikiparser.js\\\")[\\\"text/vnd.tiddlywiki\\\"];\\n\\n\\t// first pass: get all rule classes\\n\\tvar wikiParser = new WikiParser(null, '', {parseAsInline: true, wiki: $tw.wiki});\\n\\n\\t// restore all possible rules from each rule class\\n\\twikiParser.pragmaRules = collectAllRules(wikiParser.pragmaRuleClasses,'pragma');\\n\\twikiParser.blockRules = collectAllRules(wikiParser.blockRuleClasses,'block');\\n\\twikiParser.inlineRules = collectAllRules(wikiParser.inlineRuleClasses,'inline');\\n\\n\\tvar pragma = pluginOptions.renderWikiText\\n\\t\\t\\t? \\\"\\\\\\\\rules except latex-parser extlink\\\\n\\\" + pluginOptions.renderWikiTextPragma\\n\\t\\t\\t: \\\"\\\\\\\\rules only html entity commentinline commentblock\\\";\\n\\n\\twikiParser.pos = 0;\\n\\twikiParser.source = pragma;\\n\\twikiParser.sourceLength = pragma.length;\\n\\n\\t// second pass: remove uninterested rules based on \\\\rules pragma\\n\\twikiParser.parsePragmas();\\n\\n\\tresults.blockRules = {};\\n\\tresults.inlineRules = {}\\n\\tresults.blockRuleClasses = {};\\n\\tresults.inlineRuleClasses = {};\\n\\n\\t// save the rule sets for future markdown parsing\\n\\twikiParser.blockRules.forEach(function(ruleinfo) {\\n\\t\\tresults.blockRules[ruleinfo.rule.name] = ruleinfo;\\n\\t\\tresults.blockRuleClasses[ruleinfo.rule.name] = ruleinfo.rule.class;\\n\\t});\\n\\twikiParser.inlineRules.forEach(function(ruleinfo) {\\n\\t\\tresults.inlineRules[ruleinfo.rule.name] = ruleinfo;\\n\\t\\tresults.inlineRuleClasses[ruleinfo.rule.name] = ruleinfo.rule.class;\\n\\t});\\n\\treturn results;\\n}\\n\\n// Creates markdown-it parser\\nfunction createMarkdownEngine(markdownItOptions, pluginOptions) {\\n\\tvar md = new MarkdownIt(markdownItOptions)\\n\\t\\t\\t\\t.use(require(\\\"./markdown-it-sub\\\"))\\n\\t\\t\\t\\t.use(require(\\\"./markdown-it-sup\\\"))\\n\\t\\t\\t\\t.use(require(\\\"./markdown-it-ins\\\"))\\n\\t\\t\\t\\t.use(require(\\\"./markdown-it-mark\\\"))\\n\\t\\t\\t\\t.use(require(\\\"./markdown-it-footnote\\\"))\\n\\t\\t\\t\\t.use(require(\\\"./markdown-it-deflist\\\"));\\n\\n\\tvar results = setupWikiRules(pluginOptions);\\n\\n\\tMarkdownParser.prototype.blockRuleClasses = results.blockRuleClasses;\\n\\tMarkdownParser.prototype.blockRules = results.blockRules;\\n\\n\\tMarkdownParser.prototype.inlineRuleClasses = results.inlineRuleClasses;\\n\\tMarkdownParser.prototype.inlineRules = results.inlineRules;\\n\\n\\tif(pluginOptions.renderWikiText && $tw.modules.titles[\\\"$:/plugins/tiddlywiki/katex/katex.min.js\\\"]) {\\n\\t\\tmd.use(require(\\\"./markdown-it-katex\\\"));\\n\\t}\\n\\n\\tmd.use(require(\\\"./markdown-it-tiddlywiki\\\"),{\\n\\t\\t\\trenderWikiText: pluginOptions.renderWikiText,\\n\\t\\t\\tblockRules: results.blockRules,\\n\\t\\t\\tinlineRules: results.inlineRules\\n\\t\\t});\\n\\n\\t$tw.utils.each(['image','prettylink','prettyextlink'], function(rule) {\\n\\t\\tif(MarkdownParser.prototype.inlineRules[rule]) {\\n\\t\\t\\t// delegate to md; ignore the rule class in WikiParser\\n\\t\\t\\tdelete MarkdownParser.prototype.inlineRuleClasses[rule];\\n\\t\\t}\\n\\t});\\n\\treturn md;\\n}\\n\\n/// Parse tree post processing ///\\n\\nfunction deactivateLinks(tree) {\\n\\t$tw.utils.each(tree,function(node) {\\n\\t\\tif(node.type === \\\"link\\\") {\\n\\t\\t\\tnode.type = \\\"text\\\";\\n\\t\\t\\tnode.text = node.children[0].text;\\n\\t\\t\\tdelete node.attributes;\\n\\t\\t\\tdelete node.children;\\n\\t\\t\\tdelete node.attributes;\\n\\t\\t} else {\\n\\t\\t\\tdeactivateLinks(node.children);\\n\\t\\t}\\n\\t});\\n}\\n\\n// true if the node contains \\\"_codified_\\\" class attribute\\nfunction isCodified(node) {\\n\\treturn node.attributes\\n\\t\\t&& node.attributes.class\\n\\t\\t&& node.attributes.class.type === \\\"string\\\"\\n\\t\\t&& (node.attributes.class.value.split(\\\" \\\").indexOf(\\\"_codified_\\\") !== -1);\\n}\\n\\nfunction decodeEntities(s) {\\n\\treturn s.replace(/(&#?[a-zA-Z0-9]{2,8};)/g,$tw.utils.entityDecode);\\n}\\n\\n// Add e\\\"...\\\" and e'....' syntax to enable decoding of HTML entities\\n// in string literals.\\nfunction parseStringLiteralExtended(source,pos) {\\n\\tvar node = {\\n\\t\\ttype: \\\"string\\\",\\n\\t\\tstart: pos\\n\\t};\\n\\tvar reString = /(?:\\\"\\\"\\\"([\\\\s\\\\S]*?)\\\"\\\"\\\"|e?\\\"([^\\\"]*)\\\")|(?:e?'([^']*)')/g;\\n\\treString.lastIndex = pos;\\n\\tvar match = reString.exec(source);\\n\\tif(match && match.index === pos) {\\n\\t\\tnode.value = match[1] !== undefined ? match[1] :\\n\\t\\t\\t(match[2] !== undefined ? match[2] : match[3]);\\n\\t\\tnode.end = pos + match[0].length;\\n\\t\\tif(match[0].charAt(0) === \\\"e\\\") {\\n\\t\\t\\tnode.value = decodeEntities(node.value);\\n\\t\\t}\\n\\t\\treturn node;\\n\\t} else {\\n\\t\\treturn null;\\n\\t}\\n}\\n\\nfunction processWikiTree(tree,hasWikiLinkRule) {\\n\\tvar stack = [].concat(tree);\\n\\n\\tvar mergeable = function(node) {\\n\\t\\treturn node.type === \\\"element\\\" && node.tag === \\\"p\\\" && (!node.attributes || Object.keys(node.attributes).length === 0);\\n\\t};\\n\\n\\twhile(stack.length) {\\n\\t\\tvar node = stack.pop();\\n\\t\\tif(node.type === \\\"element\\\" && node.tag === \\\"p\\\") {\\n\\t\\t\\t// reduce nested \u003Cp> nodes\\n\\t\\t\\twhile(node.children && node.children.length === 1 && mergeable(node.children[0])) {\\n\\t\\t\\t\\tnode.children = node.children[0].children;\\n\\t\\t\\t}\\n\\t\\t} else if(hasWikiLinkRule && isCodified(node)) {\\n\\t\\t\\tdeactivateLinks(node.children);\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\t\\tif(node.children && node.children.length > 0) {\\n\\t\\t\\tstack.push.apply(stack,node.children);\\n\\t\\t}\\n\\t}\\n}\\n\\n// to extend MarkdownIt outside of this module, do:\\n//\\n// md = $tw.Wiki.parsers[\\\"text/markdown\\\"].prototype.md;\\n// md.use(plugin[, options]);\\nMarkdownParser.prototype.md = createMarkdownEngine(markdownOpts,pluginOpts);\\n\\nfunction MarkdownParser(type,text,options) {\\n\\tvar env = {}\\n\\tvar md = this.md;\\n\\tvar mdTree = md.parse(text,env);\\n\\tvar textToParse = '\u003Cdiv class=\\\"markdown\\\">\\\\n' + md.renderer.render(mdTree,md.options,env) + '\u003C/div>';\\n\\n\\t//console.log(JSON.stringify(mdTree,null,2));\\n\\t//console.log(\\\"\\\\n----------------\\\\n\\\" + textToParse);\\n\\n\\tvar wikiParser;\\n\\n\\tvar origParseStringLiteral = $tw.utils.parseStringLiteral;\\n\\t$tw.utils.parseStringLiteral = parseStringLiteralExtended;\\n\\n\\ttry {\\n\\t\\twikiParser = new $tw.Wiki.parsers[\\\"text/vnd.tiddlywiki\\\"](null,textToParse,{\\n\\t\\t\\tparseAsInline: true,\\n\\t\\t\\twiki: options.wiki,\\n\\t\\t\\trules: { pragma: {}, block: this.blockRuleClasses, inline: this.inlineRuleClasses }\\n\\t\\t});\\n\\t}\\n\\tcatch (err) {\\n\\t\\twikiParser = $tw.wiki.parseText(\\\"text/vnd.tiddlywiki\\\",\\n\\t\\t\\t\\\"\u003Cstrong>Error encountered while parsing the tiddler:\u003C/strong>\u003Cp>\\\" + err.message + \\\"\u003C/p>\\\",\\n\\t\\t\\t{parseAsInline: false, wiki: options.wiki});\\n\\t}\\n\\tfinally {\\n\\t\\t$tw.utils.parseStringLiteral = origParseStringLiteral;\\n\\t}\\n\\tif(wikiParser.tree.length > 0) {\\n\\t\\tvar hasWikiLinkRule = false;\\n\\t\\t// see if wikilink rule has been invoked\\n\\t\\t$tw.utils.each(wikiParser.inlineRules,function(ruleInfo) {\\n\\t\\t\\tif(ruleInfo.rule.name === \\\"wikilink\\\") {\\n\\t\\t\\t\\thasWikiLinkRule = true;\\n\\t\\t\\t\\treturn false;\\n\\t\\t\\t}\\n\\t\\t});\\n\\t\\tprocessWikiTree(wikiParser.tree,hasWikiLinkRule);\\n\\t}\\n\\tthis.tree = wikiParser.tree;\\n\\tthis.source = text;\\n\\tthis.type = type || \\\"text/markdown\\\";\\n\\tthis.wiki = options.wiki;\\n}\\n\\nexports[\\\"text/markdown\\\"] = MarkdownParser;\\nexports[\\\"text/x-markdown\\\"] = MarkdownParser;\\n})();\\n\",\"type\":\"application/javascript\",\"module-type\":\"parser\"}}}"}, -{"created":"20230423163535033","text":"\u003Cdiv style=\"height:240px\">\u003C/div>\nA tiny specification for controlling any 3D model using URLs\n{{$:/xrfragment/topmenu}}\n\u003C$action-setfield $tiddler=\"$:/state/sidebar\" text=“no” />","title":"$:/SiteSubtitle","modified":"20250509105637757","tags":"$:/tags/StartupAction"}, +{"created":"20230423163535033","text":"\u003Cdiv style=\"height:240px\">\u003C/div>\nA cute standard for (deep)linking 3D files via URI's.\n{{$:/xrfragment/topmenu}}\n\u003C$action-setfield $tiddler=\"$:/state/sidebar\" text=“no” />","title":"$:/SiteSubtitle","modified":"20250919161633137","tags":"$:/tags/StartupAction"}, {"created":"20230423163524355","title":"$:/SiteTitle","text":"XR Fragments","modified":"20230428121135697"}, {"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":"20250909115846815"}, -{"created":"20230423163641722","title":"$:/state/notebook-sidebar-section","text":"Home","modified":"20250910101332717"}, +{"created":"20230423163640468","title":"$:/state/notebook-sidebar","text":"yes","modified":"20250919155642667"}, +{"created":"20230423163641722","title":"$:/state/notebook-sidebar-section","text":"Home","modified":"20250919161641903"}, {"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"}, @@ -1107,7 +1107,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":"no","modified":"20250207145432476"}, -{"created":"20230504174435745","title":"$:/state/sidebar","text":"“no”","modified":"20250909115844062"}, +{"created":"20230504174435745","title":"$:/state/sidebar","text":"“no”","modified":"20250919155640222"}, {"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"}, @@ -1168,7 +1168,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"}, -{"title":"$:/StoryList","created":"20250909115853051","text":"","list":"[[XR Fragments]]","modified":"20250910101253259"}, +{"title":"$:/StoryList","created":"20250919155653904","text":"","list":"[[XR Fragments]]","modified":"20250919161530266"}, {"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"}, @@ -1206,7 +1206,7 @@ button.sidebar-toggle{ {"modified":"20240208125340120","title":"Draft of 'XR Fragments'"}, {"created":"20240731153010378","text":"\n[Create a button](#create%20a%20teleport%20button), but add the following metadata for HTTP-links:\n\n## dynamic 3D file via HTTP backend\n\n1. add to your button the metadata `href`:`https://yourserver.io/latest.glb`\n2. make your server programmatically return a 3D file when `latest.glb` is requested\n\n> Please refer to your backend/framework documentation on how to serve a (binary) file.\n\nThis allows for flexible server-controllable URLs inside a model. Keep in mind that this obviously reduces the portability of the model, which may (not) be a problem depending on the usecase.\n\n## webserver-backend redirect\n\n1. add to your button the metadata `href`:`https://yourserver.io/a?b`\n2. make your server return `Location: /final/link/here` based on `a` or `?b`, together with statuscode 302 (=temporary redirect).\n\n> Please refer to your server documentation on how to do a 302 redirect.\n\nThis allows for flexible server-controllable URLs inside a model. Keep in mind that this obviously reduces the portability of the model, which may (not) be a problem depending on the usecase.\n\n#### nginx static redirect\n\n```\nlocation ~ /a\\?b$ {\n return 302 https://foobar.com;\n}\n```\n\n#### apache static redirect\n\n```\nRewriteEngine On\nRewriteCond %{QUERY_STRING} ^a?b$\nRewriteRule ^(.*)$ https://foobar.com? [R=302,L]\n```\n","tags":"howto","title":"dynamic scenes via server","modified":"20250902142634725","type":"text/markdown"}, {"created":"20250905132936742","text":"There are loads of 3D editors and 3D file formats out there.\u003Cbr>\nFor maximum interoperability the [glTF](https://khronos.org/glTF) (`.glb` and `.gltf`) is suggested as fileformat.\u003Cbr>\nFor editors the following [FOSS](https://wikipedia.org/FOSS) (free) 3D editors are suggested for importing/exporting glTF files:\n\u003Cbr>\n* [ThreeJS editor](https://threejs.org/editor/) #web\n* [Blender](https://blender.org) #desktop\n* [Godot](https://godot.org) #desktop #web \n","tags":"howto","title":"Edit a 3D scene file","modified":"20250905133331695","type":"text/markdown"}, -{"created":"20240223092012710","text":"Create an empty mesh object (in Blender it's called an 'Empty') and add an [[src]] custom property with an local/external URL.\n\n* `src`: `#building`\n* `src`: `https://foo.com/world.fbx#building&-floor`\n\n> NOTE: remember that [[showing/hiding object(children)]] in an [[src]] will allow **spatial referencing** (reparenting the target object to the root of the scene).\u003Cbr>See the spec below:\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 src=\"doc/RFC_XR_Fragments.html#spatial-referencing-3d\" frameborder=\"0\" class=\"spec\">\u003C/iframe>\n","tags":"[[🧪 experimental]]","title":"embed a 3D object (subtree)","modified":"20250902143004748"}, +{"created":"20240223092012710","text":"Create an empty mesh object (in Blender it's called an 'Empty') and add an [[href]] with a value prefixed with optionally a [[#!]] (toggle) or [[#*]] (multiply)\n\n* `href`: `#!menu` (teleports object menu in front of user)\n* `href`: `#*cube` (duplicates block in front of user)\n* `href`: `https://foo.com/menu.glb#!` (spawns menu in front of user (*))\n* `href`: `https://foo.com/menu.glb#!bar` (spawns object bar in front of user (*))\n\n> * = when file contains 0 [[href]]'s\n\nThe best practice is to show a lowpoly preview-version, or image-texture of the embedded object/file.\nThis hints the user what to expect.\u003Cbr>\n\n> NOTE: the [[src]] attribute has been ''deprecated'' as it can lead to ","tags":"","title":"embed a 3D object","modified":"20250919161453769"}, {"created":"20240722085406030","text":"Since 2020, Next Generation Internet (NGI) programmes, part of European Commission's Horizon programme, fund free software in Europe using a cascade funding mechanism (see for example NLnet's calls). This year, according to the Horizon Europe working draft detailing funding programmes for 2025, we notice that Next Generation Internet is not mentioned any more as part of Cluster 4.\n\nNGI programmes have shown their strength and importance to support the European software infrastructure, as a generic funding instrument to fund digital commons and ensure their long-term sustainability. We find this transformation incomprehensible, moreover when NGI has proven efficient and ecomomical to support free software as a whole, from the smallest to the most established initiatives. This ecosystem diversity backs the strength of European technological innovation, and maintaining the NGI initiative to provide structural support to software projects at the heart of worldwide innovation is key to enforce the sovereignty of a European infrastructure.\nContrary to common perception, technical innovations often originate from European rather than North American programming communities, and are mostly initiated by small-scaled organizations.\n\nPrevious Cluster 4 allocated 27 millions euros to:\n\n \"Human centric Internet aligned with values and principles commonly shared in Europe\" ;\n \"A flourishing internet, based on common building blocks created within NGI, that enables better control of our digital life\" ;\n \"A structured eco-system of talented contributors driving the creation of new internet commons and the evolution of existing internet commons\" .\n\nIn the name of these challenges, more than 500 projects received NGI funding in the first 5 years, backed by 18 organisations managing these European funding consortia.\n\nNGI contributes to a vast ecosystem, as most of its budget is allocated to fund third parties by the means of open calls, to structure commons that cover the whole Internet scope - from hardware to application, operating systems, digital identities or data traffic supervision. This third-party funding is not renewed in the current program, leaving many projects short on resources for research and innovation in Europe.\n\nMoreover, NGI allows exchanges and collaborations across all the Euro zone countries as well as \"widening countries\"¹, currently both a success and and an ongoing progress, likewise the Erasmus programme before us. NGI also contributes to opening and supporting longer relationships than strict project funding does. It encourages to implement projects funded as pilots, backing collaboration, identification and reuse of common elements across projects, interoperability in identification systems and beyond, and setting up development models that mix diverse scales and types of European funding schemes.\n\nWhile the USA, China or Russia deploy huge public and private resources to develop software and infrastructure that massively capture private consumer data, the EU can't afford this renunciation.\nFree and open source software, as supported by NGI since 2020, is by design the opposite of potential vectors for foreign interference. It lets us keep our data local and favors a community-wide economy and know-how, while allowing an international collaboration.\nThis is all the more essential in the current geopolitical context: the challenge of technological sovereignty is central, and free software allows to address it while acting for peace and sovereignty in the digital world as a whole.\n\nL’Union Européenne doit poursuivre le financement des logiciels libres\nDepuis 2020, les programmes Next Generation Internet (NGI), sous-branche du programme Horizon Europe de la Commission Européenne financent en cascade (via les appels de NLnet) le logiciel libre en Europe. Cette année, à la lecture du brouillon du Programme de Travail de Horizon Europe détaillant les programmes de financement de la commission européenne pour 2025, nous nous apercevons que les programmes Next Generation Internet ne sont plus mentionnés dans le Cluster 4.\n\nLes programmes NGI ont démontré leur force et leur importance dans le soutien à l’infrastructure logicielle européenne, formant un instrument générique de financement des communs numériques qui doivent être rendus accessibles dans la durée. Nous sommes dans l’incompréhension face à cette transformation, d’autant plus que le fonctionnement de NGI est efficace et économique puisqu’il soutient l’ensemble des projets de logiciel libre des plus petites initiatives aux mieux assises. La diversité de cet écosystème fait la grande force de l’innovation technologique européenne et le maintien de l’initiative NGI pour former un soutien structurel à ces projets logiciels, qui sont au cœur de l’innovation mondiale, permet de garantir la souveraineté d’une infrastructure européenne. Contrairement à la perception courante, les innovations techniques sont issues des communautés de programmeurs européens plutôt que nord-américains, et le plus souvent issues de structures de taille réduite.\n\nLe Cluster 4 allouait 27 millions d’euros au service de :\n\n « Human centric Internet aligned with values and principles commonly shared in Europe » ;\n « A flourishing internet, based on common building blocks created within NGI, that enables better control of our digital life » ;\n « A structured eco-system of talented contributors driving the creation of new internet commons and the evolution of existing internet common« .\n\nAu nom de ces enjeux, ce sont plus de 500 projets qui ont reçu un financement NGI0 dans les 5 premières années d’exercice, ainsi que plus de 18 organisations collaborant à faire vivre ces consortia européens.\n\nNGI contribue à un vaste écosystème puisque la plupart du budget est dévolue au financement de tierces parties par le biais des appels ouverts (open calls). Ils structurent des communs qui recouvrent l’ensemble de l’Internet, du matériel aux applications d’intégration verticale en passant par la virtualisation, les protocoles, les systèmes d’exploitation, les identités électroniques ou la supervision du trafic de données. Ce financement des tierces parties n’est pas renouvelé dans le programme actuel, ce qui laissera de nombreux projets sans ressources adéquates pour la recherche et l’innovation en Europe.\n\nPar ailleurs, NGI permet des échanges et des collaborations à travers tous les pays de la zone euro et aussi avec ceux des widening countries¹, ce qui est actuellement une réussite tout autant qu’un progrès en cours, comme le fut le programme Erasmus avant nous. NGI0 est aussi une initiative qui participe à l’ouverture et à l’entretien de relation sur un temps plus long que les financements de projets. NGI encourage également à l’implémentation des projets financés par le biais de pilotes, et soutient la collaboration au sein des initiatives, ainsi que l’identification et la réutilisation d’éléments communs au travers des projets, l’interopérabilité notamment des systèmes d’identification, et la mise en place de modèles de développement intégrant les autres sources de financements aux différentes échelles en Europe.\n\nAlors que les États-Unis d’Amérique, la Chine ou la Russie déploient des moyens publics et privés colossaux pour développer des logiciels et infrastructures captant massivement les données des consommateurs, l’Union Européenne ne peut pas se permettre ce renoncement. Les logiciels libres et open source tels que soutenus par les projets NGI depuis 2020 sont, par construction, à l’opposée des potentiels vecteurs d’ingérence étrangère. Ils permettent de conserver localement les données et de favoriser une économie et des savoirs-faire à l’échelle communautaire, tout en permettant à la fois une collaboration internationale. Ceci est d’autant plus indispensable dans le contexte géopolitique que nous connaissons actuellement. L’enjeu de la souveraineté technologique y est prépondérant et le logiciel libre permet d’y répondre sans renier la nécessité d’œuvrer pour la paix et la citoyenneté dans l’ensemble du monde numérique.\n\nDans ces perspectives, nous vous demandons urgemment de réclamer la préservation du programme NGI dans le programme de financement 2025.\n\n¹ Tels que définis par Horizon Europe, les États Membres élargis sont la Bulgarie, la Croatie, Chypre, la République Tchèque, l’Estonie, la Grèce, la Hongrie, la Lettonie, la Lituanie, Malte, la Pologne, le Portugal, la Roumanie, la Slovaquie et la Slovénie. Les pays associés élargies (sous conditions d’un accord d’association) l’Albanie, l’Arménie, la Bosnie Herzégovine, les Iles Féroé, la Géorgie, le Kosovo, la Moldavie, le Monténégro, le Maroc, la Macédoine du Nord, la Serbie, la Tunisie, la Turquie et l’Ukraine. Les régions élargies d’outre-mer sont : la Guadeloupe, la Guyane Française, la Martinique, La Réunion, Mayotte, Saint-Martin, Les Açores, Madère, les Iles Canaries.\nIn this perpective, we urge you to claim for preserving the NGI programme as part of the 2025 funding programme.\n\n¹ As defined by Horizon Europe, widening Member States are Bulgaria, Croatia, Cyprus, the Czech Republic, Estonia, Greece, Hungary, Latvia, Lituania, Malta, Poland, Portugal, Romania, Slovakia and Slovenia. Widening associated countries (under condition of an association agreement) include Albania, Armenia, Bosnia, Feroe Islands, Georgia, Kosovo, Moldavia, Montenegro, Morocco, North Macedonia, Serbia, Tunisia, Turkey and Ukraine. Widening overseas regions are : Guadeloupe, French Guyana, Martinique, Reunion Island, Mayotte, Saint-Martin, The Azores, Madeira, the Canary Islands.","tags":"","title":"EU keeps/stops funding FOSS?","modified":"20240722085846049","type":"text/markdown"}, {"created":"20240624125444313","text":"\u003Cstyle type=\"text/css\">\n .examples img{\n\t border: 1px solid #CCC;\n\t\tborder-radius:6px;\n\t\tmargin: 20px 20px 20px 0px;\n\t\tdisplay:block;\n\t\twidth:100%;\n\t}\n\u003C/style>\n\n\u003Cdiv class=\"examples\">\n \u003Cdiv>\n \u003Ca href=\"example/aframe/sandbox\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/index.glb.jpg\"/>\n\t \u003C/a>\n\t\t\u003Cb>index.glb\u003C/b> kitchensink \n\t\u003C/div>\n\t\u003Cdiv>\n \u003Ca href=\"example/aframe/sandbox?./../../assets/example.glb\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/example.glb.jpg\"/>\n\t \u003C/a>\n\t\t\u003Cb>example.glb\u003C/b> simple startingpoint \n\t\u003C/div>\n\t\u003Cdiv>\n \u003Ca href=\"example/aframe/sandbox?./../../assets/website.glb\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/website.glb.jpg\"/>\n\t \u003C/a>\n\t\t\u003Cb>website.glb\u003C/b> website startingpoint \n\t\u003C/div>\n\t\u003Cdiv>\n \u003Ca href=\"https://coderofsalvation.codeberg.page/xrfragment-elearning-templates/?https://coderofsalvation.codeberg.page/xrfragment-elearning-templates/index.glb\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/elearning.glb.jpg\"/>\n\t \u003C/a>\n\t\t\u003Cb>elearning.glb\u003C/b> quiz startingpoint \n\t\u003C/div>\n\t\u003Cdiv>\n \u003Ca href=\"example/aframe/sandbox?./../../assets/telescopic.glb\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/telescopic.png\"/>\n\t \u003C/a>\n\t\t\u003Cb>telescopic.glb\u003C/b> reveal via [[href]] + \u003Ca href=\"#🎞%20Media%20Fragments\">media fragments\u003C/a>\n\t\u003C/div>\n\t\u003Cdiv>\n \u003Ca href=\"example/aframe/sandbox?./../../assets/victory-garden-cdrom.glb#rot=0,180,0&pos=-2,0,-8\" target=\"_blank\">\n\t \u003Cimg src=\"https://codeberg.org/coderofsalvation/xrfragment.media/raw/commit/90256763ddbc7bf727a8597ac62152a1c2c62b98/images/mediafragments-cdrom.gif\"/>\n\t \u003C/a>\n\t\t\u003Cb>cdrom.glb\u003C/b> with animations controlled via [[href]] + \u003Ca href=\"#🎞%20Media%20Fragments\">media fragments\u003C/a>\n\t\u003C/div>\t\t\n \u003Cdiv>\n \u003Ca href=\"example/aframe/xrsh\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/xrsh.jpg\"/>\n\t \u003C/a>\n\t\t\u003Ca href=\"https://xrsh.isvery.ninja\" target=\"_blank\">xrsh\u003C/a> overlay showing aria-descriptions + scene transcripts\n\t\u003C/div>\n\t\u003Cdiv>\n \u003Ca href=\"https://searxr.me\" target=\"_blank\">\n\t \u003Cimg src=\"https://coderofsalvation.codeberg.page/xrfragment.media/images/searxr.jpg\"/>\n\t \u003C/a>\n\t\t\u003Ca href=\"https://searxr.me\" target=\"_blank\">\u003Cb>searxr.me\u003C/b>\u003C/a> metasearch engine supporting XR Fragments\n\t\u003C/div>\t\n\u003C/div>","tags":"$:/tags/SideBar","title":"Examples","modified":"20250218134240827","list-before":"Reference"}, {"title":"feedback.png","text":"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","type":"image/png"}, @@ -1218,7 +1218,7 @@ button.sidebar-toggle{ {"created":"20250211165942341","text":"\u003C\u003Ctoc-selective-expandable 'Home' sort[weight]>>","tags":"$:/tags/SideBar","title":"Home","modified":"20250211170130825","list-before":"Examples"}, {"created":"20230428150217784","text":"''Short answer:'' its making 3D objects bookmarkable, clickable & teleportable.\n\n!! Soundtrack, subtitles, thumbnail \n\n[[XR Movies]] anyone?\u003Cbr>\n''Simple:'' just add those files and name them accordingly (`mymovie.xrf.ogg` for `mymovie.xrf.glb` e.g.) as [[sidecar-files|📜 level0: File]]\n\n!! Clickable links\n\nWhen clicking an ''href''-value, the user(camera) is teleport to the referenced object.\n\nThe imported/teleported destination can be another object in the same scene-file, or a different file.\n\n!! Adding a link\n\n[img[xrfragment.jpg]]\n\n\u003Cb>NOTE:\u003C/b> For a \u003Cb>technical\u003C/b> explanation see the \u003Ca href=\"/doc/RFC_XR_Fragments.html\" target=\"_blank\">specification\u003C/a> instead.\n\nFor a highlevel deepdive check this audio:\n\n\u003Cdiv style=\"text-align:center\">\n\u003Cb style=\"font-size:11px\">~10min podcast deepdive\u003C/b>\u003Cbr>\n\u003Caudio controls>\n \u003Csource src=\"https://coderofsalvation.codeberg.page/xrfragment.media/podcast-xrfragments-spec-xrwg.mp3\" type=\"audio/mpeg\" />\n\u003C/audio>\n\u003C/div>\n\u003Cbr>\n\n!! How can XR Browsers surf these worlds?\n\nUsing an \u003Cb>URL-bar\u003C/b> in your browser, app or OS, or button-object inside your 3D file (with [[href]] extra).\u003Cbr>\nThe URL should points to an 3D scene or file ([[glTF|https://en.wikipedia.org/wiki/GlTF]], [[USDZ|https://en.wikipedia.org/wiki/Universal_Scene_Description]], [[OBJ|https://en.wikipedia.org/wiki/Wavefront_.obj_file]], [[COLLADA|https://en.wikipedia.org/wiki/COLLADA]], [[FBX|https://en.wikipedia.org/wiki/FBX]] e.g.):\n\u003Cbr>\u003Cbr>\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #888\">\n\t\u003Cspan class=\"big\" style=\"width:160px; display: inline-block\">2D documents:\u003C/span>\n\t\u003Cspan class=\"big hi1\">https ://\u003C/span>\n\t\u003Cspan class=\"big hi2\">foo.org/article.html\u003C/span>\n\t\u003Cspan class=\"big hi1\">#chapter2\u003C/span>\n\u003C/div>\n\u003Cbr>\n\u003Cdiv class=\"border padding\" style=\"border:4px solid #F0F\">\n\t\u003Cspan class=\"big\" style=\"width:160px; display: inline-block\">3D documents:\u003C/span>\n\t\u003Cspan class=\"big hi1\">protocol ://\u003C/span>\n\t\u003Cspan class=\"big hi2\">foo.org/world.glb\u003C/span>\n\t\u003Cspan class=\"big hi1\">#room2\u003C/span>\n\u003C/div>\n\n\u003Cbr>\n\n!! Example: internal && external importing objects\n\n```\n\n +────────────────────────────────────────────────────────+ \n │ │\n │ index.glb │ Usecase: trigger\n │ │ │ interactive experiences\n │ ├── ◻ bar │ in front of the user\n │ │ └◻ char │ \n | | | \n │ ├── ◻ buttonA │ \n │ │ └ href: #bar │\n │ │ │ +────────────────────────+\n │ └── ◻ buttonB │ | other.usdz |\n │ └ href: other.usdz#infographic&t=0 │ | | |\n +────────────────────────────────────────────────────────+ | └── ◻ infographic |\n | └─◻ KPIs | \n +────────────────────────+\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n clicking buttonA will clone the chart in front of the user (because it has no camera)\n clicking buttonB will clone (and play) the infographic from other.usdz (because it has no camera)\n\n\n```\n\n\n!! Example: internal & external teleport\n\n```\n\n +────────────────────────────────────────────────────────+ \n │ │\n │ index.glb │\n │ │ │\n │ ├── ◻ roomB │\n │ │ └◻ camera4 │ camera's Y-coord will be changed to\n | | | ~1.6m above (roomB's) surface-origin\n │ ├── ◻ buttonA │ (in VR only)\n │ │ └ href: #roomB │\n | │ │ +────────────────────────+\n │ └── ◻ buttonB │ | other.usdz |\n │ └ href: other.usdz#foo │ | | |\n │ │ | ├── ◻ camera |\n +────────────────────────────────────────────────────────+ | └── ◻ foo |\n | └─◻ camera3 | \n +────────────────────────+\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n clicking buttonA will teleport the user to roomB (because it has a camera)\n clicking buttonB will teleport the user to foo in other.usdz (because it has a camera)\n\n\n```\n\n!! How can I add interactions to existing 3D assets/scenes?\n\nBy manually adding \u003Cb>metadata\u003C/b> inside 3D objects/asset/scene or via a [[sidecar-file|📜 level0: File]], which gives a 3D file interactive powers.\n\n\u003Cbr>\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/sharing.mp4\" type=\"video/mp4\"/>\n\u003C/$videojs>\n\u003C/div>\n\n\u003Cbr>\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 src=\"doc/RFC_XR_Fragments.html#spatial-referencing-3d\" frameborder=\"0\" class=\"spec\">\u003C/iframe>\n\n\n\n> the above paradigm allows spatial ''teleportation'', but also ''sourceportation'' (teleporting to the (author) world of which an embedded `src` object belongs). \u003Cbr>\u003Cb>NOTE\u003C/b>: the [[AFRAME/THREE libraries|https://github.com/coderofsalvation/xrfragment/tree/main/dist]] do this for you out of the box.\n\n\nsee [[Getting started]] to get going!","title":"How it works","modified":"20250906093928555","type":"text/vnd.tiddlywiki","tags":"Home"}, {"created":"20250902141401836","text":"\u003C\u003Ctoc-selective-expandable 'howto' sort[title]>>","tags":"$:/tags/SideBar","title":"Howto","modified":"20250902141443289","list-before":"$:/core/ui/SideBar/Open"}, -{"created":"20230522115709081","text":"href metadata ('extras') in a 3D object (of a 3D file), hint the viewer that the user ''can interact'' with that object :\n\n| fragment | type | example value |\n|`href`| string (uri or predefined view) | `#pyramid`\u003Cbr>`#lastvisit`\u003Cbr>`xrf://#-someobject`\u003Cbr>`://somefile.gltf#foo`\u003Cbr> |\n\n!! Interaction behaviour\n\nWhen clicking an ''href''-value, the user(camera) is teleport to the referenced object.\n\nThe imported/teleported destination can be another object in the same scene-file, or a different file.\n\n!! Adding a link\n\n[img[xrfragment.jpg]]\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-content-href-portals\" frameborder=\"0\" class=\"spec\">\u003C/iframe>\n\n> solutions in the spec were abducted from [[this|https://i.imgur.com/E3En0gJ.png]] and [[this|https://i.imgur.com/lpnTz3A.png]] survey result\n\n!!!Demo\n\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/href.mp4\" type=\"video/mp4\"/>\n\u003C/$videojs>\n\n> capture of \u003Ca href=\"./example/aframe/sandbox\" target=\"_blank\">aframe/sandbox\u003C/a>\n\n!! XR Viewer implementation\n\n| ''spec'' | ''action'' | ''feature'' |\n| level0+1 | hover 3D file [[href]] | show the preview PNG thumbnail (if any). See [[📜 level0: File]]) |\n| level0+1 | launch 3D file [[href]] | replace the current scene with a new 3D file (`href: other.glb` e.g.) |\n| level2 | click internal 3D file [[href]] (`#roomB` e.g.) | teleport the camera to the origin of object(name `roomB`). See [[teleport camera]].|\n| level2 | click external 3D file [[href]] (`foo.glb` e.g.) | replace the current scene with a new 3D file (`href: other.glb` e.g.) |\n| level2 | hover external 3D file [[href]] | show the preview PNG thumbnail (if any sidecar [[📜 level0: File]]) |\n| level2 | click [[href]] | hashbus: execute without changing the toplevel URL location (`href: xrf://#someObjectName` e.g.) |\n| level3 | click [[href]] | set the global 3D animation timeline to its Media Fragment value (`#t=2,3` e.g.) |\n\n> NOTE: hashbus links (`xrf://#foo&bar`) don't change the toplevel URL, which makes it ideal for interactions (in contrast to typical `#roomC` navigation, which benefit back/forward browser-buttons), see \u003Ca href=\"#hashbus\">hashbus\u003C/a> for more info.\n\n\n[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js]]\u003Cbr>\n[[» example 3D asset|https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192]]\u003Cbr>\n[[» discussion|https://github.com/coderofsalvation/xrfragment/issues/1]]\u003Cbr>\n","tags":"[[📜 level2: explicit links]] level2","title":"href","modified":"20250906101757604","type":"text/vnd.tiddlywiki"}, +{"created":"20230522115709081","text":"href metadata ('extras') in a 3D object (of a 3D file), hint the viewer that the user ''can interact'' with that object :\n\n| fragment | type | example value |\n|`href`| string (uri or predefined view) | `#pyramid`\u003Cbr>`#lastvisit`\u003Cbr>`xrf://#-someobject`\u003Cbr>`://somefile.gltf#foo`\u003Cbr> |\n\n!! Interaction behaviour\n\nWhen clicking an ''href''-value, the user(camera) is teleport to the referenced object.\n\nThe imported/teleported destination can be another object in the same scene-file, or a different file.\n\n!! Adding a link\n\n[img[xrfragment.jpg]]\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-content-href-portals\" frameborder=\"0\" class=\"spec\">\u003C/iframe>\n\n> solutions in the spec were abducted from [[this|https://i.imgur.com/E3En0gJ.png]] and [[this|https://i.imgur.com/lpnTz3A.png]] survey result\n\n!!!Demo\n\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/href.mp4\" type=\"video/mp4\"/>\n\u003C/$videojs>\n\n> capture of \u003Ca href=\"./example/aframe/sandbox\" target=\"_blank\">aframe/sandbox\u003C/a>\n\n!! XR Viewer implementation\n\n| ''spec'' | ''action'' | ''feature'' |\n| level0+1 | hover 3D file [[href]] | show the preview PNG thumbnail (if any). See [[📜 level0: File]]) |\n| level0+1 | launch 3D file [[href]] | replace the current scene with a new 3D file (`href: other.glb` e.g.) |\n| level2 | click internal 3D file [[href]] (`#roomB` e.g.) | teleport the camera to the origin of object(name `roomB`). See [[teleport camera]].|\n| level2 | click external 3D file [[href]] (`foo.glb` e.g.) | replace the current scene with a new 3D file (`href: other.glb` e.g.) |\n| level2 | hover external 3D file [[href]] | show the preview PNG thumbnail (if any sidecar [[📜 level0: File]]) |\n| level2 | click [[href]] | hashbus: execute without changing the toplevel URL location (`href: xrf://#someObjectName` e.g.) |\n| level3 | click [[href]] | set the global 3D animation timeline to its Media Fragment value (`#t=2,3` e.g.) |\n\n> NOTE: hashbus links (`xrf://#foo&bar`) don't change the toplevel URL, which makes it ideal for interactions (in contrast to typical `#roomC` navigation, which benefit back/forward browser-buttons), see \u003Ca href=\"#hashbus\">hashbus\u003C/a> for more info.\n\n\n[[» example implementation|https://github.com/coderofsalvation/xrfragment/blob/main/src/3rd/js/three/xrf/href.js]]\u003Cbr>\n[[» example 3D asset|https://github.com/coderofsalvation/xrfragment/blob/main/example/assets/href.gltf#L192]]\u003Cbr>\n[[» discussion|https://github.com/coderofsalvation/xrfragment/issues/1]]\u003Cbr>\n","tags":"[[📜 level2: explicit links]] level2","title":"href","modified":"20250919161056518","type":"text/vnd.tiddlywiki"}, {"created":"20230706161915394","text":"> Let's look at the browser thru the lens of XR, and not the other way around (it's a trap).\n\n* a \u003Cb>2D hyperlink\u003C/b> navigates/replaces the current document (or opens a tab)\n* a \u003Cb>hyperpreview\u003C/b> simply links/shows/summarizes an 2D/3D object/document/image\n\nA \u003Cb>hyperpreview\u003C/b> promotes \u003Cb>approximated summaries\u003C/b> of text documents, instead of fully supporting/rendering them.\u003Cbr>\nThat way, opening the content (spatially) will be offloaded to (other applications) on the client or operating system.\u003Cbr>\nThis is in contrast with traditional 2D (space-restricted) way of opening hyperlinks in new tabs (or replacing the current document).\n\n\n> Basically: the moment you want to implement HTML iframes into your spatial experience, you're looking at XR thru the lens of 2D (a common trap). The higher-dimensional recursive nature of XR Fragments \u003Cb>already allows\u003C/b> recursive (spatial i)frames.\n\n## Spec 0.5\n\n1. mimetype `text/html` instanced by [src](#src) should should be \u003Cb>hyperpreviewable\u003C/b> (a non-interactive 2D image-texture).\n\n2. When interacting with a \u003Cb>hyperpreview\u003C/b>, the XR Fragment host/client should offer copy/share of the adress (to clipboard and optionally other applications which can handle the mimetype).\n\n3. \u003Cb>hyperpreviews\u003C/b> should not aim for achieving 100% render-compatibility of all mimetypes. The goal is \u003Cb>addressbility\u003C/b> and \u003Cb>approximated summarization\u003C/b>, not embedding javascript-supported browser-iframes.\n\n4. Designers can solve unsupported mimetypes by using `src` for an image-thumbnail and `href` for the content (which should be offloaded to the (applications on) the operatingsystem)\n\nmimetype behaviour when user interacts with `src`:\n\n| mimetype | render | hyperpreview | action | update URL fragment | clipboard contents after clicking |\n|-|-|-|-|-|-|\n|\u003Cb>unknown mimetypes\u003C/b>| no | \n|text/html| no | yes |\u003Cb>summarize\u003C/b> HTML-text (first paragraph hinted by a fragment identifier e.g.) using crude html-to-image | name of object (`#website`) |\n|\u003Cb>3d objects\u003C/b>\u003Cbr>model/gltf+json\u003Cbr>model/glb\u003Cbr>model/obj\u003Cbr>..and so on | yes | no | highlight \u003Cbr>(draw boundingbox e.g.) | name of object (`#cube` e.g.) | `src`-value + linebreak + url with fragment: `http://other.com/other.gltf`\u003Cbr>`https://foo.com/#cube`\u003Cbr>Sharing such 'trail' (with the clipboardmanager) promotes backwards-reasoning (`other.gltf` is a cube in `scene.gltf` e.g.)\n|\u003Cb>images\u003C/b>\u003Cbr>image/png\u003Cbr>image/jpg\u003Cbr>image/gif\u003Cbr>..and so on | yes | no | highlight \u003Cbr>(draw border/boundingbox e.g.) | name of object (`#poster` e.g.) | object url with fragment (`https://foo.com/#cube` e.g.)\n\n\u003Chr>\n\n\u003Cb>Example\u003C/b>: embed an HTML document into your scene\n\n* create a plane with custom property [src](#src) and value `https://mysite.com/foo.html#summary` or `https://mysite.com/foo.html#chapter1`. \n* add custom property [\nso that the XR Fragment client can easily render a html-to-image conversion to a texture.\u003Cbr>\nThis is perfect for simple text.\u003Cbr>\nCRUD/scripting/animations don't belong in \u003Cb>hyperpreviews\u003C/b> and can partially be re-used in the 3D assets (using [src](#src) or fbx/gltf animations).\u003Cbr>\n\n\u003Chr>\n\n\u003Cb>Q\u003C/b>: How can I embed text from a textfile on a server?\n\n\u003Cb>A\u003C/b>: create an [src](#src) with value `https://mysite.com/foo.txt` so that the XR Fragment client can easily render a html-to-image conversion to a (non)scrolling texture.\u003Cbr>\n\n\u003Cbr>\n\n## Why are hyperpreviews so limited?\n\nBecause \u003Cb>hyperpreviews\u003C/b> separate the following concerns of hyperlinks: navigation, addressibility, interaction and rendering.\n\u003Cbr>\nIn \u003Cb>2D hyperlinks\u003C/b> we click links, which \u003Cb>navigates us to\u003C/b> AND \u003Cb>renders\u003C/b> the destination.\n\u003Cbr>\n\u003Cbr>\nIn Spatial Experiences endusers are better off \u003Cb>hyperpreviewing\u003C/b> hyperlinks, which optionally can (due to their \u003Cb>addressibility\u003C/b> be opened in another application or device).\u003Cbr>\n\u003Cbr>\n> The aim/goal of forcing a user to interact with all mimetypes spatially is not realistic.\n\nIf we would indulge on the latter, we're opening a can of worms regarding:\n\n* security (malicious actors thrive when going beyond read-only previews or `HTTP GET`)\n* the spatial browser becomes **mimetype-rendering-silos** (ballooning in size & support)\n* rendering speed / framedropping","tags":"","title":"hyperpreview vs 2D hyperlinks","modified":"20230707090417999","type":"text/markdown"}, {"created":"20240229160427482","text":"This can be done using ''Descriptive metadata'' and ARIA descriptions (see [[🧩 Object metadata]])\n\n! Demo\n\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/descriptive-metadata-implodes-3D-to-text.mp4\" type=\"video/mp4\"/>\n\u003C/$videojs>","tags":"[[🧪 experimental]]","title":"Imploding 3D scene to Text","modified":"20250902143004752","type":"text/vnd.tiddlywiki"}, {"title":"interlinked.png","text":"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","type":"image/png"},