on master help sign in
removes duplicate Udon material
55295f0Robert
using/udon.mddeleted−851
@@ -1,851 +0,0 @@
1−+++
2−title = "Udon"
3−weight = 8
4−template = "doc.html"
5−+++
6−
7−
8−## <a name="udon"></a>Udon: A Guide
9−
10−Udon is a way to write content for the web. It's a minimalist
11−markup language for creating and rendering text documents, with a
12−Markdown-inspired syntax. It's integrated with our Hoon programming language,
13−allowing it to be used as standalone prose in its own file or embedded inside a
14−Hoon source file, in which case it will be parsed into a tree of HTML nodes
15−using Hoon's XML-templating syntax, Sail.
16−
17−This document is itself written in Udon, and its source file is of the
18−Udon `.udon` extension. As such, we use some `formatted text` to make
19−it clear what is and isn't code, and to display that code to you instead of
20−actually using its semantics for formatting.
21−
22−There are quite a few similarities between Udon and the
23−CommonMark standard, but there are enough differences that you shouldn't rely on
24−existing knowledge of the latter. Udon generally supports only one
25−syntax for each type of HTML node it emits. Udon is also stricter than
26−Markdown: some syntax errors will prevent the file from being parsed at all.
27−
28−We provide a few simple examples [here](#examples) of how to publish
29−Udon files using our web interface.
30−
31−## Udon Syntax
32−
33−### Front Matter
34−
35−The first thing on your file is a chunk of code called the front matter. It
36−contains metadata about your page, such as date, title, and position relative
37−to sibling pages.
38−
39−As an example, let's look at the front matter of this very page:
40−
41−```
42−:- :~ navhome/'/docs/'
43− sort/'11'
44− title/'Udon'
45− ==
46−;>
47−```
48−
49−What's going on here?
50−
51−`:-`, the Hoon rune for creating a cell, creates a cell composed of
52−the `:~` Hoon rune for creating a list, and `;>`, which is a Sail rune
53−for Udon.
54−
55−`:~` creates a list out of the three elements: `navhome/'/docs/'`, which
56−indicates that navigating "home" will bring you to the urbit.org/docs section
57−of the website; `sort/'28',` which assigns it the 28th position of the
58−immediate section that contains it, the one you see in the sidebar;
59−and `title/'Udon'`, which gives the page its title. The `==` digraph
60−terminates the list.
61−
62−`;>` is a Sail rune that creates a node that contains everything that follows
63−it, telling the parser that that text should be interpreted as Udon.
64−It's not technically front matter, but you'll always find it following the
65−front matter, since all Udon must come after this rune.
66−
67−The categories listed in the example above -- `navhome`, `sort`, and `title` --
68−make sense to Eyre by default, but any arbitrary category can be used. The code
69−below is valid front matter.
70−
71−```
72−:- :~ date/~2018.9.12
73− author/~lodleb-ritrul
74− music/'rad'
75− ==
76−```
77−
78−Note that `~2018.9.12`, `~lodleb-ritrul`, and `'rad'` are all of of atom
79−types: `@da`(date), `@p` (ship name), and `@t` (cord), respectively. Only atom
80−types work here. Having `music/"rad"` would prevent the source file from
81−parsing.
82−
83−### Headers
84−
85−Headers in Udon begin the line with one or more `#` characters,
86−'followed by a single space. After that space comes the actual text to be
87−displayed. The number of leading `#`s corresponds to the resulting HTML
88−header-size element: `#` yields an `<h1>`, `##` yields an `<h2>`, and so on,
89−through `<h6>`. The header for this section is `### Headers`.
90−
91−**Example:**
92−```
93−#### Header (h4)
94−
95−##### Header (h5)
96−```
97−**Produces:**
98−
99−#### Header (h4)
100−
101−##### Header (h5)
102−
103−### Italics and Bold
104−
105−Enclosing text with `_` will cause that text to appear italicized, using an `<i>`
106−element.
107−
108−Enclosing text with `*` will cause that text to appear bolded, using a `<b>`
109−element.
110−
111−
112−**Example:**
113−
114−```
115−To get their *attention*, you need that _je ne sais quoi_.
116−```
117−
118−**Produces:**
119−
120−To get their **attention**, you need that _je ne sais quoi_.
121−
122−### Line Break
123−
124−A blank line is interpreted as a line break, creating a distinct
125−paragraph. However, a newline on its own is merely interpreted as a space on
126−the _same line_.
127−
128−**Example:**
129−
130−```
131−Here's the first line.
132−
133−This second line is separated by two newlines, so it's a separate paragraph.
134−
135−This line looks like a distinct paragraph, but...
136−It's only separated by a single newline, so it's included in the same paragraph.
137−```
138−**Produces:**
139−
140−
141−Here's the first line.
142−
143−This second line is separated by two newlines, so it's a separate paragraph.
144−
145−This line looks like a distinct paragraph, but...
146−It's only separated by a single newline, so it's included in the same paragraph.
147−
148−#### Backslash Line Break
149−
150−A backslash at the end of a line inserts a line break (`<br>`)
151−after that line. This contrasts with the normal udon behavior of
152−converting newlines to spaces.
153−
154−**Example:**
155−```
156−I wonder how long each line
157−will be if I put backslashes\
158−at the ends of the lines.
159−```
160−**Produces:**
161−
162−I wonder how long each line
163−will be if I put backslashes\
164−at the ends of the lines.
165−
166−### Escape
167−
168−A backslash directly _before_ a word (with no spaces) will be interpreted
169−as an escape character, causing it to be rendered raw.
170−
171−**Example:**
172−
173−```
174−Here is some *bold* text.
175−Here is some \*not bold* text.
176−```
177−
178−**Produces:**
179−
180−Here is some **bold** text.
181−Here is some \*not bold* text.
182−
183−
184−### List
185−
186−A line beginning with a `-` followed by a space is interpreted as an
187−element of an **unordered list** (`<ul>`). Each line in an unordered list is
188−prepended with a bullet point.
189−
190−A line beginning with a `+` followed by a space is interpreted as an element
191−of an **ordered list** (`<ol>`). Each line in an ordered list is prepended with
192−a number corresponding to its position in that list.
193−
194−New list elements are delineated by newlines beginning with list symbols of
195−the appropriate type (`-` or `+`).
196−
197−Just as with non-list text, text on a bare newline will appear on line before,
198−separated by a space. A `\\` is used to create a line-break that isn't the list
199−itself and isn't a list. Both of these kinds of newlines must be indented by two
200−spaces, or else the page will not parse.
201−
202−Indentation is also used for creating nested sub-lists. Sub-lists of one kind
203−can be used with parent lists of the other kind. Sub-lists can't be nested
204−directly after either kind of aforementioned newline that isn't a list element;
205−only lines that are themselves list elements can nest sub-lists.
206−
207−A newline after a blank line is interpreted as a new paragraph in normal text.
208−Between to list elements, however, a blank line is semantically equivalent to
209−a bare newline. To separate two lists with blank space, create a blank line
210−followed by a `\\` on its own line.
211−
212−**Example:**
213−
214−```
215−- Eggs
216− (cage-free)
217−- Milk
218−- Butter
219−- Chicken\
220− Make sure that you get enough for the barbecue
221−- Bread
222− + Ask the baker what's fresh
223− + Buy the second-freshest batch
224−- Cereal
225−
226−\
227−+ First, separate eggs into a bowl.
228−+ Then, add a splash of cream.
229− - If you don't have cream, you can use milk, but cream is preferred.
230− + If you don't have milk or cream, melt an eighth of a stick of butter on
231− a skillet
232− + Scrambled the eggs in the bowl.
233− + Pour the eggs onto the skillet before the butter browns
234−+ Heat the skillet
235−
236−+ Scramble eggs and put them into skillet
237−
238−\
239−+ Cool
240−+ Alright
241−```
242−
243−Produces
244−
245−- Eggs
246− (cage-free)
247−- Milk
248−- Butter
249−- Chicken\
250− Make sure that you get enough for the barbecue
251−- Bread
252− + Ask the baker what's fresh
253− + Buy the second-freshest batch
254−- Cereal
255−
256−\
257−+ First, separate eggs into a bowl.
258−+ Then, add a splash of cream.
259− - If you don't have cream, you can use milk, but cream is preferred.
260− + If you don't have milk or cream, melt an eighth of a stick of butter on
261− a skillet
262− + Scrambled the eggs in the bowl.
263− + Pour the eggs onto the skillet before the butter browns
264−+ Heat the skillet
265−
266−+ Scramble eggs and put them into skillet
267−
268−\
269−+ Cool
270−+ Alright
271−
272−### Link
273−
274−There are two ways to create links, but both contain the text be hyperlinked
275−in `[]` followed by the destination in `()`.
276−
277−The first type is an inline-style link, which simply uses the full URL as its
278−destination.
279−
280−**Example:**
281−
282−```
283−[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
284−```
285−
286−**Produces:**
287−
288−[I'm an inline-style link](https://www.urbit.org/docs/reference/shell)
289−
290−The second type is a reference-style link, which uses a relative path, based on
291−the current page's location. Instead of the full url, we use `..` to fill in
292−the all of the URL that the destination has in common with the origin page.
293−
294−**Example:**
295−
296−```
297−[I'm a reference-style link](../shell)
298−```
299−
300−**Produces:**
301−
302−[I'm a reference-style link](../shell)
303−
304−If this page is located at `https://www.urbit.org/docs/reference/`, then these two
305−examples should have the same destination.
306−
307−#### Anchor Link
308−
309−A link to a section of the same page is in the style of
310−`[text to be linked](#the-destination)`.
311−
312−The destination for the anchor link is designated with the HTML element `id`,
313−so we need to use some [Sail](#sail). If there are two or more anchors with
314−the same `id` on the page, you will arrive at the earliest instance of the the
315−anchor.
316−
317−**Example:**
318−
319−```
320−Check out this [section](#the-destination) that we want to jump to.
321−
322−Four score and seven years ago....
323−
324−It was the best of times, it was the worst of times...
325−
326−## Here we are!
327−```
328−
329−**Produces:**
330−
331−Check out this [section](#the-destination) that we want to jump to.
332−
333−Four score and seven years ago....
334−
335−It was the best of times, it was the worst of times...
336−
337−## Here we are!
338−
339−### Double Quote
340−
341−Text enclosed in double quotes (`"`) will be rendered with
342−opening and closing quotes -- that is, `“` and `”`.
343−
344−**Example:**
345−```
346−"Yes," he said. "That is the way with him."
347−```
348−
349−**Produces:**
350−
351−"Yes," he said. "That is the way with him."
352−
353−
354−### Code Literal
355−
356−There are two ways to show the literal text of code without running it: inline
357−and block. Both highlight the contained text in another color.
358−
359−Note that the backslash, due to its role as the escape character, can only be
360−displayed in a code block literal and not as inline code literal. This is a
361−bug.
362−
363−```
364−\
365−```
366−
367−#### Inline Code Literal
368−
369−Enclosing some text in
370−```
371−`
372−```
373−characters will cause it to be displayed as code,
374−inside a `<code>` HTML element with monospace font and highlighted with a
375−different background color.
376−
377−Using `` ` \`` is useful when you want to designated only part of a line as code.
378−Since this page is written in Udon, we've been using this operation
379−throughout this guide to `format text` to distinguish code from prose.
380−
381−**Example:**
382−```
383−`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
384−```
385−**Produces:**
386−
387−`*[a 2 b c] -> *[*[a b] *[a c]]` is like lisp's `apply`.
388−
389−Also, using the `++` prefix before a word will cause the word to be rendered as
390−code with the `++` displayed, since that's the standard notation for an arm in
391−Hoon.
392−
393−**Example:**
394−
395−```
396−The ++add arm is used to sum two numbers.
397−```
398−
399−**Produces:**
400−
401−The ++add arm is used to sum two numbers.
402−
403−#### Block Code Literal
404−
405−By enclosing a block of text in a tick on their own lines
406−before and after the contained text, the text will be treated as a code block.
407−
408−Most of our examples so far have used.
409−
410−**Example:**
411−
412−
413−```
414− ```
415− (def Y (fn [f]
416− ((fn [x]
417− (x x))
418− (fn [x]
419− (f (fn [y]
420− ((x x) y)))))))
421− ```
422−```
423−
424−**Produces:**
425−
426−```
427−(def Y (fn [f]
428− ((fn [x]
429− (x x))
430− (fn [x]
431− (f (fn [y]
432− ((x x) y)))))))
433−```
434−
435−### Hoon Constants
436−
437−Hoon has several syntactic forms for literals (numbers, strings, dates, etc.)
438−that can be used in udon as well. Udon detects such code, and so these
439−forms will automatically appear inside a `<code>` element like inline code.
440−
441−Example:
442−
443−```
444−~2017.8.29 \
445−0xdead.beef \
446−%term
447−```
448−
449−produces:\
450−
451−~2017.8.29 \
452−0xdead.beef \
453−%term
454−
455−
456−### Horizontal Rule
457−
458−Three or more hyphens, such as `---`, on their own line produce an `<hr>`
459−element, the 'horizontal rule'. This is rendered as a horizontal line the
460−width of its containing paragraph.
461−
462−**Example:**
463−
464−```
465−Above the line
466−---
467−Below the line
468−-----
469−And below this line, too
470−```
471−
472−**Produces:**
473−
474−
475−Above the line
476−---
477−Below the line
478−-----
479−And below this line, too
480−
481−### Block Quote
482−
483−A section of text with the first line beginning with `>` and a space,
484−and each successive newline indented by two spaces yields a
485−`<blockquote>` HTML element. This block quote can itself contain more Udon,
486−including more block quotes to render nested levels of quotation.
487−Inline italicization with `_` does not work, however.
488−
489−Blank newlines do not end the block quote, but a blank newline followed by an
490−unindented line of text _will_ end the quote.
491−
492−**Example:**
493−
494−```
495−> As Gregor Samsa awoke one morning from uneasy dreams, he
496− found himself transformed in his bed into a *monstrous* vermin.
497−
498−Quote break.
499−
500−> _See_ the child.
501−
502− He is pale and thin, he wears a thin and ragged linen shirt.
503−```
504−
505−**Produces:**
506−
507−> As Gregor Samsa awoke one morning from uneasy dreams
508− he found himself transformed in his bed into a **monstrous** vermin.
509−
510−Quote break.
511−
512−> _See_ the child.
513−
514− He is pale and thin, he wears a thin and ragged linen shirt.
515−
516−
517−### Poem
518−
519−A poem is a section of text with meaningful newlines. Recall that,
520−normally in Udon, newlines are treated as spaces and do not create a
521−new line of text. If you want to embed text where newlines are retained, then
522−indent the text in question with **eight spaces**.
523−
524−**Example:**
525−
526−```
527− A shape with lion body and the head of a man,
528− A gaze blank and pitiless as the sun,
529− Is moving its slow thighs, while all about it
530− Reel shadows of the indignant desert birds.
531−```
532−**Produces:**
533−
534− A shape with lion body and the head of a man,
535− A gaze blank and pitiless as the sun,
536− Is moving its slow thighs, while all about it
537− Reel shadows of the indignant desert birds.
538−
539−
540−## Sail Expressions
541−
542−It's possible to use Udon as an HTML templating language akin to
543−PHP, ERB, JSP, or Handlebars templates. This facility derives
544−in part from the support for embedding Hoon code inside the markup.
545−
546−
547−Sail is a domain-specific language within Hoon for creating XML nodes,
548−including HTML. It can be used directly within Udon to provide
549−scripting capability with Hoon and also to provide more precise control over the
550−resulting HTML. The [Sail guide](../sail) is a good place to learn the
551−specifics.
552−
553−Example:
554−
555−```
556−;=
557− ;p
558− ;strong: Don't panic!
559− <br>
560− ;small: [reactive publishing intensifies]
561− ==
562−==
563−```
564−
565−Produces:
566−
567−
568−<p>
569− <strong>Don't panic!</strong>
570− <br>
571− <small>[reactive publishing intensifies]</small>
572−</p>
573−
574−
575−## <a name="blog"></a>A Simple Udon Blog
576−
577−Publishing using Udon is really easy. It uses the file extension `.udon`. Here we'll create a very simple blog and publish our first posts.
578−
579−First, let's setup a desk to serve our posts from:
580−
581−```
582−|merge %site ~your-urbit %home
583−```
584−
585−Then let's mount that desk to unix:
586−
587−```
588−|mount /=site=
589−```
590−
591−You should now be able to find a `/site` folder inside of your pier
592−directory (either `comet/` or `your-urbit/`).
593−
594−To begin serving files from this new desk use `|serve`:
595−
596−```
597−|serve %site
598−```
599−
600−First let's create the landing page for our blog. Create the file
601−`site/web/blog.udon`:
602−
603−```
604−:- :~ anchor/'none'
605− ==
606−;>
607−
608−# Hello
609−
610−This is a simple blog I built on Urbit.
611−
612−;list(dataType "post");
613−```
614−
615−Try viewing this file at `http://localhost:8080`. Note that `8080` might be
616−`8081`, `8082`, and so on, depending if those ports were being used when you
617−started your urbit.
618−
619−The only special thing about this page is the `anchor/'none'` front-matter
620−which simply turns off the Tree navigation. Normally Tree gives navigation
621−controls for walking around the filesystem, but taking them away makes
622−the page seem more like a landing page.
623−
624−The page looks pretty boring now. Let's add our first post. From
625−unix run `mkdir your-urbit/site/web/blog; touch
626−your-urbit/site/web/blog/post-1.udon`. (Currently [there's a
627−bug](https://github.com/urbit/urbit/issues/321) that prevents empty
628−directories from getting created, so we have to `touch` a file inside
629−them first.) In `blog/post-1.udon` let's add some filler content:
630−
631−```
632−:- :~ navhome/'/blog'
633− type/'post'
634− date/'~2016.6.20'
635− title/'My first post!'
636− ==
637−;>
638−
639−Is this a decentralized Medium? Let's find out.
640−
641−But first, how about a long quote from Paramenides:
642−
643−> True, he said; and therefore when ideas are what they are in
644− relation to one another, their essence is determined by a relation
645− among themselves, and has nothing to do with the resemblances, or
646− whatever they are to be termed, which are in our sphere, and from
647− which we receive this or that name when we partake of them. And
648− the things which are within our sphere and have the same names
649− with them, are likewise only relative to one another, and not to
650− the ideas which have the same names with them, but belong to
651− themselves and not to them.
652−
653−Good to get that out of the way.
654−```
655−
656−You should be able to view this file at:
657−`http://localhost:8080/blog/post-1.udon`.
658−
659−You'll also notice that
660−now the list of posts here: `http://localhost:8080/blog` has
661−updated.
662−
663−Here we use two pieces of front-matter worth noting: `type` and `navhome`.
664−
665−- `type` implies that the page has some special handling by Tree. When `type` is
666− `post` we automatically put in the `date`, `title` and `author` when they're
667− specified and add some styles.
668−
669−- `navhome` sets the path used by the home button (the circle in the top left).
670− Since we want to send people back to the root of our blog, we set this to `/blog`
671−
672−Adding posts is as easy as dropping Udon files into the `blog/`
673−directory. Pretty easy!
674−
675−### Blog comments
676−
677−Now let's enable comments on a blog post.
678−
679−First, turn comments on by editing the frontmatter in `post-1.udon`. Your
680−frontmatter should look like this:
681−
682−```
683−:- :~ navhome/'/blog'
684− type/'post'
685− date/'~2018.6.20'
686− title/'Blog comments'
687− comments/'true'
688− ==
689−;>
690−```
691−
692−Now try loading your post here: `your-urbit.urbit.org/blog/post-1`.
693−You should see a comments box at the bottom of the page.
694−
695−Try posting a comment! When you do you should see the following in
696−your console:
697−
698−```
699−+ /~your-urbit/home/55/web/blog/post-1/comments/~2016.6.20..23.20.54..0b88/md
700−------------[0]
701−~your-urbit[tree]: receiving comments, ;join %comments for details
702−```
703−
704−Comments are written into the filesystem in the `comments/` folder
705−relative to the page they're enabled on. When a new comment is posted
706−a notification is also posted to the `/comments` `:talk` channel.
707−
708−Use `;join` to keep up with comments as they get posted:
709−
710−```
711−;join ~your-urbit/comments
712−```
713−
714−That's it! Easy.
715−
716−## <a name="static"></a>A Static Site
717−
718−Hosting a static tree of content is easy. Let's put together a really
719−simple site for an imaginary Urbit meetup group.
720−
721−We assume you have at least followed the beginning of [our first
722−examples](#blog) and created a desk called `site` and mounted it to
723−unix.
724−
725−Note: below we use Urbit's implementation of Markdown, [Udon](#udon).
726−This markup language allows you to use snippets of Hoon code but not HTML.
727−In particular, we use Sail, a subset of Hoon. This Sail is rendered as HTML
728−when the file is served to a client. To learn about Sail, head over to
729−the [Sail](/docs/learn/arvo/arvo-internals/sail) section of the docs.
730−
731−In `site/web/meet.udon` put:
732−
733−```
734−:- :~ navhome/'/meet'
735− navdpad/'false'
736− navpath/'/meet'
737− navmode/'navbar'
738− ==
739−;>
740−
741−# Neo-Tokyo Urbit meetup
742−
743−![](https://ofheroesandcliches.files.wordpress.com/2014/06/neo-tokyo.png)
744−
745−Hi there! We meet once a week at The Chat to work on Urbit projects
746−together.
747−
748−You can find out more about the group on the [about](about) page and
749−follow our projects in [projects](projects).
750−```
751−
752−This is our landing page. Here we're using a few new bits of frontmatter:
753−`navdpad`, `navmode` and `navpath`. `navdpad` just turns off the nav
754−arrows. `navmode` can be set to 'navbar' to switch to a horizontal top
755−nav instead of a left bar. `navpath` sets the path to load the nav
756−items from.
757−
758−Let's create `about.udon` and `projects.udon`. From Unix use the
759−technique from before to create a new directory: `mkdir
760−your-urbit/site/web/meet/; touch your-urbit/site/web/meet/about.udon`.
761−Then put the following in `site/web/about.udon`:
762−
763−```
764−:- :~ navhome/'/meet'
765− navdpad/'false'
766− navpath/'/meet'
767− navmode/'navbar'
768− title/'About'
769− ==
770−;>
771−
772−# About
773−
774−## Mission statement
775−
776−The existing framework cannot subdue the new human force that is increasing day
777−by day alongside the irresistible development of technology and the
778−dissatisfaction of its possible uses in our senseless social life.
779−
780−## Members
781−
782−Membership is open to anyone. Just send a message to `~talsur-todres`.
783−
784−- Shōtarō Kaneda
785−- Motoko Kusanagi
786−- Ishikawa
787−- Faye Valentine
788−- Spike Spiegel
789−```
790−
791−And `site/web/projects.udon`:
792−
793−```
794−:- :~ navhome/'/meet'
795− navdpad/'false'
796− navpath/'/meet'
797− navmode/'navbar'
798− title/'Projects'
799− ==
800−;>
801−
802−# Projects
803−
804−## Active
805−
806−;list;
807−
808−## Discussion
809−
810−;div(class "mini-module")
811− ;script(src "/~/at/lib/js/urb.js");
812− ;script(src "https://cdn.rawgit.com/seatgeek/react-infinite/0.8.0/dist/react-infinite.js");
813− ;script(src "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment-with-locales.js");
814− ;script(src "https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.1/moment-timezone.js");
815− ;script(src "/talk/main.js");
816− ;link(href "/talk/main.css", rel "stylesheet");
817− ;talk(readonly "", chrono="reverse", station="comments");
818−==
819−```
820−
821−This page introduces a new thing: the `:talk` module. Inside of the
822−`mini-module` div we load the scripts needed by the `;talk`
823−component. The `;talk` component is a static component for
824−displaying a feed from a talk channel inline. Here we're going to
825−display the discussion from our active projects inline.
826−
827−We'll need a few active projects though. From unix: `mkdir
828−your-urbit/site/web/meet/projects; touch
829−your-urbit/site/web/meet/projects/bike.udon`.
830−
831−In `site/web/meet/projects/bike.udon`:
832−
833−```
834−:- :~ navhome/'/meet'
835− navdpad/'false'
836− navpath/'/meet'
837− navmode/'navbar'
838− title/'Kaneda's Bike'
839− comments/'true'
840− ==
841−;>
842−
843−# Urbit on a Motorcycle
844−
845−Discussion on getting urbit to power Kaneda's motorcycle.
846−```
847−
848−Here we just use the `comments` frontmatter to enable comments on the page.
849−Adding other imaginary projects is left to the reader.
850−
851−Building a static site takes only a few minutes and a few Udon files. Have fun!