diff options
| author | s-ol <s+removethis@s-ol.nu> | 2021-10-04 14:13:31 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2021-10-04 14:48:31 +0000 |
| commit | e7b84a65084e17d5da64fe1fa716d7a186ed701c (patch) | |
| tree | 61b2c6b140c644c0544b3255aae0069550d963aa /root | |
| parent | add mmmfs pdf (diff) | |
| download | mmm-e7b84a65084e17d5da64fe1fa716d7a186ed701c.tar.gz mmm-e7b84a65084e17d5da64fe1fa716d7a186ed701c.zip | |
Split root out of mmm repo
Diffstat (limited to 'root')
513 files changed, 2 insertions, 7621 deletions
diff --git a/root/$order b/root/$order deleted file mode 100644 index 4d1bfa6..0000000 --- a/root/$order +++ /dev/null @@ -1,10 +0,0 @@ -about -blog -research -workshops -games -projects -experiments -meta -portfolio -static diff --git a/root/about/text$markdown.md b/root/about/text$markdown.md deleted file mode 100644 index e025141..0000000 --- a/root/about/text$markdown.md +++ /dev/null @@ -1,6 +0,0 @@ -about me -======== -i am s-ol bekic, a designer and creative technologist currently based in milano. -if you are looking for an overview over my work or skillset, take a look at my [portfolio][portfolio]. - -[portfolio]: /portfolio/ diff --git a/root/blog/$order b/root/blog/$order deleted file mode 100644 index a1d0650..0000000 --- a/root/blog/$order +++ /dev/null @@ -1,12 +0,0 @@ -humane_filesystems -ludum_dare_33_postmortem -video_synth_research -love_lua_photoshop_and_games -clocks_triggers_gates -stretching_gates -stencils_101 -aspect_ratios -automating_my_rice -challenging_myself -self-hosted_virtual_home -why_redirectly diff --git a/root/blog/aspect_ratios/$order b/root/blog/aspect_ratios/$order deleted file mode 100644 index 09e38bd..0000000 --- a/root/blog/aspect_ratios/$order +++ /dev/null @@ -1 +0,0 @@ -interactive diff --git a/root/blog/aspect_ratios/date: time$iso8601-date b/root/blog/aspect_ratios/date: time$iso8601-date deleted file mode 100644 index 1f5943f..0000000 --- a/root/blog/aspect_ratios/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2019-07-12 diff --git a/root/blog/aspect_ratios/interactive/_base: text$moonscript -> table.moon b/root/blog/aspect_ratios/interactive/_base: text$moonscript -> table.moon deleted file mode 100644 index 0219af6..0000000 --- a/root/blog/aspect_ratios/interactive/_base: text$moonscript -> table.moon +++ /dev/null @@ -1,119 +0,0 @@ -import div, a from require 'mmm.dom' -import interactive_link from (require 'mmm.mmmfs.util') require 'mmm.dom' - -if MODE ~= 'CLIENT' - class Dummy - render: => - div { - style: - position: 'relative' - resize: 'horizontal' - overflow: 'hidden' - - width: '480px' - height: '270px' - 'min-width': '270px' - 'max-width': '100%' - - margin: 'auto' - padding: '10px' - boxSizing: 'border-box' - background: 'var(--gray-bright)' - - interactive_link '(click here for the interactive version of this article)' - } - - return { - UIDemo: Dummy - Example: Dummy - } - -import CanvasApp from require 'mmm.canvasapp' - -class UIDemo extends CanvasApp - width: nil - height: nil - new: () => - super! - - @canvas.width = nil - @canvas.height = nil - @canvas.style.width = '100%' - @canvas.style.height = '100%' - @canvas.style.border = '2px solid var(--gray-dark)' - - @node = div @canvas, style: { - position: 'relative' - resize: 'horizontal' - overflow: 'hidden' - - width: '480px' - height: '270px' - minWidth: '270px' - maxWidth: '100%' - - margin: 'auto' - padding: '10px' - boxSizing: 'border-box' - } - - -- match size of current parent element and return it (for interactive resizing in the demo) - updateSize: => - { :clientWidth, :clientHeight } = @canvas.parentElement - @canvas.width, @canvas.height = clientWidth, clientHeight - @canvas.width, @canvas.height - - -- set up a coordinate system such that the virtual viewport - -- of size (w, h) is centered on (0,0) and fills the canvas - -- returns remaining margins on the two axes - fit: (w, h) => - width, height = @updateSize! - @ctx\translate width/2, height/2 - - -- maximum scale without cropping either axis - scale = math.min (width/w), (height/h) - @ctx\scale scale, scale - - -- calculate remaining space on x/y axis - rx = (width/scale) - w - ry = (height/scale) - h - - -- margins are half of the remaining space - rx / 2, ry / 2 - - strokeRect: (cx, cy, w, h) => - lw = @ctx.lineWidth / 2 - @ctx\strokeRect cx - w/2 + lw, cy - h/2 + lw, - w - 2*lw, h - 2*lw, - -class Box - new: (@cx, @cy, @w, @h) => - - rect: => - @cx, @cy, @w, @h - -class Example extends UIDemo - click: => - if @naive - @naive = false - else - if @show_boxes - @naive = true - @show_boxes = not @show_boxes - - text: (box, text, align='center', my=.5) => - mx = .1 - @ctx.textAlign = align - - if align == 'left' - @ctx\fillText text, box.cx + mx - box.w/2, box.cy + my - else if align == 'center' - @ctx\fillText text, box.cx, box.cy + my - if align == 'right' - @ctx\fillText text, box.cx - mx + box.w/2, box.cy + my - -{ - :UIDemo - :Example - :Box -} diff --git a/root/blog/aspect_ratios/interactive/fit: text$moonscript -> fn -> mmm$component.moon b/root/blog/aspect_ratios/interactive/fit: text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index 33478bf..0000000 --- a/root/blog/aspect_ratios/interactive/fit: text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,15 +0,0 @@ -=> - import UIDemo from @get '_base: table' - - class FitDemo extends UIDemo - draw: => - @fit 16, 9 - @ctx.fillStyle = 'red' - @ctx\fillRect -8, -4.5, 16, 9 - - @ctx.fillStyle = 'black' - @ctx.font = '6px Arial' - @ctx.textAlign = 'center' - @ctx\fillText '16:9', 0, 2 - - FitDemo! diff --git a/root/blog/aspect_ratios/interactive/perforate: text$moonscript -> fn -> mmm$component.moon b/root/blog/aspect_ratios/interactive/perforate: text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index 905c313..0000000 --- a/root/blog/aspect_ratios/interactive/perforate: text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,34 +0,0 @@ -=> - import UIDemo from @get '_base: table' - - arr = (args) -> - with js.new js.global.Array - for i in *args - \push i - - class PerforateDemo extends UIDemo - draw: => - @fit 16, 9 - - @ctx.lineWidth = 0.15 - @ctx.strokeStyle = 'green' - @strokeRect 0, -3.5, 16, 2 - @strokeRect 0, 3.5, 16, 2 - - @ctx\setLineDash arr { 0.4 } - @ctx\beginPath! - @ctx\moveTo 0, -4.5 - @ctx\lineTo 0, -2.5 - @ctx\moveTo 0, 2.5 - @ctx\lineTo 0, 4.5 - @ctx\stroke! - @ctx\setLineDash arr {} - - @ctx.strokeStyle = 'blue' - @strokeRect 0, 0, 16, 5 - - @ctx.font = '4px Arial' - @ctx.textAlign = 'center' - @ctx\fillText '16:5', 0, 1.5 - - PerforateDemo! diff --git a/root/blog/aspect_ratios/interactive/sidebar: text$moonscript -> fn -> mmm$component.moon b/root/blog/aspect_ratios/interactive/sidebar: text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index 56e6cea..0000000 --- a/root/blog/aspect_ratios/interactive/sidebar: text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,46 +0,0 @@ -=> - import Box, Example from @get '_base: table' - - class Sidebar extends Example - draw: => - margin_x, margin_y = @fit 16, 9 - if @naive - margin_x, margin_y = 0, 0 - - @ctx.font = '1.5px Arial' - sidebar = Box -7 - margin_x, -1, 2, 7 - @text sidebar, 'A', 'center', -1.8 - @text sidebar, 'B', 'center', -0.3 - @text sidebar, 'C', 'center', 1.2 - @text sidebar, 'D', 'center', 2.7 - - bottom_l = Box -4 - margin_x, 3.5 + margin_y, 8, 2 - bottom_r = Box 4 + margin_x, 3.5 + margin_y, 8, 2 - - @text bottom_l, 'levelname', 'left' - @text bottom_r, 'info a b c', 'right' - - main = Box 1, -1, 14, 7 - @ctx.lineWidth = 0.1 - @ctx.strokeStyle = 'black' - @ctx\beginPath! - for x=-5.5, 7.5 - @ctx\moveTo x, -4.5 - @ctx\lineTo x, 2.5 - - for y=-4, 2 - @ctx\moveTo -6, y - @ctx\lineTo 8, y - @ctx\stroke! - - if @show_boxes - @ctx.lineWidth = 0.1 - @ctx.strokeStyle = 'green' - @strokeRect sidebar\rect! - @strokeRect bottom_l\rect! - @strokeRect bottom_r\rect! - - @ctx.strokeStyle = 'blue' - @strokeRect main\rect! - - Sidebar! diff --git a/root/blog/aspect_ratios/interactive/tear: text$moonscript -> fn -> mmm$component.moon b/root/blog/aspect_ratios/interactive/tear: text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index 1705b80..0000000 --- a/root/blog/aspect_ratios/interactive/tear: text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,28 +0,0 @@ -=> - import UIDemo from @get '_base: table' - - arr = (args) -> - with js.new js.global.Array - for i in *args - \push i - - class TearDemo extends UIDemo - draw: => - margin_x, margin_y = @fit 16, 9 - - @ctx.lineWidth = 0.15 - @ctx.strokeStyle = 'green' - @strokeRect -4 - margin_x, -3.5 - margin_y, 8, 2 - @strokeRect 4 + margin_x, -3.5 - margin_y, 8, 2 - - @strokeRect -4 - margin_x, 3.5 + margin_y, 8, 2 - @strokeRect 4 + margin_x, 3.5 + margin_y, 8, 2 - - @ctx.strokeStyle = 'blue' - @strokeRect 0, 0, 16, 5 - - @ctx.font = '4px Arial' - @ctx.textAlign = 'center' - @ctx\fillText '16:5', 0, 1.5 - - TearDemo! diff --git a/root/blog/aspect_ratios/interactive/vtk: text$moonscript -> fn -> mmm$component.moon b/root/blog/aspect_ratios/interactive/vtk: text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index c2d17d0..0000000 --- a/root/blog/aspect_ratios/interactive/vtk: text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,55 +0,0 @@ -=> - import Box, Example from @get '_base: table' - - class VTK extends Example - draw: => - margin_x, margin_y = @fit 16, 9 - if @naive - margin_x, margin_y = 0, 0 - - levelname = Box -4 - margin_x, -3.5 - margin_y, 8, 2 - settings = Box 4 + margin_x, -3.5 - margin_y, 8, 2 - infobar = Box -4 - margin_x, 3.5 + margin_y, 8, 2 - exit = Box 4 + margin_x, 3.5 + margin_y, 8, 2 - - main = Box 0, 0, 16, 5 - - @ctx.font = '1.5px Arial' - @text levelname, 'levelname', 'left' - @text infobar, 'info a b c', 'left' - @text settings, 'settings', 'right' - @text exit, 'exit', 'right' - - @ctx.lineWidth = 0.2 - @ctx.strokeStyle = 'black' - @ctx\beginPath! - @ctx\moveTo -8 - margin_x, -2.5 - margin_y - @ctx\lineTo 8 + margin_x, -2.5 - margin_y - @ctx\moveTo -8 - margin_x, 2.5 + margin_y - @ctx\lineTo 8 + margin_x, 2.5 + margin_y - @ctx\stroke! - - @ctx.lineWidth = 0.1 - @ctx.strokeStyle = 'gray' - @ctx\beginPath! - for x=-7.5, 7.5 - @ctx\moveTo x, -2.5 - @ctx\lineTo x, 2.5 - - for y=-2, 2 - @ctx\moveTo -8, y - @ctx\lineTo 8, y - @ctx\stroke! - - if @show_boxes - @ctx.lineWidth = 0.1 - @ctx.strokeStyle = 'green' - @strokeRect levelname\rect! - @strokeRect settings\rect! - @strokeRect infobar\rect! - @strokeRect exit\rect! - - @ctx.strokeStyle = 'blue' - @strokeRect main\rect! - - VTK! diff --git a/root/blog/aspect_ratios/text$markdown.md b/root/blog/aspect_ratios/text$markdown.md deleted file mode 100644 index 2284317..0000000 --- a/root/blog/aspect_ratios/text$markdown.md +++ /dev/null @@ -1,77 +0,0 @@ -Dealing with different screen sizes and formats can be annoying. -On desktop PCs, 16:9 is the most common aspect ratio these days, but depending on where you are rendering your content, -it might still be a different format, for example when a task bar, broswer navigation bar or similar is slicing away some of your screen real-estate. -For mobile games the situation is a bit worse, because there are simply more different aspect ratios out there -and different systems may require extra space for on-screen navigation keys, statusbars etc. - -In this post I want to present a simple technique for layouting **simple UIs for games** that can work across a range of similar screens. -If you are looking for a way to design a UI-heavy app, or something that needs to work across very different environments (like phones, tablets and desktop PCs), this is probably not what you are looking for. -In any case, if you just want to take a quick look you can jump down to the [examples](#examples) at the bottom of the page as well. - -## step one: `fit` -The most trivial solution is to simply choose the aspect ratio you would like to work with, -and then fit a rectangle with that ratio into whichever space is available. -Depending on the screen, this may either be a perfect fit, leave space on the horizontal axis, or leave space on the vertical axis: -(drag the lower right corner to see this approach react to different screen sizes) - -<mmm-embed path="interactive" facet="fit" nolink></mmm-embed> - -This is pretty trivial to accomplish in code. -You can calculate the scales in relation to your reference grid on the x and y axis separately, and simply use the one with a lower value. -Establishing a reference grid and knowing the scale to translate between it and the physical screen sizes will also help -designing the layout in general, as we will see later. -Here is a simple example in JS: - -```js -// measured from somewhere -const width = 2000; -const height = 1080; - -const sx = width / 16; -const sy = height / 9; - -const scale = Math.min(sx, sy); -const offset_x = width * (1 - scale); -const offset_y = height * (1 - scale); - -// the biggest 16:9 rectangle you can fit is (scale*width, scale*height) large -// and it's top-left corner is at (offset_x/2, offset_y/2) -``` - -The problem with this is that it simply doesn't look very good. When the ratio is a perfect match there is of course no problem, -but otherwise the empty space makes the screen look empty (especially if there are system UI elements next to it). - -## step two: `perforate` -So how can this be improved? We would like to use the unused space on the x or y axis, but we can't just scale everything up, -or we would start cropping important pieces of UI. Stretching the game to fill the screen also doesn't work for obvious reasons. - -To proceed, the UI has to be 'perforated' into different sections that are independent from each other. -This is where establishing a reference grid becomes useful to orient ourselves in the layout. -In my example I am splitting the screen into a main content section that is 16:5 units large, as well as a top and bottom bar. -The two bars are also split in half vertically in the middle, for reasons that we will see in the third step. - -<mmm-embed path="interactive" facet="perforate" nolink></mmm-embed> - -It's imortant to note that how you divide the screen up depends completely on your game/interface of course. -The layout I am using here is just an example; at the end of this post you can find another one with a different layout as well. - -## step three: `tear` - -Now that the sections are defined, in the last step we can 'tear' the sections apart and decide how they should react to the -left-over space calculated in step one individiually. -In my layout, I stretch the top and bottom bars to fill the screen completely horizontally. -By dividing the bars into separate sections in the last step, I know how much space is guaranteed to be available on each side. -If there is room left on the vertical axis, I move the bars out from the center to give the content some visual space: - -<mmm-embed path="interactive" facet="tear" nolink></mmm-embed> - -Once again, how you make the pieces behave depends a lot on what elements your UI has in the first place, and how you want it to look and feel. - -# examples - -Finally, here are two examples with a bit more visual coherence to show how this actually ends up working. -You can click on these to cycle between the normal view, showing the frames used to subdivide the canvas, and viewing `fit` only for comparison. - -<mmm-embed path="interactive" facet="vtk" nolink></mmm-embed> -<mmm-embed path="interactive" facet="sidebar" nolink></mmm-embed> - diff --git a/root/blog/aspect_ratios/title: text$plain b/root/blog/aspect_ratios/title: text$plain deleted file mode 100644 index 464c7ef..0000000 --- a/root/blog/aspect_ratios/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Aspect-ratio independent UIs diff --git a/root/blog/automating_my_rice/$order b/root/blog/automating_my_rice/$order deleted file mode 100644 index 17ec504..0000000 --- a/root/blog/automating_my_rice/$order +++ /dev/null @@ -1,15 +0,0 @@ -sexy -dark -bwcube -tattooed -polysun -hotline -sidewalk -akira -laying -touching -twostripe -trippy -polar -cavetree -psych diff --git a/root/blog/automating_my_rice/akira/image$png.png b/root/blog/automating_my_rice/akira/image$png.png Binary files differdeleted file mode 100644 index e0b095d..0000000 --- a/root/blog/automating_my_rice/akira/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/bwcube/image$png.png b/root/blog/automating_my_rice/bwcube/image$png.png Binary files differdeleted file mode 100644 index 0470a3a..0000000 --- a/root/blog/automating_my_rice/bwcube/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/categories: text$plain b/root/blog/automating_my_rice/categories: text$plain deleted file mode 100644 index e56b603..0000000 --- a/root/blog/automating_my_rice/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update ricing linux themer
\ No newline at end of file diff --git a/root/blog/automating_my_rice/cavetree/image$png.png b/root/blog/automating_my_rice/cavetree/image$png.png Binary files differdeleted file mode 100644 index 9dda817..0000000 --- a/root/blog/automating_my_rice/cavetree/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/dark/image$png.png b/root/blog/automating_my_rice/dark/image$png.png Binary files differdeleted file mode 100644 index 8386f69..0000000 --- a/root/blog/automating_my_rice/dark/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/date: time$iso8601-date b/root/blog/automating_my_rice/date: time$iso8601-date deleted file mode 100644 index f54d08b..0000000 --- a/root/blog/automating_my_rice/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2015-08-08 diff --git a/root/blog/automating_my_rice/hotline/image$png.png b/root/blog/automating_my_rice/hotline/image$png.png Binary files differdeleted file mode 100644 index 1d9cf2f..0000000 --- a/root/blog/automating_my_rice/hotline/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/laying/image$png.png b/root/blog/automating_my_rice/laying/image$png.png Binary files differdeleted file mode 100644 index 4b7bc5f..0000000 --- a/root/blog/automating_my_rice/laying/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/polar/image$png.png b/root/blog/automating_my_rice/polar/image$png.png Binary files differdeleted file mode 100644 index 113b0de..0000000 --- a/root/blog/automating_my_rice/polar/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/polysun/image$png.png b/root/blog/automating_my_rice/polysun/image$png.png Binary files differdeleted file mode 100644 index 8fef054..0000000 --- a/root/blog/automating_my_rice/polysun/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/psych/image$png.png b/root/blog/automating_my_rice/psych/image$png.png Binary files differdeleted file mode 100644 index 93628f6..0000000 --- a/root/blog/automating_my_rice/psych/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/sexy/image$png.png b/root/blog/automating_my_rice/sexy/image$png.png Binary files differdeleted file mode 100644 index 00cb65d..0000000 --- a/root/blog/automating_my_rice/sexy/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/sidewalk/image$png.png b/root/blog/automating_my_rice/sidewalk/image$png.png Binary files differdeleted file mode 100644 index 3d53ff2..0000000 --- a/root/blog/automating_my_rice/sidewalk/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/tattooed/image$png.png b/root/blog/automating_my_rice/tattooed/image$png.png Binary files differdeleted file mode 100644 index 7ed2f33..0000000 --- a/root/blog/automating_my_rice/tattooed/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/text$markdown.md b/root/blog/automating_my_rice/text$markdown.md deleted file mode 100644 index 87b3405..0000000 --- a/root/blog/automating_my_rice/text$markdown.md +++ /dev/null @@ -1,46 +0,0 @@ -I spent the bigger part of today writing a small script that cylces through all my [Themer][themer] themes, -opens a dmenu, prints the theme name with figlet and shows screenfetch before taking a picture. -The script is pretty straightforward: - - #!/usr/bin/bash - - for theme in $(themer list); do - themer activate $theme - sleep 20 # wait for bar :/ - dmenu -p "Launch:" $(~/.i3/dmenuconf) < ~/.cache/dmenu_run & - dmenupid=$! - clear - screenfetch - echo - toilet --gay $theme - echo;echo;echo;echo;echo;echo;echo - themer current - - sleep 1 - scrot $theme.png - kill $dmenupid - done - -So here are all my current themes: - -<mmm-embed path="cavetree"></mmm-embed> -<mmm-embed path="akira"></mmm-embed> -<mmm-embed path="sidewalk"></mmm-embed> -<mmm-embed path="hotline"></mmm-embed> -<mmm-embed path="polar"></mmm-embed> -<mmm-embed path="polysun"></mmm-embed> -<mmm-embed path="psych"></mmm-embed> -<mmm-embed path="trippy"></mmm-embed> -<mmm-embed path="twostripe"></mmm-embed> -<mmm-embed path="bwcube"></mmm-embed> - -The wallpaper for the last one is intended to be tiled, not stretched, but that currently requries a manual change in my i3 config: -<mmm-embed path="dark"></mmm-embed> - -I am thinking about implementing this as a Themer feature, but it would require it's own *presentation* plugin type, -so everyone can choose their own commands, bars, and waiting time. - -You can find more information about [Themer on the github page][themer], along with all my [config files][dotfiles]. - -[themer]: https://github.com/s-ol/themer -[dotfiles]: https://github.com/s-ol/dotfiles diff --git a/root/blog/automating_my_rice/title: text$plain b/root/blog/automating_my_rice/title: text$plain deleted file mode 100644 index c898a4c..0000000 --- a/root/blog/automating_my_rice/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Automating my Rice
\ No newline at end of file diff --git a/root/blog/automating_my_rice/touching/image$png.png b/root/blog/automating_my_rice/touching/image$png.png Binary files differdeleted file mode 100644 index 01d1520..0000000 --- a/root/blog/automating_my_rice/touching/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/trippy/image$png.png b/root/blog/automating_my_rice/trippy/image$png.png Binary files differdeleted file mode 100644 index 7cb4354..0000000 --- a/root/blog/automating_my_rice/trippy/image$png.png +++ /dev/null diff --git a/root/blog/automating_my_rice/twostripe/image$png.png b/root/blog/automating_my_rice/twostripe/image$png.png Binary files differdeleted file mode 100644 index a935968..0000000 --- a/root/blog/automating_my_rice/twostripe/image$png.png +++ /dev/null diff --git a/root/blog/challenging_myself/categories: text$plain b/root/blog/challenging_myself/categories: text$plain deleted file mode 100644 index 77c430a..0000000 --- a/root/blog/challenging_myself/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update
\ No newline at end of file diff --git a/root/blog/challenging_myself/date: time$iso8601-date b/root/blog/challenging_myself/date: time$iso8601-date deleted file mode 100644 index 6472c5d..0000000 --- a/root/blog/challenging_myself/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2015-06-27 diff --git a/root/blog/challenging_myself/text$markdown.md b/root/blog/challenging_myself/text$markdown.md deleted file mode 100644 index aaddf08..0000000 --- a/root/blog/challenging_myself/text$markdown.md +++ /dev/null @@ -1,25 +0,0 @@ -# Yay, a first post! A blank blog! - -I am starting to blog now as part of an... experiment of sorts. -I have a lot of time on my hands at the moment and I choose to spend it all boring myself. -I re-discovered [streak.club][streak.club] a few days ago and so I decided to give it a shot and try a few new things. - -If you never heard of **streak.club**, you should definetely check it out. -It is a small social network built by [leafo](https://twitter.com/moonscript) where people can get together and participate in *Streaks*. -Once you join a streak, you submit an entry every day or every week (depending on the Streak's settings). -People can then like and comment on your entries and give you feedback for your creations. -If you miss a day, nothing bad happens, but yout streak counter gets reset. - -One of the streaks I joined is the [*Blog every week*][blogeweek] streak, which I will submit this first post to when I am done. -I also created my own streak, [*Daily Stencil Art*][stencils]. So, for the next month, I will try to design and/or paint one stencil per day. -The [first stencil](https://streak.club/p/7129/kill-bill-the-bride-stencil-by-s0lll0s) I did for the streak turned out really nice, so I will continue to design some in that art style (gold background with black shadow pieces on top and a small piece in an accent color). - -As for the future of this blog, I am not quite sure where this will go. -I think I am going to cover my stencil creation process in a post soon (maybe today, maybe next week, who knows?) and also blog about programming/development of games and other stuff I might write. -Maybe I will also port some of the tutorials I have written so far to markdown and put them here aswell. - -I hope that **streak.club** will work as well long-term as it does right now, motivation is still probably my number one enemy and streak.club is an excellent way for me to focus on new things and get away from the computer some more aswell. - -[streak.club]: https://streak.club -[stencils]: https://streak.club/s/614/daily-stencil-art -[blogeweek]: https://streak.club/s/103/blog-every-week diff --git a/root/blog/challenging_myself/title: text$plain b/root/blog/challenging_myself/title: text$plain deleted file mode 100644 index 9ec0a3e..0000000 --- a/root/blog/challenging_myself/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Challenging myself
\ No newline at end of file diff --git a/root/blog/clocks_triggers_gates/$order b/root/blog/clocks_triggers_gates/$order deleted file mode 100644 index f4ac304..0000000 --- a/root/blog/clocks_triggers_gates/$order +++ /dev/null @@ -1,6 +0,0 @@ -tyktok_test -tyktok_leds -tyktok_tired -metronome -tyktok_tomcat -threshold diff --git a/root/blog/clocks_triggers_gates/categories: text$plain b/root/blog/clocks_triggers_gates/categories: text$plain deleted file mode 100644 index ecfcf4f..0000000 --- a/root/blog/clocks_triggers_gates/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update gamedev electronics
\ No newline at end of file diff --git a/root/blog/clocks_triggers_gates/date: time$iso8601-date b/root/blog/clocks_triggers_gates/date: time$iso8601-date deleted file mode 100644 index 19880e9..0000000 --- a/root/blog/clocks_triggers_gates/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2017-06-28 diff --git a/root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg b/root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg Binary files differdeleted file mode 100644 index 70fedb5..0000000 --- a/root/blog/clocks_triggers_gates/metronome/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/clocks_triggers_gates/text$markdown.md b/root/blog/clocks_triggers_gates/text$markdown.md deleted file mode 100644 index 240cf80..0000000 --- a/root/blog/clocks_triggers_gates/text$markdown.md +++ /dev/null @@ -1,137 +0,0 @@ -A classic module in modular synthesisers is a sequencer. It allows you to create rhythms and -melodies by letting you set a sequence of values to output over some time. -For example a drum machine usually contains a step-sequencer where for every *step* in the -*sequence* you can select whether to play, or not play, a drum. - -*CV Sequencers* haver a dial in place of that on/off switch, where you can set a value for the -*Control_Voltage* to be output. -That signal can then be fed into another module to do something interesting, like control the -pitch of an oscillator, the cut-off point of a filter or the gain of an amplifier. - -Sequencers usually have an internal clock, with a dial to set the speed, but also an external clock -input, where you can feed in a square wave signal. -Every time the square wave goes from low (0V) to high (usually anything over 5V) the sequencer steps -to the next beat. - -Since we have a multitude of sound-generators that we want to use in interesing rhythms, multiple -sequencers sound natural and a central clock could certainly help. - -## hit it -However a digital, steady clock is pretty boring, so I came up with an idea. -I remembered the old wooden metronome that my grandma had at her piano and how I used to play with -it as a child. If we had a real metronome tick away, we could hold the needle in place, -tap it to add an extra beat where there wasn't supposed to be one and more. - -<mmm-embed path="metronome"></mmm-embed> - -Analog metronomes like this are actually pretty interesting little devices. -They are purely mechanical and contain a spring that you have to wind up to give it power. -On the front there is a needle with a weight at the top and the bottom. -By moving the top weight up and down the speed of the needle, -and thereby the ticking-rate can be set. -Every time the needle centers (like it is on the image below), a mechanism in the back makes a small -metal pin slam against a metal plate glued to the case, making a loud clicking noise. - -With this idea, we were on the lookout for a metronome on our trip to the fleamarket -but couldn't find one, so I ended up buying the tiny one above (the size is pretty nice anyway). - -The idea was (and it worked out that way!) to pick up the clicks somehow and use them to trigger -sequencers. -Originally I thought about putting a light dependant resistor (LDR) somewhere under the -counterweight, and measure the shadow as a signal. -In the time until I got the Metronome, I discussed this with Sam Battle, who runs the awesome -youtube channel [LOOK MUM NO COMPUTER][no-computer], and he proposed to use a piezo crystal -(sometimes referred to as *Contact Mic*) instead. - -As it turns out, the metronome has plenty of space to glue the piezo right next to the metal plate -that the metronome hits with the metal pin, where it can pick up all that very nicely. -The 1/4" (6.3mm) audio jack also fit very well behind the panel, where there is a rather large -empty compartment, I guess to amplifiy the ticking sound. -I just drilled a hole in the back, screwed the jack in and soldered two wires; done! - -<mmm-embed path="tyktok_test" nolink></mmm-embed> - -In this first test you can see the Piezo work as a microphone amplifying the ticking noise on my -speakers. - -## signal shapes -That was a first success, but the signal we get from the metronome is not very clean. -Not only does it pick up random noises from the environment (sometimes intentionally), -the click is no square wave since it resonates through the plastic material. - -To clean up the signal initially I took a look on it on the Oscilloscope. -It looks pretty much like what you would expect, swinging up and down a few times, -each with a drastic drop in amplitude. - -The first attempt was to just use a comparator. -The output from the metronome goes to the non-inverting-input, meaning that when it is higher than -the other (inverting) input, the output of the comparator swings high. -This is what I wanted since sequencers trigger on the rising edge. -The inverting input is wired to a potentiometers center pin, with the other two pins at the supply -voltage and ground (0 and 9V) to form a voltage divider that lets me tune the threshold to any -any voltage in that range. -The output signal is now what you would call a *Trigger* signal; it is usually low and sometimes -jumps up to 9V for a *very short* duration (while the tick clips over the threshold on it's first -and loudest swing). I didn't measure the pulse length, but it's probably under 10ms long. - -To test the circuit, I fed the output to a (CD)4017 counter. -This IC can be used to build sequencers or clock dividers rather easily (more on that later). -I just set it up to light up 4 LEDs in sequence, so that I could see whether the circuit was fine. -After an hour or so of figuring out stupid wiring mistakes and learning about open-drain outputs -it was working: - -<mmm-embed path="tyktok_leds" nolink></mmm-embed> -(this tweet is mislabeled, Juan's sequencer is in the next video). - -[Juan][juan] had an Akai Tomcat drum machine on hand, and we were stoked to try it out. -As usual at first, it didn't work at all. -Pretty soon we figured out that the signal was just too quiet coming off our 9V supply, -so we put an amplifier in between (alongside a whole mess of cables) and behold: - -<mmm-embed path="tyktok_tomcat" nolink></mmm-embed> - -This worked pretty well, surprisingly! -With the potentiometer set *just right*, it rarely triggered twice, and ran for some time before the -spring weakened and the sound became a tiny bit more quiet and failed to trigger every beat. -This is also a really nice effect actually and transforms rather simple beats into nice wacky ones: - -<mmm-embed path="tyktok_tired" nolink></mmm-embed> - -The schematic at this point is very simple: - -<mmm-embed path="threshold"></mmm-embed> - -I used an LM393 dual comparator and tied the unused half to ground, as the datasheet recommends. - -## dividing time -While this was working very well already, I had an idea for improving it using the universal 555 -timer IC. However, I didn't have any 555s on hand (or rather, I wasn't aware [Ludonaut][ludonaut] -had a 556 in his box next to me) so I kept that in mind but went on with other things -(more on this in the upcoming post). - -Reading up on synthesizer modules, I found *Clock Dividers* rather often. In the beginning I wasn't -quite sure what they were, but it turns out they are pretty simple: basically they just slow down a -clock (signal) by counting beats and only producing one of their own every N beats in the incoming -signal. I thought this would be very useful for us, since using clock dividers with non-multiple -divisons such as /3, /4 and /5 can create nice polyrhythms. - -My plan is to build this right into the same box as the clock threshold circuitry. -In the videos above you can already see it working with /2, /3, /4 and /6 outputs. -The schematic is largely copied from [Ken Stone's amazing synthesizer project, CGS][cgs]. -He has a nice collection of synth module circuits, and here I am using the pulse divider part of the -[CGS36 Pulse Divider and Boolean Logic][cgs36] module: - -[![CGS36 Pulse Divider][cgs36-schematic.gif]][cgs36] - -For now I left out the /7, /8 and /5 parts, but I think the /5 would be useful since it introduces -another prime division that is not much faster or slower than the /3 and /4 we already have. -The /8 would be almost 'for free' since it doesn't require a new 4017, but I'm not sure whether I -should put it in with the /7 missing. I guess it could be useful for a slow melody sequencer. - -[no-computer]: https://www.youtube.com/watch?v=fO1nbHoEZMw -[juan]: https://twitter.com/juanorloz -[ludonaut]: https://twitter.com/ludonaut -[cgs]: http://www.cgs.synth.net/modules/ -[cgs36]: http://www.elby-designs.com/webtek/cgs/cgs36/cgs36_pulse_divider.html - -[cgs36-schematic.gif]: http://www.elby-designs.com/webtek/cgs/cgs36/schem_cgs36v14_pulse_divider.gif diff --git a/root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg b/root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg Binary files differdeleted file mode 100644 index 509cd5b..0000000 --- a/root/blog/clocks_triggers_gates/threshold/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/clocks_triggers_gates/title: text$plain b/root/blog/clocks_triggers_gates/title: text$plain deleted file mode 100644 index bb8c50e..0000000 --- a/root/blog/clocks_triggers_gates/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Clicks, Clocks and Triggers
\ No newline at end of file diff --git a/root/blog/clocks_triggers_gates/tyktok_leds/URL -> twitter$tweet b/root/blog/clocks_triggers_gates/tyktok_leds/URL -> twitter$tweet deleted file mode 100644 index 48ecab3..0000000 --- a/root/blog/clocks_triggers_gates/tyktok_leds/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/879046250880008193 diff --git a/root/blog/clocks_triggers_gates/tyktok_test/URL -> twitter$tweet b/root/blog/clocks_triggers_gates/tyktok_test/URL -> twitter$tweet deleted file mode 100644 index 407ae05..0000000 --- a/root/blog/clocks_triggers_gates/tyktok_test/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/878328052744241152 diff --git a/root/blog/clocks_triggers_gates/tyktok_tired/URL -> twitter$tweet b/root/blog/clocks_triggers_gates/tyktok_tired/URL -> twitter$tweet deleted file mode 100644 index 564a9d7..0000000 --- a/root/blog/clocks_triggers_gates/tyktok_tired/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/879072879924711426 diff --git a/root/blog/clocks_triggers_gates/tyktok_tomcat/URL -> twitter$tweet b/root/blog/clocks_triggers_gates/tyktok_tomcat/URL -> twitter$tweet deleted file mode 100644 index 04aacc8..0000000 --- a/root/blog/clocks_triggers_gates/tyktok_tomcat/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/879061152520699904 diff --git a/root/blog/humane_filesystems/categories: text$plain b/root/blog/humane_filesystems/categories: text$plain deleted file mode 100644 index 21278aa..0000000 --- a/root/blog/humane_filesystems/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -design paper
\ No newline at end of file diff --git a/root/blog/humane_filesystems/date: time$iso8601-date b/root/blog/humane_filesystems/date: time$iso8601-date deleted file mode 100644 index 1c1707a..0000000 --- a/root/blog/humane_filesystems/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2018-02-28 diff --git a/root/blog/humane_filesystems/hidden: text$lua -> bool.lua b/root/blog/humane_filesystems/hidden: text$lua -> bool.lua deleted file mode 100644 index b30e187..0000000 --- a/root/blog/humane_filesystems/hidden: text$lua -> bool.lua +++ /dev/null @@ -1 +0,0 @@ -return true diff --git a/root/blog/humane_filesystems/text$markdown.md b/root/blog/humane_filesystems/text$markdown.md deleted file mode 100644 index 1f8ab79..0000000 --- a/root/blog/humane_filesystems/text$markdown.md +++ /dev/null @@ -1,73 +0,0 @@ -Lately I've been thinking about note-taking tools. - -I use a few different systems for taking notes almost daily: -- multiple paper notebooks and sheets of paper as available -- random freeform text files spread around my (various) PCs -- google keep - -I like taking paper notes because it's easy to switch to doodle and sketch and layout everything together. -I also find that it stimulates my thinking a bit more that typing text; I'm not quite sure why that is. - -Anyway, I was looking for solutions to replace google keep, mostly because I like to self-host my services. - -## file system use cases -- retrieve a file i know exists - - either file i know 100% - - or looking for a file based on content, guessing where and how it might be -- show related files to what i am looking for -- allow exploring content - -### tags and search don't solve anything -Many proposals in [FileSystemAlternatives][c2-fsalt] and [LimitsOfHierarchies][c2-loh] are to generalize up from Hierarchies to Set Theory. -This in effect means exchanging the any-to-one association between 'containers' (folders/tags) and 'contents' (files) for a any-to-any association. -Files are then no longer identified by their chain of parents, but rather by their belonging and not-belonging to all the existant tags. -Generally the proposal is to query these tag-based filesystems using combinatory logic such as `a AND (b OR NOT(C))` and so on. - -My main problem with this approach is that sooner or later you end up with a huge list of tags that is just unmanageable. -It's obvious that this won't scale as the amount of tag increases with the amount of different data, -especially in a collaborative, professional or otherwise networked context. - -Since the tags are all stored flatly in a bag of stuff, they also cannot meaningfully express relationships between each other. -This is clearly evident in any software that uses tags as the only option of organizing large amounts of data, -especially when multiple users have access. -Here is an example of a typical list of defined tags for issue tracking on github: - -![github tags][github-tags] - -As can be seen easily, users are shoehorning more information into the label name string than the label is made to store. -As this extra data is only available to humans interpreting the text, it cannot be used to create good UI: -Instead of seeing a drop-down for *Tech Complexity*, users need to go through the label list. -Even the simplest logical constraints cannot be documented and enforced with this system. - --> need for *dynamically changeable* data schemas - -/* -But even organizing and finding files with this paradigm is not a very nice experience; take these UI designs for example: - -![set picker from tablizer][tablizer-tagging] -![search dialog from tablizer][tablizer-search] - -Granted, it's not particularily fair to take these designs from 2002, but this paradigm is all around us today and the UX hasn't gotten a lot better. -Here's the same set picker functionality as seen on google keep, today: - -![labelling UI in google keep][keep-label] - -And for the search, they didn't even try. There's just a list - -A very thorough proposal for a file system can be found in [*A Novel, Tag-Based File System*][tag-based-fs]. - -This approach -*/ - -### is there more? -- the file system as a note-taking app - -[tiddlywiki]: https://tiddlywiki.com/ -[tablizer-search]: http://www.reocities.com/tablizer/setscrn1.gif -[tablizer-tagging]: http://www.reocities.com/tablizer/setpicker.gif -[tablizer-src]: http://www.reocities.com/tablizer/sets1.htm -[tag-based-fs]: http://digitalcommons.macalester.edu/cgi/viewcontent.cgi?article=1036&context=mathcs_honors -[finder-column-view]: http://cdn.osxdaily.com/wp-content/uploads/2010/03/set-column-view-size-default-mac-os-x-finder-610x307.jpg -[finder-column-view-src]: http://osxdaily.com/2010/03/25/setting-the-default-column-size-in-mac-os-x-finder-windows/ -[finder-list-view]: http://cdn.osxdaily.com/wp-content/uploads/2014/12/messages-attachments-folder-mac-osx.jpg -[finder-list-view-src]: http://osxdaily.com/2014/12/03/access-attachments-messages-mac-os-x/ diff --git a/root/blog/humane_filesystems/title: text$plain b/root/blog/humane_filesystems/title: text$plain deleted file mode 100644 index dddfa48..0000000 --- a/root/blog/humane_filesystems/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Notetaking and humane Filesystems
\ No newline at end of file diff --git a/root/blog/love_lua_photoshop_and_games/$order b/root/blog/love_lua_photoshop_and_games/$order deleted file mode 100644 index f2e95a4..0000000 --- a/root/blog/love_lua_photoshop_and_games/$order +++ /dev/null @@ -1,4 +0,0 @@ -final -animating -sheet -outside diff --git a/root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 b/root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 Binary files differdeleted file mode 100755 index 4b752b5..0000000 --- a/root/blog/love_lua_photoshop_and_games/animating/video$mp4.mp4 +++ /dev/null diff --git a/root/blog/love_lua_photoshop_and_games/categories: text$plain b/root/blog/love_lua_photoshop_and_games/categories: text$plain deleted file mode 100644 index 00c215c..0000000 --- a/root/blog/love_lua_photoshop_and_games/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update gamedev engine programming
\ No newline at end of file diff --git a/root/blog/love_lua_photoshop_and_games/date: time$iso8601-date b/root/blog/love_lua_photoshop_and_games/date: time$iso8601-date deleted file mode 100644 index de2136d..0000000 --- a/root/blog/love_lua_photoshop_and_games/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2016-05-29 diff --git a/root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 b/root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 Binary files differdeleted file mode 100755 index faa42bb..0000000 --- a/root/blog/love_lua_photoshop_and_games/final/video$mp4.mp4 +++ /dev/null diff --git a/root/blog/love_lua_photoshop_and_games/outside/image$jpeg.jpg b/root/blog/love_lua_photoshop_and_games/outside/image$jpeg.jpg Binary files differdeleted file mode 100755 index 85a29b1..0000000 --- a/root/blog/love_lua_photoshop_and_games/outside/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 b/root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 Binary files differdeleted file mode 100755 index 6cc4b2d..0000000 --- a/root/blog/love_lua_photoshop_and_games/sheet/video$mp4.mp4 +++ /dev/null diff --git a/root/blog/love_lua_photoshop_and_games/text$markdown.md b/root/blog/love_lua_photoshop_and_games/text$markdown.md deleted file mode 100644 index 85d6ce9..0000000 --- a/root/blog/love_lua_photoshop_and_games/text$markdown.md +++ /dev/null @@ -1,334 +0,0 @@ -Recently I've been building a 2d game engine for my semester project at [CGL](http://colognegamelab.de). -Below, I'll copy and paste two blog posts from my internal documentation blog: - ---- - -After nailing down the basic narrative and gameplay idea in a lengthy group discussion on the first day, -we each set goals for the next few days in order to kickstart the project. - -As we decided on a pixel art art approach and point-and-click gameplay, as the programmer I decided to write a custom engine in -[LÖVE](https://love2d.org) instead of using a bulky engine like Unity that we wouldn't really profit from anyway and that would be less specific, -and therefore less fitting, than what I could come up with. -Following this, my goal as an engine programmer was then to reduce any effort needed to put content into the engine to a minimum. -I remembered iteration speeds and how most things I did as a programmer last time I built a pixel art project in Unity really weren't programming but replacing assets; adding states in an animation state machine that I could've easily coded by hand in a fraction of the time; and generally wrestling with the development environment, and I wanted to instead create a working environment that would make my job as the gameplay programmer and the job of the artist(s) a lot easier. - -Because creating my own engine is not a minor task and obviously a very crucial one for the project, -the decision to go ahead and not use a prebuilt Engine was to be thought out thoroughly, -if I am to write my own engine it needs to work _at least_ as good as a prebuilt one or it will harm the project. -To test whether I could actually improve workflow and build something my team can profit from, without degrading the project work during the time I need to actually put it together, I set myself a three-day deadline to try and go as far as I can and see whether writing the engine myself seemed realistic. -The other goal of this trial phase was to show my team members why the switch could be worthwhile for them also. - -Therefore my main starting point was to build a feature that they would see as useful and that was central to what the engine was going to do later: **rendering and scene management.** - -Specifically, I started writing something that loads a .PSD directly and animates the sublayers. -I also added code that detects file changes and reloads them automatically. -At the end of the second project day, I had this: - -<mmm-embed path="sheet" nolink></mmm-embed> - -The code for this isn't much, but it took a few iterations to make the file- reload-watching reuseable and work on Linux and Windows alike (and efficient). -I used a 3rd party library for loading the photoshop files, but I had to patch it a lot. -Here's the main part for the animated-layer-loading: - - artal = require "lib.artal.artal" - - ALL_SHEETS = setmetatable {}, __mode: 'v' - RECHECK = 0.3 - - class PSDSheet - new: (@filename, @frametime=.1) => - @time = 0 - @frame = 1 - - @reload! - - if WATCHER - WATCHER\register @filename, @ - - reload: => - print "reloading #{@filename}..." - - - @frames = {} - target = @frames - local group - - psd = artal.newPSD @filename - for layer in *psd - if layer.type == "open" - if not group - layer.image = love.graphics.newCanvas psd.width, psd.height - love.graphics.setCanvas layer.image - table.insert target, layer - group = layer.name - elseif layer.type == "close" - if layer.name == group - love.graphics.setCanvas! - group = nil - else - if not group - table.insert target, layer - else - love.graphics.draw layer.image, -layer.ox, -layer.oy if layer.image - - update: (dt) => - @time += dt - - @frame = 1 + (math.floor(@time/@frametime) % #@frames) - - draw: (x, y, rot) => - {:image, :ox, :oy} = @frames[@frame] - love.graphics.draw image, x, y, rot, nil, nil, ox, oy if image - - { - :PSDSheet, - } - - ---- - -After being able to load simple animations from photoshop without even closing the game was working, I tried loading the scene İlke had created meanwhile: - -<mmm-embed path="outside"></mmm-embed> - -Naturally, this failed at first. -He was using clipping masks and blend modes, neither of which were implemented at the time, -but after I made a few changes to hide the affected layers for the time being, it looked fine. - -My overall engine goal was to be able to build something like 90% of the level right in photoshop - including animations, hit areas, player spawns etc. -Basically I wanted to use Photoshop as a full level editor and only write gameplay scripts and engine code outside of it. - -This meant that there would be very different types of information inside a level .psd that we would need to be accessible to the engine. - -To load information and behaviours into the level structure that is loaded from the PSD I created a layer naming conventions; -layers can specify a _Directive_ afte their name. - -The most important Directive (so far) is _load_: it loads a lua/moonscript _mixin_ via it's name and passes arguments to it . -For example there is a 'common' (shared between different scenes/levels) module called _subanim_ that treat's a group inside a bigger, -non-animated photoshop document as an animation (like what I did in the first post, but inside a complex scene). -The _subanim _module has one parameter, the frame-duration (in seconds). -To turn a group into a _subanim_, you have to append 'load:subanim,0.2' to it's name for example. - -Another Directive is _tag_, it stores the layer under a name so other scripts can access it specifically and consistently. -Because this could also be done by a mixin, i am thinking about abolishing the _Directive_ concept and only using mixins (so that the _load_ could be removed also). -You can see the system working in this clip: - - -<mmm-embed path="animating" nolink></mmm-embed> -_making an animation out of the single rain layer_ - -Moreover, I added a directory structure for mixins; to load a mixin called _name _for a scene called _scene_, it first looks in the scene specific directories: - - - game/_scene_/_name_.moon - - game/_scene.moon_ (this file can return multiple mixins) - -if neither of these exist, it checks for _common_ mixins of this name in the common directory and files: - - - games/common/_name.moon_ - - games/common.moon (this file can return multiple mixins) - -This allows to share mixins between scenes (like click-area mixins maybe, or the _subanim_ mentioned above) -but still keep a clean directory structure for specific elements (like the dialogue of a certain scene, -or the tram in the background of the scene we are working on currently). - -Mixin code can modify the scene node / layer object and overwrite the default "draw" and "update" hooks/methods. -This allows for nearly everything I can think of right now, but most mixins are still very short and concise. -As examples, you can take a look at the code that animates the tram in the background or the subanim source: - -game/first_encounter/tram.moon: - - import wrapping_, Mixin from require "util" - - wrapping_ class SubAnim extends Mixin - SPEED = 440 - new: (scene) => - super! - - @pos = 0 - - update: (dt) => - @pos = (@pos + SPEED*dt) % (WIDTH*2) - - draw: (recursive_draw) => - love.graphics.draw @image, @pos/4 - @ox - 140, -@oy - - -game/common/subanim.moon: - - import wrapping_, Mixin from require "util" - - wrapping_ class SubAnim extends Mixin - new: (scene, @frametime=0.1) => - super! - - @time = 0 - @frame = 1 - - update: (dt) => - @time += dt - - @frame = 1 + (math.floor(@time/@frametime) % #@) - - draw: (recursive_draw) => - recursive_draw {@[@frame]} - - -_wrapping_ is a small helper that allows a moonscript class to wrap an existing lua table -(= object, in this case the layer objects produced by the psd parsing phase) and Mixin is a class that handles mixin live-reloading -(yep, that works with mixins too!) and might contain utility functions to write better mixins in the future. -Here's the code for both: - - wrapping_ = (klass) -> - getmetatable(klass).__call = (cls, self, ...) -> - setmetatable self, cls.__base - cls.__init self, ... - - klass - - class Mixin - new: => - info = debug.getinfo 2 - file = string.match info.source, "@%.?[/\\]?(.*)" - - @module = info.source\match "@%.?[/\\]?(.*)%.%a+" - @module = @module\gsub "/", "." - - if WATCHER - WATCHER\register file, @ - - reload: (filename) => - print "reloading #{@module}..." - - package.loaded[@module] = nil - new = require @module - - setmetatable @, new.__base - - find_tag: => - layer = @ - while not layer.tag - layer = layer.parent - - if not layer - return nil - - layer.tag - - { - :wrapping_, - :Mixin - } - - -By the end of the three day "test phase". -This is how the first scene looked in-game: - -<mmm-embed path="final" nolink></mmm-embed> - -Here's _psdscene.moon_, wrapping most things mentioned in this article: - - artal = require "lib.artal.artal" - - class PSDScene - new: (@scene) => - @reload! - - if WATCHER - WATCHER\register "assets/#{@scene}.psd", @ - - load: (name, ...) => - _, mixin = pcall require, "game.#{@scene}.#{name}" - return mixin if _ and mixin - - _, module = pcall require, "game.#{scene}" - return module[name] if _ and module[name] - - _, mixin = pcall require, "game.common.#{name}" - return mixin if _ and mixin - - _, module = pcall require, "game.common" - return module[name] if _ and module[name] - - LOG_ERROR "couldn't find mixin '#{name}' for scene '#{@scene}'" - nil - - reload: (filename) => - filename = "assets/#{@scene}.psd" unless filename - print "reloading scene #{filename}..." - - @tree, @tags = {}, {} - target = @tree - local group - - indent = 0 - - psd = artal.newPSD filename - for layer in *psd - if layer.type == "open" - table.insert target, layer - layer.parent = target - target = layer - LOG "+ #{layer.name}", indent - indent += 1 - continue -- skip until close - elseif layer.type == "close" - layer = target - target = target.parent - indent -= 1 - else - LOG "- #{layer.name}", indent - table.insert target, layer - - cmd, params = layer.name\match "([^: ]+):(.+)" - switch cmd - when nil - "" - when "tag" - @tags[params] = tag - layer.tag = params - when "load" - params = [str for str in params\gmatch "[^,]+"] - name = table.remove params, 1 - - mixin = @load name - if mixin - LOG "loading mixin '#{@scene}/#{name}' (#{table.concat params, ", "})", indent - mixin layer, unpack params - else - LOG_ERROR "couln't find mixin for '#{@scene}/#{name}'", indent - else - LOG_ERROR "unknown cmd '#{cmd}' for layer '#{layer.name}'", indent - - update: (dt, group=@tree) => - if group == false - return - - for layer in *group - if layer.update - layer\update dt, @\update - elseif layer.type == "open" - @update dt, layer - - draw: (group=@tree) => - if group == false - return - elseif group == @tree - love.graphics.scale 4 - - for layer in *group - if layer.draw - layer\draw @\draw - elseif layer.image - {:image, :ox, :oy} = layer - love.graphics.setColor 255, 255, 255, layer.opacity or 255 - love.graphics.draw image, x, y, nil, nil, nil, ox, oy - elseif layer.type == "open" - @draw layer - - { - :PSDScene, - } - - -Seeing that everything was (and is) going very smoothly up to this point, -I decided to "end" the test phase and finalize the decision to roll out my own engine. diff --git a/root/blog/love_lua_photoshop_and_games/title: text$plain b/root/blog/love_lua_photoshop_and_games/title: text$plain deleted file mode 100644 index 55f0cb3..0000000 --- a/root/blog/love_lua_photoshop_and_games/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -LÖVE, Lua, Photoshop + Games
\ No newline at end of file diff --git a/root/blog/ludum_dare_33_postmortem/$order b/root/blog/ludum_dare_33_postmortem/$order deleted file mode 100644 index 4072e61..0000000 --- a/root/blog/ludum_dare_33_postmortem/$order +++ /dev/null @@ -1,2 +0,0 @@ -smert -split diff --git a/root/blog/ludum_dare_33_postmortem/categories: text$plain b/root/blog/ludum_dare_33_postmortem/categories: text$plain deleted file mode 100644 index daebced..0000000 --- a/root/blog/ludum_dare_33_postmortem/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update gamedev gamejam
\ No newline at end of file diff --git a/root/blog/ludum_dare_33_postmortem/date: time$iso8601-date b/root/blog/ludum_dare_33_postmortem/date: time$iso8601-date deleted file mode 100644 index 9e7bf47..0000000 --- a/root/blog/ludum_dare_33_postmortem/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2015-08-25 diff --git a/root/blog/ludum_dare_33_postmortem/smert/image$png.png b/root/blog/ludum_dare_33_postmortem/smert/image$png.png Binary files differdeleted file mode 100755 index 612695c..0000000 --- a/root/blog/ludum_dare_33_postmortem/smert/image$png.png +++ /dev/null diff --git a/root/blog/ludum_dare_33_postmortem/split/image$png.png b/root/blog/ludum_dare_33_postmortem/split/image$png.png Binary files differdeleted file mode 100755 index 0951620..0000000 --- a/root/blog/ludum_dare_33_postmortem/split/image$png.png +++ /dev/null diff --git a/root/blog/ludum_dare_33_postmortem/text$markdown.md b/root/blog/ludum_dare_33_postmortem/text$markdown.md deleted file mode 100644 index 63f99c0..0000000 --- a/root/blog/ludum_dare_33_postmortem/text$markdown.md +++ /dev/null @@ -1,93 +0,0 @@ -So, LD33 is over, and once again I made something: [*The Monster Within*][entry]. - -# Theme -The theme was *You are the Monster*, and I wanted to really incorporate the theme into the gameplay mechanics for once -(well yeah, [Curved Curse][curcur] did that, but the topic was very broad and there was no way but incorporate it into the gameplay itself). - -Many games I have seen took the theme quite literally and made the main character a monster: - -<mmm-embed path="smert"></mmm-embed> -[*image by @RedOshal*][smert_src] - -Although you play a monster in *The Monster Within*, I took the theme a bit further. -The theme reminded me of an exclamated "*Look at yourself! You've become a Monster!*", something a movie wife might say to her increasingly out-of-control husband who just killed the neighbor that found out about the family's dark secret. - -The idea I came up with was the following: your main objective is to eliminate enemies from within a crowd of mostly civilians (in a generic top-down action game). However you turn into a Monster whenever you kill someone, which grants you a lot more power, but also impairs your senses; you can no longer differentiate between civilians and enemies. -As a result, I figured, people would have to decide between two playstyles, going on a rampage and killing as many people as possible, regardless of their type, or trying to play strategically by memorizing the enemies in the crowd. - -<mmm-embed path="split"></mmm-embed> -*The Monster Within, normal and beast mode* - -To make playing in "Beast Mode" more appealing I increased the primary attack (punch) range and added a secondary lunge attack that is exclusive to that mode. This, I hope, tempts players to make use of the beast mode and facilitates players stopping to play for the original objective - eliminating enemies - and instead try to kill as many people as possible (which is an intended effect). - -To emphasize the two approaches, I introduced a dual scoring system; there is a "good" score that you can increase by eliminating enemies that is penalized whenever you kill a civilian but there is also an "evil" score that increases by the same amount regardless of the type of character you killed. -To balance the two, killing enemies yields more "good" points than "bad" ones, so both options can be viable. - -As the current comments on the [ludum dare entry page][entry] show, not everyone understood what I was trying to achieve: - ->It was fun although I didn't really like the mechanic where everyone turns into ghosts; it requires some ridiculous amount of memorization in order to get a good score, so I just ran around punching everyone indiscriminately. - -Although it seems *charliecarlo* was completely oblivious to my actual intentions with the core mechanic, which always feels a bit bad, he perfectly demonstrated that my idea worked out; his character let the *monster within* loose and went on a bloody rampage. - ->Different between beast and human score was initially confusing. Then again, that fits the theme well, a black box morality system. - ->I like the concept, the art is nice and I killed 50 innocent souls! - Cool game! - -So overall I am happy with how the mechanic turned out and was received; the three weeks of rating will hopefully yield more critique and comments. - -# Techology - -## Moonscript -Although I have been working on a networked game engine on top of [LÖVE][love] in moonscript, this is the first **complete** game that I write in [moonscript][moonscript]. -Writing aforementioned engine definetely helped me form some habits that sped up development for this game. -*The Monster Within* turned out to be an amazingly small game at 768 lines of code (excluding libraries); [Curved Curse][curcur] counted 1160. - -Every time I had to read or write Lua code (for example my older library, `st8`, which still has hiccups that I needed to iron out) the syntax seemed extremely cumbersome and restrictive. -After over a month, moonscript is still fun to write and read and I the decision to give it a shot was definetely more than worth it. Thank you leafo! - -## Steering Behaviors -A few months back I stumbled upon the [very nice series *Understanding Steering Behaviors*][steering] on *tutsplus.com*. -I used those guides, alongside the sixth chapter of *Daniel Shiffman*'s *The Nature of Code*, [*Autonomous Agents*][autonom], to implement the character AI for the enemies and civilians. - -In particular, I used the `wander`, `flee` (from the player, when he is in beast mode), `collision avoidance` and the `seperation` behaviors to make the characters move around in a more or less natural and pleasant-looking fashion. - -The implementation consists of just a few lines of vector math and the results are surprisingly lifelike for the very little effort I had to put into it. - -## Box2D -I was very unsure whether I should roll out my own simple physics system with a little Vector math, or whether I should use Box2d (which ships with LÖVE anyway). -I opted to choose `Box2D` because that would enable things like destructable environments (like houses being knocked away) and novel interactions in more carefully designed environments later down the road. - -## Optimization -I didn't really optimize anything, and if I didn't know it doesn't matter at the current level scale, I would have long added a spatial hash system, stopped simulating characters that are long out of view or at the very least culled the map. -However I worked so slowly on the first two days that there really wasn't any time left for that sort of thing, and most of the game only started working on the last day so there wasn't a lot of optimization possible before that point anyway. -If I continue working on this project, Optimization is one of the first things I will deal with. - -# Productivity -This Ludum Dare hit me entirely unprepared, I had completely forgotten about the date and only noticed a day prior. -I was initially very unsure whether to participate at all and also couldn't reach my artist from last year's game. -I put out a tweet and a post to [r/gamedev][rgamedev] and `stewartisme` contacted me as I was sleeping after looking at the theme at 3AM. -Still, I wasn't very motivated and worked slowly, procrastinated a lot and overall didn't really 'get into it'. -It amazes me that the game even turned out playable and with an acceptable look in general, but on the last day we really did work until the last minute, and as usual 90% of the perceived complete-ness were achieved in the last 10% of the time. - -# Future? -I'm not sure whether this project will continue, but I have a few ideas on how to improve the game. -In particular, I would like to add a Highscores table. -Because every *The Monster Within* run yields two scores, there are multiple options for this. -Aside from the obvious solution of two seperate high score tables, the most interesting option from a game design perspective, would be to have a single table, and to enter whichever score is higher there. -The entries could be colored white and red, denoting whether the player followed the "good" objective or let himself get carried away. -It would probably be required to fine tune the scoring system so that both playstyles are equally hard to succeed in. - -You can check out *The Monster Within* on the [Ludum Dare entry page][entry], [on itch.io][itch.io] or [view the source code on github][repo]. - -[entry]: http://ludumdare.com/compo/ludum-dare-33/?action=preview&uid=28620 -[itch.io]: http://s0lll0s.itch.io/the-monster-within -[repo]: https://github.com/s-ol/ld33 -[curcur]: http://s0lll0s.itch.io/curved-curse - -[smert_src]: http://ludumdare.com/compo/2015/08/22/what-i-imagine-most-people-are-doing-with-the-theme/ - -[love]: https://love2d.org -[moonscript]: https://moonscript.org -[steering]: http://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732 -[autonom]: http://natureofcode.com/book/chapter-6-autonomous-agents/ -[rgamedev]: https://reddit.com/r/gamedev diff --git a/root/blog/ludum_dare_33_postmortem/title: text$plain b/root/blog/ludum_dare_33_postmortem/title: text$plain deleted file mode 100644 index 3c3f2d0..0000000 --- a/root/blog/ludum_dare_33_postmortem/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Ludum Dare 33: "The Monster Within" post-mortem diff --git a/root/blog/self-hosted_virtual_home/categories: text$plain b/root/blog/self-hosted_virtual_home/categories: text$plain deleted file mode 100644 index b8309d9..0000000 --- a/root/blog/self-hosted_virtual_home/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update programming devops linux docker diff --git a/root/blog/self-hosted_virtual_home/date: time$iso8601-date b/root/blog/self-hosted_virtual_home/date: time$iso8601-date deleted file mode 100644 index b454377..0000000 --- a/root/blog/self-hosted_virtual_home/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2019-03-27 diff --git a/root/blog/self-hosted_virtual_home/text$markdown.md b/root/blog/self-hosted_virtual_home/text$markdown.md deleted file mode 100644 index e6b41a1..0000000 --- a/root/blog/self-hosted_virtual_home/text$markdown.md +++ /dev/null @@ -1,224 +0,0 @@ -In this post I'll break down the setup of my self-hosted virtual home: https://s-ol.nu. - -First a quick overview of what this guide will cover: - -- HTTPS server with multiple subdomains and varying backends - - [traefik][traefik] reverse-proxy maintains SSL certificates and serves all requests - - [docker-compose][docker-compose] manages running sites/microservices -- a private-public git server - - access control, management with [gitolite][gitolite] - - [klaus][klaus] web frontend for browsing and cloning public repos - - fine-grained permissions and SSH public-key access -- micro 'CI' setup rebuilds & redeploys docker images when updates are pushed - -**UPDATE (2019-10-03)**: I updated the git hook below to one that supports pushing and building -multiple branches based on the `docker-compose.yml`. - -Most of these projects are very well documented so I won't go into a lot of detail on setting them up. - -# HTTPS Server -To run multiple subdomains from a single machine, the HTTP requests need to be matched according to the 'Host' header. -Most HTTP servers have good facilities for doing this, e.g. apache has vhosts, nginx has server directives etc. - -In the past I had used apache as my main server, which worked well for static content and PHP apps, -but not all applications fit into this scheme too well and configuration is a tad tedious. - -With this latest iteration I am using [traefik][traefik] as a "reverse proxy". -This means traefik doesn't serve anything (not even static content) by itself, -it just delegates requests to one of multiple configured services based on a system of rules. - -It also handles letsencrypt certificate generation and updates out-of-the-box and can be tightly integrated with docker, -so that it automatically reacts to new services being added. - -Traefik can be run at system level, but currently I prefer installing the least system-level applications to have my setup -as self-contained as possible. Therefore I went with this [traefik in docker-compose][traefik-in-docker] setup from kilian.io: - - version: '3.4' - - services: - traefik: - image: traefik:1.5-alpine - restart: always - ports: - - 80:80 - - 443:443 - networks: - - web - volumes: - - /var/run/docker.sock:/var/run/docker.sock:ro - - ./traefik.toml:/traefik.toml - - ./acme.json:/acme.json - container_name: traefik - - networks: - web: - external: true - -with the small addition of the `:ro` at the end of the docker socket volume, -to prevent attacks on traefik from being able to take over the host docker system (too easily). -In the guide you can find more details, including the `traefik.toml` that I am using almost verbatim. - -# Hosting Sites -With traefik set up, dockerized services can be added and exposed trivially. -For example to start `redirectly`, a tiny link redirect service, this addition suffices: - - redirectly: - image: local/redirectly:master - restart: always - networks: - - web - labels: - - "traefik.frontend.rule=Host:s-ol.nu" - - "traefik.enable=true" - -By setting different subdomains in the frontend-rule section, many different services can be provided. - -The image `local/redirectly:git` in this case is built automatically when a repo is pushed (see below). - -note: if a container doesn't have an EXPOSE directive, or EXPOSEs multiple ports, -you will have to add a `traefik.port` label specifying which port to use. - -# private/public Git Server -While I still have a lot of code on Github, where collaboration is easy, -I prefer to own the infrastructure that I store my private projects on. -I also wanted to have a public web index of some of the projects. - -The git infrastructure itself is mananged by [gitolite][gitolite], which I really enjoy using. - - repo gitolite-admin @all - RW+ = s-ol - C = s-ol - - repo public/.* - R = @all daemon - option writer-is-owner = 1 - - repo ... ... - RW+ = ludopium - -In the first block I grant myself full access to all repos, as well as the right to automatically create repos by -attempting to push/pull from them. - -The second block makes all repos prefixed with `public/` readable by anyone in the gitolite system, -as well as the `git-daemon`, which allows cloning via `git://....` access (port 9418). -The `write-is-owner` option lets me set the git `description` field using `ssh git@git.s-ol.nu desc`. - -I chose the `public/` prefix because it results in all public repos being stored in one directory together -(`/var/lib/gitolite/repositories/public`), where klaus can easily pick them up. - -The klaus web frontend is set up using traefik above like so: - - klaus: - image: hiciu/klaus-dockerfile - restart: always - networks: - - web - volumes: - - /var/lib/gitolite/repositories/public:/srv/git:ro - command: /opt/klaus/venv/bin/uwsgi --wsgi-file /opt/klaus/venv/local/lib/python2.7/site-packages/klaus/contrib/wsgi_autoreload.py --http 0.0.0.0:8080 --processes 1 --threads 2 - environment: - KLAUS_REPOS_ROOT: /srv/git - KLAUS_SITE_NAME: git.s-ol.nu - KAUS_CTAGS_POLICY: tags-and-branches - KLAUS_USE_SMARTHTTP: y - labels: - - "traefik.frontend.rule=Host:git.s-ol.nu" - - "traefik.enable=true" - -I am using the ['autoreload' feature][klaus-autoreload] and the `hiciu/klaus-dockerfile` docker image. -Setting `KLAUS_USE_SMARTHTTP` allows cloning repos via HTTP. - -In the future I would like to modify klaus a bit, for example by showing the README in the root of a project per default -and applying a custom theme. - -# Micro-CI -The last piece of the puzzle is automatically deploying projects whenever they are pushed. -This can be realized using git's `post-receive` hooks and is generally pretty well known. - -I followed this gitolite guide for [storing repo-specific hooks in the gitolite-admin repo][gitolite-hooks]. -It requires a change in the gitolite rc file (on the server), but after that you can configure deployment processes in the conf like this: - - @dockerize = public/redirectly ... - @jekyllify = blog - - repo @dockerize - option hook.post-receive = docker-deploy - - # i actually dont have a jekyll blog anymore but its an easy one as well - repo @jekyllify - option hook.post-receive = jekyll-deploy - -The hooks are stored in the same repo under `local/hooks/repo-specific`. -Here is the `docker-deploy` hook I am using: - - #!/bin/bash - set -e - - while read oldrev newrev refname - do - BRANCH="$(git rev-parse --symbolic --abbrev-ref $refname)" - - # Get project name - PROJECT="$PWD" - PROJECT="${PROJECT#*/repositories/public/}" - PROJECT="${PROJECT#*/repositories/}" - PROJECT="${PROJECT%.git}" - PROJECT="$(echo "$PROJECT" | tr "/ " "-_")" - - # Paths - CHECKOUT_DIR=/tmp/git/$PROJECT - TARGET_DIR=/home/s-ol/aerol - IMAGE_NAME=local/$PROJECT:$BRANCH - - # this one doesn't require python & yq, but it means the container has to run already... - # SERVICES=$(docker ps --filter "ancestor=${IMAGE_NAME}" --format '{{.Label "com.docker.compose.service"}}' \ - # | sort | uniq) - - SERVICES=$(yq -r <"$TARGET_DIR/docker-compose.yml" \ - ".services | to_entries | map(select(.value.image == \"${IMAGE_NAME}\").key) \ - | join(\" \")") - - if [ -z "$SERVICES" ]; then - continue - fi - - mkdir -p "$CHECKOUT_DIR" - GIT_WORK_TREE="$CHECKOUT_DIR" git checkout -q -f $newrev - echo -e "\e[1;32mChecked out '$PROJECT'.\e[00m" - - cd "$CHECKOUT_DIR" - docker build -t "$IMAGE_NAME" . - echo -e "\e[1;32mImage '$IMAGE_NAME' built.\e[00m" - - cd "$TARGET_DIR" - docker-compose up -d $SERVICES - echo -e "\e[1;32mService(s) '$SERVICES' restarted.\e[00m" - done - -It will build a `local/$REPO:$BRANCH` image whenever you push, then run `docker-compose up -d $SERVICES` in `$TARGET_DIR`, -where `$SERVICES` are all the docker-compose services that use the image. If there are none, no image will be built. -For this to work it has to parse the `docker-compose.yaml` file, which means you have to install [`yq`][yq] and `jq`, e.g. on Ubuntu: - - sudo apt-get install jq python3-pip - sudo pip install yq - -If you would like to avoid that, you can use the commented command for `SERVICES=` above, which only relies on docker itself, -the only problem is that you will have to do the first build manually (or re-tag a dummy image) before the first build, -since it can only detect containers that are already running. - ---- - -That's basically it! -If you have questions or comments i'll be happy to hear from you on twitter, github or [mastodon][merveilles]. - -[traefik]: https://traefik.io/ -[docker-compose]: https://docs.docker.com/compose/ -[gitolite]: http://gitolite.com/gitolite/index.html -[klaus]: https://github.com/jonashaag/klaus - -[traefik-in-docker]: https://blog.kilian.io/server-setup/ -[klaus-autoreload]: https://github.com/jonashaag/klaus/wiki/Autoreloader -[gitolite-hooks]: http://gitolite.com/gitolite/cookbook#v36-variation-repo-specific-hooks -[yq]: https://github.com/kislyuk/yq - -[merveilles]: https://merveilles.town/@s_ol diff --git a/root/blog/self-hosted_virtual_home/title: text$plain b/root/blog/self-hosted_virtual_home/title: text$plain deleted file mode 100644 index 0703d19..0000000 --- a/root/blog/self-hosted_virtual_home/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -my self-hosted Virtual Home diff --git a/root/blog/stencils_101/$order b/root/blog/stencils_101/$order deleted file mode 100644 index 80bf43b..0000000 --- a/root/blog/stencils_101/$order +++ /dev/null @@ -1,7 +0,0 @@ -suits_final -killbill_progress -killbill_final -killbillstencil -balistencil_final -poster -technofist_final diff --git a/root/blog/stencils_101/balistencil_final/image$jpeg.jpg b/root/blog/stencils_101/balistencil_final/image$jpeg.jpg Binary files differdeleted file mode 100755 index 4e1ed7b..0000000 --- a/root/blog/stencils_101/balistencil_final/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stencils_101/categories: text$plain b/root/blog/stencils_101/categories: text$plain deleted file mode 100644 index 2de087d..0000000 --- a/root/blog/stencils_101/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update stencils art
\ No newline at end of file diff --git a/root/blog/stencils_101/date: time$iso8601-date b/root/blog/stencils_101/date: time$iso8601-date deleted file mode 100644 index 0202ff1..0000000 --- a/root/blog/stencils_101/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2015-06-29 diff --git a/root/blog/stencils_101/killbill_final/image$jpeg.jpg b/root/blog/stencils_101/killbill_final/image$jpeg.jpg Binary files differdeleted file mode 100755 index 5e6fd9e..0000000 --- a/root/blog/stencils_101/killbill_final/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stencils_101/killbill_progress/image$jpeg.jpg b/root/blog/stencils_101/killbill_progress/image$jpeg.jpg Binary files differdeleted file mode 100755 index a8e8560..0000000 --- a/root/blog/stencils_101/killbill_progress/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stencils_101/killbillstencil/image$png.png b/root/blog/stencils_101/killbillstencil/image$png.png Binary files differdeleted file mode 100755 index 21a657f..0000000 --- a/root/blog/stencils_101/killbillstencil/image$png.png +++ /dev/null diff --git a/root/blog/stencils_101/poster/image$jpeg.jpg b/root/blog/stencils_101/poster/image$jpeg.jpg Binary files differdeleted file mode 100755 index 8192ed4..0000000 --- a/root/blog/stencils_101/poster/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stencils_101/suits_final/image$jpeg.jpg b/root/blog/stencils_101/suits_final/image$jpeg.jpg Binary files differdeleted file mode 100755 index 332d7e4..0000000 --- a/root/blog/stencils_101/suits_final/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stencils_101/technofist_final/image$jpeg.jpg b/root/blog/stencils_101/technofist_final/image$jpeg.jpg Binary files differdeleted file mode 100755 index f73833b..0000000 --- a/root/blog/stencils_101/technofist_final/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stencils_101/text$markdown.md b/root/blog/stencils_101/text$markdown.md deleted file mode 100644 index 67a3e8e..0000000 --- a/root/blog/stencils_101/text$markdown.md +++ /dev/null @@ -1,87 +0,0 @@ -So, for the first non-meta post (don't mind this line), I'm gonna walk you through my stencil creation process. - -# Design -Right now, I design all my stencils in photoshop (CS6, running in wine). -If I get better at hand drawing maybe one day I will sketch them up freehand right on the material but as of now I only do that for text. - -As an example, let's take the Kill Bill Stencil I did a few days ago: - -<mmm-embed path="killbill_final"></mmm-embed> - -The first thing I did was create a new file in Photoshop, with the dimensions set to what I can print with my inkjet printer (International - A4). -For the design process the canvas size doesn't really matter anyway and I like to work on a familiar size so I can judge how fine the details should be, also I print the images via my phone and so I need to have them in A4 size to get consistent results later anyway. - -The next thing I did was look for a picture to use, after a (very) quick google images tour I settled on this image: - -<mmm-embed path="poster"></mmm-embed> - -In order to turn this into a stencil, I used the *Threshold* Image Adjustment, but before that I cut away all the background. -With the Magic Wand and Quick Selection, I removed the black bar and yellow background. -Because I am living in constant fear of losing work, I duplicated the layer and then popped open the *Threshold* Dialog (`Image > Adjustements > Threshold`). -I played around with the slider until I got a good ratio of light and shadow and then applied the changes. - -Often some parts of the image require a different threshold setting than other parts (for example the faces often have lower contrast and require a different threshold value). -In those cases, I just duplicate the original resource layer, find the other value and then cut away the pieces that I don't need -(because I am afraid of commitment I sometimes end up masking the layers with vector masks instead). - -After this step, there will be a lot of tiny artifacts and bubbles that are way too tiny to be cut out (or impossible because they would form tiny islands). -For the Kill Bill Stencil, I went over __all__ of those by hand on another layer with the pencil tool (the brush is terrible for stencilwork because you want a hard edge to cut later, not a gradient around what you drew). -However later on I realized that there is a good way to reliably eliminate this noise; all you need to do is apply a blur (*Gaussian Blur* is very effective and configurable, `Filter > Blur > Gaussian Blur`) and then re-apply *Threshold*. -You can play around with this process a bit to get a feeling for how hard you need to blur to eliminate the noise. - -You will still need to manually touch up the stencil though, at least to look for and fix *Islands*; -In my case, I spraypaint black color onto a white background, so everything that is black gets cut out. -This means that every white part that is surrounded completely by black is going to fall out of the stencil together with the black aswell. -Larger islands may be taped to the surface you are spraying on for art, but it's best to avoid Islands wherever possible (and especially small ones). - -To visualize the final stencil, I have looked up the exact colors of the spraypaint I own at the manufacturers website and saved them as swatches in my photoshop. -I use those to put a background behind the whole image and to color layers that I want to spraypaint in color later. - -<mmm-embed path="killbillstencil"></mmm-embed> - -One problem when you like working non-destructively on many layers, as I do, is that you normally cannot remove something on a layer below by painting over it. -There are two options, either you can just draw the background color, which means you will have to flatten the image later to get the outline, or you can use the *Layer Blend Modes* to your advantage: -What I did was put all the layers in a Layer Group, and set that groups *Blend Mode* to *Screen*. -This will result in everything Black staying Black and everything White turning into transparent, so now you can just paint white on a layer above one that is black to erase the one below. - -# Printing -To print the stencil out, I apply a *Stroke* to all the seperate color's layers (`Layer Styles > Stroke`) and turn down the *Fill* value to 0%. -That way I save toner when printing and have a clear outline guide to cut at. -If one color is scattered across layers I either merge them or put them in a group, then apply the styles to that group instead. - -Because my printer's drivers are weird I print with the phone app. I save every color's outline as a seperate JPG, push them to my phone and print them. -I used to print on standard A4 paper, tape that to thicker cardboard and cut, but I realized that my printer can actually handle the thicker cardbord paper I have. -That makes cutting a lot easier. - -# Cutting -Cutting is very straightforward, I just try to get as many details as possible. -I use a standard box cutter but a scalpel / x-acto knife would probably work even better. -I have a rubber cutting mat that is specifically made for this and works very well. - -<mmm-embed path="killbill_progress"></mmm-embed> - -For small round holes I use an old screwdriver part that turned out to be a perfect hole-punching tool and hit it into the paper with a hammer (on a piece of wood). - -# Painting -To hold down the stencils I usually tape them to the surface with painters tape. -Sometimes I just hold them or press parts flat. -If there are small, flimsy pieces inside that won't stay on the surface or that would get blown to the side or up by the aerosol, I make a small loop out of the tape and stick it to the surface with that makeshift double-sided tape. - -Then I just grab the spraycans and paint the stencil with small, short strokes. -I try not to hit the same spot too often or too long so the paint doesn't flow beneath the stencil or take too long to dry. - -# Results -Here are some of my stencils: - -<mmm-embed path="killbill_final"></mmm-embed> -<mmm-embed path="technofist_final"></mmm-embed> -<mmm-embed path="suits_final"></mmm-embed> -<mmm-embed path="balistencil_final"></mmm-embed> - -I tweet all my daily stencils with the [hashtag #astenciladay on twitter][#astenciladay] and post them in the [*Daily Stencil Art* streak on *streak.club*][dailystencil]. - -If you want any of the `psd`s or the printable outline `jpg`s, [shoot me a tweet][twitter]! - -[#astenciladay]: https://twitter.com/hashtag/astenciladay -[dailystencil]: https://streak.club/s/614/daily-stencil-art -[twitter]: https://twitter.com/S0lll0s diff --git a/root/blog/stencils_101/title: text$plain b/root/blog/stencils_101/title: text$plain deleted file mode 100644 index 498f476..0000000 --- a/root/blog/stencils_101/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Stencils 101
\ No newline at end of file diff --git a/root/blog/stretching_gates/$order b/root/blog/stretching_gates/$order deleted file mode 100644 index 22512ed..0000000 --- a/root/blog/stretching_gates/$order +++ /dev/null @@ -1,5 +0,0 @@ -case -stripboard -schematic -finished_case -crude diff --git a/root/blog/stretching_gates/case/image$jpeg.jpg b/root/blog/stretching_gates/case/image$jpeg.jpg Binary files differdeleted file mode 100644 index e1222dc..0000000 --- a/root/blog/stretching_gates/case/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stretching_gates/categories: text$plain b/root/blog/stretching_gates/categories: text$plain deleted file mode 100644 index ecfcf4f..0000000 --- a/root/blog/stretching_gates/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update gamedev electronics
\ No newline at end of file diff --git a/root/blog/stretching_gates/crude/image$png.png b/root/blog/stretching_gates/crude/image$png.png Binary files differdeleted file mode 100644 index a53df51..0000000 --- a/root/blog/stretching_gates/crude/image$png.png +++ /dev/null diff --git a/root/blog/stretching_gates/date: time$iso8601-date b/root/blog/stretching_gates/date: time$iso8601-date deleted file mode 100644 index 1f26b82..0000000 --- a/root/blog/stretching_gates/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2017-07-04 diff --git a/root/blog/stretching_gates/finished_case/URL -> twitter$tweet b/root/blog/stretching_gates/finished_case/URL -> twitter$tweet deleted file mode 100644 index bc7b385..0000000 --- a/root/blog/stretching_gates/finished_case/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/881940776749543427 diff --git a/root/blog/stretching_gates/schematic/image$jpeg.jpg b/root/blog/stretching_gates/schematic/image$jpeg.jpg Binary files differdeleted file mode 100644 index 64bd239..0000000 --- a/root/blog/stretching_gates/schematic/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stretching_gates/stripboard/image$jpeg.jpg b/root/blog/stretching_gates/stripboard/image$jpeg.jpg Binary files differdeleted file mode 100644 index f719c80..0000000 --- a/root/blog/stretching_gates/stripboard/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/stretching_gates/text$markdown.md b/root/blog/stretching_gates/text$markdown.md deleted file mode 100644 index 3c30727..0000000 --- a/root/blog/stretching_gates/text$markdown.md +++ /dev/null @@ -1,85 +0,0 @@ -As mentioned in the last post, there was some room for improvement in the last iteration of the -trigger/divider circuit. While the divider was working great as a clock source for the drum -machine, the signal output by the comparator was very short and sometimes got triggered twice -with one acoustic hit on the piezo when the reference voltage was not perfectly tuned. -On the other hand the outputs of the 4017 always stay on or off for a whole step. - -While the long steps can be useful to make an oscillator play long notes, shorter pulses each step -are much more interesting to create drum-ish sounds. -Here's a crude drawing of how what the circuit was doing vs how it's supposed to work: - -<mmm-embed path="crude"></mmm-embed> - -The black lines are the signal levels 'as they used to be': you can see that the comparator output -has very short pulses of more or less random duration, the /2 output is on half of the time, the /3 -one third of the steps and so on. -Given some way of creating the blue signal in the top diagram, that stays on a specified amount of -time after each trigger and only then drops back down, the other two blue graphs are very easy to -obtain by simply logical-AND-ing the shaped pulse signal and the divided signal for each divison. -Conveniently, there is a CMOS chip with four AND gates that are more than fast enough: the 4081. - -## hold on -The only missing part is the one that needs to hold the signal for a specified time on each trigger. -Well, the famous 555 Timer IC has our back: in the *monostable Configuration* it will do just that. -Here's a schematic of the basic circuit (pic taken from [here][555-src]): - -![monostable][monostable.jpg] - -This is really half as bad as it looks, but the details are better read up on elsewhere. -Basically, whenever the signal on the trigger (pin 2) goes __low__, the output (pin 3) goes high -and the capacitor between threshold (pin 6) and ground is charged. -When it reaches a certain charge, the output drops back to low and the capacitor is drained. - -This is exactly what is needed, except that the triggers has to go low here to start the timer. -To fix this, I simply swapped the inverting and non-inverting inputs of the comparator, so that it -always outputs the opposite result. - -## putting it together -Here's the final schematic as I built it: - -<mmm-embed path="schematic"></mmm-embed> - -Some things you may notice: - -1. I put a potentiometer into the 555s charging path so that the pulse length can be adjusted. -2. I added a switch that allows me to decide whether I want to AND the divided outputs with the - generated pulse, or basically disable that part by putting 9V there, which basically turns the - AND gate into a normal wire. -3. There are diodes on the reset pins so that I can later expand this with a reset input jack. -4. I am using both halves of the LM393 with the inputs swapped: the positive-going pulse goes to an - LED that shows me the 'raw' incoming signal, and the negative goes to the 555, with another LED - showing the 'shaped' one. With piezo triggers it is impossible to even see the raw LED turn on, - but if I use this with another clock source (LFO for example) it might be useful. -5. We're kind of low on switches so I scrapped that part, but I wanted another switch to choose - between the 555 output or the other LM393 output to be fed into the 4017 dividers. That way I - would've gotten to keep the beat-skipping properties independently of the gate length control, - but now I have to lower the gate length to minimum to disable the 555s debouncing effects. - -## wrapping it up -After this was all working on the breadboard, I started to solder a second version on stripboard. -Before finishing the design I sketched some stripboard layouts on a piece of paper, but in the end I -threw all care overboard and just placed components on the stripboard. - -<mmm-embed path="stripboard"></mmm-embed> - -I cut apart a large IC socket and soldered the two halfes to the sides of the board to simplify -testing and panel wiring, but I'm not sure if it was the best idea bceause the sockets aren't really -made to be used over and over and the wires dont hold too well. I'm thinking I might tape over the -sockets once all the cables are in place and tested. - -[Juan][juan] found this great old Video casette case as a chassis and I really liked it. -We used the Dremel that we had luckily gotten our hands on and started drilling holes for the audio -jacks with a template made from paper. - -<mmm-embed path="case"></mmm-embed> - -The inside also needed some plastic spines ground away to make room for the jacks, but the Dremel -made quick work of all that. Juan finished the top of the case with mounting holes for the two -potentiometers, the input jack, the switch, and two hot-glue-covered holes for the LEDs to shine -through. - -<mmm-embed path="finished_case" nolink></mmm-embed> - -[juan]: https://twitter.com/juanorloz -[555-src]: https://electrosome.com/monostable-multivibrator-555-timer/ -[monostable.jpg]: https://electrosome.com/wp-content/uploads/2013/05/Monostable-Multivibrator-using-555-Timer-Circuit-Diagram.jpg diff --git a/root/blog/stretching_gates/title: text$plain b/root/blog/stretching_gates/title: text$plain deleted file mode 100644 index f5e81de..0000000 --- a/root/blog/stretching_gates/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Stretching Gates
\ No newline at end of file diff --git a/root/blog/text$moonscript -> fn -> mmm$dom.moon b/root/blog/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 2c8cc85..0000000 --- a/root/blog/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,21 +0,0 @@ -import div, h3, a, p, ul, li from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' -import ropairs from require 'mmm.ordered' - -=> - div { - h3 link_to @ - ul do - posts = { (p\gett 'date: time/unix'), p for p in *@children } - - posts = for date, post in ropairs posts - continue if post\get 'hidden: bool' - li (link_to post, os.date '%F', date), ' - ', post\gett 'title: mmm/dom' - - posts - p { - "also check out my weekly posts for the 2020 FabAcademy on my " - a "fabcloud page", href: 'https://fabacademy.org/2020/labs/opendot/students/sol-bekic/' - "." - } - } diff --git a/root/blog/video_synth_research/$order b/root/blog/video_synth_research/$order deleted file mode 100644 index 604e582..0000000 --- a/root/blog/video_synth_research/$order +++ /dev/null @@ -1,8 +0,0 @@ -visualist -bent1 -LZX_reel -sketch_titler -bent2 -schematic -ich_bin_holz -mine diff --git a/root/blog/video_synth_research/LZX_reel/URL -> youtube$video b/root/blog/video_synth_research/LZX_reel/URL -> youtube$video deleted file mode 100644 index 4b95dc7..0000000 --- a/root/blog/video_synth_research/LZX_reel/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=Aba7VD4h6G4 diff --git a/root/blog/video_synth_research/bent1/URL -> youtube$video b/root/blog/video_synth_research/bent1/URL -> youtube$video deleted file mode 100644 index ccc5ce9..0000000 --- a/root/blog/video_synth_research/bent1/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=CwVHHz3ph_c diff --git a/root/blog/video_synth_research/bent2/URL -> youtube$video b/root/blog/video_synth_research/bent2/URL -> youtube$video deleted file mode 100644 index 5684f2a..0000000 --- a/root/blog/video_synth_research/bent2/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=odBDytzF7ko diff --git a/root/blog/video_synth_research/categories: text$plain b/root/blog/video_synth_research/categories: text$plain deleted file mode 100644 index ecfcf4f..0000000 --- a/root/blog/video_synth_research/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update gamedev electronics
\ No newline at end of file diff --git a/root/blog/video_synth_research/date: time$iso8601-date b/root/blog/video_synth_research/date: time$iso8601-date deleted file mode 100644 index c3cf071..0000000 --- a/root/blog/video_synth_research/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2017-06-26 diff --git a/root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg b/root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg Binary files differdeleted file mode 100644 index dc4b14b..0000000 --- a/root/blog/video_synth_research/ich_bin_holz/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/video_synth_research/mine/image$jpeg.jpg b/root/blog/video_synth_research/mine/image$jpeg.jpg Binary files differdeleted file mode 100644 index 3b4a61e..0000000 --- a/root/blog/video_synth_research/mine/image$jpeg.jpg +++ /dev/null diff --git a/root/blog/video_synth_research/schematic/image$png.png b/root/blog/video_synth_research/schematic/image$png.png Binary files differdeleted file mode 100644 index 6b8b4de..0000000 --- a/root/blog/video_synth_research/schematic/image$png.png +++ /dev/null diff --git a/root/blog/video_synth_research/sketch_titler/URL -> twitter$tweet b/root/blog/video_synth_research/sketch_titler/URL -> twitter$tweet deleted file mode 100644 index e99f085..0000000 --- a/root/blog/video_synth_research/sketch_titler/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/876077574639767552 diff --git a/root/blog/video_synth_research/text$markdown.md b/root/blog/video_synth_research/text$markdown.md deleted file mode 100644 index 4051077..0000000 --- a/root/blog/video_synth_research/text$markdown.md +++ /dev/null @@ -1,93 +0,0 @@ -When we started the *Synths and Stuff* project, we discussed how it would be cool to have video -synthesis to accompany the audio performance. In a modular synth setup, we would be able to patch -audio and control signals into the video phase to make music reactive visuals. - -## expensive toys -While I love video synthesis, and my last project before this [was sort of that][plonat-atek], I was -initially a bit worried about the complexity of it. -I had found out about [LZX Industries][lzx] a few months ago, who make amazing modular video synth -gear... that is very expensive. It looks amazing though: - -<mmm-embed path="LZX_reel" nolink></mmm-embed> - -I think the price is probably justified, as a lot of engineering goes into making this work in the -first place, and it looks very clean, which I would attribute to high quality components. - -However, for our project we don't strive to create perfect and clean audio or video. -Glitches and noise are an important part of the analog aesthetic and make the results feel as -organic as they do. - -I also found the *3trins-RGB+1c*, which looks like a nifty little thing but is also way out of my -budget. - -## visualising another way -Reinforced with these thoughts I started looking for DIY video modules. At least in relation to -audio schematics, there is *very little* content on the internet. -However I did find a few good resources. - -There is a 2013 blog with only a few posts, but it does a great job of filtering out relevant -information in [this post summarizing forum gold][vfold]. - -This led me onto the track of the MC1377 chip, an RGB-to-PAL/NTSC video encoder IC. -At some point I found this video showcasing a video effect device based on it, the *Visualist*: - -<mmm-embed path="visualist" nolink></mmm-embed> - -The best thing is that there is [awesome documentation][visualist] (hotlinked from original dropbox, -I have a copy if it goes down) for this thing. -It's not very detailed but the circuit is rather minimal and the color logic easily removed. -The stripped down version that parses an incoming video signal brightness and encodes RGB values you -make from that as the signals scans over the screen is handleable even if not completely understood. - -To practice my understanding and work it into my brain, I broke the original schematic out into -logical units with single connections. - -My plan is to make the *Visualist* color logic, that pseudo-randomly assigns a color to each -brightness level in a 7-step scale that you can adjust into a small module that can be used, -but also mixed with other effects (perhaps an oscillator and external color input) so that we can -sync to our music control signals. - -<mmmdom path="schematic"></mmmdom> -<mmmdom path="mine"></mmmdom> - -If you look closely you can see that I left some parts out and added a bit of logic to allow setting -the amount of steps the brightness scale is sliced into. - -## OBS -2.3 -The other videoish thing we have going on sofar is this: - -<mmm-embed path="sketch_titler" nolink></mmm-embed> - -this *SONY Family Studio* 'Video Sketch Titler' is basically a little box that you connect inbetween -your video camera with some awesome family vacation clips on tape and your VHS recorder, which is -hooked up to your PC. - -You can then draw an amazing title screen over your video with this touchpad-ish device. -When you are ready, you rewind the camera to the beginning, press play and start recording on VHS at -the same time. Then you hit the 'fade in' and 'fade out' buttons on the Sketch Titler and go win -that home video contest. - -Well, this is how it's intended to be used anyway. If your camera doesn't work (like mine), you can -instead practice on a gray background: - -<mmmdom path="ich_bin_holz"></mmmdom> - -So ideally, we can get a live camera as an input to this, and draw on it in *real time*! -Like an ancient livestreaming tool like OBS. -(and then hopefully we will also have a Visualist to either hook up before or after this device) - -Also some other people else has already circuit-bent this. -It looks amazing, so we might just give that a go aswell: - -<mmm-embed path="bent1" nolink></mmm-embed> -<mmm-embed path="bent2" nolink></mmm-embed> - -Since taking this for a spin and making a BOM for the *Visualist*, -I haven't spent any more time on the *Visualist* and turned to the audio side of things for now. -The next step on this front will probably be to lay out (parts of) the circuitry on stripboard and' -get ready to solder :) - -[plonat-atek]: https://s-ol.itch.io/plonat-atek -[lzx]: https://www.lzxindustries.net/ -[vfold]: https://vfoldsynth.wordpress.com/2013/01/23/hidden-stores-of-forum-gold/ -[visualist]: https://www.dropbox.com/s/uhjd2e6gur972yo/VisualistKl.pdf?dl=0 diff --git a/root/blog/video_synth_research/title: text$plain b/root/blog/video_synth_research/title: text$plain deleted file mode 100644 index 19689c8..0000000 --- a/root/blog/video_synth_research/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Video Synth Research
\ No newline at end of file diff --git a/root/blog/video_synth_research/visualist/URL -> youtube$video b/root/blog/video_synth_research/visualist/URL -> youtube$video deleted file mode 100644 index 7ace2f2..0000000 --- a/root/blog/video_synth_research/visualist/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=99j3V9t26pY diff --git a/root/blog/why_redirectly/categories: text$plain b/root/blog/why_redirectly/categories: text$plain deleted file mode 100644 index 18e1a49..0000000 --- a/root/blog/why_redirectly/categories: text$plain +++ /dev/null @@ -1 +0,0 @@ -update programming devops diff --git a/root/blog/why_redirectly/date: time$iso8601-date b/root/blog/why_redirectly/date: time$iso8601-date deleted file mode 100644 index bf5faec..0000000 --- a/root/blog/why_redirectly/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2019-10-26 diff --git a/root/blog/why_redirectly/text$markdown.md b/root/blog/why_redirectly/text$markdown.md deleted file mode 100644 index 4bddd0e..0000000 --- a/root/blog/why_redirectly/text$markdown.md +++ /dev/null @@ -1,56 +0,0 @@ -# Why I'm running a personal URL shortening service -This blog you are reading at the moment is currently running it's third reincarnation. -Originally, it was a Jekyll blog hosted on github pages, -before I moved to my own web platform. -That platform is currently undergoing its second big rewrite. - -Even while still running on github pages, -the blog moved from https://s0lll0s.github.io, to https://s0lll0s.me and finally to https://s-ol.nu. -Once arrived at https://s-ol.nu, I had to move the blog posts to a different route (`/blog` vs just living in the root) -at some point, to make space for other routes. -Then with my custom platform everything changed again, -since now my main system is actually located at https://mmm.s-ol.nu. - -As you might imagine, at every change all the old URLs stop working. -Noone likes finding dead links, but if you post links on social media -it is often extremely unwieldy or impossible to update all the posts. - -If you run your own website or blog ([maybe][sir] you [should][indie]?), -your site may have gone throug similar transitions, -or maybe it is about to go through one - -or perhaps you are deferring making a change because you worry about this? - -To partially solve this issue, I built a tiny URL redirection service, [redirectly][redirectly]. -It works much the same as those URL shortening services you may have used before (bit.ly, tinyurl etc.), -except that I manually specify the shortened URLs in a file (in the git repo). - -Nowadays, when I post a link to some content on my website (such as this blog post), -I first allocate a new `slug` (shortlink) and set it up in `redirectly`. -Then I use the shortened link, such as https://s-ol.nu/why-redirectly in this case, -instead of directly linking to the content. - -This way, whenever I make changes to my content's adressing scheme, -I simply change the URL location, and any old links that are floating around remain functional. -It's also helpful to direct people to the best documentation for a particular project: -when I start working on something, it might exist only as a git repo, -but later in the project's lifecycle I may add a descriptive article on my website or as part of the blog. -Perhaps one of my projects will outgrow this website and need its own domain some time. -By always linking using a canonical project-URL, I can make sure that old links always point to the best place. -Also if I ever decide to move to a different domain again, -I can simply leave the redirection service running on here, at least for a few years :) - -Of course all of this doesn't work when visitors of my page navigate around by themselves, -and then share the URL from their address bar. -This could be solved by using the JS [history API][history] by overriding the displayed URL with the permalink whenever one exists, -but I haven't tried implementing this type of bi-directional querying yet. - -I am also aware that running Clojure (and therefore a JVM) is not necessarily -the best choice for a service that is so light, -but I wrote `redirectly` as a little experiment while learning Clojure, -and it is such a simple project that if it ever bugs me I can just throw it out and implement it in something else. - -[sir]: https://drewdevault.com/make-a-blog -[indie]: https://indieweb.org/why - -[redirectly]: https://s-ol.nu/redirectly/src -[history]: https://developer.mozilla.org/en-US/docs/Web/API/History_API diff --git a/root/blog/why_redirectly/title: text$plain b/root/blog/why_redirectly/title: text$plain deleted file mode 100644 index 63c6ff7..0000000 --- a/root/blog/why_redirectly/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Why I'm running a personal URL shortening service diff --git a/root/description: text$plain b/root/description: text$plain deleted file mode 100644 index 90d0358..0000000 --- a/root/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -mmm is not the www, because it runs on MoonScript. diff --git a/root/experiments/$order b/root/experiments/$order deleted file mode 100644 index 6eca172..0000000 --- a/root/experiments/$order +++ /dev/null @@ -1,5 +0,0 @@ -tags -glitch_cube -torus4d -center_of_mass -parallax_panels diff --git a/root/experiments/center_of_mass/_web_view: type b/root/experiments/center_of_mass/_web_view: type deleted file mode 100644 index bde5644..0000000 --- a/root/experiments/center_of_mass/_web_view: type +++ /dev/null @@ -1 +0,0 @@ -text/html+interactive diff --git a/root/experiments/center_of_mass/description: text$plain b/root/experiments/center_of_mass/description: text$plain deleted file mode 100644 index 256df66..0000000 --- a/root/experiments/center_of_mass/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -Fonts aligned by Center-of-Mass diff --git a/root/experiments/center_of_mass/text$moonscript -> mmm$dom.moon b/root/experiments/center_of_mass/text$moonscript -> mmm$dom.moon deleted file mode 100644 index a43ea69..0000000 --- a/root/experiments/center_of_mass/text$moonscript -> mmm$dom.moon +++ /dev/null @@ -1,171 +0,0 @@ -assert MODE == 'CLIENT', '[nossr]' - -import CanvasApp from require 'mmm.canvasapp' -import rgb from require 'mmm.color' -import article, h1, p, div, span, input, button from require 'mmm.dom' - -fast = true -center = true -center_char = do - canvas = document\createElement 'canvas' - ctx = canvas\getContext '2d' - - cache = {} - - (char, font, height) -> - name = "#{char} #{height} #{font}" - return table.unpack cache[name] if cache[name] - - ctx\resetTransform! - ctx.font = "#{height}px #{font}" - width = (ctx\measureText char).width - canvas.width, canvas.height = width, height * 1.2 - - ctx.font = "#{height}px #{font}" - ctx.textBaseline = 'top' - ctx.fillStyle = rgb 0, 0, 0 - ctx\fillText char, 0, 0 - - data = ctx\getImageData 0, 0, width, height * 1.2 - - local xx, yy - if fast - loop = window\eval '(function(data) { - var xx = 0, yy = 0, n = 0; - for (var x = 0; x < data.width - 1; x++) { - for (var y = 0; y < data.height - 1; y++) { - var i = y * (data.width * 4) + x * 4; - var alpha = data.data[i + 3] / 255; - xx += x * alpha; - yy += y * alpha; - n += alpha; - } - } - - xx /= n; - yy /= n; - return [xx, yy]; - })' - res = loop nil, data - xx, yy = res[0], res[1] - else - xx, yy, n = 0, 0, 0 - for x = 0, data.width - 1 - for y = 0, data.height - 1 - i = y * (data.width * 4) + x * 4 - alpha = data.data[i + 3] / 255 - xx += x * alpha - yy += y * alpha - n += alpha - - xx /= n - yy /= n - cache[name] = { xx, yy, width } - xx, yy, width - -class CenterOfMass extends CanvasApp - width: window.innerWidth - 20 - height: 300 - new: (text, @font, @size) => - super! - @text = {} - for i = 1,#text - @add text\sub i, i - - add: (char) => - rcx, rcy, w = center_char char, @font, @size - cx, cy = w/2, @size/2 - vx, vy = 0, 0 - table.insert @text, { - :char, :rcx, :rcy, :w - :cx, :cy, :vx, :vy - } - - refresh: => - for char in *@text - char.rcx, char.rcy, char.w = center_char char.char, @font, @size - - keydown: (key) => - if key == "Backspace" or key == "Delete" - table.remove @text - elseif string.len(key) == 1 - @add key - - update: (dt) => - super dt - - ACCEL = 4 * dt - DAMPING = 8 * dt - - for char in *@text - { :rcx, :rcy, :cx, :cy, :w } = char - if not center - rcx, rcy = w/2, @size/2 - dx, dy = rcx - cx, rcy - cy - char.vx += dx * ACCEL - char.vy += dy * ACCEL - char.cx += char.vx - char.cy += char.vy - char.vx *= DAMPING - char.vy *= DAMPING - - draw: => - @ctx\clearRect 0, 0, @width, @height - - @ctx.font = "#{@size}px #{@font}" - @ctx.textBaseline = 'top' - - x, y = @size * .1, @size - for { :char, :cx, :cy, :w } in *@text - if x + w > @width - x = 0 - y += @size * 1.2 - - @ctx\fillText char, x + w/2 - cx, y - cy - x += w - -_content = {} -append = (x) -> table.insert _content, x - -append h1 'Fonts aligned by Center-of-Mass' -app = CenterOfMass "Click here and type Away!", "Times New Roman", 40 -append app.canvas -app.canvas.style.backgroundColor = '#eee' - -add = => - append div { - span 'font: ', - with @font_input = input! - .type = 'text' - .value = 'Times New Roman' - with button 'set' - .onclick = (_, e) -> - app.font = @font_input.value - app\refresh! - } - - append div { - span 'size: ', - input type: 'range', min: 2, max: 120, value: 40, onchange: (_, e) -> - size = e.target.value - @size_label.innerText = size - app.size = size - app\refresh! - with @size_label = span '40' - '' - } - - append div { - span 'center characters by weight: ', - input type: 'checkbox', checked: center, onchange: (_, e) -> - center = e.target.checked - } - - append div { - span 'optimize inner loop: ', - input type: 'checkbox', checked: fast, onchange: (_, e) -> - fast = e.target.checked - } -add {} - -article _content diff --git a/root/experiments/glitch_cube/description: text$plain b/root/experiments/glitch_cube/description: text$plain deleted file mode 100644 index b38c873..0000000 --- a/root/experiments/glitch_cube/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -program interpreting random parts of itself as textures for a cube. diff --git a/root/experiments/glitch_cube/link: URL -> tweet b/root/experiments/glitch_cube/link: URL -> tweet deleted file mode 100644 index 3625985..0000000 --- a/root/experiments/glitch_cube/link: URL -> tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/984465155445678080 diff --git a/root/experiments/parallax_panels/$order b/root/experiments/parallax_panels/$order deleted file mode 100644 index c4fca74..0000000 --- a/root/experiments/parallax_panels/$order +++ /dev/null @@ -1,2 +0,0 @@ -picture -viewer diff --git a/root/experiments/parallax_panels/description: text$plain b/root/experiments/parallax_panels/description: text$plain deleted file mode 100644 index 0eed9db..0000000 --- a/root/experiments/parallax_panels/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -A Parallax SVG Viewer, for Prototyping (Eurorack) Panels diff --git a/root/experiments/parallax_panels/picture/URL -> twitter$tweet b/root/experiments/parallax_panels/picture/URL -> twitter$tweet deleted file mode 100644 index 8d5bce2..0000000 --- a/root/experiments/parallax_panels/picture/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1141006444793405440 diff --git a/root/experiments/parallax_panels/text$markdown.md b/root/experiments/parallax_panels/text$markdown.md deleted file mode 100644 index 7453762..0000000 --- a/root/experiments/parallax_panels/text$markdown.md +++ /dev/null @@ -1,16 +0,0 @@ -parallax-panels -=============== - -I'm prototyping an aesthetic for (eurorack) panels that relies on multiple layers of parallax visuals for dramatic effect. - -<mmm-embed path="picture" nolink></mmm-embed> - -parallax-viewer -=============== - -I built a little SVG viewer that stacks the layers and lets you view them in parallax. -You can find it <mmm-link path="viewer">here</mmm-link>. - -And here's a little demonstration: - -<mmm-embed path="viewer/demo" nolink></mmm-embed> diff --git a/root/experiments/parallax_panels/viewer/$order b/root/experiments/parallax_panels/viewer/$order deleted file mode 100644 index 1549b67..0000000 --- a/root/experiments/parallax_panels/viewer/$order +++ /dev/null @@ -1 +0,0 @@ -demo diff --git a/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 b/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 Binary files differdeleted file mode 100755 index f3600cc..0000000 --- a/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 +++ /dev/null diff --git a/root/experiments/parallax_panels/viewer/link: URL b/root/experiments/parallax_panels/viewer/link: URL deleted file mode 100644 index f1bc92e..0000000 --- a/root/experiments/parallax_panels/viewer/link: URL +++ /dev/null @@ -1 +0,0 @@ -https://codepen.io/s-ol/full/rExrey diff --git a/root/experiments/tags/_web_view: type b/root/experiments/tags/_web_view: type deleted file mode 100644 index bde5644..0000000 --- a/root/experiments/tags/_web_view: type +++ /dev/null @@ -1 +0,0 @@ -text/html+interactive diff --git a/root/experiments/tags/description: text$plain b/root/experiments/tags/description: text$plain deleted file mode 100644 index e585bb8..0000000 --- a/root/experiments/tags/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -defining toggles, categories etc. with tags and functional hooks diff --git a/root/experiments/tags/hidden: text$lua -> bool b/root/experiments/tags/hidden: text$lua -> bool deleted file mode 100644 index b30e187..0000000 --- a/root/experiments/tags/hidden: text$lua -> bool +++ /dev/null @@ -1 +0,0 @@ -return true diff --git a/root/experiments/tags/tags: text$moonscript -> table.moon b/root/experiments/tags/tags: text$moonscript -> table.moon deleted file mode 100644 index 198392e..0000000 --- a/root/experiments/tags/tags: text$moonscript -> table.moon +++ /dev/null @@ -1,146 +0,0 @@ -join = (tbl, sep) -> - ret = '' - for tag in pairs tbl - ret ..= (tostring tag) .. sep - ret - -handlers = { - add: {} - rmv: {} -} - -class Node - new: (@name) => - @tags = {} - - inspect: => - "#{@name}: [#{join @tags, ' '}]" - - has: (tag) => @tags[tag] - add: (tag) => @tags[tag] = tag - rmv: (tag) => @tags[tag] = nil - -any = -> true -literal = (def) -> (val) -> def == val -oneof = (defs) -> (val) -> - for def in *defs - return true if def == val - false -has = (tag) -> (node) -> node\has tag - -add_tag = (node, tag) -> - return if node\has tag - node\add tag - for hand, _ in pairs handlers.add - hand\match node, tag - -rmv_tag = (node, tag) -> - return if not node\has tag - node\rmv tag - for hand, _ in pairs handlers.rmv - hand\match node, tag - -class Handler - new: (@rule, @action, match, @func) => - @args = for arg in *match - if 'string' == type arg - literal arg - elseif 'table' == type arg - oneof arg - else - arg - - match: (...) => - supplied = { ... } - assert #supplied == #@args, 'length of arguments doesnt match' - for i = 1, #supplied - return false if not @args[i] supplied[i] - - @.func @rule, ... - - name: => "#{@rule.name}:#{@action}" - -class Rule - new: (@name="#{@@__name}") => - @owned_handlers = {} - - hook: (action, ...) => - handler = Handler @, action, ... - table.insert @owned_handlers, handler - handlers[action][handler] = handler - - destroy: => - for hand in *@owned_handlers - handlers[hand.action][hand] = nil - -class Hierarchy extends Rule - new: (@parent, @child) => - super! - - -- when something is tagged with the child-tag, apply the parent tag - @hook 'add', { any, @child }, (node) => - add_tag node, @parent - - -- when child tag is removed, remove parent tag - @hook 'rmv', { any, @child }, (node) => - rmv_tag node, @parent - - -- when parent tag is removed, remove child tag - @hook 'rmv', { any, @parent }, (node) => - rmv_tag node, @child - -class Toggle extends Rule - new: (@a, @b) => - super! - - either = { @a, @b } - opposite = (tag) -> if tag == @a then @b else @a - - -- when a is added, remove b and vice-versa - @hook 'add', { any, either }, (node, tag) => - rmv_tag node, opposite tag - - -- when a is removed, add b and vice-versa - @hook 'rmv', { any, either }, (node, tag) => - add_tag node, opposite tag - -class NamespacedToggle extends Rule - new: (@ns, @a, @b) => - super! - - namespaced = has @ns - either = { @a, @b } - opposite = (tag) -> if tag == @a then @b else @a - - -- when node enters namespace, add default tag - @hook 'add', { any, @ns }, (node) => - add_tag node, @a - - -- when node leaves namespace, remove tags - @hook 'rmv', { any, @ns }, (node) => - rmv_tag node, @a - rmv_tag node, @b - - -- when a is added, remove b and vice-versa - @hook 'add', { namespaced, either }, (node, tag) => - rmv_tag node, opposite tag - - -- when a is removed, add b and vice-versa - @hook 'rmv', { namespaced, either }, (node, tag) => - add_tag node, opposite tag - -{ - :Node, - :Rule, - - :any, - :literal, - :oneof, - :has, - :add_tag, - :rmv_tag, - - :Hierarchy, - :Toggle, - :NamespacedToggle, -} diff --git a/root/experiments/tags/text$moonscript -> fn -> mmm$component.moon b/root/experiments/tags/text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index 24972ac..0000000 --- a/root/experiments/tags/text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,92 +0,0 @@ -=> - assert MODE == 'CLIENT', '[nossr]' - - import add_tag, rmv_tag, Node, Hierarchy, Toggle, NamespacedToggle from @get 'tags: table' - import ReactiveVar, tohtml, text, elements from require 'mmm.component' - import article, div, form, span, h3, a, input, textarea, button from elements - - clone = (set) -> - assert set and 'table' == (type set), 'not a set' - { k,v for k,v in pairs set } - - set_append = (val) -> (set) -> - with copy = clone set - copy[val] = val - - set_remove = (val) -> (set) -> - with copy = clone set - copy[val] = nil - - set_join = (tbl, sep=' ') -> - ret = '' - for tag in pairs tbl - ret ..= (tostring tag) .. sep - ret - - entries = div! - - class ReactiveNode extends Node - new: (...) => - super ... - @tags = ReactiveVar @tags - @_node = div { - span @name, style: { 'font-weight': 'bold' }, - @tags\map (tags) -> with div! - for tag,_ in pairs tags - \append a (text tag), href: '#', style: { - display: 'inline-block', - margin: '0 5px', - } - } - - @node = tohtml @_node - - has: (tag) => @tags\get![tag] - add: (tag) => @tags\transform set_append tag - rmv: (tag) => @tags\transform set_remove tag - - rules = { - Hierarchy 'home', 'sol' - Hierarchy 'sol', 'desktop' - Hierarchy 'desktop', 'vacation' - Hierarchy 'desktop', 'documents' - NamespacedToggle 'documents', 'work', 'personal' - -- Toggle 'work', 'personal' - -- Hierarchy 'documents', 'work' - -- Hierarchy 'documents', 'personal' - } - - pictures = for i=1,10 - with node = ReactiveNode "picture#{i}.jpg" - entries\append node - add_tag node, 'vacation' - - pers = ReactiveNode 'mypersonalfile.doc' - entries\append pers - - article entries, div do - yield = coroutine.yield - step = coroutine.wrap -> - yield "mark document" - add_tag pers, 'documents' - - yield "mark personal" - add_tag pers, 'personal' - - yield "mark work" - add_tag pers, 'work' - - yield "unmark work" - rmv_tag pers, 'work' - - yield "remove from documents" - rmv_tag pers, 'documents' - - yield false - - next_step = ReactiveVar step! - next_step\map (desc) -> - if desc - button (text desc), onclick: (e) => next_step\set step! - else - text '' diff --git a/root/experiments/text$moonscript -> fn -> mmm$dom.moon b/root/experiments/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 70779be..0000000 --- a/root/experiments/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,11 +0,0 @@ -import div, h3, ul, li from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - div { - h3 link_to @ - ul for child in *@children - continue if child\get 'hidden: bool' - desc = child\gett 'description: mmm/dom' - li (link_to child), ': ', desc - } diff --git a/root/experiments/title: text$plain b/root/experiments/title: text$plain deleted file mode 100644 index 0487531..0000000 --- a/root/experiments/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -various experiments diff --git a/root/experiments/torus4d/description: text$plain b/root/experiments/torus4d/description: text$plain deleted file mode 100644 index 07b0020..0000000 --- a/root/experiments/torus4d/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -Attempt at rendering a spiral pattern on a 4d meta-torus. diff --git a/root/experiments/torus4d/link: URL -> git b/root/experiments/torus4d/link: URL -> git deleted file mode 100644 index a134ff1..0000000 --- a/root/experiments/torus4d/link: URL -> git +++ /dev/null @@ -1 +0,0 @@ -https://github.com/s-ol/torus4d diff --git a/root/games/$order b/root/games/$order deleted file mode 100644 index 85fb1ff..0000000 --- a/root/games/$order +++ /dev/null @@ -1,13 +0,0 @@ -the_sacculi -zebra_painting -gtglg -the_monster_within -IYNX -vision-training-kit -curved_curse -two_shooting_stars -moving_out -channel_83 -plonat_atek -lorem_ipsum -fake-artist diff --git a/root/games/IYNX/$order b/root/games/IYNX/$order deleted file mode 100644 index e46078b..0000000 --- a/root/games/IYNX/$order +++ /dev/null @@ -1,6 +0,0 @@ -cryptex -teaser -pin_pad -pictures -ui_demo -boot_sequence diff --git a/root/games/IYNX/boot_sequence/URL -> twitter$tweet b/root/games/IYNX/boot_sequence/URL -> twitter$tweet deleted file mode 100644 index 77b85f6..0000000 --- a/root/games/IYNX/boot_sequence/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/817332363273310209 diff --git a/root/games/IYNX/cryptex/URL -> twitter$tweet b/root/games/IYNX/cryptex/URL -> twitter$tweet deleted file mode 100644 index 4d7974b..0000000 --- a/root/games/IYNX/cryptex/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/825476278732148736 diff --git a/root/games/IYNX/date: time$iso8601-date b/root/games/IYNX/date: time$iso8601-date deleted file mode 100644 index b12bb99..0000000 --- a/root/games/IYNX/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2017-01-20 diff --git a/root/games/IYNX/description: text$plain b/root/games/IYNX/description: text$plain deleted file mode 100644 index 0d21752..0000000 --- a/root/games/IYNX/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a narrative, tangible, physical puzzle incorporating digital elements. diff --git a/root/games/IYNX/icon: image$png.png b/root/games/IYNX/icon: image$png.png Binary files differdeleted file mode 100755 index 0765350..0000000 --- a/root/games/IYNX/icon: image$png.png +++ /dev/null diff --git a/root/games/IYNX/jam: text$markdown+span b/root/games/IYNX/jam: text$markdown+span deleted file mode 100644 index a95a990..0000000 --- a/root/games/IYNX/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -semester project diff --git a/root/games/IYNX/pictures/$order b/root/games/IYNX/pictures/$order deleted file mode 100644 index 8a44d99..0000000 --- a/root/games/IYNX/pictures/$order +++ /dev/null @@ -1,6 +0,0 @@ -ui_menu -c -ui_sample -d -a -b diff --git a/root/games/IYNX/pictures/a/image$jpeg.jpg b/root/games/IYNX/pictures/a/image$jpeg.jpg Binary files differdeleted file mode 100644 index 286c406..0000000 --- a/root/games/IYNX/pictures/a/image$jpeg.jpg +++ /dev/null diff --git a/root/games/IYNX/pictures/b/image$jpeg.jpg b/root/games/IYNX/pictures/b/image$jpeg.jpg Binary files differdeleted file mode 100644 index 48190c0..0000000 --- a/root/games/IYNX/pictures/b/image$jpeg.jpg +++ /dev/null diff --git a/root/games/IYNX/pictures/c/image$jpeg.jpg b/root/games/IYNX/pictures/c/image$jpeg.jpg Binary files differdeleted file mode 100644 index 2eb5db7..0000000 --- a/root/games/IYNX/pictures/c/image$jpeg.jpg +++ /dev/null diff --git a/root/games/IYNX/pictures/d/image$jpeg.jpg b/root/games/IYNX/pictures/d/image$jpeg.jpg Binary files differdeleted file mode 100644 index 3a00dae..0000000 --- a/root/games/IYNX/pictures/d/image$jpeg.jpg +++ /dev/null diff --git a/root/games/IYNX/pictures/text$moonscript -> fn -> mmm$dom.moon b/root/games/IYNX/pictures/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 531c6c3..0000000 --- a/root/games/IYNX/pictures/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,16 +0,0 @@ -import div from require 'mmm.dom' -import embed from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - images = for child in *@children - embed child, nil, nil, wrap: 'raw', style: { - height: '15em' - margin: '0 .5em' - } - - div with images - .style = { - display: 'flex' - overflow: 'auto hidden' - height: '15rem' - } diff --git a/root/games/IYNX/pictures/ui_menu/image$jpeg.jpg b/root/games/IYNX/pictures/ui_menu/image$jpeg.jpg Binary files differdeleted file mode 100644 index 6372f3f..0000000 --- a/root/games/IYNX/pictures/ui_menu/image$jpeg.jpg +++ /dev/null diff --git a/root/games/IYNX/pictures/ui_sample/image$jpeg.jpg b/root/games/IYNX/pictures/ui_sample/image$jpeg.jpg Binary files differdeleted file mode 100644 index b8fa2cb..0000000 --- a/root/games/IYNX/pictures/ui_sample/image$jpeg.jpg +++ /dev/null diff --git a/root/games/IYNX/pin_pad/URL -> twitter$tweet b/root/games/IYNX/pin_pad/URL -> twitter$tweet deleted file mode 100644 index 73a2ad6..0000000 --- a/root/games/IYNX/pin_pad/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/818230279269679104 diff --git a/root/games/IYNX/teaser/URL -> youtube$video b/root/games/IYNX/teaser/URL -> youtube$video deleted file mode 100644 index 078b3e9..0000000 --- a/root/games/IYNX/teaser/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=i7D_9P2semQ diff --git a/root/games/IYNX/text$markdown.md b/root/games/IYNX/text$markdown.md deleted file mode 100644 index cfd7944..0000000 --- a/root/games/IYNX/text$markdown.md +++ /dev/null @@ -1,66 +0,0 @@ -IYNX -==== -<mmm-embed path="pictures" nolink></mmm-embed> - -An engaging, tangible and physical electronic puzzle where a mysterious device is found with no indication of its purpose, -and alongside it is a personality chip owned by a man named John. -The device looks tampered with, as if someone has tried to sabotage or access what it contains. -Who’s John and what’s inside? - -You only need to figure a way in to find out. - -<mmm-embed path="teaser" nolink inline> - a project teaser -</mmm-embed> - -Concept -------- -IYNX is a physical object in the form of a cube, surrounded by mechanical and digital puzzles. -The Player is given the object with no explanation and encouraged to experiment. -The game consists of a set of puzzles, each unlocking new content accessible from the screen, slowly fleshing a narrative around them. - -As the player progresses and solves the game puzzle by puzzle, -it becomes increasingly clear that the AI that is 'trapped' in the cube is malicious and highly manipulative. -Lore that can be pieced together by attentive players suggests -that the cube has been built especially to contain the AI in an electronic prison of sorts. -It is continuously hinted at, and finally revealed, that every puzzle solved was in fact a security -mechanism the player disabled, following the AIs suggestions and instructions. -At the end of the game the AI escapes by uploading itself into the internet. -Initially the player is lead to believe that he is impersonating the original user of the AI, -but it turns out that the AI knew this since the beginning and used the player's curiosity to its own advantage. - -Technical Realisation ---------------------- -The cube is powered by a Raspberry Pi 3 and two Arduino Micros. -The Arduinos are connected as Serial devices. - -The Raspberry Pi is connected to a Touchscreen Panel as well as USB Speakers. -It runs a custom electron app that interfaces with the Serial ports, -plays back video and audio files and displays a futuristic OS that lets you browse a filesystem. - -<mmm-embed path="ui_demo" nolink> - the User Interface was built using react and electron -</mmm-embed> - -The game consists of several smaller puzzle components that are arranged to form a story as a whole, -through which the player is guided by the 'AI' that posseses the artifact. - - -<div style="display: flex; flex-wrap: wrap; align-items: flex-start;"> - <mmm-embed path="boot_sequence" nolink inline> - a fake boot sequence for a component of the cube - </mmm-embed> - <mmm-embed path="pin_pad" nolink inline> - a pinpad that grants access to the higher systems of the cube - </mmm-embed> - <mmm-embed path="cryptex" nolink inline> - an early prototype of the Cryptex puzzle that marks the end of the game - </mmm-embed> -</div> - -Credits -------- -- Trent Davies: Puzzle and Narrative Design -- Sol Bekic: Programming and Electronics -- Dominique Bodden: Art and Physical Construction -- Ilke Karademir: Puzzle and Graphic Design diff --git a/root/games/IYNX/title: text$plain b/root/games/IYNX/title: text$plain deleted file mode 100644 index bb857ce..0000000 --- a/root/games/IYNX/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -IYNX diff --git a/root/games/IYNX/ui_demo/URL -> twitter$tweet b/root/games/IYNX/ui_demo/URL -> twitter$tweet deleted file mode 100644 index 9ea54e1..0000000 --- a/root/games/IYNX/ui_demo/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/825864142116491264 diff --git a/root/games/channel_83/date: time$iso8601-date b/root/games/channel_83/date: time$iso8601-date deleted file mode 100644 index 3c0b19b..0000000 --- a/root/games/channel_83/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2017-08-30 diff --git a/root/games/channel_83/description: text$plain b/root/games/channel_83/description: text$plain deleted file mode 100644 index 0a65c94..0000000 --- a/root/games/channel_83/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a low-fi raycasting shooter. diff --git a/root/games/channel_83/icon: image$png.png b/root/games/channel_83/icon: image$png.png Binary files differdeleted file mode 100755 index 092404b..0000000 --- a/root/games/channel_83/icon: image$png.png +++ /dev/null diff --git a/root/games/channel_83/jam: text$markdown+span b/root/games/channel_83/jam: text$markdown+span deleted file mode 100644 index 9dced70..0000000 --- a/root/games/channel_83/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[Ludum Dare 36](http://ludumdare.com/compo/ludum-dare-36/?action=preview&uid=28620) diff --git a/root/games/channel_83/link: URL -> itchio$game b/root/games/channel_83/link: URL -> itchio$game deleted file mode 100644 index 44221dd..0000000 --- a/root/games/channel_83/link: URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/channel-83 diff --git a/root/games/channel_83/title: text$plain b/root/games/channel_83/title: text$plain deleted file mode 100644 index 64a716e..0000000 --- a/root/games/channel_83/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Channel 83: a last-gen entertainment experience diff --git a/root/games/curved_curse/date: time$iso8601-date b/root/games/curved_curse/date: time$iso8601-date deleted file mode 100644 index 378bfb8..0000000 --- a/root/games/curved_curse/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2015-04-20 diff --git a/root/games/curved_curse/description: text$plain b/root/games/curved_curse/description: text$plain deleted file mode 100644 index 5645632..0000000 --- a/root/games/curved_curse/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a dungeon shooter with an unconventional gun. diff --git a/root/games/curved_curse/icon: image$png.png b/root/games/curved_curse/icon: image$png.png Binary files differdeleted file mode 100755 index c5caaf9..0000000 --- a/root/games/curved_curse/icon: image$png.png +++ /dev/null diff --git a/root/games/curved_curse/jam: text$markdown+span b/root/games/curved_curse/jam: text$markdown+span deleted file mode 100644 index ca4a318..0000000 --- a/root/games/curved_curse/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[Ludum Dare 32](http://ludumdare.com/compo/ludum-dare-32/?action=preview&uid=28620) diff --git a/root/games/curved_curse/link: URL -> itchio$game b/root/games/curved_curse/link: URL -> itchio$game deleted file mode 100644 index 576cac6..0000000 --- a/root/games/curved_curse/link: URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/curved-curse diff --git a/root/games/curved_curse/title: text$plain b/root/games/curved_curse/title: text$plain deleted file mode 100644 index b02b5f5..0000000 --- a/root/games/curved_curse/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Curved Curse diff --git a/root/games/fake-artist/date: time$iso8601-date b/root/games/fake-artist/date: time$iso8601-date deleted file mode 100644 index 5fb953f..0000000 --- a/root/games/fake-artist/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2020-04-22 diff --git a/root/games/fake-artist/description: text$plain b/root/games/fake-artist/description: text$plain deleted file mode 100644 index c7efb6d..0000000 --- a/root/games/fake-artist/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -quarantine implementation of a bluffing-drawing game. diff --git a/root/games/fake-artist/text$html.html b/root/games/fake-artist/text$html.html deleted file mode 100644 index cf6f8b5..0000000 --- a/root/games/fake-artist/text$html.html +++ /dev/null @@ -1,124 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js"></script> - <style> - html { - margin: 0; - padding: 0; - background: #272727; - - display: flex; - min-height: 100vh; - align-items: center; - overflow-y: auto; - } - - body { - font-family: sans-serif; - - width: 12em; - margin: 1em auto; - border: 4px solid #696969; - border-radius: 0.5rem; - background: #eeeeee; - overflow: hidden; - } - - header { - padding: .5rem; - background: #696969; - color: #eeeeee; - } - - h2 { - margin: 0; - } - - #main, #setup { - padding: .5rem; - } - - main .inner { - margin-bottom: .5em; - } - - main .inner { - overflow: hidden; - max-height: 12em; - - transition: all 0.3s; - } - - main .inner > div { - display: flex; - } - main .inner > div > input { - flex: 1; - width: 0; - margin-left: 1em; - } - - #setup { - display: none; - } - .setup #setup { - display: block; - } - - .sensitive { - position: relative; - - padding: 0.3em; - border: 0.2em solid #696969; - } - - .sensitive .cover { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - padding: 0.5em; - color: #eeeeee; - background: #696969; - transition: opacity 300ms; - } - - .sensitive:hover .cover { - opacity: 0; - pointer-events: none; - } - - pre { - font-size: 2em; - font-weight: bold; - margin: 0; - } - pre.spy { - color: #c33; - } - - a { color: inherit; } - </style> - </head> - <body> - <main> - <header> - <h2>Fake Artist</h2> - <div id="head"></div> - </header> - <div id="setup" class="inner"> - <div>spies: <input id="spies" type="number" value="1" /></div> - <div>players:</div> - <ul id="players"></ul> - <div> - <button id="add">add</button> - <input id="name" type="text" /> - </div> - </div> - <div id="main"></div> - </main> - <script src=":text/javascript"></script> - </body> -</html> diff --git a/root/games/fake-artist/text$javascript.js b/root/games/fake-artist/text$javascript.js deleted file mode 100644 index 18c63f8..0000000 --- a/root/games/fake-artist/text$javascript.js +++ /dev/null @@ -1,368 +0,0 @@ -const words = [ - "airplane", - "alive", - "alligator", - "angel", - "ant", - "apple", - "arm", - "baby", - "backpack", - "ball", - "balloon", - "banana", - "bark", - "baseball", - "basketball", - "bat", - "bathroom", - "beach", - "beak", - "bear", - "bed", - "bee", - "bell", - "bench", - "bike", - "bird", - "blanket", - "blocks", - "boat", - "bone", - "book", - "bounce", - "bow", - "bowl", - "box", - "boy", - "bracelet", - "branch", - "bread", - "bridge", - "broom", - "bug", - "bumblebee", - "bunk bed", - "bunny", - "bus", - "butterfly", - "button", - "camera", - "candle", - "candy", - "car", - "carrot", - "cat", - "caterpillar", - "chair", - "cheese", - "cherry", - "chicken", - "chimney", - "clock", - "cloud", - "coat", - "coin", - "comb", - "computer", - "cookie", - "corn", - "cow", - "crab", - "crack", - "crayon", - "cube", - "cup", - "cupcake", - "curl", - "daisy", - "desk", - "diamond", - "dinosaur", - "dog", - "doll", - "door", - "dragon", - "dream", - "drum", - "duck", - "ear", - "ears", - "Earth", - "egg", - "elephant", - "eye", - "eyes", - "face", - "family", - "feather", - "feet", - "finger", - "fire", - "fish", - "flag", - "float", - "flower", - "fly", - "football", - "fork", - "frog", - "ghost", - "giraffe", - "girl", - "glasses", - "grapes", - "grass", - "hair", - "hamburger", - "hand", - "hat", - "head", - "heart", - "helicopter", - "hippo", - "hook", - "horse", - "house", - "ice cream cone", - "inchworm", - "island", - "jacket", - "jail", - "jar", - "jellyfish", - "key", - "king", - "kite", - "kitten", - "knee", - "ladybug", - "lamp", - "leaf", - "leg", - "legs", - "lemon", - "light", - "line", - "lion", - "lips", - "lizard", - "lollipop", - "love", - "man", - "Mickey Mouse", - "milk", - "mitten", - "monkey", - "monster", - "moon", - "motorcycle", - "mountain", - "mountains", - "mouse", - "mouth", - "music", - "nail", - "neck", - "night", - "nose", - "ocean", - "octopus", - "orange", - "oval", - "owl", - "pants", - "pen", - "pencil", - "person", - "pie", - "pig", - "pillow", - "pizza", - "plant", - "popsicle", - "purse", - "rabbit", - "rain", - "rainbow", - "ring", - "river", - "robot", - "rock", - "rocket", - "sea", - "seashell", - "sheep", - "ship", - "shirt", - "shoe", - "skateboard", - "slide", - "smile", - "snail", - "snake", - "snowflake", - "snowman", - "socks", - "spider", - "spider web", - "spoon", - "stairs", - "star", - "starfish", - "suitcase", - "sun", - "sunglasses", - "swimming pool", - "swing", - "table", - "tail", - "train", - "tree", - "truck", - "turtle", - "water", - "whale", - "wheel", - "window", - "woman", - "worm", - "zebra", - "zoo", -]; - -const main = document.getElementById('main'); -const head = document.getElementById('head'); -const players = document.getElementById('players'); -const spies = document.getElementById('spies'); -const name = document.getElementById('name'); -const add = document.getElementById('add'); - -const shuffle = (array, rng) => { - for (let i = array.length - 1; i > 0; i--) { - let j = Math.floor(rng() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } -}; - -const infect = a => { - a.onclick = () => { - const hash = a.href.split('#')[1]; - update('#' + hash); - }; -}; - -const genSeed = rng => ( - words[Math.floor(rng() * words.length)].replace(' ', '-').toLowerCase() - + '_' + words[Math.floor(rng() * words.length)].replace(' ', '-').toLowerCase() - + '_' + words[Math.floor(rng() * words.length)].replace(' ', '-').toLowerCase() -); - -const update = (hash) => { - const [ mode, seed, n, ...names ] = hash.split(/,/); - const rng = new Math.seedrandom(seed); - const nextSeed = genSeed(rng); - - while (main.lastChild) - main.removeChild(main.lastChild); - - while (head.lastChild) - head.removeChild(head.lastChild); - - if (mode === '#link') { - const code = document.createElement('code'); - code.innerText = seed; - head.append(code); - - document.body.className = ''; - names.forEach((name, i) => { - const a = document.createElement('a'); - a.innerText = 'play'; - a.href = `#play,${seed},${n},${names.join(',')},${i}`; - infect(a); - - const div = document.createElement('div'); - div.append(`${name}: `); - div.append(a); - main.append(div); - }); - - const a = document.createElement('a'); - a.innerText = 'next round'; - a.href = `#link,${nextSeed},${n},${names.join(',')}`; - infect(a); - main.append(document.createElement('br')); - main.append(a); - } else if (mode === '#play') { - const code = document.createElement('code'); - code.innerText = seed; - head.append(code); - - document.body.className = ''; - const i = names.pop(); - - const word = words[Math.floor(rng() * words.length)]; - const list = names.map((x, i) => i < +n); - shuffle(list, rng); - - const div = document.createElement('div'); - div.className = 'sensitive'; - - if (list[+i]) { - const span = document.createElement('pre'); - span.className = 'spy'; - span.innerText = 'SPY!'; - div.append("you are a"); - div.append(document.createElement('br')); - div.append(span); - } else { - const span = document.createElement('pre'); - span.innerText = word; - div.append("the word is"); - div.append(document.createElement('br')); - div.append(span); - } - - const cover = document.createElement('div'); - cover.className = 'cover'; - cover.innerText = '(hover here)'; - cover.innerText = `${names[i]}, please hover here to read.`; - div.append(cover); - - const a = document.createElement('a'); - a.innerText = 'next round'; - a.href = `#play,${nextSeed},${n},${names.join(',')},${i}`; - infect(a); - - main.append(div); - main.append(document.createElement('br')); - main.append(a); - } else { - document.body.className = 'setup'; - const seed = genSeed(Math.random); - const names = []; - const a = document.createElement('a'); - a.innerText = 'start'; - a.href = `#link,${seed},${spies.value},${names.join(',')}`; - main.append(a); - infect(a); - - add.onclick = () => { - if (!name.value) - return; - - const li = document.createElement('li'); - li.innerText = name.value; - players.append(li); - names.push(name.value); - a.href = `#link,${seed},${spies.value},${names.join(',')}`; - name.value = ''; - }; - - spies.onchange = () => { - a.href = `#link,${seed},${spies.value},${names.join(',')}`; - } - } -} - -update(window.location.hash); diff --git a/root/games/fake-artist/title: text$plain b/root/games/fake-artist/title: text$plain deleted file mode 100644 index 30c9364..0000000 --- a/root/games/fake-artist/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Fake Artist diff --git a/root/games/gtglg/date: time$iso8601-date b/root/games/gtglg/date: time$iso8601-date deleted file mode 100644 index 3279291..0000000 --- a/root/games/gtglg/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2014-12-23 diff --git a/root/games/gtglg/description: text$plain b/root/games/gtglg/description: text$plain deleted file mode 100644 index bcbb922..0000000 --- a/root/games/gtglg/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a slightly psychedelic physics puzzler with gary, a green-legged giraffe. diff --git a/root/games/gtglg/icon: image$png.png b/root/games/gtglg/icon: image$png.png Binary files differdeleted file mode 100755 index 59c2908..0000000 --- a/root/games/gtglg/icon: image$png.png +++ /dev/null diff --git a/root/games/gtglg/link: URL b/root/games/gtglg/link: URL deleted file mode 100644 index 18e6125..0000000 --- a/root/games/gtglg/link: URL +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/gary-the-green-legged-giraffe diff --git a/root/games/gtglg/title: text$plain b/root/games/gtglg/title: text$plain deleted file mode 100644 index 167d1df..0000000 --- a/root/games/gtglg/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Gary, the green-legged Giraffe diff --git a/root/games/lorem_ipsum/date: time$iso8601-date b/root/games/lorem_ipsum/date: time$iso8601-date deleted file mode 100644 index f83d721..0000000 --- a/root/games/lorem_ipsum/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2016-09-01 diff --git a/root/games/lorem_ipsum/description: text$markdown+span b/root/games/lorem_ipsum/description: text$markdown+span deleted file mode 100644 index 9291ee6..0000000 --- a/root/games/lorem_ipsum/description: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -a labyrinth game concering medialisation and multiple viewpoints. developed with the [ForChange research alliance](http://www.forchange.de/ergebnisse/resilienzspiele/). diff --git a/root/games/lorem_ipsum/icon: image$png.png b/root/games/lorem_ipsum/icon: image$png.png Binary files differdeleted file mode 100755 index 65b2b39..0000000 --- a/root/games/lorem_ipsum/icon: image$png.png +++ /dev/null diff --git a/root/games/lorem_ipsum/jam: text$plain b/root/games/lorem_ipsum/jam: text$plain deleted file mode 100644 index 06967b6..0000000 --- a/root/games/lorem_ipsum/jam: text$plain +++ /dev/null @@ -1 +0,0 @@ -GamesForChange diff --git a/root/games/lorem_ipsum/link: URL b/root/games/lorem_ipsum/link: URL deleted file mode 100644 index f276d7f..0000000 --- a/root/games/lorem_ipsum/link: URL +++ /dev/null @@ -1 +0,0 @@ -https://loremipsum.s-ol.nu/ diff --git a/root/games/lorem_ipsum/title: text$plain b/root/games/lorem_ipsum/title: text$plain deleted file mode 100644 index 9a8d8aa..0000000 --- a/root/games/lorem_ipsum/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Lorem Ipsum diff --git a/root/games/moving_out/date: time$iso8601-date b/root/games/moving_out/date: time$iso8601-date deleted file mode 100644 index 758ee06..0000000 --- a/root/games/moving_out/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2016-12-11 diff --git a/root/games/moving_out/description: text$plain b/root/games/moving_out/description: text$plain deleted file mode 100644 index 3ca32c9..0000000 --- a/root/games/moving_out/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a QWOP-y platformer in which you play a room. diff --git a/root/games/moving_out/icon: image$png.png b/root/games/moving_out/icon: image$png.png Binary files differdeleted file mode 100644 index 85e68a9..0000000 --- a/root/games/moving_out/icon: image$png.png +++ /dev/null diff --git a/root/games/moving_out/jam: text$markdown+span b/root/games/moving_out/jam: text$markdown+span deleted file mode 100644 index 1ba7343..0000000 --- a/root/games/moving_out/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[Ludum Dare 37](http://ludumdare.com/compo/ludum-dare-37/?action=preview&uid=28620) diff --git a/root/games/moving_out/link: URL -> itchio$game b/root/games/moving_out/link: URL -> itchio$game deleted file mode 100644 index 40fe825..0000000 --- a/root/games/moving_out/link: URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/moving-out diff --git a/root/games/moving_out/title: text$plain b/root/games/moving_out/title: text$plain deleted file mode 100644 index 0c19b06..0000000 --- a/root/games/moving_out/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Moving Out diff --git a/root/games/plonat_atek/$order b/root/games/plonat_atek/$order deleted file mode 100644 index f1b9bd1..0000000 --- a/root/games/plonat_atek/$order +++ /dev/null @@ -1,3 +0,0 @@ -itch_page -video -pictures diff --git a/root/games/plonat_atek/date: time$iso8601-date b/root/games/plonat_atek/date: time$iso8601-date deleted file mode 100644 index 8bc80ba..0000000 --- a/root/games/plonat_atek/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2017-04-25 diff --git a/root/games/plonat_atek/description: text$plain b/root/games/plonat_atek/description: text$plain deleted file mode 100644 index 96166f1..0000000 --- a/root/games/plonat_atek/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a sound-only breakout game, displayable on an oscilloscope and realized in the PureData visual programming environment. diff --git a/root/games/plonat_atek/icon: image$png.png b/root/games/plonat_atek/icon: image$png.png Binary files differdeleted file mode 100755 index abbbfc9..0000000 --- a/root/games/plonat_atek/icon: image$png.png +++ /dev/null diff --git a/root/games/plonat_atek/itch_page/URL -> itchio$game b/root/games/plonat_atek/itch_page/URL -> itchio$game deleted file mode 100644 index c2707e1..0000000 --- a/root/games/plonat_atek/itch_page/URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/plonat-atek diff --git a/root/games/plonat_atek/jam: text$markdown+span b/root/games/plonat_atek/jam: text$markdown+span deleted file mode 100644 index 38f540e..0000000 --- a/root/games/plonat_atek/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[Ludum Dare 38](https://ldjam.com/events/ludum-dare/38/plonat-atek) diff --git a/root/games/plonat_atek/pictures/$order b/root/games/plonat_atek/pictures/$order deleted file mode 100644 index 934d2fd..0000000 --- a/root/games/plonat_atek/pictures/$order +++ /dev/null @@ -1,3 +0,0 @@ -setup -amaze -mockup diff --git a/root/games/plonat_atek/pictures/amaze/attribution: text$markdown+span b/root/games/plonat_atek/pictures/amaze/attribution: text$markdown+span deleted file mode 100644 index 7a5a6fb..0000000 --- a/root/games/plonat_atek/pictures/amaze/attribution: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -photo by [Rick Hoppmann](https://twitter.com/tinyruin) diff --git a/root/games/plonat_atek/pictures/amaze/image$jpeg.jpg b/root/games/plonat_atek/pictures/amaze/image$jpeg.jpg Binary files differdeleted file mode 100644 index 70025b8..0000000 --- a/root/games/plonat_atek/pictures/amaze/image$jpeg.jpg +++ /dev/null diff --git a/root/games/plonat_atek/pictures/mockup/image$jpeg.jpg b/root/games/plonat_atek/pictures/mockup/image$jpeg.jpg Binary files differdeleted file mode 100644 index 1cfa03a..0000000 --- a/root/games/plonat_atek/pictures/mockup/image$jpeg.jpg +++ /dev/null diff --git a/root/games/plonat_atek/pictures/setup/image$jpeg.jpg b/root/games/plonat_atek/pictures/setup/image$jpeg.jpg Binary files differdeleted file mode 100644 index feec066..0000000 --- a/root/games/plonat_atek/pictures/setup/image$jpeg.jpg +++ /dev/null diff --git a/root/games/plonat_atek/pictures/text$moonscript -> fn -> mmm$dom.moon b/root/games/plonat_atek/pictures/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 4938596..0000000 --- a/root/games/plonat_atek/pictures/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,18 +0,0 @@ -import div from require 'mmm.dom' -import embed from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - images = for child in *@children - embed child, nil, nil, attr: { - style: { - height: '15em' - margin: '0 .5em' - flex: '1 0 auto' - } - } - - div with images - .style = { - display: 'flex' - overflow: 'auto hidden' - } diff --git a/root/games/plonat_atek/text$markdown.md b/root/games/plonat_atek/text$markdown.md deleted file mode 100644 index fe6879f..0000000 --- a/root/games/plonat_atek/text$markdown.md +++ /dev/null @@ -1,57 +0,0 @@ -# <mmm-embed nolink facet="title"></mmm-embed> - -<mmm-embed nolink path="pictures"></mmm-embed> - -*Plonat Atek* is a digital game that communicates itself to the player only via the stereo headphone jack. -The signal is split, and one of the streams is fed into a pair of headphones that show the game to the player as a melody, -interlaced with a series of blips and bursts of noise. -The other stream leads into an oscilloscope, that visualises the two channels by moving a dot across the screen in correspondence to the signal. -On the screen, the game manifests as a ball bouncing around in a circular version of *Breakout*. - -Both the oscilloscope and the speakers are analog devices that interpret the signal and generate a representation of the game. -The representations are based on interrelated properties of the same signal. -Thus, the relationship between the audio and visual components is not merely designed, rather the two emerge from identical information: -In *Plonat Atek*, the sound is designed to be seen and the visuals are designed to be heard. -For example the blip heard when the ball bounces is the distortion seen in the same moment, -and the noise heard when the ball is lost is visible as a glitch on the oscilloscope. - -<mmm-embed nolink path="video"></mmm-embed> - -## Awards and Exhibitions -*Plonat Atek* was awarded first place in the *Innovation* category, 8th in *Audio* and 24th overall at the *Ludum Dare 38 Compo* in 2017. -The project has been exhibited at *A MAZE. Berlin 2018* and *Maker Faire Rome 2019*. - -## History -*Plonat Atek* was originally developed in 48 hours for the *Ludum Dare 38 Compo* in June 2017. -You can find the original submission [here][ld] and documentation on how to download and run the jam version on the [itch.io page][itch]. - -Articles on the game accompanied by the video recording above have been published by [Hackaday][hackaday], [VICE Motherboard][motherboard] and others. - -The jam version is designed to run on an end-user Computer and is played using the keyboard. -In early 2018 I decided to build a self-contained hardware version that is played using a rotary knob. -This is the version pictured above. - -## Artist Statement -*Plonat Atek* is an exploration into the unification of audiovisual signals in the context of feedback in interactive systems. -Both digital and analog audio signals are very thin encodings, -as they map directly to the vibrations on our tympana and thereby the sensations they represent. -In contrast, raster video signals or image encodings are a very contrived, optimized and complicated; -the discrete and serial pixel-per-pixel description of shapes does not come close at all to the way our human perception works. -This is also obvious as the technology required to decode a video signal or image into something a human can perceive is extremely complex. -In *Plonat Atek*, the visual output on the oscilloscope is as directly based on the waveforms encoding it as the audio is. -The thinner encoding allows the simultaneous use of the exact same signal for both the audio output on the speakers and -the visual output on the oscilloscope, thereby intrinsically connecting the two. - -At the same time Plonat Atek is a media archaeological project and hommage. -The earliest video games, such as *Tennis for Two* and *Spacewar!*, as well as later arcade games like *Asteroids*, -and even consoles like the *Vectrex* share the CRT screen whose warm glow transports a unique feeling of messy analogue-ness -coupled with a homely sense of healthy imperfection. -The game itself is a reinterpretation of the classic *Breakout*, a game many players may recognize nostalgically and -that has already gone through transformations from hardware to software, and from an arcade to a pc and finally a mobile game -or something found on a children’s toy that comes free with an order at a fast-food restaurant. - -[ld]: https://ldjam.com/events/ludum-dare/38/plonat-atek -[itch]: https://s-ol.itch.io/plonat-atek - -[hackaday]: https://hackaday.com/2017/11/05/programming-an-oscilloscope-breakout-game-in-pure-data/ -[motherboard]: https://motherboard.vice.com/en_us/article/59yw9z/watch-this-awesome-oscilloscope-breakout-game diff --git a/root/games/plonat_atek/title: text$plain b/root/games/plonat_atek/title: text$plain deleted file mode 100644 index ee49dec..0000000 --- a/root/games/plonat_atek/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Plonat Atek diff --git a/root/games/plonat_atek/video/URL -> youtube$video b/root/games/plonat_atek/video/URL -> youtube$video deleted file mode 100644 index bf07555..0000000 --- a/root/games/plonat_atek/video/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=SIQAk9_nc-s diff --git a/root/games/text$moonscript -> fn -> mmm$dom.moon b/root/games/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 55e93a6..0000000 --- a/root/games/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,45 +0,0 @@ -import div, span, h3, ul, li, a, h4, img, p from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' -import ropairs from require 'mmm.ordered' - -=> - div { - h3 link_to @ - ul do - games = { (p\gett 'date: time/unix'), p for p in *@children } - - children = for k, child in ropairs games - desc = child\gett 'description: mmm/dom' - jam = if link = child\get 'jam: mmm/dom' - span '[', link, ']', style: float: 'right', clear: 'right', color: 'var(--gray-dark)' - - li (link_to child), ': ', desc, jam - - children --- ul with for child in *@children --- link_if_content = (opts) -> --- a with opts --- if true or child\find 'mmm/dom' --- .style = { 'text-decoration': 'none' } --- .href = child.path --- .onclick --- --- li link_if_content { --- h4 { --- style: { 'margin-bottom': 0 } --- (child\get 'title: mmm/dom') or child\gett 'name: alpha' --- } --- div { --- -- style: { --- -- display: 'flex' --- -- 'justify-content': 'space-around' --- -- } --- -- img src: child\gett 'icon: URL -> image/.*' --- p (child\gett 'description: mmm/dom'), style: { 'flex': '1 0 0', margin: '1em' } --- } --- } --- --- .style = { --- 'list-style': 'none' --- } - } diff --git a/root/games/the_monster_within/date: time$iso8601-date b/root/games/the_monster_within/date: time$iso8601-date deleted file mode 100644 index 9e7bf47..0000000 --- a/root/games/the_monster_within/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2015-08-25 diff --git a/root/games/the_monster_within/description: text$plain b/root/games/the_monster_within/description: text$plain deleted file mode 100644 index e0f0605..0000000 --- a/root/games/the_monster_within/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a top down action brawler with a twist. diff --git a/root/games/the_monster_within/icon: image$png.png b/root/games/the_monster_within/icon: image$png.png Binary files differdeleted file mode 100755 index 484bf4c..0000000 --- a/root/games/the_monster_within/icon: image$png.png +++ /dev/null diff --git a/root/games/the_monster_within/jam: text$markdown+span b/root/games/the_monster_within/jam: text$markdown+span deleted file mode 100644 index 61b7b19..0000000 --- a/root/games/the_monster_within/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[Ludum Dare 33](http://ludumdare.com/compo/ludum-dare-33/?action=preview&uid=28620) diff --git a/root/games/the_monster_within/link: URL -> itchio$game b/root/games/the_monster_within/link: URL -> itchio$game deleted file mode 100644 index fd5ff72..0000000 --- a/root/games/the_monster_within/link: URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/the-monster-within diff --git a/root/games/the_monster_within/title: text$plain b/root/games/the_monster_within/title: text$plain deleted file mode 100644 index f44820c..0000000 --- a/root/games/the_monster_within/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -The Monster Within diff --git a/root/games/the_sacculi/date: time$iso8601-date b/root/games/the_sacculi/date: time$iso8601-date deleted file mode 100644 index 3e81523..0000000 --- a/root/games/the_sacculi/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2018-08-14 diff --git a/root/games/the_sacculi/description: text$markdown+span b/root/games/the_sacculi/description: text$markdown+span deleted file mode 100644 index 7355980..0000000 --- a/root/games/the_sacculi/description: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -a series of Point-and-Click minigames with a common structure. diff --git a/root/games/the_sacculi/jam: text$markdown+span b/root/games/the_sacculi/jam: text$markdown+span deleted file mode 100644 index 10b43bd..0000000 --- a/root/games/the_sacculi/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[Ludum Dare 42](https://ldjam.com/events/ludum-dare/42/sacculos-the-game) diff --git a/root/games/the_sacculi/link: URL -> itchio$collection b/root/games/the_sacculi/link: URL -> itchio$collection deleted file mode 100644 index 441246b..0000000 --- a/root/games/the_sacculi/link: URL -> itchio$collection +++ /dev/null @@ -1 +0,0 @@ -https://itch.io/c/367008/the-sacculi diff --git a/root/games/the_sacculi/title: text$plain b/root/games/the_sacculi/title: text$plain deleted file mode 100644 index d401052..0000000 --- a/root/games/the_sacculi/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -The Sacculos Saga diff --git a/root/games/title: text$plain b/root/games/title: text$plain deleted file mode 100644 index 84d4140..0000000 --- a/root/games/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -games diff --git a/root/games/two_shooting_stars/date: time$iso8601-date b/root/games/two_shooting_stars/date: time$iso8601-date deleted file mode 100644 index 1da7b90..0000000 --- a/root/games/two_shooting_stars/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2016-06-01 diff --git a/root/games/two_shooting_stars/description: text$plain b/root/games/two_shooting_stars/description: text$plain deleted file mode 100644 index 375c5d9..0000000 --- a/root/games/two_shooting_stars/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a narrative point-and-click adventure. diff --git a/root/games/two_shooting_stars/icon: image$png.png b/root/games/two_shooting_stars/icon: image$png.png Binary files differdeleted file mode 100755 index c531bd3..0000000 --- a/root/games/two_shooting_stars/icon: image$png.png +++ /dev/null diff --git a/root/games/two_shooting_stars/jam: text$markdown+span b/root/games/two_shooting_stars/jam: text$markdown+span deleted file mode 100644 index a95a990..0000000 --- a/root/games/two_shooting_stars/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -semester project diff --git a/root/games/two_shooting_stars/link: URL b/root/games/two_shooting_stars/link: URL deleted file mode 100644 index 7efac98..0000000 --- a/root/games/two_shooting_stars/link: URL +++ /dev/null @@ -1 +0,0 @@ -http://www.colognegamelab.de/studentprojects/i-looked-at-the-sky-and-saw-two-shooting-stars-but-couldnt-come-up-with-a-wish-2016/ diff --git a/root/games/two_shooting_stars/title: text$plain b/root/games/two_shooting_stars/title: text$plain deleted file mode 100644 index 7464871..0000000 --- a/root/games/two_shooting_stars/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -I looked at the sky and saw two shooting stars but couldn't come up with a wish diff --git a/root/games/vision-training-kit/date: time$iso8601-date b/root/games/vision-training-kit/date: time$iso8601-date deleted file mode 100644 index 9fd465a..0000000 --- a/root/games/vision-training-kit/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2016-08-05 diff --git a/root/games/vision-training-kit/description: text$plain b/root/games/vision-training-kit/description: text$plain deleted file mode 100644 index 0511e77..0000000 --- a/root/games/vision-training-kit/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a puzzle game based on a famicase cartridge design. diff --git a/root/games/vision-training-kit/icon: image$png.png b/root/games/vision-training-kit/icon: image$png.png Binary files differdeleted file mode 100755 index ef73861..0000000 --- a/root/games/vision-training-kit/icon: image$png.png +++ /dev/null diff --git a/root/games/vision-training-kit/jam: text$markdown+span b/root/games/vision-training-kit/jam: text$markdown+span deleted file mode 100644 index 326870e..0000000 --- a/root/games/vision-training-kit/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[AGBIC 2016](https://itch.io/jam/a-game-by-its-cover-2016) diff --git a/root/games/vision-training-kit/link: URL -> itchio$game b/root/games/vision-training-kit/link: URL -> itchio$game deleted file mode 100644 index 72edd8a..0000000 --- a/root/games/vision-training-kit/link: URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/vision-training-kit diff --git a/root/games/vision-training-kit/title: text$plain b/root/games/vision-training-kit/title: text$plain deleted file mode 100644 index d131a1c..0000000 --- a/root/games/vision-training-kit/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -視能訓練キット | vision-training-kit diff --git a/root/games/zebra_painting/date: time$iso8601-date b/root/games/zebra_painting/date: time$iso8601-date deleted file mode 100644 index fdf764e..0000000 --- a/root/games/zebra_painting/date: time$iso8601-date +++ /dev/null @@ -1 +0,0 @@ -2018-09-13 diff --git a/root/games/zebra_painting/description: text$plain b/root/games/zebra_painting/description: text$plain deleted file mode 100644 index 3225e87..0000000 --- a/root/games/zebra_painting/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a small reaction/dexteriy game about painting zebras. diff --git a/root/games/zebra_painting/jam: text$markdown+span b/root/games/zebra_painting/jam: text$markdown+span deleted file mode 100644 index a47c5e4..0000000 --- a/root/games/zebra_painting/jam: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -[AGBIC 2018](https://itch.io/jam/a-game-by-its-cover-2018) diff --git a/root/games/zebra_painting/link: URL -> itchio$game b/root/games/zebra_painting/link: URL -> itchio$game deleted file mode 100644 index 7b14c43..0000000 --- a/root/games/zebra_painting/link: URL -> itchio$game +++ /dev/null @@ -1 +0,0 @@ -https://s-ol.itch.io/zebra-painting diff --git a/root/games/zebra_painting/title: text$plain b/root/games/zebra_painting/title: text$plain deleted file mode 100644 index aae11b5..0000000 --- a/root/games/zebra_painting/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Zebra Painting diff --git a/root/meta/text$moonscript -> fn -> mmm$dom.moon b/root/meta/text$moonscript -> fn -> mmm$dom.moon index d3e27e1..5430212 100644 --- a/root/meta/text$moonscript -> fn -> mmm$dom.moon +++ b/root/meta/text$moonscript -> fn -> mmm$dom.moon @@ -4,8 +4,8 @@ import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' => div { style: { 'max-width': '700px' } h3 link_to @ - p "mmm is a collection of Lua/Moonscript modules for web development. - All modules are 'polymorphic' - they can run in the ", (i 'browser'), + p "mmm.dom and mmm.component are Lua/Moonscript modules for web development. + Both modules are 'polymorphic' - they can run in the ", (i 'browser'), ", using the native browser API for creating and interacting with DOM content, as well as on the ", (i 'server'), ", where they operate on and produce equivalent HTML strings." p "As the two implementations of each module are designed to be compatible, diff --git a/root/portfolio/1u-mod/media: image$jpeg.jpg b/root/portfolio/1u-mod/media: image$jpeg.jpg Binary files differdeleted file mode 100644 index 2d6f26f..0000000 --- a/root/portfolio/1u-mod/media: image$jpeg.jpg +++ /dev/null diff --git a/root/portfolio/VJmidiKit/media: video$mp4.mp4 b/root/portfolio/VJmidiKit/media: video$mp4.mp4 Binary files differdeleted file mode 100644 index 92d0645..0000000 --- a/root/portfolio/VJmidiKit/media: video$mp4.mp4 +++ /dev/null diff --git a/root/portfolio/_web_view: type b/root/portfolio/_web_view: type deleted file mode 100644 index bde5644..0000000 --- a/root/portfolio/_web_view: type +++ /dev/null @@ -1 +0,0 @@ -text/html+interactive diff --git a/root/portfolio/alv/media: video$mp4.mp4 b/root/portfolio/alv/media: video$mp4.mp4 Binary files differdeleted file mode 100644 index a0248c0..0000000 --- a/root/portfolio/alv/media: video$mp4.mp4 +++ /dev/null diff --git a/root/portfolio/harold-halibut/media: image$png.png b/root/portfolio/harold-halibut/media: image$png.png Binary files differdeleted file mode 100644 index d6dba98..0000000 --- a/root/portfolio/harold-halibut/media: image$png.png +++ /dev/null diff --git a/root/portfolio/hex-pad/media: image$jpeg.jpg b/root/portfolio/hex-pad/media: image$jpeg.jpg Binary files differdeleted file mode 100644 index 36324e0..0000000 --- a/root/portfolio/hex-pad/media: image$jpeg.jpg +++ /dev/null diff --git a/root/portfolio/hidden: text$lua -> bool b/root/portfolio/hidden: text$lua -> bool deleted file mode 100644 index b30e187..0000000 --- a/root/portfolio/hidden: text$lua -> bool +++ /dev/null @@ -1 +0,0 @@ -return true diff --git a/root/portfolio/lame: text$markdown.md b/root/portfolio/lame: text$markdown.md deleted file mode 100644 index c6c1f4c..0000000 --- a/root/portfolio/lame: text$markdown.md +++ /dev/null @@ -1,85 +0,0 @@ -skillset --------- -<p style="max-width: 800px;"> - Here you can find a selection of technologies, languages and skills I have acquired and used in the past, - together with select projects demonstrating these abilities. - Projects marked in <em>italic</em> represent employment / professional consulting (see below for details). -</p> - -- programming - - C++ - - openFrameworks: [VJmidiKit][VJmidiKit] - - JS - - nodejs & react: [*rise*][rise], [iii telefoni][tre_telefoni], [IYNX][iynx] - - Lua & Moonscript: [this website](/meta), [vision-training-kit][vtk], [gayngine][gayngine] - - Python: [themer][themer] - - GLSL & HLSL: [*Vectronom*][vectronom], [*Harold Halibut*][hh], [VJmidiKit][VJmidiKit] (raymarching content) - - C# & Unity: [*Vectronom*][vectronom], [*Harold Halibut*][hh] - - Clojure: [*Vectronom*][vectronom] (UGC backend) -- electronics - - PCB Design: [btrktrl][btrktrl] - - embedded programming - - micro controllers: [IYNX][iynx], [*Vectronom*][vectronom] (fair booth) - - FPGAs: [btrktrl][btrktrl] -- general technologies - - avid linux user - - docker & docker-compose: [*rise*][rise] - - mongodb: [*rise*][rise] -- visual & motion design: [demoloops][demoloops], [VJmidiKit][VJmidiKit] - -professinal work ------------------- -### slow bros - Harold Halibut -<p style="max-width: 800px;"> - I am working with Slow Bros on their upcoming game <a href="http://haroldhalibut.com/">Harold Halibut</a> - For Harold Halibut I do Gameplay- and Tools Programming, as well as Shaders and Porting. -</p> - -### ludopium - Vectronom -I have worked on [Vectronom](https://vectronom.arte.fr), -where I implemented and worked on many systems in and around the game: - -- gamplay programming -- UI programming -- palette system using HLSL shaders -- clojure-based REST API for storing and sharing UGC - - integration with backend services by Steam and Nintendo -- development of tech for the fair booth - - realtime speedrunning leaderboard - - custom driver for LED lettering -- porting (Nintendo Switch, Android, iOS) - -### rise technologies -<p style="max-width: 800px;"> - I worked as a full-stack developer with rise technologies on their remote support solution for three years. - In this time I designed, created and worked on multiple systems and layers of the product: -</p> - -- front-end development (react, material-ui) -- back-end development - - main application (meteorjs, node, monogdb) - - microservice architecture (nodejs, rabbit MQ) - - notification handling & delivery (APN, FCM) -- mobile development & debuggin (cordova for Android, iOS) -- webRTC conferencing - - using janus-gateway - - contributed C patches reinforcing the communication security for our needs - - implemented client-side logic - - implemented gateway orchestration -- dev-ops - - designed a custom CI system - - designed deployment infrastructure on MS Azure (docker, docker-compose) - - supervised migration from MS Azure to Amazon AWS - -[themer]: https://github.com/s-ol/themer -[vtk]: https://s-ol.itch.io/vision-training-kit -[iynx]: /games/IYNX -[btrktrl]: /projects/btrktrl -[VJmidiKit]: /projects/VJmidiKit -[demoloops]: /projects/demoloops -[tre_telefoni]: /projects/iii-telefoni -[gayngine]: /blog/love_lua_photoshop_and_games - -[vectronom]: #ludopium-vectronom -[hh]: #slow-bros-harold-halibut -[rise]: #rise-technologies diff --git a/root/portfolio/lorem_ipsum/media: image$jpeg.jpg b/root/portfolio/lorem_ipsum/media: image$jpeg.jpg Binary files differdeleted file mode 100644 index f52b200..0000000 --- a/root/portfolio/lorem_ipsum/media: image$jpeg.jpg +++ /dev/null diff --git a/root/portfolio/lorem_ipsum/media: image$png.png b/root/portfolio/lorem_ipsum/media: image$png.png Binary files differdeleted file mode 100644 index 994884a..0000000 --- a/root/portfolio/lorem_ipsum/media: image$png.png +++ /dev/null diff --git a/root/portfolio/mmm/media: image$png.png b/root/portfolio/mmm/media: image$png.png Binary files differdeleted file mode 100644 index 34a562e..0000000 --- a/root/portfolio/mmm/media: image$png.png +++ /dev/null diff --git a/root/portfolio/playreactive/media: image$png.png b/root/portfolio/playreactive/media: image$png.png Binary files differdeleted file mode 100644 index 6bb41b3..0000000 --- a/root/portfolio/playreactive/media: image$png.png +++ /dev/null diff --git a/root/portfolio/rise/media: image$png.png b/root/portfolio/rise/media: image$png.png Binary files differdeleted file mode 100644 index b33cc13..0000000 --- a/root/portfolio/rise/media: image$png.png +++ /dev/null diff --git a/root/portfolio/spline/media: image$png.png b/root/portfolio/spline/media: image$png.png Binary files differdeleted file mode 100644 index d4f3125..0000000 --- a/root/portfolio/spline/media: image$png.png +++ /dev/null diff --git a/root/portfolio/text$moonscript -> mmm$dom.moon b/root/portfolio/text$moonscript -> mmm$dom.moon deleted file mode 100644 index 563fb2a..0000000 --- a/root/portfolio/text$moonscript -> mmm$dom.moon +++ /dev/null @@ -1,439 +0,0 @@ -import ReactiveVar, tohtml, text, elements from require 'mmm.component' -import article, a, b, span, video, img, h1, div, p, ul, li, br from elements -import embed, link_to from (require 'mmm.mmmfs.util') elements - -embed_img = (src) -> (style) -> img :src, :style -embed_vid = (src) -> (style) -> video autoplay: true, loop: true, muted: true, :src, :style - -import artistic, game, js, lua, shader, hardware, tool, collab, professional, cs, cpp from setmetatable {}, __index: (t, k) -> k - -padded_ul = (tbl) -> - ul with tbl - .style = padding: '0 2rem 0.5rem' - -projects = { - { - name: 'Spline' - desc: 'Full-Stack Development, Web & App' - extra: 'September 2020 - ongoing' - content: padded_ul { - li { - text 'graphics programming' - ul { - li text 'mesh generation' - li text 'parametric primitives' - li text 'geometry datastructures' - } - } - li text 'front-end development' - li text 'migration to TS and module system' - } - href: 'https://spline.design' - media: (style) -> - icon = (embed_img '/portfolio/spline/media:image/png') { - 'object-fit': 'contain' - 'width': '100%' - 'height': '100%' - } - style.position = 'relative' - style.padding = '2em' - style.background = '#232323' - style.overflow = 'hidden' - div icon, :style - tags: :professional, :js, :tool, :shader - } - { - name: 'Vectronom / Ludopium' - desc: 'Technical Artist, Game Development' - extra: 'July 2018 - December 2019' - content: padded_ul { - li text 'Unity/C# development (gameplay, UI, tools)' - li { - text 'backend for storing and sharing UGC across platforms' - ul { - li text 'SQL-backed storage of user-created levels' - li text 'implemented in clojure with clojure-ring' - li text 'integration with Steam and Nintendo services' - } - } - li { - text 'development of tech for showcase booths' - ul { - li text 'realtime speedrunning leaderboard (node, react)' - li text 'custom RGB LED driver and lettering' - } - } - li text 'porting to Nintendo Switch, Android, iOS, tvOS' - li text 'HLSL shader palette system' - } - href: 'https://vectronom.arte.tv' - media: embed_vid '/portfolio/vectronom/media:video/webm' - tags: :cs, :professional, :js, :shader, :game - } - { - name: 'Harold Halibut / Slow Bros' - desc: 'Tool & Game Development' - extra: 'April 2019 - December 2020' - content: padded_ul { - li { - text 'Unity/C# development' - ul { - li text 'developed multiple mini-games and interactions' - } - } - li text 'tool development' - li text 'shader programming' - li text 'porting (various consoles)' - } - href: 'http://haroldhalibut.com/' - media: embed_img '/portfolio/harold-halibut/media:image/png' - tags: :cs, :professional, :game - } - { - name: 'Earthrise One / Playreactive' - desc: 'Electronics Design, Escape Room Gadgets' - extra: 'September - December 2018 (consulting)' - content: padded_ul { - li text 'developed and implemented circuits for various portable and fixed devices in an escape room' - li { - text 'interfaced MCUs with various I/O devices' - ul { - li text 'controllable LED lighting' - li text 'maglocks' - li text 'piezo buzzers' - } - } - } - href: 'https://www.playreactive.com/earthrise-one' - media: embed_img '/portfolio/playreactive/media:image/png' - tags: :hardware, :professional, :game - } - { - name: 'rise technologies' - desc: 'Full-Stack Development, Web & App' - extra: 'April 2016 - April 2019' - content: padded_ul { - li text 'front-end development (react, material-ui)' - li { - text 'back-end development', - ul { - li text 'main application (meteor.js, node, MongoDB)' - li text 'microservice architecture (node, RabbitMQ)' - li text 'notification handling & delivery (APN, FCM)' - } - } - li text 'mobile development' - li { - text 'webRTC conferencing (janus-gateway)' - ul { - li text 'contributed C patches reinforcing the communication security for our needs' - li text 'implemented client-side logic' - li text 'implemented gateway orchestration' - } - } - li { - text 'dev-ops' - ul { - li text 'designed and implemented a custom CI system' - li text 'designed deployment infrastructure on MS Azure (docker, docker-compose)' - li text 'supervised migration from MS Azure to Amazon AWS' - } - } - } - href: 'https://rise.tech' - media: embed_img '/portfolio/rise/media:image/png' - tags: :professional, :js, :tool - } - { - name: 'ForChange Reserach Fund' - desc: 'Game Design and Development' - extra: 'March - June 2017 (consulting)' - content: padded_ul { - li { - text "designed 'Lorem Ipsum' together with two research scientists" - ul { - li text 'design goal was to communicate their research findings' - li text 'created a paper prototype' - li text 'designed a 4-player social game about truth and perspectives' - } - } - li { - text 'developed the game as a web application' - ul { - li text 'front-end using react' - li text 'back-end hosts game sessions via WebSockets' - li text 'joining games via link or QR-code scanning (in-app)' - li text 'gameplay implemented in immutable/functional-style' - } - } - } - href: 'https://loremipsum.s-ol.nu/' - media: embed_img '/portfolio/lorem_ipsum/media:image/jpeg' - tags: :professional, :js, :collab, :game - } - - - { - name: '0xC.pad' - desc: 'a hexagonal macropad' - entries: { - 'custom designed and machined keycaps' - 'per-key RGB backlighting' - 'low-profile mechanical keyswitches' - 'machined aluminum case' - 'ESD-protected USB-C port' - 'ATMega32U2 MCU with QMK firmware support' - } - href: 'https://docs.google.com/forms/d/e/1FAIpQLSccvUj4WobsxLP0yTdObMYbdXgTbWaAEnlu7WoOhmo262PaQA/viewform' - media: embed_img '/portfolio/hex-pad/media:image/jpeg' - tags: :hardware, :tool - } - { - name: 'alv' - desc: 'an innovative realtime programming language' - entries: { - 'Lisp syntax, dataflow semantics' - 'designed to be edited while running' - 'whole program is reloaded on evaluation, but state is guaranteed to be retained' - 'Atom plugin for realtime state visualisation' - 'integrates with soft- & hardware for performances (MIDI, OSC, SuperCollider)' - } - href: 'https://alv.s-ol.nu/master/' - media: embed_vid '/portfolio/alv/media:video/mp4' - tags: :tool, :lua, :javascript - } - { - name: 'btrktrl' - desc: 'a custom MIDI/OSC control surface' - entries: { - 'encoders with capacitive touch and RGB feedback' - 'custom PCBs based on iCE40 FPGAs' - 'motherboard with Arduino MCU' - 'communication via OSC/USB' - 'individually programmable daughterboards' - } - href: '/projects/btrktrl/' - media: embed_img '/projects/btrktrl/pcb_glamour_top/:image/jpeg' - tags: :hardware, :tool, :cpp - } - { - name: 'VJmidiKit' - desc: 'a tool for MIDI-reactive visuals' - entries: { - 'GLSL shader livecoding' - 'block-based language for MIDI-music reactivity' - 'implemented in openFrameworks/C++' - } - href: '/projects/VJmidiKit/' - media: embed_vid '/portfolio/VJmidiKit/media:video/mp4' - tags: :tool, :cpp, :shader - } --- { --- name: 'IYNX' --- desc: 'a narrative, tangible, physical puzzle incorporating digital elements' --- entries: { --- 'powered by a raspberry pi 3 and two arduino nanos' --- 'touch-panel UI and control software with node, electron and react' --- 'interfaces with analog potentiometers, keypad matrix, switches' --- } --- href: '/games/IYNX/' --- media: embed_img '/games/IYNX/pictures/ui_menu/:image/jpeg' --- tags: :collab, :game, :js, :hardware --- } - { - name: 'Plonat Atek' - desc: 'a sound-only breakout game, displayable on an oscilloscope' - entries: { - 'uses stereo sound to draw visuals on an oscilloscope' - 'programmed in PureData' - 'runs on a Raspberry Pi Zero in a custom case with hardware controls' - "1st place in Innovation, LudumDare 38 Compo" - } - href: '/games/plonat_atek/' - media: embed_img '/games/plonat_atek/pictures/amaze/:image/jpeg' - tags: :artistic, :game, :hardware - } - { - name: 'tre telefoni' - desc: 'an experimental interactive installation piece about communication' - content: padded_ul { - li text 'realtime voice chat between three participants, in an unusual configuration' - li { - text 'web-based prototype' - ul { - li text 'realized using webRTC, react' - li text '3-player matchmaking' - } - } - } - href: '/projects/iii-telefoni/' - media: embed_img '/projects/iii-telefoni/heads/:image/jpeg' - tags: :artistic, :game, :js - } --- { --- name: '1u matrix mixer' --- desc: 'a eurorack module' --- entries: { --- "embedded programming for a Eurorack module" --- "C++, targetting Teensy 3.5" --- "8 encoders with RGB lighting" --- "digtally controls a 8x8 switching matrix and 8 channels of volume modulation" --- } --- media: embed_img '/portfolio/1u-mod/media:image/jpeg' --- tags: :collab, :hardware, :cpp --- } - { - name: 'mmm' - desc: 'an experimental file-system/CMS/digital working space' - content: padded_ul { - style: padding: '0 2em 1em' - li text 'powers this website' - li text 'implemented in Lua/MoonScript' - li text 'innovative type-coercion system' - li text 'client/server polymorphic UI framework' - li text 'built-in server-side rendering and interactive editing support' - } - href: '/research/mmmfs/' - media: embed_img '/portfolio/mmm/media:image/png' - tags: :tool, :lua - } - { - name: 'Toy Box Orchestra' - desc: 'an interactive audio-visual performance project' - entries: { - "circuit bent childrens' toys" - "developed a realtime video effect inspired by analog video synthesisers in openframeworks and GLSL" - "interactive MIDI controls for the effect for performing it on stage" - } - href: 'https://chimpanzeebukkaque.bandcamp.com/releases' - media: embed_img '/portfolio/visualist/media:image/jpeg' - tags: :collab, :artistic, :cpp, :hardware, :shader - } - } - -project_row = (tag, exclude) -> - with ul style: display: 'flex', 'flex-wrap': 'wrap', 'align-items': 'top' - for pp in *projects - continue if tag and not pp.tags[tag] - continue if not tag and exclude and pp.tags[exclude] - - \append li { - style: - 'border-radius': '6px' - display: 'flex' - 'flex-direction': 'column' - width: '22rem' - margin: '0.5em' - 'padding-bottom': '0.5em' - background: 'var(--gray-bright)' - overflow: 'hidden' - 'font-size': '0.9em' - - a { - style: - display: 'block' - position: 'relative' - color: 'var(--gray-bright)' - background: 'var(--gray-dark)' - filter: 'none' - - href: pp.href - - pp.media { - width: '100%' - height: '13rem' - background: 'var(--gray-bright)' - 'box-sizing': 'border-box' - 'object-fit': 'cover' - } - - h1 pp.name, style: - padding: '0.2rem 1rem' - } - - if pp.extra - div pp.extra, style: - background: 'var(--gray-darker)' - color: 'var(--gray-bright)' - padding: '0.2em 1rem' - - p (text pp.desc), style: 'padding': '0 1rem' - text ' ' - pp.content or padded_ul for line in *pp.entries - li text line - } - -tohtml with article! - filter = ReactiveVar! - - taglink = (label, tag=label) -> - a label, { - href: '#' - onclick: (e) => - e\preventDefault! - filter\transform (old) -> if old == tag then nil else tag - } - - \append p "I have worked with a wide range of technologies and frameworks. ", - "Below you can find a breakdown of the ones I am proficient in.", br!, - "You can click on any of the tags marked in bold to filter the projects below accordingly." - - \append ul { - li { - "spoken languages" - ul { - li "excellent english" - li "native german" - li "good italian" - } - } - li { - "software programming" - ul { - li (taglink "JavaScript", js), ": react, nodejs, electron, meteor" - li (taglink "C and C++", cpp), ": openFrameworks, intermediate openGL" - li (taglink "GLSL and HLSL", shader), ": animated shaders, raymarching, SDFs" - li taglink "C# and Unity", cs - li taglink "Lua/MoonScript", lua - li "Python" - } - } - li { - (taglink hardware), " and embedded programming" - ul { - li "PCB Design" - li text "embedded programming (C++) and interfacing" - li "FPGA development (Verilog)" - } - } - li { - "other" - ul { - li "Linux" - li "docker, docker-compose" - li "HTML, CSS" - } - } - } - - \append with h1 "selected projects", style: 'margin-top': '1em' - \append filter\map (tag) -> - return unless tag - span { - style: - 'font-size': '0.7em' - 'font-weight': 'normal' - 'margin-left': '2em' - - "showing only " - b text tag - " projects - " - a "reset filter", href: '#', style: { 'font-weight': 'bold' }, onclick: (e) => - e\preventDefault! - filter\set! - } - \append filter\map => project_row @, professional - - \append h1 "professional work", style: 'margin-top': '1em' - \append p "I have worked for or with the following companies and organisations in the past:" - \append project_row professional diff --git a/root/portfolio/vectronom/media: video$webm.webm b/root/portfolio/vectronom/media: video$webm.webm Binary files differdeleted file mode 100644 index 46b6596..0000000 --- a/root/portfolio/vectronom/media: video$webm.webm +++ /dev/null diff --git a/root/portfolio/visualist/media: image$jpeg.jpg b/root/portfolio/visualist/media: image$jpeg.jpg Binary files differdeleted file mode 100644 index 17dc06d..0000000 --- a/root/portfolio/visualist/media: image$jpeg.jpg +++ /dev/null diff --git a/root/projects/$order b/root/projects/$order deleted file mode 100644 index 5153662..0000000 --- a/root/projects/$order +++ /dev/null @@ -1,9 +0,0 @@ -themer -btrktrl -chimpanzee_bukkaque -HowDoIOS -VJmidiKit -iii-telefoni -demoloops -gayngine -vcv_mods diff --git a/root/projects/HowDoIOS/description: text$plain b/root/projects/HowDoIOS/description: text$plain deleted file mode 100644 index b2b050a..0000000 --- a/root/projects/HowDoIOS/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -dcpu-16 operating system. diff --git a/root/projects/HowDoIOS/link: URL -> git b/root/projects/HowDoIOS/link: URL -> git deleted file mode 100644 index 046a09e..0000000 --- a/root/projects/HowDoIOS/link: URL -> git +++ /dev/null @@ -1 +0,0 @@ -https://github.com/s-ol/HowDoIOS diff --git a/root/projects/VJmidiKit/$order b/root/projects/VJmidiKit/$order deleted file mode 100644 index 6697bc5..0000000 --- a/root/projects/VJmidiKit/$order +++ /dev/null @@ -1,11 +0,0 @@ -tomcat -pineapple -boxy_visualist -boxy -jam -pillars -tomcat_tunnel -stills -kaleidoscope -dancing_pineapple -boxy_dnb diff --git a/root/projects/VJmidiKit/boxy/URL -> twitter$tweet b/root/projects/VJmidiKit/boxy/URL -> twitter$tweet deleted file mode 100644 index 5521568..0000000 --- a/root/projects/VJmidiKit/boxy/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1171136990118649857 diff --git a/root/projects/VJmidiKit/boxy_dnb/URL -> twitter$tweet b/root/projects/VJmidiKit/boxy_dnb/URL -> twitter$tweet deleted file mode 100644 index 41a8326..0000000 --- a/root/projects/VJmidiKit/boxy_dnb/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1171137508991787008 diff --git a/root/projects/VJmidiKit/boxy_visualist/URL -> twitter$tweet b/root/projects/VJmidiKit/boxy_visualist/URL -> twitter$tweet deleted file mode 100644 index a5dfd73..0000000 --- a/root/projects/VJmidiKit/boxy_visualist/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1171137921858056192 diff --git a/root/projects/VJmidiKit/dancing_pineapple/URL -> twitter$tweet b/root/projects/VJmidiKit/dancing_pineapple/URL -> twitter$tweet deleted file mode 100644 index 09625ee..0000000 --- a/root/projects/VJmidiKit/dancing_pineapple/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1009523556001173506 diff --git a/root/projects/VJmidiKit/description: text$plain b/root/projects/VJmidiKit/description: text$plain deleted file mode 100644 index 78c48eb..0000000 --- a/root/projects/VJmidiKit/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -MIDI-reactive realtime visual effects platform. diff --git a/root/projects/VJmidiKit/jam/URL -> youtube$video b/root/projects/VJmidiKit/jam/URL -> youtube$video deleted file mode 100644 index 5c8dd95..0000000 --- a/root/projects/VJmidiKit/jam/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=QiMCIsrlNIQ diff --git a/root/projects/VJmidiKit/kaleidoscope/URL -> twitter$tweet b/root/projects/VJmidiKit/kaleidoscope/URL -> twitter$tweet deleted file mode 100644 index 2152177..0000000 --- a/root/projects/VJmidiKit/kaleidoscope/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1050731951689101313 diff --git a/root/projects/VJmidiKit/pillars/URL -> twitter$tweet b/root/projects/VJmidiKit/pillars/URL -> twitter$tweet deleted file mode 100644 index 1a3435a..0000000 --- a/root/projects/VJmidiKit/pillars/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1050771730384343041 diff --git a/root/projects/VJmidiKit/pineapple/URL -> twitter$tweet b/root/projects/VJmidiKit/pineapple/URL -> twitter$tweet deleted file mode 100644 index 9f8b953..0000000 --- a/root/projects/VJmidiKit/pineapple/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1010276414321512448 diff --git a/root/projects/VJmidiKit/stills/URL -> twitter$tweet b/root/projects/VJmidiKit/stills/URL -> twitter$tweet deleted file mode 100644 index 0ea3752..0000000 --- a/root/projects/VJmidiKit/stills/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1044844729878413312 diff --git a/root/projects/VJmidiKit/text$markdown+wide.md b/root/projects/VJmidiKit/text$markdown+wide.md deleted file mode 100644 index 7767e93..0000000 --- a/root/projects/VJmidiKit/text$markdown+wide.md +++ /dev/null @@ -1,31 +0,0 @@ -VJmidiKit -========= - -VJmidiKit is a tool for VJing using livecoded (raymarching) shaders and connecting shaders to MIDI signals -from live music and controllers for music reactivity. -The interactions between MIDI signals and shader variables can be programmed in many different ways using a visual block language. - -VJmidiKit is a C++ application built on top of [openFrameworks][of], [Dear Imgui][imgui], [RtMidi][rtmidi] and [yaml-cpp][yaml]. -The Shaders in the following media are all written in GLSL by me, using the excellent [hg\_sdf][hgsdf] library. - -If you are interested in trying VJmidiKit for yourself, feel free to message me. -You can find my email address at the top, and social media at the bottom of this website. - -<div style="align-items: flex-start; display: flex; flex-wrap: wrap; margin: -0.5em;"> - <mmm-embed nolink inline path="boxy_dnb"></mmm-embed> - <mmm-embed nolink inline path="boxy_visualist"></mmm-embed> - <mmm-embed nolink inline path="stills"></mmm-embed> - <mmm-embed nolink inline path="pineapple"></mmm-embed> - <mmm-embed nolink inline path="kaleidoscope"></mmm-embed> - <mmm-embed nolink inline path="pillars"></mmm-embed> - <mmm-embed nolink inline path="tomcat_tunnel"></mmm-embed> - <mmm-embed nolink inline path="dancing_pineapple"></mmm-embed> - <mmm-embed nolink inline path="tomcat"></mmm-embed> - <mmm-embed nolink inline path="jam"></mmm-embed> -</div> - -[of]: https://openframeworks.cc/ -[imgui]: https://github.com/ocornut/imgui -[rtmidi]: https://github.com/thestk/rtmidi -[yaml]: https://github.com/jbeder/yaml-cpp -[hgsdf]: http://mercury.sexy/hg_sdf/ diff --git a/root/projects/VJmidiKit/tomcat/URL -> twitter$tweet b/root/projects/VJmidiKit/tomcat/URL -> twitter$tweet deleted file mode 100644 index a7a08f3..0000000 --- a/root/projects/VJmidiKit/tomcat/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1006220929519816708 diff --git a/root/projects/VJmidiKit/tomcat_tunnel/URL -> twitter$tweet b/root/projects/VJmidiKit/tomcat_tunnel/URL -> twitter$tweet deleted file mode 100644 index 48497c4..0000000 --- a/root/projects/VJmidiKit/tomcat_tunnel/URL -> twitter$tweet +++ /dev/null @@ -1 +0,0 @@ -https://twitter.com/S0lll0s/status/1006217163240280080 diff --git a/root/projects/btrktrl/$order b/root/projects/btrktrl/$order deleted file mode 100644 index c804056..0000000 --- a/root/projects/btrktrl/$order +++ /dev/null @@ -1,13 +0,0 @@ -pcb_glamour_connector -pcb_dev_configuration -knobs_testing -pcb_glamour_top -pcb_glamour -proto_rgb -proto_spi -knobs_all -proto_encoder -pcb_glamour_far -pcb_osc -pcb_glamour_close -pcb_dev_encoder diff --git a/root/projects/btrktrl/description: text$plain b/root/projects/btrktrl/description: text$plain deleted file mode 100644 index d7e3402..0000000 --- a/root/projects/btrktrl/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a FPGA-based modular MIDI/OSC control surface diff --git a/root/projects/btrktrl/knobs_all/description: text$plain b/root/projects/btrktrl/knobs_all/description: text$plain deleted file mode 100644 index 1a43de0..0000000 --- a/root/projects/btrktrl/knobs_all/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -sampling machined aluminum knobs from chinese supplier diff --git a/root/projects/btrktrl/knobs_all/image$jpeg.jpg b/root/projects/btrktrl/knobs_all/image$jpeg.jpg Binary files differdeleted file mode 100644 index c523f8f..0000000 --- a/root/projects/btrktrl/knobs_all/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/knobs_testing/description: text$plain b/root/projects/btrktrl/knobs_testing/description: text$plain deleted file mode 100644 index 9588122..0000000 --- a/root/projects/btrktrl/knobs_testing/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -testing different knob spacings diff --git a/root/projects/btrktrl/knobs_testing/image$jpeg.jpg b/root/projects/btrktrl/knobs_testing/image$jpeg.jpg Binary files differdeleted file mode 100644 index 09ea47d..0000000 --- a/root/projects/btrktrl/knobs_testing/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/pcb_dev_configuration/description: text$plain b/root/projects/btrktrl/pcb_dev_configuration/description: text$plain deleted file mode 100644 index b15f4f0..0000000 --- a/root/projects/btrktrl/pcb_dev_configuration/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -configuring the FPGA on the custom PCB via an arduino for the first time diff --git a/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 b/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 Binary files differdeleted file mode 100644 index c8113cd..0000000 --- a/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/btrktrl/pcb_dev_encoder/description: text$plain b/root/projects/btrktrl/pcb_dev_encoder/description: text$plain deleted file mode 100644 index 530be5a..0000000 --- a/root/projects/btrktrl/pcb_dev_encoder/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -encoder & capacitive sensing working on the custom PCB diff --git a/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 b/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 Binary files differdeleted file mode 100644 index fa41799..0000000 --- a/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg Binary files differdeleted file mode 100644 index 5864822..0000000 --- a/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg Binary files differdeleted file mode 100644 index 5d572aa..0000000 --- a/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg Binary files differdeleted file mode 100644 index 6503f84..0000000 --- a/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg Binary files differdeleted file mode 100644 index 661f4fe..0000000 --- a/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg Binary files differdeleted file mode 100644 index bbefc13..0000000 --- a/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/pcb_osc/description: text$plain b/root/projects/btrktrl/pcb_osc/description: text$plain deleted file mode 100644 index 2f0df00..0000000 --- a/root/projects/btrktrl/pcb_osc/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a browser application talking to the encoders through a websocket/serial OSC bridge (nodejs) diff --git a/root/projects/btrktrl/pcb_osc/video$mp4.mp4 b/root/projects/btrktrl/pcb_osc/video$mp4.mp4 Binary files differdeleted file mode 100644 index 3562d43..0000000 --- a/root/projects/btrktrl/pcb_osc/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/btrktrl/proto_encoder/description: text$plain b/root/projects/btrktrl/proto_encoder/description: text$plain deleted file mode 100644 index e0f620b..0000000 --- a/root/projects/btrktrl/proto_encoder/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -getting the encoder and capacitive sensing working on the prototype diff --git a/root/projects/btrktrl/proto_encoder/video$mp4.mp4 b/root/projects/btrktrl/proto_encoder/video$mp4.mp4 Binary files differdeleted file mode 100644 index acb32c8..0000000 --- a/root/projects/btrktrl/proto_encoder/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/btrktrl/proto_rgb/description: text$plain b/root/projects/btrktrl/proto_rgb/description: text$plain deleted file mode 100644 index 43b7f69..0000000 --- a/root/projects/btrktrl/proto_rgb/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -driving WS2812 RGB LEDs on the prototype board diff --git a/root/projects/btrktrl/proto_rgb/video$mp4.mp4 b/root/projects/btrktrl/proto_rgb/video$mp4.mp4 Binary files differdeleted file mode 100644 index 8e06fcc..0000000 --- a/root/projects/btrktrl/proto_rgb/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/btrktrl/proto_spi/description: text$plain b/root/projects/btrktrl/proto_spi/description: text$plain deleted file mode 100644 index c38b56e..0000000 --- a/root/projects/btrktrl/proto_spi/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -developing and debugging the SPI protocol diff --git a/root/projects/btrktrl/proto_spi/image$jpeg.jpg b/root/projects/btrktrl/proto_spi/image$jpeg.jpg Binary files differdeleted file mode 100644 index c89341c..0000000 --- a/root/projects/btrktrl/proto_spi/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon b/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 4d12d25..0000000 --- a/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,69 +0,0 @@ -import div, h3, p, a from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - text = (...) -> - div with for text in *{...} - p text - .style = { 'max-width': '900px' } - - filtered_block = (pattern) -> - div with for child in *@children - continue unless (child\gett 'name: alpha')\match pattern - - div { - style: { - display: 'inline-block' - width: '500px' - margin: '0.5em' - padding: '0.4em 1em' - background: 'var(--gray-bright)' - } - div (link_to child), style: { 'margin-bottom': '0.2em' } - child\gett 'mmm/dom' - (child\get 'description: mmm/dom') - } - - .style = { - display: 'flex' - 'flex-wrap': 'wrap' - 'align-items': 'flex-start' - margin: '-0.5em' - } - - div { - h3 @gett 'name: alpha' - text "For this project I am builiding a modular, FPGA powered MIDI/OSC Control Surface.", - "The setup consists of an arduino MCU as a master controller, that communicates to the PC over - SLIP-encoded Serial OSC messages. The controller talks to daughterboards over SPI. - Each daugherboard contains a rotary encoder, 8 RGB LEDs and does capacitive sensing on the knob.", - "This was the first time I worked with an FPGA, and the first time I designed my own PCBs as well. - The FPGA I used is an ICE40UP5k, it was targeted using the icestorm open toolchain and Verilog. - I started by prototyping using an UPduino v2 Prototyping board (orange), and my failed rev1 PCBs (green). - On the FPGAs I implemented capacitive sensing, the SPI slave and control logic before moving on." - - filtered_block '^proto_' - - text "Once I got everything working there I designed my custom boards with the FPGA integrated directly, - including power conditioning and configuration. - There is also a busboard that manages SPI addressing / multiplexing as well as latching the power state - for each daughterboard, so that they can be started and configured individually." - - filtered_block '^pcb_glamour' - filtered_block '^pcb_dev' - - text "I also contacted some suppliers of machined aluminum knobs online and ordered a some samples from one of them.", - "I selected only knobs that are made made from solid aluminum and that use a set-screw for fastening to make sure - that the aluminum and the encoder would make electrical contact through the set-screw, which is required for the - capacitive sensing to work (at leas the way I implemented it)." - - filtered_block '^knobs' - - text "The daughterboards and controller communicate over a custom SPI protocol I designed. - The controller configures the daughterboards on boot or request from the PC. - It sends and receives OSC messages over SLIP-encoded Serial. - On the PC a small nodejs application relays the OSC messages over UDP or WebSocket, - so that native and web applications can consume them and interact with the control surface." - - filtered_block '^pcb_osc' - } diff --git a/root/projects/chimpanzee_bukkaque/description: text$plain b/root/projects/chimpanzee_bukkaque/description: text$plain deleted file mode 100644 index 43d6c41..0000000 --- a/root/projects/chimpanzee_bukkaque/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a ludic mesh of home-built interactive sound devices, circuit bent toys and an improvisational live performance. diff --git a/root/projects/chimpanzee_bukkaque/link: URL b/root/projects/chimpanzee_bukkaque/link: URL deleted file mode 100644 index e52b113..0000000 --- a/root/projects/chimpanzee_bukkaque/link: URL +++ /dev/null @@ -1 +0,0 @@ -https://chimpanzeebukkaque.bandcamp.com/ diff --git a/root/projects/demoloops/$order b/root/projects/demoloops/$order deleted file mode 100644 index b98a31c..0000000 --- a/root/projects/demoloops/$order +++ /dev/null @@ -1,16 +0,0 @@ -toroid -squaregrid -zoom -koch -triangles -twisted -cube -planetary -flipping -weekly3 -dots -shutter -goldfish -divide -circle -fracture diff --git a/root/projects/demoloops/_web_view: type b/root/projects/demoloops/_web_view: type deleted file mode 100644 index bde5644..0000000 --- a/root/projects/demoloops/_web_view: type +++ /dev/null @@ -1 +0,0 @@ -text/html+interactive diff --git a/root/projects/demoloops/circle/video$mp4.mp4 b/root/projects/demoloops/circle/video$mp4.mp4 Binary files differdeleted file mode 100644 index 69b2410..0000000 --- a/root/projects/demoloops/circle/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/cube/video$mp4.mp4 b/root/projects/demoloops/cube/video$mp4.mp4 Binary files differdeleted file mode 100644 index f8ceb51..0000000 --- a/root/projects/demoloops/cube/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/description: text$plain b/root/projects/demoloops/description: text$plain deleted file mode 100644 index 24abffc..0000000 --- a/root/projects/demoloops/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -geometric 2d and 3d looping animations. diff --git a/root/projects/demoloops/divide/video$mp4.mp4 b/root/projects/demoloops/divide/video$mp4.mp4 Binary files differdeleted file mode 100644 index 4cbe907..0000000 --- a/root/projects/demoloops/divide/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/dots/description: text$markdown+span b/root/projects/demoloops/dots/description: text$markdown+span deleted file mode 100644 index b0c8fd2..0000000 --- a/root/projects/demoloops/dots/description: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -inspired by [this reddit post](https://www.reddit.com/r/gifs/comments/5bayiu/dont_click_on_this_if_you_are_currently_drunk/). diff --git a/root/projects/demoloops/dots/video$mp4.mp4 b/root/projects/demoloops/dots/video$mp4.mp4 Binary files differdeleted file mode 100644 index 2412b28..0000000 --- a/root/projects/demoloops/dots/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/flipping/video$mp4.mp4 b/root/projects/demoloops/flipping/video$mp4.mp4 Binary files differdeleted file mode 100644 index 1d762d6..0000000 --- a/root/projects/demoloops/flipping/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/fracture/video$mp4.mp4 b/root/projects/demoloops/fracture/video$mp4.mp4 Binary files differdeleted file mode 100644 index 895a29d..0000000 --- a/root/projects/demoloops/fracture/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/goldfish/description: text$plain b/root/projects/demoloops/goldfish/description: text$plain deleted file mode 100644 index b956e72..0000000 --- a/root/projects/demoloops/goldfish/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -pssst, this is for my mom's birthday. don't tell her yet! diff --git a/root/projects/demoloops/goldfish/video$mp4.mp4 b/root/projects/demoloops/goldfish/video$mp4.mp4 Binary files differdeleted file mode 100644 index 4fcb625..0000000 --- a/root/projects/demoloops/goldfish/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/koch/text$moonscript -> mmm$component.moon b/root/projects/demoloops/koch/text$moonscript -> mmm$component.moon deleted file mode 100644 index 8528272..0000000 --- a/root/projects/demoloops/koch/text$moonscript -> mmm$component.moon +++ /dev/null @@ -1,104 +0,0 @@ -assert MODE == 'CLIENT', '[nossr]' -Math = window.Math - -import CanvasApp from require 'mmm.canvasapp' -import hsl from require 'mmm.color' - -class KochDemo extends CanvasApp - width: 500 - height: 400 - length: math.pi * 2 - - new: (@iterations=3) => - super true - hue = Math.random! - @background = {1 - hue, .3, .3} - - @shades = setmetatable {}, __index: (tbl, key) -> - with val = hsl { hue, .7, .9 - .5 * (key / @iterations)} do rawset tbl, key, val - - a_sixth = math.pi / 3 - a_third = 2 * a_sixth - cossin = (a) -> (math.cos a), math.sin a - triangle: (color) => - @ctx.fillStyle = color - @ctx\beginPath! - @ctx\moveTo cossin 0 - @ctx\lineTo cossin a_third - @ctx\lineTo cossin 2*a_third - @ctx\fill! - - update: (dt) => - super dt * 1.6 - - draw: => - @ctx.fillStyle = hsl @background - @ctx\fillRect 0, 0, @width, @height - - @ctx\translate @width/2, @height/2 - s = .3 * math.min @width, @height - @ctx\scale s, s - - _scale = 0.8 + 0.2 * math.sin math.pi + @time - - ttime = @time - math.pi/2 - transfer, flipped = 0 - if ttime > 0 and ttime < math.pi - transfer = .5 - .5 * math.cos ttime - flipped = true - - draw = (i, pop) -> - @triangle @shades[i] - - extra = not pop and flipped - return unless i > (if extra then -1 else 0) - - scale = _scale - if (pop and i < 1) or (not pop and i < 0) - scale = transfer - - @ctx\save! - @ctx\rotate -(a_sixth + a_third) - @ctx\scale scale, scale - - for o=1,2 - @ctx\rotate a_third - @ctx\save! - @ctx\translate .5 + .5/scale, 0 - draw i - 1, pop - @ctx\restore! - - @ctx\restore! - - @ctx\rotate a_sixth/2 - @ctx\translate -transfer, 0 - @ctx\rotate a_sixth * transfer - - @triangle @shades[3 - transfer] - - @ctx\save! - @ctx\rotate a_sixth - @ctx\scale _scale, _scale - - @ctx\save! - @ctx\translate .5 + .5/_scale, 0 - draw 2 - transfer - @ctx\restore! - - @ctx\rotate a_third - - @ctx\save! - @ctx\translate .5 + .5/_scale, 0 - draw 2 - transfer - @ctx\restore! - - @ctx\rotate a_third - - @ctx\save! - @ctx\translate .5 + .5/_scale, 0 - draw 2 + transfer, true - @ctx\restore! - - @ctx\restore! - -KochDemo! diff --git a/root/projects/demoloops/planetary/video$mp4.mp4 b/root/projects/demoloops/planetary/video$mp4.mp4 Binary files differdeleted file mode 100644 index 6a74bc4..0000000 --- a/root/projects/demoloops/planetary/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/shutter/video$mp4.mp4 b/root/projects/demoloops/shutter/video$mp4.mp4 Binary files differdeleted file mode 100644 index adf5fe6..0000000 --- a/root/projects/demoloops/shutter/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/squaregrid/$order b/root/projects/demoloops/squaregrid/$order deleted file mode 100644 index 7ec8787..0000000 --- a/root/projects/demoloops/squaregrid/$order +++ /dev/null @@ -1,3 +0,0 @@ -rotated -overlaid -rounded diff --git a/root/projects/demoloops/squaregrid/overlaid/video$mp4.mp4 b/root/projects/demoloops/squaregrid/overlaid/video$mp4.mp4 Binary files differdeleted file mode 100644 index 258d154..0000000 --- a/root/projects/demoloops/squaregrid/overlaid/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/squaregrid/rotated/video$mp4.mp4 b/root/projects/demoloops/squaregrid/rotated/video$mp4.mp4 Binary files differdeleted file mode 100644 index 9452aa7..0000000 --- a/root/projects/demoloops/squaregrid/rotated/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/squaregrid/rounded/video$mp4.mp4 b/root/projects/demoloops/squaregrid/rounded/video$mp4.mp4 Binary files differdeleted file mode 100644 index 163c35a..0000000 --- a/root/projects/demoloops/squaregrid/rounded/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/squaregrid/text$html+frag b/root/projects/demoloops/squaregrid/text$html+frag deleted file mode 100644 index aa33399..0000000 --- a/root/projects/demoloops/squaregrid/text$html+frag +++ /dev/null @@ -1,5 +0,0 @@ -<div> - <mmm-embed path="rotated"></mmm-embed> - <mmm-embed path="rounded"></mmm-embed> - <mmm-embed path="overlaid"></mmm-embed> -</div> diff --git a/root/projects/demoloops/text$moonscript -> fn -> mmm$dom.moon b/root/projects/demoloops/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index dd49f6f..0000000 --- a/root/projects/demoloops/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,28 +0,0 @@ -import div, h3, p, ul, li, a from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - div { - link_to @ - p @gett 'description: mmm/dom', style: { 'margin-bottom': '-.5em' }, - div with for child in *@children - name = child\gett 'name: alpha' - desc = child\get 'description: mmm/dom' - li { - style: { - display: 'inline-block' - width: '500px' - margin: '0.5em' - padding: '1em' - background: 'var(--gray-bright)' - } - child\get 'mmm/dom' - div link_to child - } - - .style = { - display: 'flex' - 'flex-wrap': 'wrap' - 'align-items': 'flex-start' - } - } diff --git a/root/projects/demoloops/toroid/description: text$markdown+span b/root/projects/demoloops/toroid/description: text$markdown+span deleted file mode 100644 index 1e783c6..0000000 --- a/root/projects/demoloops/toroid/description: text$markdown+span +++ /dev/null @@ -1 +0,0 @@ -built at 34c3 with \[moritz\] as a stepping stone towards [torus3d](https://github.com/s-ol/torus3d). diff --git a/root/projects/demoloops/toroid/video$mp4.mp4 b/root/projects/demoloops/toroid/video$mp4.mp4 Binary files differdeleted file mode 100644 index 6e91a3a..0000000 --- a/root/projects/demoloops/toroid/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/triangles/video$mp4.mp4 b/root/projects/demoloops/triangles/video$mp4.mp4 Binary files differdeleted file mode 100644 index aca459b..0000000 --- a/root/projects/demoloops/triangles/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/twisted/text$moonscript -> mmm$component.moon b/root/projects/demoloops/twisted/text$moonscript -> mmm$component.moon deleted file mode 100644 index 3fd11b0..0000000 --- a/root/projects/demoloops/twisted/text$moonscript -> mmm$component.moon +++ /dev/null @@ -1,43 +0,0 @@ -assert MODE == 'CLIENT', '[nossr]' -import CanvasApp from require 'mmm.canvasapp' -import hsl from require 'mmm.color' - -Math = window.Math - -class TwistedDemo extends CanvasApp - width: 500 - height: 400 - length: math.pi * 4 - new: (preview) => - if preview - @width, @height = 120, 120 - super false, true - else - super true - @background = {Math.random!, Math.random!/3+.2, Math.random!/4} - hue = Math.random! - @shades = setmetatable {}, __index: (key) => - with val = { hue, .7, key * .3 + .1} do rawset @, key, val - - draw: => - @ctx.fillStyle = hsl @background - @ctx\fillRect 0, 0, @width, @height - @ctx\translate @width/2, @height/2 + 70 - - draw = (i) -> - @ctx\save! - @ctx\translate 0, -120*i - s = 1 - 0.1 * math.sin @time + i*2 - s *= 0.8 - i * .4 * math.cos @time - @ctx\scale s, s/2 - @ctx\rotate @time/4 + i * .6 * math.cos @time - @ctx.fillStyle = hsl table.unpack @shades[i] - @ctx\fillRect -80, -80, 160, 160 - @ctx\restore! - - for i=0,1,1/(20 + 19 * math.sin(@time / 2)) - draw i - draw 1 - --- .props['preview: fn -> mmm/component'] = => TwistedDemo true -TwistedDemo! diff --git a/root/projects/demoloops/twisted/video: video$mp4.mp4 b/root/projects/demoloops/twisted/video: video$mp4.mp4 Binary files differdeleted file mode 100644 index c77e1ee..0000000 --- a/root/projects/demoloops/twisted/video: video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/weekly3/video$mp4.mp4 b/root/projects/demoloops/weekly3/video$mp4.mp4 Binary files differdeleted file mode 100644 index 8e20ac8..0000000 --- a/root/projects/demoloops/weekly3/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/demoloops/zoom/video$mp4.mp4 b/root/projects/demoloops/zoom/video$mp4.mp4 Binary files differdeleted file mode 100644 index 0359073..0000000 --- a/root/projects/demoloops/zoom/video$mp4.mp4 +++ /dev/null diff --git a/root/projects/gayngine/description: text$plain b/root/projects/gayngine/description: text$plain deleted file mode 100644 index 9a37a84..0000000 --- a/root/projects/gayngine/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -photoshop-document-based 2d game engine. diff --git a/root/projects/gayngine/link: URL -> git b/root/projects/gayngine/link: URL -> git deleted file mode 100644 index 9ef9b61..0000000 --- a/root/projects/gayngine/link: URL -> git +++ /dev/null @@ -1 +0,0 @@ -https://github.com/s-ol/gayngine diff --git a/root/projects/iii-telefoni/$order b/root/projects/iii-telefoni/$order deleted file mode 100644 index d69cdf5..0000000 --- a/root/projects/iii-telefoni/$order +++ /dev/null @@ -1,2 +0,0 @@ -boxes -heads diff --git a/root/projects/iii-telefoni/boxes/image$jpeg.jpg b/root/projects/iii-telefoni/boxes/image$jpeg.jpg Binary files differdeleted file mode 100644 index c3f9613..0000000 --- a/root/projects/iii-telefoni/boxes/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/iii-telefoni/boxes/orig: image$jpeg.jpg b/root/projects/iii-telefoni/boxes/orig: image$jpeg.jpg Binary files differdeleted file mode 100644 index c74b2f4..0000000 --- a/root/projects/iii-telefoni/boxes/orig: image$jpeg.jpg +++ /dev/null diff --git a/root/projects/iii-telefoni/description: mmm$dom b/root/projects/iii-telefoni/description: mmm$dom deleted file mode 100644 index 9c673ae..0000000 --- a/root/projects/iii-telefoni/description: mmm$dom +++ /dev/null @@ -1 +0,0 @@ -an experiment on human communication. diff --git a/root/projects/iii-telefoni/heads/image$jpeg.jpg b/root/projects/iii-telefoni/heads/image$jpeg.jpg Binary files differdeleted file mode 100644 index cc1228f..0000000 --- a/root/projects/iii-telefoni/heads/image$jpeg.jpg +++ /dev/null diff --git a/root/projects/iii-telefoni/hidden: text$lua -> bool.lua b/root/projects/iii-telefoni/hidden: text$lua -> bool.lua deleted file mode 100644 index b30e187..0000000 --- a/root/projects/iii-telefoni/hidden: text$lua -> bool.lua +++ /dev/null @@ -1 +0,0 @@ -return true diff --git a/root/projects/iii-telefoni/text$markdown.md b/root/projects/iii-telefoni/text$markdown.md deleted file mode 100644 index aa9c078..0000000 --- a/root/projects/iii-telefoni/text$markdown.md +++ /dev/null @@ -1,45 +0,0 @@ -<mmm-embed path="boxes" nolink></mmm-embed> -tre telefoni -============ - -*Tre Telefoni* is an installation piece and experimental cooperative game that seeks to unite three strangers by -tasking them with getting to know each other despite complications. - -It consists of three wall-mounted telephone boxes set up out of earshot from each other. -When a player is ready on each of the stations, the phones become active and the three players are connected to each other. -However their communication is complicated by the unconventional nature of the phone system they are using: -Each phone is set up to only relay sound from its microphone to the next station in turn: - -- player A's speech is transmitted only to player B, -- player B's speech is only transmitted to player C, and -- player C's speech is only transmitted to player A. - -<mmm-embed path="heads" nolink></mmm-embed> - -The players have to try to figure out a way to communicate to each other despite not being able to directly respond to each other in order to find out each other's identities. -If they succeed, they can optionally try to arrange a meeting point on the grounds of the showcase to debrief and reflect on their experience. - -Though *Tre Telefoni* has been designed as an installation piece as described above, -a [web-based prototype][proto] is also available to playtest the premise itself. - -artist statement ----------------- -*Tre telefoni* seeks to challenge our notion of *conversation* by letting us experience a mode of communication designed for use by digital agents. - -Conversation traditionally presumes bidirectionality and a way for its subjects to respond directly to each other. -However we are not the only agents conversing: digital devices all around us are also steadily communicating, and while these digital conversations borrow human communication as a metaphor, they mostly take very different forms than our human conversations. -The 'ring topology' (also called 'daisy chaining') is one of the many *network topologies* that digital devices use to communicate. -In a 'ring network topology' each member of the network only talks to its successor, and all members need to collaborate in order to pass messages around. - -technical realisation ---------------------- -Each station is powered by a single-board computer (Raspberry Pi) connected to -- a USB headset (remade into a telephone handle) -- an ethernet switch shared by all stations to network them together -- a small speaker for the ringing sound - -The physical realisation of the station enclosures and telephone handles are currently a work in progress. -The software exists as a protoype version that can be accessed at [iii-telefoni.s-ol.nu][proto] -and playtested for example on mobile phones (compatibility with iOS devices may vary). - -[proto]: //iii-telefoni.s-ol.nu diff --git a/root/projects/text$moonscript -> fn -> mmm$dom.moon b/root/projects/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index aec02d9..0000000 --- a/root/projects/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,10 +0,0 @@ -import div, h3, ul, li from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - div { - h3 link_to @ - ul for child in *@children - desc = child\gett 'description: mmm/dom' - li (link_to child), ': ', desc - } diff --git a/root/projects/themer/description: text$plain b/root/projects/themer/description: text$plain deleted file mode 100644 index 96c9895..0000000 --- a/root/projects/themer/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -colorscheme generator and manager for your desktop. diff --git a/root/projects/themer/link: URL -> git b/root/projects/themer/link: URL -> git deleted file mode 100644 index e69179c..0000000 --- a/root/projects/themer/link: URL -> git +++ /dev/null @@ -1 +0,0 @@ -https://github.com/s-ol/themer diff --git a/root/projects/title: text$plain b/root/projects/title: text$plain deleted file mode 100644 index c28a565..0000000 --- a/root/projects/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -other projects diff --git a/root/projects/vcv_mods/description: text$markdown+span b/root/projects/vcv_mods/description: text$markdown+span deleted file mode 100644 index 255f88e..0000000 --- a/root/projects/vcv_mods/description: text$markdown+span +++ /dev/null @@ -1,4 +0,0 @@ -Plugins for [VCV Rack][rack], designed for [Oscilloscope Music][music]. - -[rack]: https://github.com/VCVRack/Rack -[music]: https://oscilloscopemusic.com/ diff --git a/root/projects/vcv_mods/link: URL -> youtube$video b/root/projects/vcv_mods/link: URL -> youtube$video deleted file mode 100644 index a4f7e47..0000000 --- a/root/projects/vcv_mods/link: URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=DnxmfnkGxiY diff --git a/root/research/$order b/root/research/$order deleted file mode 100644 index e05ba2c..0000000 --- a/root/research/$order +++ /dev/null @@ -1,4 +0,0 @@ -realities -mmmfs -watch-cad -alivecoding diff --git a/root/research/alivecoding/$order b/root/research/alivecoding/$order deleted file mode 100644 index 1549b67..0000000 --- a/root/research/alivecoding/$order +++ /dev/null @@ -1 +0,0 @@ -demo diff --git a/root/research/alivecoding/demo/URL -> youtube$video b/root/research/alivecoding/demo/URL -> youtube$video deleted file mode 100644 index 61512a6..0000000 --- a/root/research/alivecoding/demo/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=z0XZYnY3Evc diff --git a/root/research/alivecoding/description: text$plain b/root/research/alivecoding/description: text$plain deleted file mode 100644 index 1b1a6fc..0000000 --- a/root/research/alivecoding/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -livecoding with persistent expressions diff --git a/root/research/alivecoding/text$markdown+sidenotes.md b/root/research/alivecoding/text$markdown+sidenotes.md deleted file mode 100644 index ce40193..0000000 --- a/root/research/alivecoding/text$markdown+sidenotes.md +++ /dev/null @@ -1,145 +0,0 @@ -# alivecoding: <mmm-embed wrap="raw" facet="description"></mmm-embed> -Persistent expressions are an approach to livecoding that unifies direct -manipulation of a dataflow engine with a textual representation and -lisp-based programming language. - -<mmm-embed wrap="raw" path="demo"></mmm-embed> - -## shortcomings of repl-based programming -In repl-based environments, a scratch file is opened in a text editor. In it, -commands are staged and can be added, removed and edited without consequence. -The livecoding system generally has no knowledge about this scratch buffer at -all. The user is free to select and send individual commands (or groups of -commands) at any time and execute them by transmitting them to the server via -an editor plugin. - -Commands are incremental changes (deltas) that get sent to the server, which -keeps an entirely separate and invisible model of the project. Generally no -feedback about the state of this model is made available to the user. - -Code is only executed when the user evaluates a block, although code run in -this fashion may cause other code to execute outside of the user-evaluated -execution flow via side effects, for example by registering a handler for -events such as incoming messages or scheduling execution based on system time. -These mechanisms however are implementation details within the code the user -executed originally, and no uniform mechanism for noticing, visualizing or -undoing these side-effects exists. - -This design has the following consequences: - -- The view of the scratch buffer is not correlated with the code and state the - server is currently executing. This results in overhead for keeping the - mental synchronized with what the system is actually performing for the user, - but also makes it much harder for the audience to follow along. -- Sessions cannot be reopened reliably, because the state of the server depends - on the full sequence of commands that were sent to the server in order, which - is not represented in the scratch buffer. -- If parts of the execution model on the server have not been explicitly - labelled (i.e. assigned to a variable) in the textual representation, often - many potentially important actions for modifying the current behaviour are - unavailable: for example long-running sounds may not be cancellable, effects' - parameters may not be adjustable without recreating the signal chain, etc. - -## persistent expressions -The *persistent expression* paradigm, on the other hand, reconciles the user- -facing, text-based representation of the system and the server-internal model -and execution flow. - -### execution flow -Code execution happens in two different phases alternatingly: at *eval-time*, -whenever the buffer is (re)evaluated; and at *run-time*, continuously between -evaluations. - -At *eval-time*, execution is analogous to common functional and lisp-style -languages. Expressions are evaluated depth-first starting from the root. -For each expression, the head of the expression is first evaluated, and -depending on the type of that subexpression different actions are taken. In the -general case, the head of an expression is an *Op* (operator) type, an instance -of which will continue to run at *run-time*. In this case, all other arguments -are then evaluated and passed to the *Op* instance, which is either created or -reused (see below). -On the other hand, some expressions (for example `def`, `use`, ...) do not -execute at *run-time*, but cause *eval-time* side-effects like declaring a -symbol in the active scope. Because *eval-time* execution only happens once and -in a deterministic order, and no *eval-time* state persists across evaluations, -despite these side-effects, the *eval-time* execution is equivalent to -functionally pure execution with an implicit scope parameter. - -Unlike normal lisps, when evaluating expressions, not only a value is -generated. In parallel to the tree of return values, a tree of *run-time* -dependencies is built, that tracks all instantiated *Op*s and their inputs. - -At *run-time*, *Op* instances update based on this dependency tree. Starting -from a periodic root event polled by the interpreter, dependent *Op*s are -executed (following the outside-in, depth-first order that the dependencies have -been created in at *eval-time*). *Op*s whose inputs are unchanged and 'pure' -subtrees that do not have any dependency on the root event are not executed. -In this way, the *run-time* behaviour of the system is that of a event-driven -dataflow language with clearly defined execution flow. - -### expression tagging -In order to maintain the congruency between the representations across edits -and reevaluations, the identity of individual expressions is tracked using -tags. Tags are noted using unique numbers in square brackets before the head of -expressions (e.g. `([1]head arg1 arg2...)`) and are optional when parsed. - -At *eval-time* (see below), every expression that is not tagged will be -assigned a new unique tag number. 'Cloned' expressions, such as the expressions -from a function definition body, are assigned composite tags that can be noted -as a list of tags joined by periods (e.g. `[2.1]`): - -``` -([1]defn add-two-and-multiply (a b) - ([2]mul b ([3]add a 2))) - -([4]add-two-and-multiply 1 2) -([5]add-two-and-multiply 3 4) -``` - -will be expanded (at *eval-time*) to approximately<span class="sidenote"> -The actual implementation does not actually create sub expressions as shown -here, but the results behave equivalently.</span>: - -``` -(do - (def a 1 - b 2) - ([4.2]mul a ([4.3]add b 2))) -(do - (def a 3 - b 4) - ([5.2]mul a ([5.3]add b 2))) -``` - -The expression tags are used to associate the *run-time* representations (*Op* -instances) of expressions with their textual representations, and track their -identity as the user changes the code. When the code is evaluated, *Op*s are -instantiated whenever the expression was previously untagged, or when the head -of the expression no longer resolves to the same value. Otherwise, the previous -*Op* instance continues to exist and parameter changes are forward to it. *Op*s -that are no longer referenced in the code are destroyed. - -### benefits -This approach combines the benefits of dataflow programming for livecoding with -those of a textual representation and the user-controlled evaluation moment. - -From visual dataflow programming, the following benefits over common textual, -REPL-based livecoding systems are inherited: - -- direct manipulation of individual parameters of a system without disturbing - the system at large -- execution and dataflow are aligned and evident in the editable representation -- state is isolated and compartmentalized in local elements -- opportunity to visualize dataflow and local state<span class="sidenote"> - visualizing state of individual *Op*s in editor-dependent and editor-agnostic - ways that integrate with the textual representation is an ongoing research - direction of this project.</span> - -On the other hand, the following advantages from such textual systems are -preserved, that are generally absent in visual dataflow environments: - -- high information density -- fast editing experience -- accessibility and editability from a wide range of tools (any text editor) -- ability to harness powerful meta-programming facilities (from Lisp) -- complex changes can be made without intermittently disrupting the system diff --git a/root/research/mmmfs/$order b/root/research/mmmfs/$order deleted file mode 100644 index 45f4eb8..0000000 --- a/root/research/mmmfs/$order +++ /dev/null @@ -1,15 +0,0 @@ -title -abstract -table-of-contents -introduction -motivation -historical-approaches -framework -mmmfs -examples -evaluation -conclusion -references -ba_log -statement-of-originality -defense diff --git a/root/research/mmmfs/_web_view: type b/root/research/mmmfs/_web_view: type deleted file mode 100644 index bde5644..0000000 --- a/root/research/mmmfs/_web_view: type +++ /dev/null @@ -1 +0,0 @@ -text/html+interactive diff --git a/root/research/mmmfs/abstract/text$markdown+sidenotes.md b/root/research/mmmfs/abstract/text$markdown+sidenotes.md deleted file mode 100644 index c7d6c9c..0000000 --- a/root/research/mmmfs/abstract/text$markdown+sidenotes.md +++ /dev/null @@ -1,14 +0,0 @@ -abstract -======== - -Current end-user operating systems are based on a set of design principles and computing paradigms that make them -simple to use in some circumstances but are very inflexible for user customization and adaptation. In this thesis, these -limitations and design principles will be discussed and contrasted by an analysis of historic systems that solved these -issues by following different design goals. Based on this analysis, as well as further literature, an evaluation -framework for end-user computing systems is established. -The design and implementation of a new end-user computing system, which focuses on a file system with rich file types -and a type coercion system as its central paradigm, is discussed. Following this, the capabilities of the system are -demonstrated using multiple example use-cases. An evaluation of these examples as well as the system itself according -to the framework established earlier shows that the proposed system is indeed very flexible and useful for a wide -variety of uses involving multimedia content from various sources, although the system has many flaws that would hinder -widespread adoption. diff --git a/root/research/mmmfs/ba_log/$order b/root/research/mmmfs/ba_log/$order deleted file mode 100644 index a77277a..0000000 --- a/root/research/mmmfs/ba_log/$order +++ /dev/null @@ -1,15 +0,0 @@ -start -2019-10-07 -2019-10-08 -2019-10-09 -2019-10-10 -2019-10-11 -2019-10-14 -2019-10-15 -2019-10-24 -2019-10-26 -2019-10-27 -2019-10-29 -2019-11-01 -2019-11-25 -2019-12-20 diff --git a/root/research/mmmfs/ba_log/2019-10-07/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-07/text$markdown.md deleted file mode 100644 index 46c6892..0000000 --- a/root/research/mmmfs/ba_log/2019-10-07/text$markdown.md +++ /dev/null @@ -1,40 +0,0 @@ -Today I started working on the HTTP server that finds, converts and serves content stored in the (SQL) backend just-in-time (later the server could also cache content). - -The server can handle these types of requests: - -## Fileder Index Requests -A request like `GET /path/to/fileder/` (note the trailing slash) is used to query the contents of a fileder. -It solicits a JSON-encoded response that contains the full paths to all children of this fileder, as well as all facets currently stored, e.g: - - { - "children": [ - "/projects/vcv_mods", - "/projects/HowDoIOS", - "/projects/iii-telefoni", - "/projects/btrktrl", - "/projects/demoloops", - "/projects/VJmidiKit", - "/projects/gayngine", - "/projects/themer", - "/projects/chimpanzee_bukkaque" - ], - "facets": [ - ["", "text/moonscript -> fn -> mmm/dom"], - ["name", "alpha"], - ["title", "text/plain"] - ] - } - -## Facet Requests -A request like `GET /path/to/fileder/facet_name` is used to query a facet. -To differentiate a request for the 'unnamed' facet from an index request, unnamed facets are represented as a `:` character instead. -The type to ask for can be specified in a `MMM-Accept` header separately, it defaults to `text/html`. - -The server either sends back the (possibly converted) facet with a `200 OK` status, -or a `406 Not Acceptable` error if no conversion was possible. - -I also restructured the code a bit and moved some of the HTML-rendering code into the main mmmfs code. -Then I renamed the `text/html` type to `text/html+frag`, since it refers to only a fragment of HTML code, not a whole document, -and added a new *convert* from `text/html+frag` to `text/html` that wraps the fragment in the HTML template and style. - -the full code change is in commits [81e143f](https://git.s-ol.nu/mmm/commit/81e143fa8181a6adb58d7fba632bd31a13164410/) and [ad26c7c](https://git.s-ol.nu/mmm/commit/ad26c7c4e374f66a978f9946bbb083377f2224a6/) diff --git a/root/research/mmmfs/ba_log/2019-10-08/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-08/text$markdown.md deleted file mode 100644 index c10b75f..0000000 --- a/root/research/mmmfs/ba_log/2019-10-08/text$markdown.md +++ /dev/null @@ -1,58 +0,0 @@ -Today I mostly fixed the output/rendering of the 'live' server I implemented yesterday. - -I changed the URL scheme, it no longer uses headers, which made it hard to link to resources through `<link>` and `<script>` tags. -Instead the path, facet-name and type are now all part of the URI: - -| URI | fileder path | facet name | type | -| ---------------------------------------------- | ------------------ | --------------- | ------------------------------ | -| `/fileder/facet: type/subtype -> wrapped/type` | `/path/to/fileder` | `facet` | `type/subtype -> wrapped/type` | -| `/fileder/: some/type` | `/fileder` | (default facet) | `some/type` | -| `/fileder/alternate:` | `/fileder` | `alternate` | `text/html` (default type) | -| `/path` | `/path` | (default facet) | `text/html` (default type) | -| `/` | `/` | (default facet) | `text/html` (default type) | - -The fileder-index metadata was moved to a `?index` 'pseudofacet' (e.g. `/fileder/?index`). - -**EDIT 2019-10-09:** -> I will take this chance to show and hopefully explain the point of this all again: -> With the system running it is now possible to demonstrate the type-coercion that powers the system. -> -> In the system, every piece of data (the *facet*s) is stored together with it's *type*. -> When requesting data, it can of course be loaded with that *type*, yielding the data unmodified, -> but it is also possible to demand a different *type* that may be more useful to the receiving application. -> -> as an example we can take for example this article about one of the internal libraries for writing HTML documents: -> [`/meta/mmm.dom/`](/meta/mmm.dom/). -> -> The path `/meta/mmm.dom/` corresponds, according to the table above, to the default facet of the `/meta/mmm.dom` fileder, -> and since no type was specified, it is assumed that the browser wants a `text/html` document. -> The follwing path gives the same result, but makes this explicit: -> [`/meta/mmm.dom/:text/html`](/meta/mmm.dom/:text/html) -> -> now, instead of asking for the rendered HTML document, we can also ask for the source, which is of the type -> `text/moonscript -> mmm/dom` (a Moonscript file that evaluates to a website-fragment): -> [`meta/mmm.dom/:text/moonscript -> mmm/dom`](/meta/mmm.dom/:text/moonscript%20-%3E%20mmm/dom) -> -> the source code was written in MoonScript, which compiles to Lua before it is executed. -> We can also ask the server to do that for us: -> `text/lua -> mmm/dom` (a Lua file that evaluates to a website-fragment): -> [`meta/mmm.dom/:text/lua -> mmm/dom`](/meta/mmm.dom/:text/lua%20-%3E%20mmm/dom) -> -> or, we could ask for the generated html fragment, but without the full HTML layout around it - -> that would be the type `text/html+frag`, as mentioned in the last post: -> [`meta/mmm.dom/:text/html+frag`](/meta/mmm.dom/:text/html+frag) -> -> lastly, we could also ask the system to generate a link to this content, in the `text/html` format (`URL -> text/html`): -> [`meta/mmm.dom/:URL -> text/html`](/meta/mmm.dom/:URL%20-%3E%20text/html) -> this might seem somewhat redundant, since we need a link to access this link, -> but it can be useful when a component cannot work with binary data directly, e.g. when mentioning or embedding an image -> or a video file. - -I also added support to the server for serving static assets (e.g. the CSS stylesheet) from the `static` directory. -These files are accessible through the `/.static/` route (e.g. `/.static/main.css`), where they shouldn't interfere -with the mmmfs contents. -With the layout adjsuted to use these new paths, the live server now looks properly styled again too! - -Finally I worked on the Dockerfile and my deployment a bit, -so that my updates to the code will now be automatically applied to my test site, -which is available at [ba.s-ol.nu](//ba.s-ol.nu) (which might be where you are reading this right now!). diff --git a/root/research/mmmfs/ba_log/2019-10-09/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-09/text$markdown.md deleted file mode 100644 index 702620d..0000000 --- a/root/research/mmmfs/ba_log/2019-10-09/text$markdown.md +++ /dev/null @@ -1,9 +0,0 @@ -I added another driver/store that loads files straight from disk \[[`86bbe80`][86bbe80]\], -and made the server load the fileder tree when it receives a request for content, rather than loading the whole tree up front. -This means that I can work on the content again and see changes in the browser without restarting the server every time \[[`97bc4a0`][97bc4a0]\], -This feature should be made unnecessary by the in-page editing feature, but until then it's important for my workflow. - -I also started cleaning up the mmmfs article a bit, and integrating this project log in a way that will make it available online soon. - -[86bbe80]: https://git.s-ol.nu/mmm/commit/86bbe805a7ec49a8b891412713ea43d6e46d0d73/ -[97bc4a0]: https://git.s-ol.nu/mmm/commit/97bc4a0d8d866026905eac6f0ba08b75f166219a/ diff --git a/root/research/mmmfs/ba_log/2019-10-10/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-10/text$markdown.md deleted file mode 100644 index c207b83..0000000 --- a/root/research/mmmfs/ba_log/2019-10-10/text$markdown.md +++ /dev/null @@ -1,46 +0,0 @@ -Today I moved the static resources needed by the web-frontend into the content of the mmmfs itself: -The server doesn't make an exception for static files anymore (as described in [a previous update][2019-10-08]), -but rather the files are just in a fileder called `static` now, and properly typed, here: - -- [/static/style/](/static/style/:%20text/html+interactive) -- [/static/mmm/](/static/mmm/:%20text/html+interactive) - -This removed a big exception and left the server implementation much cleaner and shorter, as can be seen in the corresponding commit [`005cc9b`][005cc9b]. - -I also changed the route syntax introduced in [`2019-10-08`][2019-10-08] for getting the fileder index, -now instead of being hard-coded to return a JSON value at `?index` \[[`b36a1a6`][b36a1a6]\]. -`?index` is treated as a pseudo-facet that can be requested in different types, just like real facets. -I also added a second pseudo-facet `?tree`, which works like `?index`, except that it recurses and includes -all content below the current fileder, rather than just including the child-fileders. - -Here are some example links for viewing these: - -- [`/?index: text/html`](/?index:%20text/html) -- [`/research/mmmfs/ba_log/?index: text/html`](/research/mmmfs/ba_log/?index:%20text/html) - -Finally I added a third pseudo-facet called `?interactive` that renders the Inspector that the old page ran on, -allowing to inspect raw facets, and bringing back the navbar \[[`9ab2f0f`][9ab2f0f]\]. - -Now that there was a way to serve the Browser to the client again, I got to work on fixing it there. -This involved a bigger changes in the shared mmm internals: - -Up to this point, for each request to render a fileder, the server would load that fileder, -with all its facets and their values, as well as all children and their facets and children recursively. -That means that when the root fileder is rendered, currently 120MB of data have to be loaded from disk (or a database). -Now that the client can render content within the web browser again, that would be even worse due to the network delay. - -To solve this, the Fileder implementation now lazy-loads \[[`9632233`][9632233]\]. -When a Fileder is created, it initially knows only its path, but doesn't know which facets or children it contains. -As soon as that data is attempted to be accessed, the fileder loads in the list of its children and facets from the datastore. -The facet contents are loaded only when they are actually needed to fulfill a data request or conversion. - -With this need for optimization taken care of, I added a new datastore (`web`) \[[`91546d1`][91546d1]\], that can run on the client. -Instead of directly accessing a database or physical file system, like the `sql` and `fs` stores, the `web` store delegates all -requests to the server APIs I have been building, such as the new `?index` pseudo-facet. - -[2019-10-08]: /research/mmmfs/ba_log/2019-10-08/ -[005cc9b]: https://git.s-ol.nu/mmm/commit/005cc9b3914128267017620984aee921999e173f/ -[b36a1a6]: https://git.s-ol.nu/mmm/commit/b36a1a6c61a6e8bff156ce4e2dc66fe8ed8cd95e/ -[9ab2f0f]: https://git.s-ol.nu/mmm/commit/9ab2f0fe3a1a043300536a057bafe5058d987d7f/ -[9632233]: https://git.s-ol.nu/mmm/commit/9632233c16a26f017c648faf36a6b26833e62f2e/ -[91546d1]: https://git.s-ol.nu/mmm/commit/91546d12919736b08567d7174bf1063cab0838f0/ diff --git a/root/research/mmmfs/ba_log/2019-10-11/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-11/text$markdown.md deleted file mode 100644 index 0b58c75..0000000 --- a/root/research/mmmfs/ba_log/2019-10-11/text$markdown.md +++ /dev/null @@ -1,30 +0,0 @@ -Yesterday I got client-side access to the whole mmmfs tree to work via the new `web` datastore, -but the requests were still extremely inefficient. -This was because the organisation of the interface between the `Fileder` implementation and the datastore, -which required the Fileder to make two separate requests to `?index` to fetch its children and facets, -and also couldn't take advantage of the `?tree` pseudo-facet to bundle together multiple indexes in a single request. - -To fix this I added a new datastore method called `get_index` that returns both facet and child information \[[`e2a4257`][e2a4257]\] -The Fileder implementation now uses this method instead of asking individually for the two pieces of information -when lazy-loading fileder contents. -The `get_index` method can also be instructed to recursively load to a fixed depth. -A Fileder can also be instantiated using such a nested index, -which causes it to immediately preload up to the same depth without the need for fetching more data. -This allows some more optimizations, like having the client preload 3-levels deep when it launches, -which seems like a decent heuristic of the data actually required for most pages and minimizes load time. - -I also added some tests for the `Key` class that I use in many different places to represent facet names and types \[[`782d072`][782d072]\]]. - -The `?interactive` pseudo-facet from yesterday was changed to the `text/html+interactive` type instead \[[`8cdf5d4`][8cdf5d4]\]. -This was a bit of a tough decision, because it is a bit un-idiomatic: rendering the browser page still requires an exception in the browser. -In the end the motivation for the change was that it should be possible, -for user ergonomics, to link to the interactive view of a given facet of a given fileder. -With `?interactive` being a facet, it wasn't possible to specify the facet without jumping out of the adressing system. -With these updates on the other hand it is possible to link fo example: - -- to the main content of the root fileder, as an interactive view: [`/: text/html+interactive`](/:%20text/html+interactive) -- to the page title of the root fileder, as an interactive view: [`/title: text/html+interactive`](/title:%20text/html+interactive) - -[e2a4257]: https://git.s-ol.nu/mmm/commit/e2a4257fc05d37822df2b7bbe0f587645375edf2/ -[782d072]: https://git.s-ol.nu/mmm/commit/782d0725f3f29eaa7d4a12213fb00c6643795348/ -[8cdf5d4]: https://git.s-ol.nu/mmm/commit/8cdf5d4a363ba99a6356e7e1dfe0dfb39e6fb13e/ diff --git a/root/research/mmmfs/ba_log/2019-10-14/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-14/text$markdown.md deleted file mode 100644 index e42f8be..0000000 --- a/root/research/mmmfs/ba_log/2019-10-14/text$markdown.md +++ /dev/null @@ -1,101 +0,0 @@ -I finally added a better type-conversion-path-finding algorithm \[[`deb21aa`][deb21aa]\]. -The old algorithm only took into consideration how many steps it took to get from type A (stored on disk) to type B (requested). -This could lead to problems, for example in this situation: - -On Disk: `text/moonscript -> fn -> mmm/dom` (a moonscript file that contains a function that returns a bit of UI) -Requested: `mmm/dom` -Known Conversions: -1. `text/moonscript` to `mmm/dom` (displays the source code with highlighting) -2. `text/moonscript -> ???` to `???` (evaluates the moonscript file) -3. `fn -> ???` to `???` (calls the function, providing access to children and other facets) - -Since conversion 1 only takes a single step, it would have been preferred by the old algorithm (although there were workarounds for this). -The new algorithm adds the concept of conversion-cost, that has to be specified for each conversion. -The conversions 2 and 3 now have a cost of `1`, while conversion 1 has a cost of `5`. -The conversions are simply added up and the path with the lowest cost is chosen. -Like in other pathfinding applications like digital games, the cost metric is also used by the algorithm to enhance the search itself, -it prioritises searching further on the path with the least current cost. - -To implement this optimization I implemented a priority queue: - - -- a priority queue with an index - -- only one element with a given key may exist at a time - -- when an element with an existing key is added, - -- the element with lower priority survives. - class Queue - new: => - @values = {} - @index = {} - - -- add a value with a given priority to the queue - -- if no key is specified, assume the element is uniq - add: (value, priority, key) => - entry = { :value, :key, :priority } - - if key - if old_entry = @index[key] - -- already have an entry for this key - -- if it is lower priority, we leave it there and do nothing - if old_entry.priority < priority - return - - -- otherwise we remove the old one and continue as normal - -- find the index of the old entry - local i - for ii, entry in ipairs @values - if entry == old_entry - i = ii - break - - -- remove it - table.remove @values, i - - -- store this entry in the index - @index[key] = entry - - -- store lowest priority last - for i, v in ipairs @values - if v.priority < priority - -- i is the first key that is lower, - -- we want to insert right before it - table.insert @values, i, entry - return - - -- couldn't find a key with a lower priority, - -- so insert at the end - table.insert @values, entry - - peek: => - entry = @values[#@values] - if entry - { :value, :priority, :key } = entry - @index[key] = nil if key - value, priority - - pop: => - entry = table.remove @values - if entry - { :value, :priority, :key } = entry - @index[key] = nil if key - value, priority - - -- iterator, yields (value, priority), low priority first - poll: => @.pop, @ - - { - :Queue - } - -This priority queue behaves mostly as expected, but I added an extra feature to make sure that only the -best conversion path to a specific type is considered for further searching: -When adding a new element to the Queue, an extra `key` can be passed. -If a key is passed, the Queue makes sure that there is only ever one element with that key in the queue. -When a second element would be introduced, the queue discards whichever element has a higher priority value. - -This way I can use the type that a conversion path leads to as the key, -and the queue will automatically discard a worse solution if a better one is found that leads to the same type result. - -To make sure the Queue implementation was solid, I also added unit tests for it: [`spec/queue_spec.moon`][spec] - -[deb21aa]: https://git.s-ol.nu/mmm/commit/deb21aa43fe8bf11eb276803973b272913b7e716/ -[spec]: https://git.s-ol.nu/mmm/blob/deb21aa43fe8bf11eb276803973b272913b7e716/spec/queue_spec.moon diff --git a/root/research/mmmfs/ba_log/2019-10-15/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-15/text$markdown.md deleted file mode 100644 index 7e5ee02..0000000 --- a/root/research/mmmfs/ba_log/2019-10-15/text$markdown.md +++ /dev/null @@ -1,70 +0,0 @@ -I'm giving a workshop next weekend, and I had to create the slides for that. -Since one of the aspirations of `mmmfs` is to be easily adaptable to any kind of data organization and -presentation task, -that was a good opportunity to try and implement a simple slideshow system. - -I started by creating a new fileder to hold the slideshow, [`/workshops/xy-music`](/workshops/xy-music/). -In the main facet, I created a MoonScript file. -Since the facet needs to access its children (the individual slides), I also used the `fn ->` type, -that injects the current fileder into the script. - -`text/moonscript -> fn -> mmm/dom` - - import ReactiveVar, tohtml, fromhtml, text, elements from require 'mmm.component' - import article, button, div, span from elements - - => - index = ReactiveVar 1 - slide = index\map (index) -> @children[index] - - local view - view = div { - style: ... -- styling ommited here - - div { - style: ... -- styling omitted here - - slide\map => @get 'mmm/dom' - } - } - - local left, right - if MODE == 'CLIENT' - left = (_, e) -> - e\preventDefault! - index\transform (a) -> math.max 1, a - 1 - - right = (_, e) -> - e\preventDefault! - index\transform (a) -> math.min #@children, a + 1 - - tohtml with article! - \append div { - button '<', onclick: left - ' ' - span index\map (t) -> text t - ' ' - button '>', onclick: right - } - \append view - -I used the `mmm.component` library that lets me create reactive UIs. -First I declare the reactive variable `index`, the current slide number. -Then I derive the `slide` reactive variable, that is defined to be the child with index `index` - -since these are `ReactiveVar`s, whenever `index` changes, `slide` will automatically load the current slide fileder. - -Then I create the main slide view, which consists mainly of two containers and some styling. -Inside, I derive another reactivevar from `slide`: whenever a new `slide` is selected, -this piece of code will request the main content in `mmm/dom` format and replace the current view content with that. - -Lastly I construct a little navigation UI, consisting of the left and right buttons. -When one of them is clicked, it modifies the `index` variable, making sure to stay in the range of existing slides. -The rest of the UI then reactively updates accordingly. - -Lastly I added keyboard controls for cycling through the slides, as well as a button to enter fullscreen mode. -You can find the extended code for that in the commit [`ca24ef1`][ca24ef1], -but it is not a lot either: with the additions the file is 70 lines long. - -With this done, it is just a matter of creating children-fileders and placing whichever content I want in them, -they behave just like any other page of the system now. - -[ca24ef1]: https://git.s-ol.nu/mmm/blob/ca24ef108dbb11860e719711e4e7fbd6323aee0e/root/articles/xy-workshop/text%24moonscript%20-%3E%20fn%20-%3E%20mmm%24dom.moon diff --git a/root/research/mmmfs/ba_log/2019-10-24/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-24/text$markdown.md deleted file mode 100644 index 8a2fe2b..0000000 --- a/root/research/mmmfs/ba_log/2019-10-24/text$markdown.md +++ /dev/null @@ -1,32 +0,0 @@ -While writing some of the main section of the thesis today, -I felt the need to illustrate some subject matter with a diagram depicting a folder structure. -Knowing of some similar tools that generate SVG diagrams from textual descriptions, -some quick research turned up [mermaid JS][mermaid]. - -I tried it in their online live editor first to verify that it would indeed do what I needed it to, -and then added it to the set of supported types in mmm (on the clientside only) \[[`2ff6f90`][2ff6f90]\]. -This was pretty easy in the end, all it took was adding mermaid.js to the interactive version's resources (in `build/server.moon`) -and then definig the `convert` (and thereby implicitly defining the corresponding type, `text/mermaid-graph`): - - { - inp: 'text/mermaid-graph' - out: 'mmm/dom' - cost: 1 - transform: (source) => - with container = document\createElement 'div' - cb = (svg, two) => - .innerHTML = svg - window.mermaid\render "mermaid-#{id_counter}", source, cb - } - -The code is quite short, since all it needs to do is create a container element, -then tell mermaid.js to render the textual definition. -Once mermaid.js is done, the rendered content is added in the container element. - -Here is one of the two diagrams that I implemented the feature for, -you can also follow the link through to the source and view the textual representation using the 'inspect' button. - -<mmm-embed path="/research/mmmfs/mmmfs/tree_mainstream"></mmm-embed> - -[mermaid]: https://mermaidjs.github.io/mermaid-live-editor/ -[2ff6f90]: https://git.s-ol.nu/mmm/commit/2ff6f906c498c1b742dd8437a09c97ebe29a652a/ diff --git a/root/research/mmmfs/ba_log/2019-10-26/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-26/text$markdown.md deleted file mode 100644 index ff97871..0000000 --- a/root/research/mmmfs/ba_log/2019-10-26/text$markdown.md +++ /dev/null @@ -1,62 +0,0 @@ -Besides some smaller fixes with the styling of the page, and in particular the diagrams introduced in [`2019-10-24`][2019-10-24], -I finally (re-)implemented children-ordering in the `fs`-store of mmmmfs -(the `sql` store is still missing it, but I am not currently using it either) \[[`a62f63b`][a62f63b]\]: -Files on the regular filesystem don't have a particular order, but in mmmfs the order of children is is guaranteed, -so that arranging children in a particular order becomes a meaningful tool. - -To store the ordering data, a 'magic' file called `$order` is (optionally) stored in each directory in the filesystem. -The file lists all child fileders by name in the given order. -When the children of a fileder are requested (in `list_fileders_in` or `get_index`, which relies on the former), -all children that are mentioned in `$order` are returned in that order, -while all remaining children are sorted alphabetically and appended at the end of the list. -This way the order is guaranteed to be stable even if no `$order` file is specified, -or when the `$order` file has not been updated after adding new children. - -Here is the commented implementation in MoonScript: - - list_fileders_in: (path='') => - -- create a mapping of all child-fileders - -- in 'entries' (name -> path) - entries = {} - for entry_name in lfs.dir @root .. path - continue if '.' == entry_name\sub 1, 1 - entry_path = @root .. "#{path}/#{entry_name}" - if 'directory' ~= lfs.attributes entry_path, 'mode' - continue - - entries[entry_name] = "#{path}/#{entry_name}" - - -- where we will store our sorted list of children - sorted = {} - - -- check for existance of the order file - order_file = @root .. "#{path}/$order" - if 'file' == lfs.attributes order_file, 'mode' - for line in io.lines order_file - path = assert entries[line], "entry in $order but not on disk: #{line}" - - -- add all $order-entries to the sorted output in the same order they appear. - -- also flag these entries as already added - table.insert sorted, path - sorted[line] = true - - -- find the he remaining (non-flagged) entries, sort them alphabetically - -- and then append them to the sorted output list - entries = [path for entry, path in pairs entries when not sorted[entry]] - table.sort entries - for path in *entries - table.insert sorted, path - - -- return an iterator over the sorted output - coroutine.wrap -> - for path in *sorted - coroutine.yield path - -The interface for reordering fileders is still missing in the code, -and just while writing this I realized that the current implementation is in fact buggy: -when a fileder that is mentioned in `$order` is deleted via the `stores.fs` API, -it is not removed from `$order`, causing an error the next time the fileder is listed. -I will probably get around to fixing both of these problems when I build the corresponding UI. - -[2019-10-24]: /research/mmmfs/ba_log/2019-10-24/ -[a62f63b]: https://git.s-ol.nu/mmm/commit/a62f63bc00cd63a98b349a2574e3e9e14c95a441/ diff --git a/root/research/mmmfs/ba_log/2019-10-27/$order b/root/research/mmmfs/ba_log/2019-10-27/$order deleted file mode 100644 index 2b68b52..0000000 --- a/root/research/mmmfs/ba_log/2019-10-27/$order +++ /dev/null @@ -1 +0,0 @@ -video diff --git a/root/research/mmmfs/ba_log/2019-10-27/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-27/text$markdown.md deleted file mode 100644 index 3e9f886..0000000 --- a/root/research/mmmfs/ba_log/2019-10-27/text$markdown.md +++ /dev/null @@ -1,77 +0,0 @@ -Today I finally reached the ability of editing content inside of mmmfs directly! - -<mmm-embed path="video" nolink></mmm-embed> - -Content is currently not saved anywhere, but the basis of the feature is there. -For the moment this is implemented as yeat another *convert* that simply converts -from `text/.*` (any textual code) to `mmm/dom` (web UI) \[[`28653c9`][28653c9]\]. -However this *convert* is only applied in the inspector view (more on that below). -First, here is the convert itself: - - { - inp: 'text/([^ ]*).*' - out: 'mmm/dom' - cost: 0 - transform: (value, fileder, key) => - mode = @from\match @convert.inp - Editor value, mode, fileder, key - } - -and the main part of the code, the `Editor` widget: - -```moonscript -class Editor - new: (value, mode, @fileder, @key) => - @node = div class: 'editor' - -- 'o' is a little helper for converting a Lua table to a JS object - @cm = window\CodeMirror @node, o { - :value - :mode - lineNumber: true - lineWrapping: true - autoRefresh: true - theme: 'hybrid' - } - - @cm\on 'changes', (_, mirr) -> - window\clearTimeout @timeout if @timeout - @timeout = window\setTimeout (-> @change!), 300 - - change: => - @timeout = nil - doc = @cm\getDoc! - if @lastState and doc\isClean @lastState - -- no changes since last event - return - - @lastState = doc\changeGeneration true - value = doc\getValue! - - @fileder.facets[@key] = value - BROWSER\refresh! -``` - -I chose the [CodeMirror][codemirror] library as the basis for the editor, -because it seemed like one of the leanest ones I could find -(and yet it is quite heavy at 100kb plus styling and language support addons). -The code for the editor is also quite minimale it really just creates a wrapper for the editor -and tells CodeMirror to set itself up inside. -Whenever changes are detected, a timeout of 300ms is started, -after which the preview is refreshed to preview the changes. -If more changes are made within the 300ms, the timer is reset to 300ms, -so that the preview update doesn't interrupt the typing flow. - -I also spent some time refactoring the global list of converts out into multiple smaller plugins -(although a lot of global converts remain at the moment) \[[`abefbf8`][abefbf8]\]. -A plugin can export a list of converts as well as a list of 'editors', which are essentially no different, -except that they are taken into consideration only when converting content for the inspector. - -Breaking the converts up into little packages like that makes it a lot easier to edit, -and allows enabling and disabling individual features very easily. -I am also considering moving the converts into the mmmfs data itself, -to make extending the system and working inside the system more congruent, -and this is a good way of testing my idea of how the modularization of the system should work. - -[codemirror]: https://codemirror.net/ -[28653c9]: https://git.s-ol.nu/mmm/commit/28653c9ae46b2b3e42c2c75879589138c731f37b/ -[abefbf8]: https://git.s-ol.nu/mmm/commit/abefbf82531021f5ca4149675932a7fe2ff37dde/ diff --git a/root/research/mmmfs/ba_log/2019-10-27/video/video$webm.webm b/root/research/mmmfs/ba_log/2019-10-27/video/video$webm.webm Binary files differdeleted file mode 100644 index 020e352..0000000 --- a/root/research/mmmfs/ba_log/2019-10-27/video/video$webm.webm +++ /dev/null diff --git a/root/research/mmmfs/ba_log/2019-10-29/$order b/root/research/mmmfs/ba_log/2019-10-29/$order deleted file mode 100644 index 2b68b52..0000000 --- a/root/research/mmmfs/ba_log/2019-10-29/$order +++ /dev/null @@ -1 +0,0 @@ -video diff --git a/root/research/mmmfs/ba_log/2019-10-29/text$markdown.md b/root/research/mmmfs/ba_log/2019-10-29/text$markdown.md deleted file mode 100644 index 4119d21..0000000 --- a/root/research/mmmfs/ba_log/2019-10-29/text$markdown.md +++ /dev/null @@ -1,38 +0,0 @@ -Today I implemented updating/saving content in the server, and bridged the feature to the client. -In the inspector there is now a `save changes` button that (attempts to) save the content on -the server's filesystem \[[`4b8d9be`][4b8d9be]\]. - -<mmm-embed path="video" nolink>demonstration of editing and persistantly saving facet</mmm-embed> - -Originally I wanted to create a `sandbox` fileder that was to be edited by any one online \[[`d9eafa2`][d9eafa2]\]. -I restricted editing to only fileders underneath `/sandbox`, but then upon publishing quickly realized -that this left open a major security vulnerability, since content can be evaluated on server or client: -if a client were to create a facet `exploit: text/lua -> text/plain` with the following content in the root: - -```lua -pass = io.open('/etc/passwd', 'r') -return pass:read("*all") -``` - -...and then request that facet as converted to `text/plain` (`GET /exploit: text/plain`), -then that Lua code would be executed on the server, and return the confidential `passwd` file on the server. -This basically meant handing anyone online full unconditionaly access to my server -(or at least the VM running the website, and potentially options to escalate from there). - -As a result I had to choose to either disable public editing, or disable server-side code execution. -Because server-side execution is a major feature of mmmfs, I settled for the following compromise \[[`1e3b0a1`][1e3b0a1]\]: - -- when developing and running locally, editing and code execution are both enabled in 'unsafe mode' -- on https://ba.s-ol.nu, editing is disabled but code execution is possible -- on https://sandbox.s-ol.nu, editing is enabled but code server-side code execution is disabled - -The Sandbox can now be found at the following address, at least until the thesis project is concluded: - -# [`sandbox.s-ol.nu`](https://sandbox.s-ol.nu) - -Currently it is only possible to edit existing facets, -but creation and deletion of facets and fileders should be implemented soon. - -[4b8d9be]: https://git.s-ol.nu/mmm/commit/4b8d9be10e4517114c0c216fa24aaaa310503d4a/ -[d9eafa2]: https://git.s-ol.nu/mmm/commit/d9eafa21ad1d6ad340b5744d69e9fc68ce2083cb/ -[1e3b0a1]: https://git.s-ol.nu/mmm/commit/1e3b0a12060dce916b686921c94520202c4cb130/ diff --git a/root/research/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4 b/root/research/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4 Binary files differdeleted file mode 100644 index 162d0fc..0000000 --- a/root/research/mmmfs/ba_log/2019-10-29/video/video$mp4.mp4 +++ /dev/null diff --git a/root/research/mmmfs/ba_log/2019-11-01/$order b/root/research/mmmfs/ba_log/2019-11-01/$order deleted file mode 100644 index 1549b67..0000000 --- a/root/research/mmmfs/ba_log/2019-11-01/$order +++ /dev/null @@ -1 +0,0 @@ -demo diff --git a/root/research/mmmfs/ba_log/2019-11-01/demo/video$webm.webm b/root/research/mmmfs/ba_log/2019-11-01/demo/video$webm.webm Binary files differdeleted file mode 100644 index 1463897..0000000 --- a/root/research/mmmfs/ba_log/2019-11-01/demo/video$webm.webm +++ /dev/null diff --git a/root/research/mmmfs/ba_log/2019-11-01/text$markdown.md b/root/research/mmmfs/ba_log/2019-11-01/text$markdown.md deleted file mode 100644 index c9c4214..0000000 --- a/root/research/mmmfs/ba_log/2019-11-01/text$markdown.md +++ /dev/null @@ -1,18 +0,0 @@ -In the last two days I implemented the remaining features for full editing support in the browser: - -- support for adding, removing facets in the inspector \[[`dc08e26`][dc08e26]\] -- support for adding, removing fileders in the inspector \[[`ff9ee8e`][ff9ee8e]\] -- implemented the API for reordering fileders as mentioned in [`2019-10-26`][2019-10-26] \[[`053e607`][053e607]\] -- support for reordering fileders in the inspector \[[`16232a2`][16232a2]\] - -Here is a short demo video of these features: - -<mmm-embed nolink path="demo"></mmm-embed> - -As usual, this can be tried out immediately at [`sandbox.s-ol.nu`](//sandbox.s-ol.nu) - -[2019-10-26]: /research/mmmfs/ba_log/2019-10-26/ -[dc08e26]: https://git.s-ol.nu/mmm/commit/dc08e262cd53a48480a88235aa58500f0638ad79/ -[ff9ee8e]: https://git.s-ol.nu/mmm/commit/ff9ee8e99cd5f5c420ba0501c335ac18f1b10769/ -[053e607]: https://git.s-ol.nu/mmm/commit/053e607a49989b2d4491c20ff14c839b7161d713/ -[16232a2]: https://git.s-ol.nu/mmm/commit/16232a2509a87a900b69b2d0f826a2e3edec3f96/ diff --git a/root/research/mmmfs/ba_log/2019-11-25/$order b/root/research/mmmfs/ba_log/2019-11-25/$order deleted file mode 100644 index 1549b67..0000000 --- a/root/research/mmmfs/ba_log/2019-11-25/$order +++ /dev/null @@ -1 +0,0 @@ -demo diff --git a/root/research/mmmfs/ba_log/2019-11-25/demo/video$webm.webm b/root/research/mmmfs/ba_log/2019-11-25/demo/video$webm.webm Binary files differdeleted file mode 100644 index bdf9d9c..0000000 --- a/root/research/mmmfs/ba_log/2019-11-25/demo/video$webm.webm +++ /dev/null diff --git a/root/research/mmmfs/ba_log/2019-11-25/text$markdown.md b/root/research/mmmfs/ba_log/2019-11-25/text$markdown.md deleted file mode 100644 index e458b51..0000000 --- a/root/research/mmmfs/ba_log/2019-11-25/text$markdown.md +++ /dev/null @@ -1,89 +0,0 @@ -There was a longer break in development of the projects as I have been focusing on the thesis, -where progress is not represented accurately in the repository. - -There was also some progress on featurse that haven't been tidied up and committed yet, -such as drag'n'drop / direct file upload. Those features will probably get their own post sometime soon. - -Today I spent some time to implement one of the example use-cases that will be part of the theoretical text as well, -[the 'pinwall' demo][pinwall] \[[`5ec1fe2`][5ec1fe2]\]. - -The Pinwall example renders all its children as resizeable and movable boxes that can be freely positioned on a canvas: - -<mmm-embed nolink path="demo"></mmm-embed> - -Any changes to the box positions and sizes are saved persistently as a `pinwall_info` facet on each child. -For example the size and coordinates of the image can be found at [`image/pinwall_info: text/json`][info]. - -Rendering the children themselves is pretty easy: - -```moon -import article, div from require 'mmm.dom' -import convert from require 'mmm.mmmfs.conversion' - -update_info = (fileder, x, y, w, h) -> - info = (fileder\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300 - info.x = x if x - info.y = y if y - info.w = w if w - info.h = h if h - - json = convert 'table', 'text/json', info, fileder, 'pinwall_info' - fileder\set 'pinwall_info: text/json', json - -=> - observe = ... -- (ommited - calls `update_info` when child is resized) - - children = for child in *@children - info = (child\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300 - wrapper = div { - style: - position: 'absolute' - -- (more styling omitted here) - - left: "#{info.x}px" - top: "#{info.y}px" - width: "#{info.w}px" - height: "#{info.h}px" - - -- handle for moving the child - div { - style: - -- (styling omitted here) - - onmousedown: ... -- (omitted) - } - - -- child content - div { - style: - width: '100%' - height: '100%' - background: 'var(--white)' - - (child\gett 'mmm/dom') - } - } - - observe wrapper, child - - wrapper - - children.style = { - width: '1000px' - height: '500px' - } - - children.onmouseup = ... -- (omitted) - children.onmousemove = ... -- (omitted) - children.onmouseleave = ... -- (omitted) - - article children -``` - -[The rest of the code][source] is just about catching the events when the mouse is clicked/release/moved and when a child is resized, -and then calling `update_info` as appropriate. - -[info]: /research/mmmfs/examples/pinwall/image/pinwall_info:%20text/html+interactive -[pinwall]: /research/mmmfs/examples/pinwall/ -[source]: https://git.s-ol.nu/mmm/blob/5ec1fe2fc943ad4123fac138de70d4152e8b341d/root/research/mmmfs/examples/pinwall/text%24moonscript%20-%3E%20fn%20-%3E%20mmm%24dom.moon -[5ec1fe2]: https://git.s-ol.nu/mmm/blob/5ec1fe2fc943ad4123fac138de70d4152e8b341d/ diff --git a/root/research/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md b/root/research/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md deleted file mode 100644 index 3de1a9c..0000000 --- a/root/research/mmmfs/ba_log/2019-12-20/text$markdown+sidenotes.md +++ /dev/null @@ -1,39 +0,0 @@ -In the last three days I have been working extensively on support for sidenotes and academic referencing, -inspired by Edward Tufte's style of publishing (as seen in *Beatiful Evidence* and documented in [tufte-css][tufte-css]. - -To this end margin-notes have been implemented in the CSS styling of the page using two classes, `sidenote` and -`sidenote-container`, which are to be applied to individual sidenotes and the containing document respectively. -Sidenotes are then pulled out of their surrounding context using `position: absolute` and placed in a margin that is -left free by `sidenote-container`. - -Inside of markdown files, sidenotes can then be added simply using basic HTML, like so: - -```md -<div class="sidenote">additional information to be found on the margin</div> -An example paragraph of text, describing something. -``` - -Which will render like this: - -> <div class="sidenote">additional information to be found on the margin</div> -> An example paragraph of text, describing something. - -Additionally, conversions from `text/bibtex`, a reference specification format, to `mmm/dom` have been added, that -create citations using the metadata available in the BibTeX file. - -For example the following BibTeX is rendered like this: - -<mmm-embed nolink path="../../references/inkandswitch" facet="markdown"></mmm-embed> - -> <mmm-embed wrap="raw" path="../../references/inkandswitch"></mmm-embed> - -I also added a special override that links to -BibTeX files by placing the citation in a sidenote, and adding a footnote indicator in-text. - -There is also a handy convert that turns ACM Digital Library links into URLs that directly return the BibTeX file, -which allows me to cite the links directly without manually adding the BibTeX information to my document. - -All of this is implemented in the `cites` plug-in: [`cites.moon`][cites.moon]. - -[cites.moon]: https://git.s-ol.nu/mmm/blob/ba/mmm/mmmfs/plugins/cites.moon -[tufte-css]: https://edwardtufte.github.io/tufte-css/ diff --git a/root/research/mmmfs/ba_log/intro: text$markdown.md b/root/research/mmmfs/ba_log/intro: text$markdown.md deleted file mode 100644 index 37366cf..0000000 --- a/root/research/mmmfs/ba_log/intro: text$markdown.md +++ /dev/null @@ -1,4 +0,0 @@ -The following pages document the development of the `mmmfs` system described above in the form of a project log. -Please note that the log has been written primarily for viewing using a web browser, and as such makes extensive use of -hyperlinking, and also includes some videos that cannot be reproduced in print. It is therefore recommended to view the -live version of the log online at the following address: [s-ol.nu/ba/log](https://s-ol.nu/ba/log). diff --git a/root/research/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 97ebd4c..0000000 --- a/root/research/mmmfs/ba_log/print: text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,19 +0,0 @@ -import div, section, h1, h2, hr from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' -import ropairs from require 'mmm.ordered' - -=> - div { - class: 'print-ownpage' - - h1 (link_to @, "appendix: project log"), id: 'ba-log' - @gett 'intro: mmm/dom' - table.unpack for post in *@children - continue if post\get 'hidden: bool' - - section { - hr! - h2 link_to post, post\gett 'name: mmm/dom' - (post\gett 'mmm/dom') - } - } diff --git a/root/research/mmmfs/ba_log/start/text$markdown.md b/root/research/mmmfs/ba_log/start/text$markdown.md deleted file mode 100644 index d56130b..0000000 --- a/root/research/mmmfs/ba_log/start/text$markdown.md +++ /dev/null @@ -1,25 +0,0 @@ -The system described in the thesis and subject to the following blog posts was partially pre-existing to the work -done as part of the thesis and thesis project. The `mmmfs` system was originally developed as the software for my -personal website, with development beginning around May 2018. In this phase of development the website and system -changed shape drastically multiple times. In the following paragraphs I will describe the state of the project at -the last revision prior to the beginning of the thesis project, as it existed before the 7th of October 2019. -All developments since this revision have been tracked in the following project log entries, and are to be considered -the practical contributions to the thesis project. - -In this revision, the system existed as a tool to produce a static website representing the contents of the `mmmfs` -system in browsable HTML format. The tool had to be run manually after changes, or using a build tool like [`tup`][tup]. -A primitive *Inspector* tab was present in the HTML output and allowed viewing the raw `mmmfs` contents, but all editing -of content had to be done with external tools and in the external file-system. To see changes in the browser, a -compilation phase had to be triggered and completed, and consecutively the page reloaded in the browser. There was no -server-side component that could convert content or store changes for clients. The tool could only accept content from -the filesystem, not from zip archives or SQLite databases. The conversion algorithm used was more naive and was not -able to track cost values, which meant that some more advanced conversions couldn't be implemented. - -There was already an example implementation of a simple slideshow present, but due to the lack of editing capabilities -there was no pinwall examle. There was also no support for side- or marginnotes, or academic referencing and citations. -There also was no support for [`mermaid`][mermaid] diagrams or JSON-encoded data, and there was no plugin interface. -The HTML template, CSS styling and JS runtime were all built and tracked outside of the `mmmfs` system itself. -There was no unit tests for any of the project. - -[tup]: http://gittup.org/tup/ -[mermaid]: https://mermaidjs.github.io/ diff --git a/root/research/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index b6b0756..0000000 --- a/root/research/mmmfs/ba_log/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,15 +0,0 @@ -import div, h1, ul, li from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' -import ropairs from require 'mmm.ordered' - -=> - div { - h1 (link_to @, "appendix: project log"), id: 'ba-log' - @gett 'intro: mmm/dom' - ul do - posts = for post in *@children - continue if post\get 'hidden: bool' - li link_to post, post\gett 'name: mmm/dom' - - posts - } diff --git a/root/research/mmmfs/conclusion/text$markdown+sidenotes.md b/root/research/mmmfs/conclusion/text$markdown+sidenotes.md deleted file mode 100644 index 92230a0..0000000 --- a/root/research/mmmfs/conclusion/text$markdown+sidenotes.md +++ /dev/null @@ -1,11 +0,0 @@ -# 8 conclusion - -The historical analysis and the evaluation of the proposed system show that many of the limitations of current -mainstream operating systems can be worked around effectively. The flaws can also be attributed in part to some -concrete design paradigms, which future system designers may seek to avoid. To this end, the framework provided for -evaluation may also be useful. - -The system proposed and developed in the project corresponding to this thesis has been shown to successfully implement -many of the properties were hoped to be achieved, such as a modular and consistent architecture and strong support for -mixed-content transclusions. On the other hand, some limitations in the design are apparent. Many of these limitations -constitute candidate topics for further research, and most can be attributed to trade-offs made in the development process. diff --git a/root/research/mmmfs/defense/$order b/root/research/mmmfs/defense/$order deleted file mode 100644 index 278bf54..0000000 --- a/root/research/mmmfs/defense/$order +++ /dev/null @@ -1,13 +0,0 @@ -01 -02 -03a -03b -03c -04a -04b -04c -05a -05b -06 -07 -08 diff --git a/root/research/mmmfs/defense/01/text$html+frag.html b/root/research/mmmfs/defense/01/text$html+frag.html deleted file mode 100644 index f84e3b5..0000000 --- a/root/research/mmmfs/defense/01/text$html+frag.html +++ /dev/null @@ -1,8 +0,0 @@ -<div style="margin-top: 3em"> - <h2>Empowered End-User Computing</h2> - <br /> - <h4>A Historical Investigation and Development of a File-System-Based Environment</h3> - <br /> - <br /> - <p>sol bekic, 2019 - 2020</p> -</div> diff --git a/root/research/mmmfs/defense/02/text$markdown+wide.md b/root/research/mmmfs/defense/02/text$markdown+wide.md deleted file mode 100644 index e797a7a..0000000 --- a/root/research/mmmfs/defense/02/text$markdown+wide.md +++ /dev/null @@ -1,13 +0,0 @@ -what are we talking about? --------------------------- - -<br /> - -- personal computing - - journaling - - collecting, producing, organising content - - multi-format, multi-media content -- online presence - - blogging - - publishing - - project documentation diff --git a/root/research/mmmfs/defense/03a/text$markdown+wide.md b/root/research/mmmfs/defense/03a/text$markdown+wide.md deleted file mode 100644 index c3d2441..0000000 --- a/root/research/mmmfs/defense/03a/text$markdown+wide.md +++ /dev/null @@ -1,12 +0,0 @@ -design principles ------------------ - -<br /> - -### modularity (UNIX Philosophy) - -- few, strong concepts and metaphors - -- customizability - -- openness for integrations diff --git a/root/research/mmmfs/defense/03b/text$markdown+wide.md b/root/research/mmmfs/defense/03b/text$markdown+wide.md deleted file mode 100644 index cfd9e44..0000000 --- a/root/research/mmmfs/defense/03b/text$markdown+wide.md +++ /dev/null @@ -1,10 +0,0 @@ -design principles ------------------ - -<br /> - -### 'living system' (Ink & Switch) - -- small feedback loops - -- (perceived) direct manipulation of concrete entitites diff --git a/root/research/mmmfs/defense/03c/text$markdown+wide.md b/root/research/mmmfs/defense/03c/text$markdown+wide.md deleted file mode 100644 index 234caff..0000000 --- a/root/research/mmmfs/defense/03c/text$markdown+wide.md +++ /dev/null @@ -1,10 +0,0 @@ -design principles ------------------ - -<br /> - -### 'in-place toolchain' (Ink & Switch) - -- tools for creation embedded in the substrate - -- small step between 'passively using' and 'actively creating' diff --git a/root/research/mmmfs/defense/04a/text$markdown+wide.md b/root/research/mmmfs/defense/04a/text$markdown+wide.md deleted file mode 100644 index fe36f82..0000000 --- a/root/research/mmmfs/defense/04a/text$markdown+wide.md +++ /dev/null @@ -1,11 +0,0 @@ -contrast to current mainstream ------------------------------- - -<br /> - -### devs vs users - -- users access to technology inherently limited - -- developers are non-experts - - no development from practice diff --git a/root/research/mmmfs/defense/04b/text$markdown+wide.md b/root/research/mmmfs/defense/04b/text$markdown+wide.md deleted file mode 100644 index b90a203..0000000 --- a/root/research/mmmfs/defense/04b/text$markdown+wide.md +++ /dev/null @@ -1,12 +0,0 @@ -contrast to current mainstream ------------------------------- - -<br /> - -### apps vs tools - -- customer lock-in - - customizibility disincentivized - -- unhealthy competition ('NIH' syndrome) - - interoperability disincentivized diff --git a/root/research/mmmfs/defense/04c/text$markdown+wide.md b/root/research/mmmfs/defense/04c/text$markdown+wide.md deleted file mode 100644 index 14cc529..0000000 --- a/root/research/mmmfs/defense/04c/text$markdown+wide.md +++ /dev/null @@ -1,11 +0,0 @@ -contrast to current mainstream ------------------------------- - -<br /> - -### cloud vs local - -- dependence and reliability - -- literal and perceived data ownership - - file formats diff --git a/root/research/mmmfs/defense/05a/text$markdown+wide.md b/root/research/mmmfs/defense/05a/text$markdown+wide.md deleted file mode 100644 index 53c5fcf..0000000 --- a/root/research/mmmfs/defense/05a/text$markdown+wide.md +++ /dev/null @@ -1,10 +0,0 @@ -implementation concepts ------------------------ - -<br /> - -### *Fileders* and *Facets* - -<br /> - -<mmm-embed wrap="raw" path="../../mmmfs/tree_mmmfs"></mmm-embed> diff --git a/root/research/mmmfs/defense/05b/text$markdown+wide.md b/root/research/mmmfs/defense/05b/text$markdown+wide.md deleted file mode 100644 index 63a1b68..0000000 --- a/root/research/mmmfs/defense/05b/text$markdown+wide.md +++ /dev/null @@ -1,10 +0,0 @@ -implementation concepts ------------------------ - -<br /> - -### *Types* and *Type Coercion* - -<br /> - -<mmm-embed wrap="raw" path="../../mmmfs/type_coercion_graph"></mmm-embed> diff --git a/root/research/mmmfs/defense/06/text$markdown+wide.md b/root/research/mmmfs/defense/06/text$markdown+wide.md deleted file mode 100644 index caf80d4..0000000 --- a/root/research/mmmfs/defense/06/text$markdown+wide.md +++ /dev/null @@ -1,6 +0,0 @@ -demo ----- - -<br /> - -- (this presentation) diff --git a/root/research/mmmfs/defense/07/text$markdown+wide.md b/root/research/mmmfs/defense/07/text$markdown+wide.md deleted file mode 100644 index 2688f4e..0000000 --- a/root/research/mmmfs/defense/07/text$markdown+wide.md +++ /dev/null @@ -1,4 +0,0 @@ -demo ----- - -<mmm-embed wrap="raw" path="../../examples/pinwall"></mmm-embed> diff --git a/root/research/mmmfs/defense/08/$order b/root/research/mmmfs/defense/08/$order deleted file mode 100644 index 773b222..0000000 --- a/root/research/mmmfs/defense/08/$order +++ /dev/null @@ -1 +0,0 @@ -image diff --git a/root/research/mmmfs/defense/08/image/image$png.png b/root/research/mmmfs/defense/08/image/image$png.png Binary files differdeleted file mode 100644 index ff82a9d..0000000 --- a/root/research/mmmfs/defense/08/image/image$png.png +++ /dev/null diff --git a/root/research/mmmfs/defense/08/text$markdown+wide.md b/root/research/mmmfs/defense/08/text$markdown+wide.md deleted file mode 100644 index 472b796..0000000 --- a/root/research/mmmfs/defense/08/text$markdown+wide.md +++ /dev/null @@ -1,10 +0,0 @@ -demo ----- - -<br /> - -### in-system editing - -- <mmm-link path="../../examples/pinwall">the pinwall example</mmm-link> - -- (time to leave this box) diff --git a/root/research/mmmfs/defense/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/defense/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 12781b8..0000000 --- a/root/research/mmmfs/defense/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,77 +0,0 @@ -import ReactiveVar, tohtml, fromhtml, text, elements from require 'mmm.component' -import article, button, div, span from elements - -after = (promise, fn) -> - print promise - promise['then'] promise, fn - -=> - index = ReactiveVar 1 - slide = index\map (index) -> @children[index] - - local view - view = div { - style: - position: 'relative' - 'padding-top': '56.25%' - - div { - style: - position: 'absolute' - display: 'flex' - 'flex-direction': 'column' - top: 0 - left: 0 - right: 0 - bottom: 0 - padding: '1em' - background: '#eeeeee' - 'box-sizing': 'border-box' - 'text-justify': 'none' - - slide\map => @get 'mmm/dom' - } - } - - local left, right, viewNode - if MODE == 'CLIENT' - left = (_, e) -> - e\preventDefault! - index\transform (a) -> math.max 1, a - 1 - - right = (_, e) -> - e\preventDefault! - index\transform (a) -> math.min #@children, a + 1 - - viewNode = tohtml view - viewNode.tabIndex = 1 - scale = -> - size = viewNode.offsetHeight / 15 - viewNode.style.fontSize = "#{size}px" - viewNode\addEventListener 'keydown', (_, e) -> - switch e.key - when 'f' - after viewNode\requestFullscreen!, scale - when 'r' - scale! - when 'ArrowLeft' - left _, e - when 'ArrowRight' - right _, e - - tohtml with article! - \append div { - style: - display: 'flex' - - button '<', onclick: left - ' ' - span index\map (t) -> text t - ' ' - button '>', onclick: right - div style: flex: '1' - button 'fullscreen', onclick: (_, e) -> - e\preventDefault! - after viewNode\requestFullscreen!, scale - } - \append view diff --git a/root/research/mmmfs/description: text$plain b/root/research/mmmfs/description: text$plain deleted file mode 100644 index 1322f1d..0000000 --- a/root/research/mmmfs/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -a file, operating and content-management system to live in (powers this site) diff --git a/root/research/mmmfs/evaluation/text$markdown+sidenotes.md b/root/research/mmmfs/evaluation/text$markdown+sidenotes.md deleted file mode 100644 index 65024d4..0000000 --- a/root/research/mmmfs/evaluation/text$markdown+sidenotes.md +++ /dev/null @@ -1,173 +0,0 @@ -# 7 evaluation -In this section, I will first take a look at the implementations of the examples for the use cases outlined above, -and evaluate them with regard to the framework derived in the corresponding section above. After that, some general -concerns and insights that have become apparent while developing the system and working with it will be reviewed. - -## 7.1 examples -### 7.1.1 publishing and blogging -Since mmmfs has grown out of the need for a versatile content management system for a personal website and blog, it is -not surprising to see that it is still up to that job. Nevertheless, it is worth taking a look at its strengths and -weaknesses in this context: - -The system has proven itself perfect for publishing small- and medium-size articles and blog posts, especially for its -ability to flexibly transclude content from any source. This includes diagrams (such as in this thesis), -videos (as in the documentation in the appendix), but also less conventional media such as -interactive diagrams<mmm-embed path="../references/aspect-ratios" wrap="sidenote"></mmm-embed> or twitter postings. - -On the other hand, the development of the technical framework for this thesis has posed greater challenges. -While the reference and sidenote systems integrated well with the rest of the system, some features like automated -table-of-contents and section numbering were less obvious to tackle and finally completed manually. -This is mostly due to the approach of splitting up the thesis into a multitude of fileders, and the current lack of -mechanisms to re-capture information spread throughout the resulting hierarchy effectively. - -### 7.1.2 pinwall -The pinwall example shows some strengths of the mmmfs system pretty convincingly. -The type coercion layer completely abstracts away the complexities of transcluding different types of content, -and only positioning and sizing the content, as well as enabling interaction, remain to handle in the pinwall fileder. - -A great benefit of the use of mmmfs versus other technology for realizing this example is that the example can -seamlessly embed not only plain text, markdown, images, videos, and interactive widgets, but also follow links to all -of these types of content, and display them meaningfully. Accomplishing this with traditional frameworks would take -great effort, where mmmfs benefits from the reuse of these conversions across the whole system. - -In addition, the script for the pinwall folder is 120 lines long, of which 30 lines are styling, while almost 60 lines -take care of capturing and handling JS events. The bulk of complexity is therefore shifted towards interacting with the -UI layer (in this case the browser), which could feasibly be simplified through a custom abstraction layer or the use of -output means other than the web. - -### 7.1.3 slideshow -A simplified image slideshow example consists of only 20 lines of code and demonstrates how the reactive component -framework simplifies the generation of ad-hoc UI dramatically: - -```moon -import ReactiveVar, text, elements from require 'mmm.component' -import div, a, img from elements - -=> - index = ReactiveVar 1 - - prev = (i) -> math.max 1, i - 1 - next = (i) -> math.min #@children, i + 1 - - div { - div { - a 'prev', href: '#', onclick: -> index\transform prev - index\map (i) -> text " image ##{i} " - a 'next', href: '#', onclick: -> index\transform next - }, - index\map (i) -> - child = assert @children[i], "image not found!" - img src: @children[i]\gett 'URL -> image/png' - } -``` - -The presentation framework is a bit longer, but the added complexity is again required to deal with browser quirks, -such as the fullscreen API and sizing content proportionally to the viewport size. -The parts of the code dealing with the content are essentially identical, except that content is transcluded via the -more general `mmm/dom` type-interface, allowing for a greater variety of types of content to be used as slides. - -## 7.2 general concerns -While the system has proven pretty successful and moldable to the different use-cases that it has been tested in, -there are also limitations in the proposed system that have become obvious in developing and working with the system. -In this section, these limitations will be discussed individually, and directions for further research and solutions will -be given where apparent. - -### 7.2.1 global set of converts -In the current system, there is only a single, global set of *converts* that can be potentially applied to facets -anywhere in the system. -Therefore it is necessary to encode behavior directly (as code) in facets wherever exceptional behavior is required. -For example, if a fileder containing multiple images wants to provide custom UI for each image when viewed independently, -this code has to either be attached to every image individually (and redundantly), or added as a global convert. -To make sure this convert does not interfere with images elsewhere in the system, it would be necessary to introduce -a new type and change the images to use it, which may present even more problems, and works against the principle of -compatibility that the system has been constructed for. - -A potential direction of research in the future is to allow specifying *converts* as part of the fileder tree. -Application of *converts* could then be scoped to their fileders' subtrees, such that for any facet only the *converts* -stored in the chain of its parents upwards are considered. -This way, *converts* can be added locally if they only make sense within a given context. -Additionally, it could be made possible to use this mechanism to locally override *converts* inherited from -further up in the tree, for example, to specialize types based on their context in the system. - -<mmm-embed wrap="marginnote" path="../references/alternatives-to-trees">See also </mmm-embed> -The biggest downside to this approach would be that it presents another pressure factor for, while also reinforcing, -the hierarchical organization of data, thereby exacerbating the limits of hierarchical structures. - -### 7.2.2 code outside of the system -At the moment, a large part of the mmmfs codebase is still separate from the content and developed outside of mmmfs -itself. This is a result of the development process of mmmfs and was necessary to start the project as the filesystem -itself matured, but has now become a limitation of the user experience: potential users of mmmfs would generally start -by becoming familiar with the operation of mmmfs from within the system, as this is the expected (and designated) -experience developed for them. All of the code that lives outside of the mmmfs tree is therefore invisible and opaque -to them, actively limiting their understanding, and thereby the customizability, of the system. - -This weakness represents a failure to (fully) implement the quality of a "Living System" as proposed by -*Ink and Switch*<mmm-embed path="../references/inkandswitch" wrap="sidenote"></mmm-embed>. - -In general, however, some portion of code may always have to be left outside of the system. -This also wouldn't necessarily represent a problem, but in this case it is particularly relevant -for the global set of *converts* (see above), as well as the layout used to render the web view. -Both of these are expected to undergo changes as users adapt the system to their own content types and -domains of interest, as well as their visual identity, respectively. - -### 7.2.3 type system -The currently used type system based on strings and pattern matching has been largely satisfactory -but has proven problematic for some anticipated use cases. -It should be considered to switch to a more intricate, -structural type system that allows encoding more concrete meta-data alongside the type, -and to match *converts* based on a more flexible scheme of pattern matching. -For example, it is envisaged to store the resolution of an image file in its type. -Many *converts* might choose to ignore this additional information, -but others could use this information to generate lower-resolution 'thumbnails' of images automatically. -Using these mechanisms for example images could be requested with a maximum-resolution constraint to save on bandwidth -when embedded in other documents. - -<div style="break-before: page;"></div> - -### 7.2.4 type-coercion -By giving the system more information about the data it is dealing with, -and then relying on the system to automatically transform between data-types, -it is easy to lose track of which format data is concretely stored in. -In much the same way that the application-centric paradigm alienates users from an understanding -and feeling of ownership of their data by overemphasizing the tools in between, -the automagical coercion of data types introduces distance between the user and -an understanding of the data in the system. -This poses a threat to the transparency of the system, and potentially a lack of the "Embodiment" quality (see above). - -Potential solutions could be to communicate the conversion path clearly and explicitly together with the content, -as well as making this display interactive to encourage experimentation with custom conversion queries. -Emphasizing the conversion process more strongly in this way might be a way to turn this feature from an opaque -hindrance into a transparent tool. This should represent a challenge mostly in terms of UX and UI design. - -### 7.2.5 in-system editing -Because many *converts* are not necessarily reversible, it is very hard to implement generic ways of editing stored data -in the same format it is viewed. For example, the system trivially converts markdown-formatted text sources into -viewable HTML markup, but it is hardly possible to propagate changes to the viewable HTML back to the markdown source. -This particular instance of the problem might be solvable using a Rich-Text editor, but the general problem worsens when -the conversion path becomes more complex: If the markdown source was fetched via HTTP from a remote URL (e.g. if the -facet's type was `URL -> text/markdown`), it is not possible to edit the content at all, since the only data owned by -the system is the URL string itself, which is not part of the viewable representation. Similarly, when viewing output -that is generated by code (e.g. `text/moonscript -> mmm/dom`), the code itself is not visible to the user, and if the -user wishes to change parts of the representation, the system is unable to relate these changes to elements of the code -or assist the user in doing so. - -However, even where plain text is used and edited, a shortcoming of the current approach to editing is evident: -The content editor is wholly separate from the visible representation, and only facets of the currently viewed fileder -can be edited. This means that content cannot be edited in its context, which is exacerbated by the extreme -fragmentation of content that mmmfs encourages. - -As a result, interacting with the system at large is still a very different experience from editing content (and -thereby extending the system) in it. This is expected to represent a major hurdle for users getting started with the -system and is a major shortcoming in enabling end-user programming, as set as a goal for this project. -A future iteration should carefully reconsider how editing could be integrated more holistically with the other core -concepts of the design. - -<div style="break-before: page;"></div> - -### 7.2.6 end-user adoption -As mentioned above, a conscious choice was made to exclude the implementation of a dedicated end-user programming -facility in the system, and instead conventional programming languages and mechanisms were relied upon as the central -way of customizing the system and experience. While this was a crucial choice to make in order to proceed with the -project as a whole, it means that the system currently can not be adopted and used to its full extent by -end-users. This also means that a full evaluation of the system with regard to end-user empowerment has to be left open -until this can be changed by further work. diff --git a/root/research/mmmfs/examples/$order b/root/research/mmmfs/examples/$order deleted file mode 100644 index 4ee3140..0000000 --- a/root/research/mmmfs/examples/$order +++ /dev/null @@ -1,5 +0,0 @@ -language_support -image -markdown -gallery -pinwall diff --git a/root/research/mmmfs/examples/gallery/$order b/root/research/mmmfs/examples/gallery/$order deleted file mode 100644 index 9d438bd..0000000 --- a/root/research/mmmfs/examples/gallery/$order +++ /dev/null @@ -1,2 +0,0 @@ -link_to_image -actual_image diff --git a/root/research/mmmfs/examples/gallery/actual_image/image$png.png b/root/research/mmmfs/examples/gallery/actual_image/image$png.png Binary files differdeleted file mode 100644 index b499413..0000000 --- a/root/research/mmmfs/examples/gallery/actual_image/image$png.png +++ /dev/null diff --git a/root/research/mmmfs/examples/gallery/actual_image/preview: image$png.png b/root/research/mmmfs/examples/gallery/actual_image/preview: image$png.png Binary files differdeleted file mode 100644 index f9dbfad..0000000 --- a/root/research/mmmfs/examples/gallery/actual_image/preview: image$png.png +++ /dev/null diff --git a/root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png b/root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png deleted file mode 100644 index 7cf76ff..0000000 --- a/root/research/mmmfs/examples/gallery/link_to_image/URL -> image$png +++ /dev/null @@ -1 +0,0 @@ -https://picsum.photos/600/600/?image=101 diff --git a/root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png b/root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png deleted file mode 100644 index 2b2233b..0000000 --- a/root/research/mmmfs/examples/gallery/link_to_image/preview: URL -> image$png +++ /dev/null @@ -1 +0,0 @@ -https://picsum.photos/200/200/?image=101 diff --git a/root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon b/root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon deleted file mode 100644 index 0178ac2..0000000 --- a/root/research/mmmfs/examples/gallery/slideshow: text$moonscript -> fn -> mmm$component.moon +++ /dev/null @@ -1,19 +0,0 @@ -import ReactiveVar, text, elements from require 'mmm.component' -import div, a, img from elements - -=> - index = ReactiveVar 1 - - prev = (i) -> math.max 1, i - 1 - next = (i) -> math.min #@children, i + 1 - - div { - div { - a 'prev', href: '#', onclick: -> index\transform prev - index\map (i) -> text " image ##{i} " - a 'next', href: '#', onclick: -> index\transform next - }, - index\map (i) -> - child = assert @children[i], "image not found!" - img src: @children[i]\gett 'URL -> image/png' - } diff --git a/root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 9bdac54..0000000 --- a/root/research/mmmfs/examples/gallery/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,12 +0,0 @@ -import div, h1, a, img, br from require 'mmm.dom' - -=> - link = (child) -> a { - href: '#', - onclick: -> BROWSER\navigate child.path - img src: child\gett 'preview', 'URL -> image/png' - } - - content = [link child for child in *@children] - table.insert content, 1, h1 'gallery index' - div content diff --git a/root/research/mmmfs/examples/gallery/title: text$plain b/root/research/mmmfs/examples/gallery/title: text$plain deleted file mode 100644 index 2e9ef34..0000000 --- a/root/research/mmmfs/examples/gallery/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -a gallery of images diff --git a/root/research/mmmfs/examples/image/URL -> image$png b/root/research/mmmfs/examples/image/URL -> image$png deleted file mode 100644 index c586722..0000000 --- a/root/research/mmmfs/examples/image/URL -> image$png +++ /dev/null @@ -1 +0,0 @@ -https://picsum.photos/200?random diff --git a/root/research/mmmfs/examples/image/title: text$plain b/root/research/mmmfs/examples/image/title: text$plain deleted file mode 100644 index dca924f..0000000 --- a/root/research/mmmfs/examples/image/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -link to a remote image diff --git a/root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md b/root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md deleted file mode 100644 index 8a6a185..0000000 --- a/root/research/mmmfs/examples/implementation: text$markdown+sidenotes.md +++ /dev/null @@ -1,88 +0,0 @@ -## 6.1 publishing and blogging -### 6.1.1 blogging -Blogging is pretty straightforward since it generally just involves publishing lightly-formatted text, -interspersed with media such as images and videos or perhaps social media posts. -Markdown is a great tool for this job, and has been integrated into the system to much success: -There are two different types registered with *converts*: `text/markdown` and `text/markdown+span`. -They both render to HTML (and DOM nodes), so they are immediately viewable as part of the system. -The only difference for `text/markdown+span` is that it is limited to a single line, -and doesn't render as a paragraph but rather just a line of text. -This makes it suitable for denoting formatted-text titles and other small strings of text. - -The problem of embedding other content together with text comfortably is also solved easily -because Markdown allows embedding arbitrary HTML in the document. -This made it possible to define a set of pseudo-HTML elements in the Markdown-convert, -`<mmm-embed>` and `<mmm-link>`, which respectively embed and link to other content native to mmmfs. - -### 6.1.2 academic publishing -<div class="sidenote" style="margin-top: 1.25rem"> -One of the 'standard' solutions, <a href="https://www.latex-project.org/">LaTeX</a>, -is arguably at least as complex as the mmm system proposed here, but has a much narrower scope, -since it does not support interaction. -</div> - -Academic publishing is notoriously complex, involving not only the transclusion of diagrams -and other media but generally requiring precise and consistent control over formatting and layout. -Some of these complexities are tedious to manage but present good opportunities for programmatic -systems and media to do work for the writer. - -One such topic is the topic of references. -References appear in various formats at multiple positions in an academic document; -usually, they are referenced via a reduced visual form within the text of the document -and then shown again with full details at the end of the document. - -For the sake of this thesis, referencing has been implemented using a subset of the popular -BibTeX format for describing citations. Converts have been implemented for the `text/bibtex` -type to convert to a full reference format (to `mmm/dom`) and to an inline side-note reference -(`mmm/dom+link`) that can be transcluded using the `<mmm-link>` pseudo-tag. - -For convenience, a convert from the `URL -> cite/acm` type has been provided to `URL -> text/bibtex`, -which generates links to the ACM Digital Library<mmm-embed path="../references/acm-dl" wrap="sidenote"></mmm-embed> -API for accessing BibTeX citations for documents in the library. This means that it is enough to store the link to the -ACM DL entry in mmmfs, and the reference will automatically be fetched, and therefore stay up to date with potential -remote corrections. - -## 6.2 pinwall -In many situations, and particularly for creative work, it is often useful to compile resources of -different types for reference or inspiration and arrange them spatially so that they can be viewed -at a glance or organized into different contexts, etc. -Such a pinwall could serve for example to organize references to articles, -to collect visual inspiration for a mood board, etc. - -As a collection, the Pinwall is primarily mapped to a Fileder in the system. -Any content that is placed within can then be rendered by the Pinwall, -which can constrain every piece of content to a rectangular piece on its canvas. -This is possible through a simple script, e.g. of the type `text/moonscript -> fn -> mmm/dom`, -which enumerates the list of children, wraps each in such a rectangular container -and outputs the list of containers as DOM elements. - -The position and size of each panel are stored in an ad-hoc facet, encoded in the JSON data format: -`pinwall_info: text/json`. Such a facet is set on each child and read whenever the script is called -to render the children, plugging the values within the facet into the visual styling of the document. - -The script can also set event handlers that react to user input while the document is loaded, -and allow the user to reposition and resize the individual pinwall items by clicking and dragging -on the upper border or lower right-hand corner respectively. -Whenever a change is made the event handler can then update the value in the `pinwall_info` facet, -so that the updated position and size are stored for the next time the pinwall is opened. - -## 6.3 slideshow -Another common use of digital documents is as aids in a verbal presentation. -These often take the form of slideshows, for the creation of which a number of established applications exist. -In simple terms, a slideshow is simply a linear series of screen-sized documents, that can be -advanced (and rewound) one by one using keypresses. - -The implementation of this is rather straightforward as well. -The slideshow as a whole becomes a fileder with a script that generates a designated viewport rectangle, -as well as a control interface with keys for advancing the active slide. -It also allows putting the browser into fullscreen mode to maximize screen space and remove visual elements -of the website that may distract from the presentation, and register an event handler for keyboard accelerators -for moving through the presentation. - -Finally, the script simply embeds the first of its child-fileders into the viewport rectangle. -Once the current slide is changed, the next embedded child is simply chosen. - -<!-- -## code documentation -/meta/mmm.dom/:%20text/html+interactive ---> diff --git a/root/research/mmmfs/examples/intro: text$markdown+sidenotes.md b/root/research/mmmfs/examples/intro: text$markdown+sidenotes.md deleted file mode 100644 index 126f407..0000000 --- a/root/research/mmmfs/examples/intro: text$markdown+sidenotes.md +++ /dev/null @@ -1,10 +0,0 @@ -# 6 example use-cases -To illustrate the capabilities of the proposed system, and to compare the results with the framework introduced above, -a number of example use cases have been chosen and implemented from the perspective of a user. -In the following section I will introduce these use cases and briefly summarize the implementation -approach in terms of the capabilities of the proposed system. - -<div style="break-before: page;"></div> - -<span class="sidenote">The online version is available at [s-ol.nu/ba](https://s-ol.nu/ba).</span> -The following examples can be viewed and inspected in the interactive version online: diff --git a/root/research/mmmfs/examples/language_support/$order b/root/research/mmmfs/examples/language_support/$order deleted file mode 100644 index 3cc0e47..0000000 --- a/root/research/mmmfs/examples/language_support/$order +++ /dev/null @@ -1,3 +0,0 @@ -javascript -moonscript -lua diff --git a/root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js b/root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js deleted file mode 100644 index de56531..0000000 --- a/root/research/mmmfs/examples/language_support/javascript/text$javascript -> mmm$dom.js +++ /dev/null @@ -1,15 +0,0 @@ -const e = (elem, children) => { - const node = document.createElement(elem); - - if (typeof children === 'string') - node.innerText = children; - else - children.forEach(child => node.appendChild(child)); - - return node; -}; - -return e('article', [ - e('h1', 'JavaScript'), - e('p', 'JavaScript is supported natively in the browser but is not currently pre-rendered on the server.'), -]); diff --git a/root/research/mmmfs/examples/language_support/javascript/title: text$plain b/root/research/mmmfs/examples/language_support/javascript/title: text$plain deleted file mode 100644 index 581fbc7..0000000 --- a/root/research/mmmfs/examples/language_support/javascript/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -JavaScript diff --git a/root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua b/root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua deleted file mode 100644 index 62e79f1..0000000 --- a/root/research/mmmfs/examples/language_support/lua/text$lua -> mmm$dom.lua +++ /dev/null @@ -1,9 +0,0 @@ -local d = require 'mmm.dom' - -local lua = d.a { 'Lua', href = 'https://www.lua.org/' } -local fengari = d.a { 'fengari.io', href = 'https://fengari.io/' } - -return d.article { - d.h1 'Lua', - d.p { lua, ' is fully supported using ', fengari, ' on the Client.' } -} diff --git a/root/research/mmmfs/examples/language_support/lua/title: text$plain b/root/research/mmmfs/examples/language_support/lua/title: text$plain deleted file mode 100644 index 0f9d550..0000000 --- a/root/research/mmmfs/examples/language_support/lua/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -Lua diff --git a/root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon b/root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon deleted file mode 100644 index 5cc50e6..0000000 --- a/root/research/mmmfs/examples/language_support/moonscript/text$moonscript -> mmm$dom.moon +++ /dev/null @@ -1,10 +0,0 @@ -import a, article, h1, p from require 'mmm.dom' - -moonscript = a 'MoonScript', href: 'https://moonscript.org/' -lua = a 'Lua', href: 'https://www.lua.org/' -fengari = a 'fengari.io', href: 'https://fengari.io/' - -article { - h1 'MoonScript', - p moonscript, " is compiled to ", lua, " on the server, which is then executed on the client using ", fengari, "." -} diff --git a/root/research/mmmfs/examples/language_support/moonscript/title: text$plain b/root/research/mmmfs/examples/language_support/moonscript/title: text$plain deleted file mode 100644 index f8871ac..0000000 --- a/root/research/mmmfs/examples/language_support/moonscript/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -MoonScript diff --git a/root/research/mmmfs/examples/language_support/preview: text$markdown b/root/research/mmmfs/examples/language_support/preview: text$markdown deleted file mode 100644 index d6c2845..0000000 --- a/root/research/mmmfs/examples/language_support/preview: text$markdown +++ /dev/null @@ -1,6 +0,0 @@ -this Fileder contains some minimal examples showing support for various languages `mmmfs` supports currently. - -Language support is mostly limited by the fact that `mmmfs` currently targets web browsers, -on the server any scripting language that can be executed can theoretically be integrated with minimal effort. - -Using the inspector mode to view the source of the Fileders below is encouraged. diff --git a/root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 4ae0679..0000000 --- a/root/research/mmmfs/examples/language_support/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,16 +0,0 @@ -import article, h1, p, ul, li, a from require 'mmm.dom' - -single = (a) -> a - -=> - children = for child in *@children - title = child\gett 'title: text/plain' - li a title, href: child.path, onclick: (e) => - e\preventDefault! - BROWSER\navigate child.path - - article { - h1 single @gett 'title: text/plain' - p single @gett 'preview: mmm/dom' - ul children - } diff --git a/root/research/mmmfs/examples/language_support/title: text$plain b/root/research/mmmfs/examples/language_support/title: text$plain deleted file mode 100644 index ae06474..0000000 --- a/root/research/mmmfs/examples/language_support/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -scripting language support diff --git a/root/research/mmmfs/examples/markdown/text$markdown.md b/root/research/mmmfs/examples/markdown/text$markdown.md deleted file mode 100644 index 880eedb..0000000 --- a/root/research/mmmfs/examples/markdown/text$markdown.md +++ /dev/null @@ -1,20 +0,0 @@ -This is a markdown document rendered using [marked][marked] on the client, and [discount][discount] on the server. -All Markdown features are supported, for example there is support for lists... - -- a list of things -- (two things) - -...and syntax-highlighted code tags: - -``` -print "Hello World" -``` - -Since Markdown supports inline HTML, mmmfs shorthands can also be used to embed and reference content from elsewhere in -the system. For example, the title of this fileder can be embedded using -`<mmm-embed facet="title"></mmm-embed>`: - -<mmm-embed facet="title"></mmm-embed> - -[marked]: https://marked.js.org/ -[discount]: https://luarocks.org/modules/craigb/discount diff --git a/root/research/mmmfs/examples/markdown/title: text$plain b/root/research/mmmfs/examples/markdown/title: text$plain deleted file mode 100644 index 7915148..0000000 --- a/root/research/mmmfs/examples/markdown/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -markdown content diff --git a/root/research/mmmfs/examples/pinwall/$order b/root/research/mmmfs/examples/pinwall/$order deleted file mode 100644 index 4a12798..0000000 --- a/root/research/mmmfs/examples/pinwall/$order +++ /dev/null @@ -1,4 +0,0 @@ -image -text -video -youtube_video diff --git a/root/research/mmmfs/examples/pinwall/image/image$png.png b/root/research/mmmfs/examples/pinwall/image/image$png.png Binary files differdeleted file mode 100644 index 1628d99..0000000 --- a/root/research/mmmfs/examples/pinwall/image/image$png.png +++ /dev/null diff --git a/root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json deleted file mode 100644 index 7149346..0000000 --- a/root/research/mmmfs/examples/pinwall/image/pinwall_info: text$json +++ /dev/null @@ -1 +0,0 @@ -{"x": 117.0, "y": 592.0, "w": 403.0, "h": 296.0}
\ No newline at end of file diff --git a/root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 90822f2..0000000 --- a/root/research/mmmfs/examples/pinwall/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,121 +0,0 @@ -import article, div from require 'mmm.dom' -import convert from require 'mmm.mmmfs.conversion' - -update_info = (fileder, x, y, w, h) -> - info = (fileder\get 'pinwall_info: table') or x: 100, y: 100, w: 300, h: 300 - info.x = x if x - info.y = y if y - info.w = w if w - info.h = h if h - - json = convert 'table', 'text/json', info, fileder, 'pinwall_info' - fileder\set 'pinwall_info: text/json', json - -CLIENT = MODE == 'CLIENT' - -=> - - pending = {} - observe = if CLIENT - map = {} - observer = js.new js.global.ResizeObserver, (_, entries) -> - for entry in js.of entries - if child = map[entry.target] - rect = entry.contentRect - pending[child] = -> update_info child, nil, nil, rect.width, rect.height - - (node, child) -> - map[node] = child - observer\observe node - - drag = nil - - children = for child in *@children - info = (child\get 'pinwall_info: table') or x: 100, y: 100, w: 560, h: 315 - - wrapper = div { - style: - position: 'absolute' - padding: '10px' - resize: 'both' - overflow: 'hidden' - background: 'var(--gray-dark)' - border: '1px solid var(--gray-bright)' - - left: "#{info.x}px" - top: "#{info.y}px" - width: "#{info.w}px" - height: "#{info.h}px" - - -- handle for moving the child - div { - style: - top: '0' - left: '0' - right: '0' - height: '10px' - cursor: 'pointer' - position: 'absolute' - - onmousedown: CLIENT and (_, e) -> - node = e.target.parentElement - drag = { - :child - :node - - startX: tonumber node.style.left\match '(%d+)px' - startY: tonumber node.style.top\match '(%d+)px' - startMouseX: e.clientX - startMouseY: e.clientY - } - } - - -- child content - div { - style: - width: '100%' - height: '100%' - background: 'var(--white)' - - (child\get 'mmm/dom') or div '(unrenderable)' - } - } - - -- listen for resize events - observe wrapper, child if CLIENT - wrapper - - children.style = { - width: '1000px' - height: '500px' - } - - if CLIENT - children.onmousemove = (_, e) -> - return unless drag - - x = drag.startX + (e.clientX - drag.startMouseX) - y = drag.startY + (e.clientY - drag.startMouseY) - drag.node.style.left = "#{x}px" - drag.node.style.top = "#{y}px" - - children.onmouseup = (_, e) -> - for k, func in pairs pending - func! - pending = {} - - return unless drag - - x = drag.startX + (e.clientX - drag.startMouseX) - y = drag.startY + (e.clientY - drag.startMouseY) - update_info drag.child, x, y - drag = nil - - children.onmouseleave = (_, e) -> - return unless drag - - drag.node.style.left = "#{drag.startX}px" - drag.node.style.top = "#{drag.startY}px" - drag = nil - - article children diff --git a/root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json deleted file mode 100644 index 07a9448..0000000 --- a/root/research/mmmfs/examples/pinwall/text/pinwall_info: text$json +++ /dev/null @@ -1 +0,0 @@ -{"x": 28.0, "y": 179.0, "w": 1457.0, "h": 246.0}
\ No newline at end of file diff --git a/root/research/mmmfs/examples/pinwall/text/text$plain.txt b/root/research/mmmfs/examples/pinwall/text/text$plain.txt deleted file mode 100644 index 8838e5a..0000000 --- a/root/research/mmmfs/examples/pinwall/text/text$plain.txt +++ /dev/null @@ -1,4 +0,0 @@ -This is a pinwall example. -Every box is a separate fileder. -The boxes can be rearranged and resized freely. -If the server is in read-write mode, the changes are saved persistently in real time. diff --git a/root/research/mmmfs/examples/pinwall/title: text$plain b/root/research/mmmfs/examples/pinwall/title: text$plain deleted file mode 100644 index c629992..0000000 --- a/root/research/mmmfs/examples/pinwall/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -a pinwall diff --git a/root/research/mmmfs/examples/pinwall/video/URL -> video$mp4 b/root/research/mmmfs/examples/pinwall/video/URL -> video$mp4 deleted file mode 100644 index 6364771..0000000 --- a/root/research/mmmfs/examples/pinwall/video/URL -> video$mp4 +++ /dev/null @@ -1 +0,0 @@ -https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_480_1_5MG.mp4 diff --git a/root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json deleted file mode 100644 index fefad32..0000000 --- a/root/research/mmmfs/examples/pinwall/video/pinwall_info: text$json +++ /dev/null @@ -1 +0,0 @@ -{"x": 1247.0, "y": 643.0, "w": 483.0, "h": 272.0}
\ No newline at end of file diff --git a/root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video b/root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video deleted file mode 100644 index 7552ebe..0000000 --- a/root/research/mmmfs/examples/pinwall/youtube_video/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=ZXqgFb1U7q0
\ No newline at end of file diff --git a/root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json b/root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json deleted file mode 100644 index 3e145f1..0000000 --- a/root/research/mmmfs/examples/pinwall/youtube_video/pinwall_info: text$json +++ /dev/null @@ -1 +0,0 @@ -{"x": 391.0, "y": 238.0, "w": 560.0, "h": 315.0}
\ No newline at end of file diff --git a/root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 2988f29..0000000 --- a/root/research/mmmfs/examples/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,44 +0,0 @@ --- main content --- doesn't have a name prefix (e.g. preview: fn -> mmm/dom) --- uses the 'fn ->' conversion to execute the lua function on @get --- resolves to a value of type mmm/dom -=> - html = require 'mmm.dom' - import h4, div, a, span, ul, li from html - import link_to from (require 'mmm.mmmfs.util') html - - -- render a preview block - preview = (child) -> - -- get 'title' as 'text/plain' (error if no value or conversion possible) - title = child\gett 'title', 'text/plain' - - -- get 'preview' as a DOM description (nil if no value or conversion possible) - -- content = child\get 'preview', 'mmm/dom' - - -- div { - -- h4 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate child.path - -- content or span '(no renderable content)', style: { color: 'red' }, - -- style: { - -- display: 'inline-block', - -- width: '300px', - -- height: '200px', - -- padding: '4px', - -- margin: '8px', - -- border: '4px solid #eeeeee', - -- overflow: 'hidden', - -- }, - -- } - - li link_to child - - examples = ul for child in *@children - preview child - - div { - style: - 'break-after': 'page' - - (@gett 'intro: mmm/dom') - examples - (@gett 'implementation: mmm/dom') - } diff --git a/root/research/mmmfs/framework/text$markdown+sidenotes.md b/root/research/mmmfs/framework/text$markdown+sidenotes.md deleted file mode 100644 index e5f3c7e..0000000 --- a/root/research/mmmfs/framework/text$markdown+sidenotes.md +++ /dev/null @@ -1,96 +0,0 @@ -# 4 evaluation framework - -In this section, I will collect approaches and reviews of different end-user software systems from current literature, -as well as derive and present my own requirements and guiding principles for the development of a new system. - -Firstly, I will take a look at a framework for evaluating end-user computing systems from literature, before presenting -three concrete design principles and components for a new system. - -4.1 qualities of successful end-user computing ---------------------------------------------------- - -*Ink and Switch* suggest three qualities for tools striving to support <span style="display: inline-block;"> -end-user programming<mmm-embed path="../references/inkandswitch" wrap="sidenote"></mmm-embed>:</span> - -- *Embodiment*, i.e. reifying central concepts of the programming model as more concrete, tangible objects - in the digital space (for example, through visual representation), - in order to reduce cognitive load on the user. -- *Living System*, by which they seem to describe the malleability of a system or environment, - and in particular the ability to make changes at different levels of depth in the system with - very short feedback loops and a feeling of direct experience. -- *In-place toolchain*, denoting the availability of tools to customize and author the experience, - as well as a certain accessibility of these tools, granted by a conceptual affinity between the - use of the tools and general 'passive' use of containing system at large. - -These serve as guiding principles for the design and evaluation of computer systems for end-users but are by nature -very abstract. The following properties are therefore derived as more concrete proposals based on more specific -constraints: namely the construction of a system for end-users to keep, structure and display personal information and -thoughts. - -<div style="break-after: page;"></div> - -4.2 modularity -------------------- - -The *UNIX Philosophy*<mmm-embed path="../references/unix" wrap="sidenote"></mmm-embed> describes the software design -paradigm pioneered in the creation of the Unix operating system at the AT&T Bell Labs research center in the 1960s. The -concepts are considered quite influential and are still notably applied in the Linux community. Many attempts at -summaries exist, but the following includes the pieces that are especially relevant even today: - -<mmm-embed path="../references/unix" wrap="marginnote"></mmm-embed> -> Even though the UNIX system introduces a number of innovative programs and techniques, no single program or idea makes -> it work well. Instead, what makes it effective is the approach to programming, a philosophy of using the computer. -> Although that philosophy can't be written down in a single sentence, at its heart is the idea that the power of a -> system comes more from the relationships among programs than from the programs themselves. Many UNIX programs do quite -> trivial things in isolation, but, combined with other programs, become general and useful tools. - -This approach has multiple benefits with regard to end-user programmability: Assembling the system out of simple, -modular pieces means that for any given task a user may want to implement, it is very likely that preexisting parts -of the system can help the user realize a solution. Wherever such a preexisting part exists, it pays off designing it -in such a way that it is easy to integrate for the user later. Assembling the system as a collection of modular, -interacting pieces also enables future growth and customization, since pieces may be swapped out with customized or -alternate software at any time. - -Settling on a specific modular design model, and reifying other components of a system in terms of it, also corresponds -directly to the concept of *Embodiment* described by Ink & Switch. - -4.3 content transclusion ------------------------------ - -The strengths of modular architectures should similarly extend also into the way the system will be used by users. -If users are to store their information and customized behavior in such an architecture, then powerful tools need to be -present in order to assemble more complex solutions out of such parts. Therefore static content should be able to be -linked to (as envisioned for the *Memex*, see above), but also to be <mmm-embed wrap="marginnote" -path="../references/transclusion">The term <i>transclusion</i> refers to the concept of including content from a -separate document, possibly stored remotely, by reference rather than by duplication. See also -</mmm-embed>*transcluded*, -to facilitate the creation of flexible data formats and interactions, such that e.g. a slideshow slide can include -content in a variety other formats (such as images and text) from anywhere else in the system. Behaviors also should be -able to be transcluded and reused to facilitate the creation of ad-hoc systems and applets based on user needs. For -example, a user-created todo list should be able to take advantage of a sketching tool the user already has access to. - -By forming the immediately user-visible layer of the system out of the same abstractions that the deeper levels of the -system are made of, the sense of a *Living System* is also improved: skills that are learned at one (lower) level of the -system carry on into further interaction with the system on deeper levels, as does progress in understanding the -system's mechanisms. - -While there are drawbacks to cloud-storage of data (as outlined above), the utility of distributed systems is -acknowledged, and the system should therefore be able to include content and behaviors via the network. -This ability should be integrated deeply into the system, so that data can be treated independently of its origin and -storage conditions, with as little caveats as possible. In particular, the interactions of remote data access and -content transclusion should be paid attention to and taken into consideration for a system's design. - -4.4 end-user programming ------------------------------ - -In order to provide users full access to their information as well as the computational infrastructure, -users need to be able to finely customize and reorganize the smallest pieces to suit their own purposes, -in other words: be able to program. - -While there is an ongoing area of research focusing on the development of new programming paradigms, -methodologies, and tools that are more accessible and cater to the wide -range of end-users<mmm-embed path="../references/subtext" wrap="sidenote"></mmm-embed>, -in order to keep the scope of this work appropriate, -conventional programming languages are used for the time being. -Confidence is placed in the fact that eventually more user-friendly languages will be available and, -given the goal of modularity, should be implementable in a straightforward fashion. diff --git a/root/research/mmmfs/historical-approaches/$order b/root/research/mmmfs/historical-approaches/$order deleted file mode 100644 index b98a91b..0000000 --- a/root/research/mmmfs/historical-approaches/$order +++ /dev/null @@ -1 +0,0 @@ -star-graph diff --git a/root/research/mmmfs/historical-approaches/star-graph/image$png.png b/root/research/mmmfs/historical-approaches/star-graph/image$png.png Binary files differdeleted file mode 100644 index ed4003c..0000000 --- a/root/research/mmmfs/historical-approaches/star-graph/image$png.png +++ /dev/null diff --git a/root/research/mmmfs/historical-approaches/star-graph/note: text$markdown.md b/root/research/mmmfs/historical-approaches/star-graph/note: text$markdown.md deleted file mode 100644 index eb115dd..0000000 --- a/root/research/mmmfs/historical-approaches/star-graph/note: text$markdown.md +++ /dev/null @@ -1,4 +0,0 @@ -<p><i>How systems influenced later systems. This graph summarizes how various systems related to Star have influenced -one another over the years. Time progresses downwards. Double arrows indicate direct successors (i.e., -follow-on versions). [...]</i></p> -<mmm-embed wrap="raw" path="../../references/xerox-star"></mmm-embed> diff --git a/root/research/mmmfs/historical-approaches/text$markdown+sidenotes.md b/root/research/mmmfs/historical-approaches/text$markdown+sidenotes.md deleted file mode 100644 index dfe9390..0000000 --- a/root/research/mmmfs/historical-approaches/text$markdown+sidenotes.md +++ /dev/null @@ -1,73 +0,0 @@ -<div style="break-before: page;"></div> - -# 3 historical approaches - -Two of the earliest holistic computing systems, the Xerox Alto and Xerox Star, both developed at Xerox PARC and -introduced in the 70s and early 80s pioneered not only graphical user-interfaces but also the "Desktop Metaphor". -The desktop metaphor presents information as stored in "Documents" that can be organized in folders and on the -"Desktop". It invokes a strong analogy to physical tools. One of the differences between the Xerox Star system and -other systems at the time, as well as the systems we use currently, is that the type of data a file represents is -directly known to the system. - -In a retrospective analysis of the Xerox Star's impact on the computer industry, the desktop metaphor is described as -follows: - -<mmm-embed path="../references/xerox-star" wrap="marginnote"></mmm-embed> -> In a Desktop metaphor system, users deal mainly with data files, oblivious to the existence of programs. -> They do not "invoke a text editor", they "open a document". -> The system knows the type of each file and notifies the relevant application program when one is opened. -> -> The disadvantage of assigning data files to applications is that users sometimes want to operate on a file with a -> program other than its "assigned" application. \[...\] -> Star's designers feel that, for its audience, the advantages of allowing users to forget about programs outweighs -> this disadvantage. - -Other systems at the time lacked any knowledge of the type of files, and while mainstream operating systems of today -have retro-fit the ability to associate and memorize the preferred applications to use for a given file based on its -name suffix, the intention of making applications a secondary, technical detail of working with the computer has -surely been lost. - -Another design detail of the Star system is the concept of "properties" that are stored for "objects" throughout the -system (the objects being anything from files to characters or paragraphs). These typed pieces of information are -labeled with a name and persistently stored, providing a mechanism to store metadata such as user preference for -ordering or the default view mode of a folder for example. - -The earliest indirect influence for the Xerox Alto and many other systems of its time was the *Memex*. -The *Memex* is a hypothetical device and system for knowledge management. Proposed by Vannevar Bush in 1945<mmm-embed -path="../references/memex" wrap="sidenote"></mmm-embed>, the concept predates much of the technology that later was used -to implement many parts of the vision. - -<mmm-embed path="star-graph" facet="note" wrap="marginnote" style="margin-top: 1rem;"></mmm-embed> -<mmm-embed path="star-graph" nolink></mmm-embed> - -<!-- -While the article extrapolates from existing technology at the time, describing at times -very concrete machinery based on microfilm and mechanical contraptions, many of the conceptual predictions became -true or inspired .... ---> - -One of the most innovative elements of Bush's predictions is the idea of technologically cross-referenced and -connected information, which would later be known and created as *hypertext*. While hypertext powers the majority of -today's internet, many of the advantages that Bush imagined have not carried over into the personal use of computers. -There are very few tools for creating personal, highly-interconnected knowledge bases, even though it is technologically -feasible and a proven concept (exemplified for example by the massively successful online encyclopedia -*Wikipedia*<mmm-embed path="../references/wikipedia" wrap="sidenote"></mmm-embed>). - -While there are few such tools available today, one of the systems that could be said to have come closest to a -practical implementation of a Memex-inspired system for personal use might be Apple's *HyperCard*. - -In a live demonstration<mmm-embed path="../references/hypercard" wrap="sidenote"></mmm-embed>, the creators of the -software showcase a system of stacks of cards that together implement, amongst others, a calendar (with yearly and -weekly views), a list of digital business cards for storing phone numbers and addresses, and a todo list. However these -stacks of cards are not just usable by themselves, it is also demonstrated how stacks can link to each other in -meaningful ways, such as jumping to the card corresponding to a specific day from the yearly calendar view or -automatically looking up the card corresponding to a person's first name from a mention of the name in the text on a -different card. - -Alongside Spreadsheets, *HyperCard* remains one of the most successful implementations of end-user programming, even -today. While its technical abilities have been long matched and surpassed by other software (such as the ubiquitous -*Hypertext Markup Language* HTML, and the associated programming language *JavaScript*), these technical successors have -failed the legacy of *HyperCard* as an end-user tool: While it is easier than ever to publish content on the web -(through various social media and microblogging services), the benefits of hypermedia as a customizable medium for -personal management have nearly vanished. End-users do not create hypertext anymore. - diff --git a/root/research/mmmfs/introduction/text$markdown.md b/root/research/mmmfs/introduction/text$markdown.md deleted file mode 100644 index b8550fe..0000000 --- a/root/research/mmmfs/introduction/text$markdown.md +++ /dev/null @@ -1,18 +0,0 @@ -1 introduction -==================== - -As of December 2019, there are only four major operating systems available to end-users for desktop and mobile -devices<mmm-embed path="../references/market-share" wrap="sidenote"></mmm-embed>. All of these systems are comparatively inflexible and -can only be customized by users where the system or application developers have anticipated a need with corresponding -options. Only a small minority of professional or hobby developers have the knowledge and tools at their disposal to -create their own digital experiences, and even for them, the process is often too complex and inefficient to do so -effectively. -However, historically, empowered ownership of the computing experience was not meant to be restricted only to -end-users. Many computing systems designed during the computer revolution were designed specifically with the goal of -complete customizability by users, but little of this approach remains in the systems we use today. - -In the first section of this thesis, I will discuss some of the limitations of mainstream operating systems and -potential causes in detail. Next, I will highlight some of the contrasting approaches found in historic computing -systems, and then derive a framework for the evaluation of end-user computing systems with regard to user empowerment. -I will then discuss a new computing system, demonstrate it in some example use cases, and evaluate it using the -framework. diff --git a/root/research/mmmfs/mmmfs/$order b/root/research/mmmfs/mmmfs/$order deleted file mode 100644 index 5a5d5ab..0000000 --- a/root/research/mmmfs/mmmfs/$order +++ /dev/null @@ -1,3 +0,0 @@ -type_coercion_graph -tree_mmmfs -tree_mainstream diff --git a/root/research/mmmfs/mmmfs/text$markdown+sidenotes.md b/root/research/mmmfs/mmmfs/text$markdown+sidenotes.md deleted file mode 100644 index f04e671..0000000 --- a/root/research/mmmfs/mmmfs/text$markdown+sidenotes.md +++ /dev/null @@ -1,197 +0,0 @@ -# 5 system description - -Alongside this thesis, a new end-user computing system has been developed together with the framework presented above. -The system, `mmmfs`, is a personal data storage and processing system that was initially developed as a tool for -generating static websites but has now been extended with capabilities for live interaction and introspection, as well -as embedded editing, as part of this work. - -mmmfs has been designed with a focus on data ownership for users. One of the main driving ideas is to unlock data -from external data silos and file formats by making data available uniformly across different storage systems and -formats. Secondly, computation and interactive elements are also integrated into this paradigm, so that mmmfs can be -seamlessly extended and molded to the user's needs. - -The abstraction of data types is accomplished using two major components, the *Type System and Coercion Engine* and -the *Fileder Unified Data Model* for unified data storage and access. In the next sections, the design and -implementation of these two components will be described in detail. - -## 5.1 data storage model -The Fileder Model is the underlying unified data storage model. -Like many data storage models it is based fundamentally on the concept of a hierarchical tree-structure. - -<mmm-embed path="tree_mainstream">schematic view of an example tree in a mainstream filesystem</mmm-embed> - -In common filesystems, as pictured, data can be organized hierarchically into *folders* (or *directories*), -which serve only as containers of *files*, in which data is actually stored. While *directories* are fully transparent -to both system and user (they can be created, browsed, listed and viewed by both), *files* are, from the system -perspective, mostly opaque and inert blocks of data. - -Some metadata, such as file size and access permissions, is associated with each file, -but notably, the type of data is generally not actually stored in the filesystem, -but determined loosely based on multiple heuristics depending on the system and context. -Some notable mechanisms are: - -- Suffixes at the end of the filename are often used to indicate which kind of data a file contains. However there is no - centralized standardization of suffixes, and often one suffix is used for multiple incompatible versions of a - file-formats, or multiple suffixes are used interchangeably for one format. -- Many file-formats specify a specific data-pattern either at the very beginning or very end of a given file. - On UNIX systems the `libmagic` database and library of these so-called *magic constants* is commonly used to guess - the file-type based on these fragments of data. -- on UNIX systems, files to be executed are checked by a variety of methods<mmm-embed path="../references/linux-exec" - wrap="sidenote"></mmm-embed> in order to determine which format would fit. For example, script files, the "shebang" - symbol, `#!`, can be used to specify the program that should parse this file in the first line of the file. - -It should be clear already from this short list that to mainstream operating systems, as well as the applications -running on them, the format of a file is almost completely unknown and, at best, educated guesses can be made. - -Because these various mechanisms are applied at different times by the operating system and applications, it is possible -for files to be labeled or considered as being in different formats at the same time by different components of the -system. - -This leads to confusion about the factual format of data among users<mmm-embed path="../references/renaming" -wrap="sidenote" style="margin-top: -3rem;">For example, the difference between changing a file extension and converting -a file between two formats is often unclear to users, as evident from questions like this: </mmm-embed>, but can -also pose a serious security risk: -Under some circumstances, it is possible that a file contains maliciously-crafted code and is treated as an executable -by one software component, while a security mechanism meant to detect such code determines the same file to be a -legitimate image<mmm-embed path="../references/poc-or-gtfo" wrap="sidenote" style="margin-top: 2rem"></mmm-embed> -(the file may in fact be valid in both formats). - -In mmmfs, the example above might look like this instead: -<mmm-embed path="tree_mmmfs">schematic view of an example mmmfs tree</mmm-embed> - -Superficially, this may look quite similar: there are still only two types of nodes (referred to as *fileders* and -*facets*), and again one of them, the *fileders* are used only to hierarchically organize *facets*. Unlike *files*, -*facets* don't only store a freeform *name*, there is also a dedicated *type* field associated with every *facet*, that -is explicitly designed to be understood and used by the system. - -Despite the similarities, the semantics of this system are very different: In mainstream filesystems, each *file* stands -for itself only; i.e. in a *directory*, no relationship between *files* is assumed by default, and files are most of the -time read or used outside of the context they exist in in the filesystem. - -In mmmfs, a *facet* should only ever be considered an aspect of its *fileder*, and never as separate from it. -A *fileder* can contain multiple *facets*, but they are meant to be alternate or equivalent representations of the -*fileder* itself. Though for some uses it is required, software generally does not have to be directly aware of the -*facets* existing within a *fileder*, rather it assumes the presence of content in the representation that it requires, -and simple requests it. The *Type Coercion Engine* (see below) will then attempt to satisfy this request based on the -*facets* that are in fact present. - -Semantically a *fileder*, like a *directory*, also encompasses all the other *fileders* nested within itself -(recursively). Since *fileders* are the primary unit of data to be operated upon, *fileder* nesting emerges as a natural -way of structuring complex data, both for access by the system and its components, as well as the user themself. - -<div style="break-after: page;"></div> - -## 5.2 type system and coercion engine -As mentioned above, *facets* store data alongside its *type*, and when a component of the system requires data from a -*fileder*, it has to specify the *expected type* (or a list of these) that it requires the data to be in. The system -then attempts to coerce one of the existing facets into the *expected type*, if possible. This process can involve many -steps such as converting between similar file formats, running executable code stored in a facet, or fetching remote -content. The component that requested the data is isolated from this process and does not have to deal with any of the -details. - -In the current iteration of the type system, types are simple strings of text and loosely based on MIME-types<mmm-embed -path="../references/mime-types" wrap="sidenote"></mmm-embed>. -MIME types consist of a major- and minor category, and optionally a 'suffix'. -Here are some common MIME-types that are also used in mmmfs: - -- `text/html` and `text/html+frag` (mmmfs only) -- `text/javascript` -- `image/png` -- `image/jpeg` - -While these types allow some amount of specificity, they fall short of describing their content especially in cases -where formats overlap: Source code, for example, is often distributed in `.tar.gz` archive files (directory-trees that -are first bundled into an `application/x-tar` archive, and then compressed into an `application/gzip` archive). Using -either of these two types is respectively incorrect or insufficient information to properly treat and extract the -contained data. - -To mitigate this problem, mmmfs *types* can be nested. This is denoted in mmmfs *type* strings using the `->` symbol, -e.g. the mmmfs *types* `application/gzip -> application/tar -> dirtree` and `URL -> image/jpeg` describe a -tar-gz-compressed directory tree and the URL linking to a JPEG-encoded picture respectively. - -Depending on the outer type this nesting can mean different things: -for URLs, the nested type is expected to be found after fetching the URL with HTTP, -compression formats are expected to contain contents of the nested types, -and executable formats are expected to output data of the nested type. - -It is a lot more important to be able to accurately describe the type of a *facet* in mmmfs than in mainstream operating -systems because while in the latter types are mostly used only associate an application that will then prompt the user -for further steps if necessary, mmmfs uses the *type* to automatically find one or more programs to execute, in order to -convert or transform the data stored in a *facet* into the *type* required in the context where it was requested. - -This process of *type coercion* uses a database of known *converts* that can be applied to data. Every *convert* -consists of a description of the input *types* that it can accept, the output *type* it would produce for a given input -type, as well as the code for actually converting a given piece of data. Simple *converts* may simply consist of a fixed -in and output type, such as this *convert* for rendering Markdown-encoded text to an HTML hypertext fragment: - - { - inp: 'text/markdown' - out: 'text/html+frag' - transform: (value, ...) -> - -- implementation stripped for brevity - } - -Other *converts*, on the other hand, may accept a wide range of input types: - - { - inp: 'URL -> image/.*' - out: 'text/html+frag' - transform: (url) -> img src: url - } - -This convert uses a Lua Pattern to specify that it can accept an URL to any type of image, -and convert it to an HTML fragment. - -By using the pattern substitution syntax provided by the Lua `string.gsub` function, converts can also make the type -they return depend on the input type, as is required often when nested types are unpacked: - - { - inp: 'application/gzip -> (.*)' - out: '%1' - transform: (data) -> - -- implementation stripped for brevity - } - -This *convert* accepts an `application/gzip` *type* wrapping any other *type*, and captures that nested type in a -pattern group. It then uses the substitution syntax to specify that nested type as the output of the conversion. -For an input *type* of `application/gzip -> image/png` this *convert* would therefore generate the type `image/png`. - -This last example further demonstrates the flexibility of this approach: - - { - inp: 'text/moonscript -> (.*)' - out: 'text/lua -> %1' - transform: (code) -> moonscript.to_lua code - } - -This *convert* transpiles MoonScript source-code into Lua source-code, while keeping the nested type -(in this case the result expected when executing either script) the same. - -In addition to the attributes shown above, every *convert* is also rated with a *cost* value. The cost value is meant to -roughly estimate both the cost (in terms of computing power) of the conversion, as well as the accuracy or immediacy of -the conversion. For example, resizing an image to a lower size should have a high cost, because the process is -computationally expensive, but also because a smaller image represents the original image to a lesser degree. -Similarly, a URL to a piece of content is a less immediate representation than the content itself, so the cost of a -*convert* that simply generates the URL to a piece of data should be high even if the process is very cheap to compute. - -Cost is defined in this way to make sure that the result of a type-coercion operation reflects the content that was -present as accurately as possible. It is also important to prevent some nonsensical results from occurring, such as -displaying a link to content instead of the content itself because the link is cheaper to create than completely -converting the content does. - -Type coercion is implemented using a general pathfinding algorithm, based on *Dijkstra's Algorithm*<mmm-embed -path="../references/dijkstra" wrap="sidenote"></mmm-embed>. First, the set of given *types* is found by selecting all -*facets* of the *fileder* that match the *name* given in the query. The set of given *types* is marked in green in the -following example graph. -From there the algorithm recursively checks whether it can reach other *types* by applying all matching *converts* to -the *type* that is the cheapest to reach currently, excluding any *types* that have already been exhaustively-searched -in this way. All *types* found that have not yet been inserted into the set of given *types* are then added to the -set, so that they may be searched as well. - -The algorithm doesn't stop immediately after reaching a *type* from the result set, it continues to search until it -either completely exhausts the result-space, or until all non-exhaustively searched paths already have costs higher than -the allowed maximum. This ensures that the optimal path is found, even if a more expensive path is found more quickly -initially. - -<mmm-embed path="type_coercion_graph">excerpt of the graph of conversion paths from two starting facets to mmm/dom -</mmm-embed> diff --git a/root/research/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph b/root/research/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph deleted file mode 100644 index 3227e47..0000000 --- a/root/research/mmmfs/mmmfs/tree_mainstream/text$mermaid-graph +++ /dev/null @@ -1,11 +0,0 @@ -graph TD - Documents --> Movies --> m1{{A Movie.mp4}} - Documents --> Pictures --> vacation[Summer Vacation] - vacation --> v1{{1.jpg}} - vacation --> v2{{2.jpg}} - Pictures --> Projects - Projects --> p1{{1.jpg}} - Projects --> p2{{2.jpg}} - - classDef file fill:#f9f; - class m1,v1,v2,p1,p2 file; diff --git a/root/research/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph b/root/research/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph deleted file mode 100644 index 7b4f6f4..0000000 --- a/root/research/mmmfs/mmmfs/tree_mmmfs/text$mermaid-graph +++ /dev/null @@ -1,21 +0,0 @@ -graph TD - Documents --> Movies --> m1[A Movie.mp4] - m1 --> m1.f{{video/mp4}} - - Documents --> Pictures --> vacation[Summer Vacation] - vacation --> slideshow{{slideshow: script -> UI}} - vacation --> gallery{{gallery: script -> UI}} - vacation --> v1[1.jpg] - vacation --> v2[2.jpg] - v1 --> v1.f{{image/jpeg}} - v2 --> v2.f{{image/jpeg}} - - Pictures --> Projects - Projects --> p1[1.jpg] - Projects --> p2[2.jpg] - p1 --> p1.f{{image/jpeg}} - p2 --> p2.f{{image/jpeg}} - - classDef default fill:#f00,stroke:#333,stroke-width:4px; - classDef file fill:#f9f; - class slideshow,gallery,m1.f,v1.f,v2.f,p1.f,p2.f file; diff --git a/root/research/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph b/root/research/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph deleted file mode 100644 index cf2cf1e..0000000 --- a/root/research/mmmfs/mmmfs/type_coercion_graph/text$mermaid-graph +++ /dev/null @@ -1,22 +0,0 @@ -graph LR - md_lua[text/lua -> text/markdown] - md[text/markdown] - moon[text/moonscript -> fn -> mmm/dom] - lua[text/lua -> fn -> mmm/dom] - fn[fn -> mmm/dom] - dom[mmm/dom] - moon_url[URL -> text/moonscript -> fn -> mmm/dom] - lua_url[URL -> text/lua -> fn -> mmm/dom] - - md_lua -- cost: 1 --> md -- cost: 2 --> dom - moon -- cost: 5 --> moon_url - moon -- cost: 1 --> fn -- cost: 2 --> dom - moon -- cost: 2 --> lua -- cost: 5 --> lua_url - lua -- cost: 1 --> fn - moon_url -- cost: 10 --> dom - lua_url -- cost: 10 -->dom - - classDef given fill:#ada; - classDef path stroke:#ada; - linkStyle 3,1,0,4 stroke:#8d8,stroke-width:2px - class md_lua,moon given diff --git a/root/research/mmmfs/motivation/$order b/root/research/mmmfs/motivation/$order deleted file mode 100644 index accfc0b..0000000 --- a/root/research/mmmfs/motivation/$order +++ /dev/null @@ -1,2 +0,0 @@ -app-types -creative diff --git a/root/research/mmmfs/motivation/app-types/text$markdown.md b/root/research/mmmfs/motivation/app-types/text$markdown.md deleted file mode 100644 index aedef1c..0000000 --- a/root/research/mmmfs/motivation/app-types/text$markdown.md +++ /dev/null @@ -1,3 +0,0 @@ -While there can be a distinction between *Native Applications* and *Web Applications* or *Cloud Services*, the following -arguments apply to all different technical implementations of this same concept. The problems associated specifically -with Web- and Cloud-based application models will be discussed separately below. diff --git a/root/research/mmmfs/motivation/creative/text$markdown.md b/root/research/mmmfs/motivation/creative/text$markdown.md deleted file mode 100644 index 9dd6162..0000000 --- a/root/research/mmmfs/motivation/creative/text$markdown.md +++ /dev/null @@ -1,2 +0,0 @@ -Note that 'creative' here does not only mean 'artistic': this applies to any field, and limits the ability of domain -experts to push the boundaries of practice by using technology in innovative ways. diff --git a/root/research/mmmfs/motivation/text$markdown+sidenotes.md b/root/research/mmmfs/motivation/text$markdown+sidenotes.md deleted file mode 100644 index 64a3459..0000000 --- a/root/research/mmmfs/motivation/text$markdown+sidenotes.md +++ /dev/null @@ -1,138 +0,0 @@ -# 2 drawbacks of current systems - -The project that this thesis accompanies was created out of frustration with the computing systems that are currently -popular and widely available to end-users. The following sections document and exemplify the perceived shortcomings that -these systems exhibit, as attributed to specific concepts or paradigms that the systems seem to be designed around. - -2.1 application-centric design ------------------------------------ - -The majority of users interact with modern computing systems in the form of smartphones, laptops or desktop PCs, -using the mainstream operating systems Apple iOS and Mac OS X, Microsoft Windows or Android. - -<mmm-embed path="app-types" wrap="marginnote"></mmm-embed> -All of these operating systems share the concept of *Applications* (or *Apps*) as one of the core pieces of their -interaction model. The functionality and capabilities of digital devices are bundled, marketed, sold and distributed -as applications. This focus on applications as the primary unit of systems can be seen as the root cause of multiple -problems. - -For one, since applications are produced by private companies on the software market, -developers compete on features integrated into their applications. To stay relevant, monolithic software or software -suites tend to accrete features rather then modularize and delegate to other software<mmm-embed wrap="sidenote" -path="../references/appliances"></mmm-embed>. This makes many software packages more complex and unintuitive than -they need to be, and also cripples interoperability between applications and data formats. - -Because (private) software developers are incentivized to keep customers, they make use of network effects to keep -customers locked-in. This often means re-implementing services and functionality that is already available to users, -and integrating it directly in other applications or as a new product by the same organization. -While this strategy helps big software companies retain customers, it harms users, who have to navigate a complex -landscape of multiple incompatible, overlapping, and competing software ecosystems. -Data of the same kind, a rich-text document, for example, can be shared easily within the software systems of a certain -manufacturer and with other users of the same, but sharing with users of a competing system, even if it has almost the -same capabilities, can often be problematic<mmm-embed path="../references/lock-in" wrap="sidenote"></mmm-embed>. - -Another issue is that due to the technical challenges of development in this paradigm, applications are designed and -developed by experts in application development, rather than experts in the domain of the tool. While developers may -solicit feedback, advice, and ideas from domain experts, communication is a barrier. Additionally, domain experts are -generally unfamiliar with the technical possibilities, and may therefore not be able to express feedback that would lead -to more significant advances. -<mmm-embed path="creative" wrap="marginnote"></mmm-embed> -As a result, creative use of computer technology is limited to programmers, since applications constrain their users to -the paths and abilities that the developers anticipated and deemed useful. - -The application-centric computing metaphor treats applications as black boxes and provides no means to understand, -customize or modify the behavior of apps, intentionally obscuring the inner-workings of applications and -completely cutting users off from this type of ownership over their technology. While the trend seems to be to further -hide the way desktop operating systems work<mmm-embed path="../references/osx-files" wrap="sidenote"></mmm-embed>, -mobile systems like Apple's *iOS* were designed as such *walled gardens* from the start. - -2.2 cloud computing ------------------------- - -*Web Apps* often offer similar functionality to other applications but are subject to additional limitations: -In most cases, they are only accessible or functional in the presence of a stable internet connection, -and they have very limited access to the resources of the physical computer they are running on. -For example, they usually cannot interact directly with the file system, hardware peripherals or other applications, -other than through a standardized set of interactions (e.g. selecting a file via a visual menu, capturing audio and -video from a webcam, opening another website). - -Cloud software, as well as subscription-model software with online-verification mechanisms, are additionally subject -to license changes, updates modifying, restricting or simply removing past functionality, etc. Additionally, many cloud -software solutions and ecosystems store the users' data in the cloud, often across national borders, where legal and -privacy concerns are intransparently handled by the companies. If a company, for any reason, is unable or unwilling to -continue servicing a customer, the user's data may be irrecoverably lost (or access prevented). This can have serious -consequences<mmm-embed path="../references/adobe" wrap="sidenote"></mmm-embed>, especially for professional users, for -whom an inability to access their tools or their cloud-stored data can pose an existential threat. - -2.3 inert data (and data formats) --------------------------------------- - -Cragg coins the term "inert data"<mmm-embed path="../references/super-powers" wrap="sidenote"></mmm-embed> for the data -created and left behind by apps and applications in the computing model that is currently prevalent: Most data today -is either intrinsically linked to one specific application, that controls and limits access to the actual information, -or, even worse, stored in the cloud where users have no direct access at all. In the latter case, users depend solely on -online tools that require a stable network connection and a modern browser and could be modified, removed, or otherwise -negatively impacted at any moment. - -Aside from being inaccessible to users, the resulting complex proprietary formats are also opaque and useless to other -applications and the operating system, which often is a huge missed opportunity: -The .docx format, for example, commonly used for storing mostly textual data enriched with images and on occasion videos, -is in fact a type of archive that can contain many virtual files internally, such as the various media files contained -within. However this is completely unknown to the user and operating system, and so users are unable to access the -contents in this way. As a result, editing an image contained in a word document is far from a trivial task: first the -document has to be opened in a word processing application, then the image has to be exported from it and saved in its -own, temporary file. This file can then be edited and saved back to disk. Once updated, the image may be reimported -into the .docx document. If the word-processing application supports this, the old image may be replaced directly, -otherwise, the user may have to remove the old image, insert the new one, and carefully ensure that the positioning in -the document remains intact. - -2.4 disjointed filesystems -------------------------------- - -The filesystems and file models used on modern computing devices generally operate on the assumption that every -individual file stands for itself. Grouping of files in folders is allowed as a convenience for users, but most -applications only ever concern themselves with a single file at a time, independent of the context the file is stored -in. - -Data rarely really fits this concept of individual files very well, and even when it does, it is rarely exposed to -the user that way: The 'Contacts' app on a mobile phone, for example, does not store each contact's information in a -separate 'file' (as the word may suggest initially), but rather keeps all information in a single database file, -which is hidden away from the user. Consequently, access to the information contained in the database is only enabled -through the contacts application's graphical interface, and not through other applications that generically operate on -files. - -Another example illustrates how a more powerful file (organization) system could render such formats and applications -obsolete: Given the simple task of collecting and arranging a mixed collection of images, videos, and texts to -brainstorm, many might be tempted to open an application like *Microsoft Word* or *Adobe Photoshop* and create a new -document there. Both *Photoshop* files and *Word* documents are capable of containing texts and images, but when such -content is copied into them from external sources, such as other files on the same computer, or quotes and links from -the internet, these relationships are irrevocably lost. As illustrated above, additionally, it becomes a lot harder to -edit the content once it is aggregated. To choose an application for this task is a hard trade-off to make, because in -applications primarily designed for word processing, arranging content visually is hard to do, and image editing and -video embedding options are limited, while tools better suited to these tasks lack nuance when working with text. - -To avoid facing this dilemma, a more sensible system could leave the task of positioning and aggregating content of -different types to one software component, while multiple different software components could be responsible for editing -the individual pieces of content so that the most appropriate one can be chosen for each element. While creating the -technological interface between these components is certainly a challenge, the resulting system would greatly benefit -from the exponentially-growing capabilities resulting from the modular reuse of components across many contexts: A rich -text editor component could be used for example not just in a mixed media collection as proposed above, but also for -an email editor or the input fields in a browser. - -<div style="height: 2rem;"></div> - -To summarize, for various reasons, the metaphors and driving concepts of computing interfaces today prevent users from -deeply understanding the software they use and the data they own, from customizing and improving their experience and -interactions, and from properly owning, contextualizing and connecting their data. - -Interestingly, these deficits do not appear throughout the history of today's computing systems but are based in rather -recent developments in the field. In fact, the most influential systems in the past aspired to the polar opposites, as I -will show in the next section. - -<!-- -Chiusano blames these issues on the metaphor of the *machine*, and likens apps and applications to appliances. -According to him, what should really be provided are *tools*: -composable pieces of software that naturally lend themselves to, or outrightly call for, -integration into the users' other systems and customization, -rather than lure into the walled-gardens of corporate ecosystems using network-effects. ---> diff --git a/root/research/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 615075a..0000000 --- a/root/research/mmmfs/print: text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,26 +0,0 @@ --- main content --- doesn't have a name prefix (e.g. preview: fn -> mmm/dom) --- uses the 'fn ->' conversion to execute the lua function on @get --- resolves to a value of type mmm/dom -=> - html = require 'mmm.dom' - import article, h1, p, div from html - import moon from (require 'mmm.highlighting').languages - - article with _this = class: 'sidenote-container spacious', style: { 'max-width': '640px', 'line-height': '1.5' } - append = (a) -> table.insert _this, a - - append div { - h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 } - p { - style: - 'margin-top': 0 - 'padding-bottom': '0.2em' - 'border-bottom': '1px solid black' - - "A Historical Investigation and Development of a File-System-Based Environment" - } - } - - for child in *@children - append (child\get 'print: mmm/dom') or (child\gett 'mmm/dom') diff --git a/root/research/mmmfs/references/$order b/root/research/mmmfs/references/$order deleted file mode 100644 index d2a668b..0000000 --- a/root/research/mmmfs/references/$order +++ /dev/null @@ -1,22 +0,0 @@ -poc-or-gtfo -aspect-ratios -memex -appliances -super-powers -dijkstra -subtext -mime-types -alternatives-to-trees -xerox-star -unix -transclusion -adobe -acm-dl -hypercard -inkandswitch -linux-exec -wikipedia -market-share -osx-files -renaming -lock-in diff --git a/root/research/mmmfs/references/acm-dl/text$bibtex b/root/research/mmmfs/references/acm-dl/text$bibtex deleted file mode 100644 index 8fb36a2..0000000 --- a/root/research/mmmfs/references/acm-dl/text$bibtex +++ /dev/null @@ -1,5 +0,0 @@ -@online{acm-dl, - title = {ACM Digital Library}, - url = {https://dl.acm.org}, - year = {n. d.}, -} diff --git a/root/research/mmmfs/references/adobe/text$bibtex b/root/research/mmmfs/references/adobe/text$bibtex deleted file mode 100644 index 55904aa..0000000 --- a/root/research/mmmfs/references/adobe/text$bibtex +++ /dev/null @@ -1,8 +0,0 @@ -@online{adobe, - title = {Adobe is cutting off users in Venezuela due to US sanctions}, - url = {https://www.theverge.com/2019/10/7/20904030/adobe-venezuela-photoshop-behance-us-sanctions}, - publisher = {The Verge}, - author = {Lee, Dami}, - year = {2019, October 7}, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/alternatives-to-trees/text$bibtex b/root/research/mmmfs/references/alternatives-to-trees/text$bibtex deleted file mode 100644 index 19c134e..0000000 --- a/root/research/mmmfs/references/alternatives-to-trees/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@web{alternatives:to:trees, - title = {Alternatives to Trees}, - url = {https://www.oocities.org/tablizer/sets1.htm}, - author = {Jacobs, B.} - year = {2004}, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/appliances/text$bibtex b/root/research/mmmfs/references/appliances/text$bibtex deleted file mode 100644 index 56fa8c8..0000000 --- a/root/research/mmmfs/references/appliances/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{appliances, - title = {The future of software, the end of apps, and why UX designers should care about type theory}, - url = {http://pchiusano.github.io/2013-05-22/future-of-software.html}, - author = {Chiusano, Paul}, - year = {2013}, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/aspect-ratios/text$bibtex b/root/research/mmmfs/references/aspect-ratios/text$bibtex deleted file mode 100644 index 37cea92..0000000 --- a/root/research/mmmfs/references/aspect-ratios/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@web{aspect:ratios, - title = {Aspect-ratio independent UIs}, - url = {https://s-ol.nu/aspect-ratios}, - author = {Bekic, Sol} - year = {2019}, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/dijkstra/text$bibtex b/root/research/mmmfs/references/dijkstra/text$bibtex deleted file mode 100644 index c38a470..0000000 --- a/root/research/mmmfs/references/dijkstra/text$bibtex +++ /dev/null @@ -1,17 +0,0 @@ -@article{10.1007/BF01386390, - author = {Dijkstra, Edsger W.}, - title = {A Note on Two Problems in Connexion with Graphs}, - year = {1959}, - issue_date = {December 1959}, - publisher = {Springer-Verlag}, - address = {Berlin, Heidelberg}, - volume = {1}, - number = {1}, - issn = {0029-599X}, - url = {https://doi.org/10.1007/BF01386390}, - doi = {10.1007/BF01386390}, - journal = {Numer. Math.}, - month = dec, - pages = {269–271}, - numpages = {3} -} diff --git a/root/research/mmmfs/references/hypercard/text$bibtex b/root/research/mmmfs/references/hypercard/text$bibtex deleted file mode 100644 index b23cfcb..0000000 --- a/root/research/mmmfs/references/hypercard/text$bibtex +++ /dev/null @@ -1,6 +0,0 @@ -@online{hypercard, - title = {Computer Chronicles, Episode 501}, - url = {https://archive.org/details/CC501_hypercard}, - visited = {2019-12-18}, - year = {1987}, -} diff --git a/root/research/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md b/root/research/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md deleted file mode 100644 index 9439841..0000000 --- a/root/research/mmmfs/references/inkandswitch/markdown: text$moonscript -> fn -> text$markdown.md +++ /dev/null @@ -1 +0,0 @@ -=> "```\n" .. (@gett 'text/bibtex') .. "\n```" diff --git a/root/research/mmmfs/references/inkandswitch/text$bibtex b/root/research/mmmfs/references/inkandswitch/text$bibtex deleted file mode 100644 index 8b5f298..0000000 --- a/root/research/mmmfs/references/inkandswitch/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{inkandswitch, - title = {End-user Programming}, - url = {https://inkandswitch.com/end-user-programming.html}, - publisher = {Ink & Switch}, - year = {2019}, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/linux-exec/text$bibtex b/root/research/mmmfs/references/linux-exec/text$bibtex deleted file mode 100644 index e0e415f..0000000 --- a/root/research/mmmfs/references/linux-exec/text$bibtex +++ /dev/null @@ -1,8 +0,0 @@ -@online{linux:exec, - title = {How does Linux execute a file?}, - url = {https://stackoverflow.com/a/23295724/1598293}, - publisher = {stackoverflow.com}, - note = {answered by osgx}, - visited = {2019-12-18}, - year = 2014, -} diff --git a/root/research/mmmfs/references/lock-in/text$bibtex b/root/research/mmmfs/references/lock-in/text$bibtex deleted file mode 100644 index 28d780c..0000000 --- a/root/research/mmmfs/references/lock-in/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{lock:in, - title = {The Cloud is the Ultimate Vendor Lock-in}, - url = {https://www.digital-manifesto.org/the-cloud-is-the-ultimate-vendor-lock-in/}, - author = {Zielemans, François}, - year = {2017}, - visited = {2019-11-18}, -} diff --git a/root/research/mmmfs/references/market-share/text$bibtex b/root/research/mmmfs/references/market-share/text$bibtex deleted file mode 100644 index 430af2f..0000000 --- a/root/research/mmmfs/references/market-share/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{market:share, - title = {Operating System Market Share - Desktop and Mobile}, - year = {2019}, - url = {https://s-ol.nu/ba/ref/nms}, - oldURL = {https://netmarketshare.com/operating-system-market-share.aspx?options=%7B%22filter%22%3A%7B%22%24and%22%3A%5B%7B%22deviceType%22%3A%7B%22%24in%22%3A%5B%22Desktop%2Flaptop%22%2C%22Mobile%22%5D%7D%7D%5D%7D%2C%22dateLabel%22%3A%22Trend%22%2C%22attributes%22%3A%22share%22%2C%22group%22%3A%22platform%22%2C%22sort%22%3A%7B%22share%22%3A-1%7D%2C%22id%22%3A%22platformsDesktop%22%2C%22dateInterval%22%3A%22Monthly%22%2C%22dateStart%22%3A%222018-12%22%2C%22dateEnd%22%3A%222019-11%22%2C%22hiddenSeries%22%3A%7B%7D%2C%22tableOrder%22%3A%5B%5B2%2C%22desc%22%5D%5D%2C%22segments%22%3A%22-1000%22%7D}, - publisher = {NetMarketShare}, -} diff --git a/root/research/mmmfs/references/memex/text$bibtex b/root/research/mmmfs/references/memex/text$bibtex deleted file mode 100644 index 313eec7..0000000 --- a/root/research/mmmfs/references/memex/text$bibtex +++ /dev/null @@ -1,8 +0,0 @@ -@online{memex, - author = {Bush, Vannevar}, - title = {As we may think}, - journal = {Atlantic Monthly}, - year = {1945}, - visited = {2019-12-18}, - url = {https://www.theatlantic.com/magazine/archive/1945/07/as-we-may-think/303881/} -} diff --git a/root/research/mmmfs/references/mime-types/text$bibtex b/root/research/mmmfs/references/mime-types/text$bibtex deleted file mode 100644 index c49b553..0000000 --- a/root/research/mmmfs/references/mime-types/text$bibtex +++ /dev/null @@ -1,14 +0,0 @@ -@article{rfc6838, - series = {Request for Comments}, - number = 6838, - howpublished = {RFC 6838}, - publisher = {Internet Engineering Task Force}, - doi = {10.17487/RFC6838}, - url = {https://tools.ietf.org/html/rfc6838}, - author = {Freed, Ned and Klensin, John C. and Hansen, Tony}, - title = {Media Type Specifications and Registration Procedures}, - pagetotal = 32, - year = 2013, - month = jan, - abstract = {This document defines procedures for the specification and registration of media types for use in HTTP, MIME, and other Internet protocols. This memo documents an Internet Best Current Practice.}, -} diff --git a/root/research/mmmfs/references/osx-files/text$bibtex b/root/research/mmmfs/references/osx-files/text$bibtex deleted file mode 100644 index 7c70a87..0000000 --- a/root/research/mmmfs/references/osx-files/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{osx:files, - title = {Where is "Show Package Contents"}, - url = {https://discussions.apple.com/thread/6740790}, - publisher = {Apple Communities}, - visited = {2019-12-27}, - year = 2014, -} diff --git a/root/research/mmmfs/references/poc-or-gtfo/text$bibtex b/root/research/mmmfs/references/poc-or-gtfo/text$bibtex deleted file mode 100644 index 7cac092..0000000 --- a/root/research/mmmfs/references/poc-or-gtfo/text$bibtex +++ /dev/null @@ -1,8 +0,0 @@ -@article{PoC:or:GTFO, - author = {Albertini, Ange}, - title = {Abusing file formats; or, Corkami, the Novella}, - year = {2015}, - journal = {PoC||GTFO}, - volume = {7}, - pages = {18-41}, -} diff --git a/root/research/mmmfs/references/renaming/text$bibtex b/root/research/mmmfs/references/renaming/text$bibtex deleted file mode 100644 index 660bc2c..0000000 --- a/root/research/mmmfs/references/renaming/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{renaming, - title = {Why is it possible to convert a file just by renaming it?}, - url = {https://askubuntu.com/q/166602}, - publisher = {askubuntu.com}, - year = 2012, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/subtext/cite$doi b/root/research/mmmfs/references/subtext/cite$doi deleted file mode 100644 index 2ac65b5..0000000 --- a/root/research/mmmfs/references/subtext/cite$doi +++ /dev/null @@ -1 +0,0 @@ -10.1145/1103845.1094851 diff --git a/root/research/mmmfs/references/subtext/text$bibtex b/root/research/mmmfs/references/subtext/text$bibtex deleted file mode 100644 index 7e9eb9d..0000000 --- a/root/research/mmmfs/references/subtext/text$bibtex +++ /dev/null @@ -1,18 +0,0 @@ -@article{10.1145/1103845.1094851, - author = {Edwards, Jonathan}, - title = {Subtext: Uncovering the Simplicity of Programming}, - year = {2005}, - issue_date = {October 2005}, - publisher = {Association for Computing Machinery}, - address = {New York, NY, USA}, - volume = {40}, - number = {10}, - issn = {0362-1340}, - url = {https://doi.org/10.1145/1103845.1094851}, - doi = {10.1145/1103845.1094851}, - journal = {SIGPLAN Not.}, - month = oct, - pages = {505–518}, - numpages = {14}, - keywords = {copying, non-textual programming, prototypes, visual programming}, -} diff --git a/root/research/mmmfs/references/super-powers/text$bibtex b/root/research/mmmfs/references/super-powers/text$bibtex deleted file mode 100644 index 5eabda8..0000000 --- a/root/research/mmmfs/references/super-powers/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{super:powers, - title = {Super-powers, but not yours}, - url = {http://object.network/manifesto-negative.html}, - author = {Cragg, Duncan}, - year = {2016}, - visited = {2019-12-18}, -} diff --git a/root/research/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 7b96c10..0000000 --- a/root/research/mmmfs/references/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,13 +0,0 @@ -=> - html = require 'mmm.dom' - import div, h1, ol, li from html - - refs = for ref in *@children - li ref\gett 'mmm/dom' - div { - class: 'print-ownpage' - - h1 "references", id: 'references' - ol with refs - refs.style = 'line-height': 'normal' - } diff --git a/root/research/mmmfs/references/transclusion/text$bibtex b/root/research/mmmfs/references/transclusion/text$bibtex deleted file mode 100644 index e323662..0000000 --- a/root/research/mmmfs/references/transclusion/text$bibtex +++ /dev/null @@ -1,10 +0,0 @@ -@article{article, - author = {Kolbitsch, Josef and Maurer, Hermann}, - year = {2006}, - month = {06}, - pages = {161-173}, - title = {Transclusions in an HTML-Based Environment}, - volume = {14}, - journal = {CIT}, - doi = {10.2498/cit.2006.02.07}, -} diff --git a/root/research/mmmfs/references/unix/text$bibtex b/root/research/mmmfs/references/unix/text$bibtex deleted file mode 100644 index 70b139d..0000000 --- a/root/research/mmmfs/references/unix/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@book{10.5555/577766, - author = {Kernighan, Brian W. and Pike, Rob}, - title = {The UNIX Programming Environment}, - year = {1983}, - isbn = {0139376992}, - publisher = {Prentice Hall Professional Technical Reference} -} diff --git a/root/research/mmmfs/references/wikipedia/text$bibtex b/root/research/mmmfs/references/wikipedia/text$bibtex deleted file mode 100644 index d88d58c..0000000 --- a/root/research/mmmfs/references/wikipedia/text$bibtex +++ /dev/null @@ -1,7 +0,0 @@ -@online{wikipedia, - title = {Hyperlink - Wikis}, - url = {https://en.wikipedia.org/wiki/Hyperlink#Wikis}, - publisher = {wikipedia.org}, - visited = {2019-12-18}, - year = {n. d.}, -} diff --git a/root/research/mmmfs/references/xerox-star/cite$doi b/root/research/mmmfs/references/xerox-star/cite$doi deleted file mode 100644 index b849172..0000000 --- a/root/research/mmmfs/references/xerox-star/cite$doi +++ /dev/null @@ -1 +0,0 @@ -10.1109/2.35211 diff --git a/root/research/mmmfs/references/xerox-star/text$bibtex b/root/research/mmmfs/references/xerox-star/text$bibtex deleted file mode 100644 index 870eed4..0000000 --- a/root/research/mmmfs/references/xerox-star/text$bibtex +++ /dev/null @@ -1,18 +0,0 @@ -@article{10.1109/2.35211, - oldauthor = {Johnson, Jeff and Roberts, Teresa L. and Verplank, William and Smith, David C. and Irby, Charles H. and Beard, Marian and Mackey, Kevin}, - author = {Johnson, Jeff et al.}, - title = {The Xerox Star: A Retrospective}, - year = {1989}, - issue_date = {September 1989}, - publisher = {IEEE Computer Society Press}, - address = {Washington, DC, USA}, - volume = {22}, - number = {9}, - issn = {0018-9162}, - url = {https://doi.org/10.1109/2.35211}, - doi = {10.1109/2.35211}, - journal = {Computer}, - month = sep, - pages = {11–26, 28–29}, - numpages = {1}, -} diff --git a/root/research/mmmfs/statement-of-originality/text$html+frag.html b/root/research/mmmfs/statement-of-originality/text$html+frag.html deleted file mode 100644 index d6dcbc0..0000000 --- a/root/research/mmmfs/statement-of-originality/text$html+frag.html +++ /dev/null @@ -1,13 +0,0 @@ -<div class="print-only print-ownpage" style="margin: 4cm 0 0;"> -<h1 id="statement">statement of originality</h1> -<p style="margin-top: 5cm"> -This is to certify that the content of this project, documentation and thesis is my own work. It -has not been submitted for any other degree or other purposes. I certify that the intellectual -content of my submission is the product of my own work and that all the assistance received in -preparing it as well as all sources used have been properly acknowledged. -</p> - -<div style="border-top: 1px solid #000; width: 7cm; margin-top: 3cm;"> -Sol Bekic -</div> -</div> diff --git a/root/research/mmmfs/table-of-contents/text$html+frag.html b/root/research/mmmfs/table-of-contents/text$html+frag.html deleted file mode 100644 index 2b94109..0000000 --- a/root/research/mmmfs/table-of-contents/text$html+frag.html +++ /dev/null @@ -1,91 +0,0 @@ -<!-- -{ - const fmt = x => `<a href="#${x.id}">${x.innerText}</a>`; - - const parse = e => ({ - num: +e.tagName.substr(1), - fmt: fmt(e), - }); - - const render = (list) => { - let str = ''; - let num = 0; - for (e of list) { - while (e.num > num) { - str += '<ol style="list-style: none; padding-left: 2rem;">' - num += 1; - } - - while (e.num < num) { - str += '</ol>'; - num -= 1; - } - - str += `<li>${e.fmt}</li>`; - } - return str; - }; - - render([...$0.querySelectorAll('h1, h2, h3, h4, h5').values()].map(parse)); -} ---> -<section class="print-ownpage"> - <h1 id="table-of-contents">table of contents</h1> - <ol style="list-style: none;"> - <li><a href="#abstract">abstract</a></li> - <li><a href="#table-of-contents">table of contents</a></li> - <li><a href="#1introduction">1 introduction</a></li> - <li><a href="#2drawbacks-of-current-systems">2 drawbacks of current systems</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#21application-centric-design">2.1 application-centric design</a></li> - <li><a href="#22cloud-computing">2.2 cloud computing</a></li> - <li><a href="#23inert-data-and-data-formats">2.3 inert data (and data formats)</a></li> - <li><a href="#24disjointed-filesystems">2.4 disjointed filesystems</a></li> - </ol> - <li><a href="#3historical-approaches">3 historical approaches</a></li> - <li><a href="#4evaluation-framework">4 evaluation framework</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#41qualities-of-successful-end-user-computing">4.1 qualities of successful end-user computing</a></li> - <li><a href="#42modularity">4.2 modularity</a></li> - <li><a href="#43content-transclusion">4.3 content transclusion</a></li> - <li><a href="#44end-user-programming">4.4 end-user programming</a></li> - </ol> - <li><a href="#5system-description">5 system description</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#51data-storage-model">5.1 data storage model</a></li> - <li><a href="#52type-system-and-coercion-engine">5.2 type system and coercion engine</a></li> - </ol> - <li><a href="#6example-use-cases">6 example use-cases</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#61publishing-and-blogging">6.1 publishing and blogging</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#611blogging">6.1.1 blogging</a></li> - <li><a href="#612scientific-publishing">6.1.2 scientific publishing</a></li> - </ol> - <li><a href="#62pinwall">6.2 pinwall</a></li> - <li><a href="#63slideshow">6.3 slideshow</a></li> - </ol> - <li><a href="#7evaluation">7 evaluation</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#71examples">7.1 examples</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#711publishing-and-blogging">7.1.1 publishing and blogging</a></li> - <li><a href="#712pinwall">7.1.2 pinwall</a></li> - <li><a href="#713slideshow">7.1.3 slideshow</a></li> - </ol> - <li><a href="#72general-concerns">7.2 general concerns</a></li> - <ol style="list-style: none; padding-left: 2rem;"> - <li><a href="#721global-set-of-converts">7.2.1 global set of converts</a></li> - <li><a href="#722code-outside-of-the-system">7.2.2 code outside of the system</a></li> - <li><a href="#723type-system">7.2.3 type system</a></li> - <li><a href="#724type-coercion">7.2.4 type-coercion</a></li> - <li><a href="#725in-system-editing">7.2.5 in-system editing</a></li> - <li><a href="#726end-user-adoption">7.2.6 end-user adoption</a></li> - </ol> - </ol> - <li><a href="#8conclusion">8 conclusion</a></li> - <li><a href="#references">references</a></li> - <li><a href="#ba-log">appendix: project log</a></li> - <li><a href="#statement">statement of originality</a></li> - </ol> -</section> diff --git a/root/research/mmmfs/text$moonscript -> fn -> mmm$dom.moon b/root/research/mmmfs/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 6c5b1d3..0000000 --- a/root/research/mmmfs/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,26 +0,0 @@ --- main content --- doesn't have a name prefix (e.g. preview: fn -> mmm/dom) --- uses the 'fn ->' conversion to execute the lua function on @get --- resolves to a value of type mmm/dom -=> - html = require 'mmm.dom' - import article, h1, p, div from html - import moon from (require 'mmm.highlighting').languages - - article with _this = class: 'sidenote-container spacious', style: { 'max-width': '640px', 'line-height': '1.5' } - append = (a) -> table.insert _this, a - - append div { - h1 'Empowered End-User Computing', style: { 'margin-bottom': 0 } - p { - style: - 'margin-top': 0 - 'padding-bottom': '0.2em' - 'border-bottom': '1px solid black' - - "A Historical Investigation and Development of a File-System-Based Environment" - } - } - - for child in *@children - append child\gett 'mmm/dom' diff --git a/root/research/mmmfs/title/text$html+frag.html b/root/research/mmmfs/title/text$html+frag.html deleted file mode 100644 index 063b52a..0000000 --- a/root/research/mmmfs/title/text$html+frag.html +++ /dev/null @@ -1,21 +0,0 @@ -<div class="print-only print-ownpage" style="font-size: 1.5rem; width: calc(100% + var(--sidenote-width))"> - <div style="font-size: 2rem; margin-top: 4cm"> - <h1>Empowered End-User Computing:</h1> - <span>A Historical Investigation and Development of a File-System-Based Environment</span> - </div> - <div style="width: 14cm; margin: 7cm auto 0"> - <p>by</p> - <p> - Sol Bekic<br /> - Student ID 11114279<br /> - sol.bekic+ba@s-ol.nu - </p> - <p> - written in the Winter Term 2019/20<br /> - for BA Digital Games<br /> - at Cologne Game Lab / TH Köln - </p> - <p>supervised by Prof. Dr. Gundolf S. Freyermuth</p> - <p>submitted on 2020-01-07</p> - </div> -</div> diff --git a/root/research/realities/description: text$plain b/root/research/realities/description: text$plain deleted file mode 100644 index c7a0891..0000000 --- a/root/research/realities/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -exploring the nesting relationships of virtual and other realities diff --git a/root/research/realities/text$moonscript -> mmm$component.moon b/root/research/realities/text$moonscript -> mmm$component.moon deleted file mode 100644 index f6947db..0000000 --- a/root/research/realities/text$moonscript -> mmm$component.moon +++ /dev/null @@ -1,545 +0,0 @@ -import elements from require 'mmm.component' -import h1, h2, p, a, i, div, ol, li, br, hr, span, button, section, article from elements -import interactive_link from (require 'mmm.mmmfs.util') elements - -_content = div! -append = _content\append - -if MODE == 'SERVER' - export ^ - class Diagram - style = { - display: 'inline-block', - width: '150px', - height: '80px', - padding: '12px' - 'line-height': '20px', - 'box-sizing': 'border-box' - color: '#fff', - background: '#666', - } - - @id = 1 - new: (@func) => - @id = "diagram-#{@@id}" - @@id += 1 - - render: => - rplc = with div id: @id, :style - \append interactive_link 'click for interactive version' - -- \append "<script type=\"text/lua\"> - -- local rplc = js.global.document:getElementById('#{@id}'); - -- local fn = #{compile @func} - -- diag = Diagram(fn) - -- rplc.parentNode:replaceChild(diag.node, rplc) - -- </script>" - rplc\render! - -if MODE == 'CLIENT' - export ^ - export o - eval = js.global\eval - GRID_W = 50 - GRID_H = 40 - - SVG = - doc: eval "(function() { return SVG(document.createElement('svg')); })", - G: eval "(function() { return new SVG.G(); })", - setmetatable SVG, __call: => @doc! - - o = do - mkobj = eval "(function () { return {}; })" - (tbl) -> - with obj = mkobj! - for k,v in pairs(tbl) - obj[k] = v - - class Diagram - new: (f) => - @svg = SVG! - @arrows = SVG.G! - @width, @height = 0, 0 - @y = 0 - - f @ - - txtattr = o { - fill: 'white', - 'font-size': '14px', - 'text-anchor': 'middle', - } - block: (color, label, h=1) => - @svg\add with SVG.G! - with \rect GRID_W, h * GRID_H - \attr o fill: color - if label - with \plain label - \move GRID_W/2, 0 - \attr txtattr - - \move @width * GRID_W, (@y + h) * -GRID_H - @y += h - if @y > @height - @height = @y - - arrattr = o { - fill: 'white', - 'font-size': '18px', - 'text-anchor': 'middle', - } - arrow: (char, x, y) => - with @arrows\plain char - \attr arrattr - \move (x + 1) * GRID_W, (y - 0.5) * -GRID_H - 11 - - -- inout: (x=@width, y=@y) => @arrow '⇋', x, y -- U+21CB - -- inn: (x=@width, y=@y) => @arrow '↼', x, y+0.25 -- U+21BC - -- out: (x=@width, y=@y) => @arrow '⇁', x, y-0.25 -- U+21C1 - inout: (x=@width, y=@y) => @arrow '⇆', x, y -- U+21C6 - inn: (x=@width, y=@y) => @arrow '←', x, y+0.25 -- U+2190 - out: (x=@width, y=@y) => @arrow '→', x, y-0.25 -- U+2192 - - mind: (label='mind', ...) => @block '#fac710', label, ... - phys: (label='phys', ...) => @block '#8fd13f', label, ... - digi: (label='digi', ...) => @block '#9510ac', label, ... - - next: => - @y = 0 - @width += 1 - - finish: => - return if @node - @svg\add @arrows - - @width += 1 - w, h = @width * GRID_W, @height * GRID_H - - l = GRID_W / 6.5 - @svg\add with @svg\line 0, -GRID_H, w, -GRID_H - \stroke o width: 2, color: '#ffffff', dasharray: "#{l}, #{l}" - - @svg\size w, h - @svg\viewbox 0, -h, w, h - @node = @svg.node - -addlabel = (label, diagram) -> - with div style: { display: 'inline-block', margin: '20px', 'text-align': 'center' } - \append diagram - \append div label - -figures = do - style = - display: 'flex' - 'align-items': 'flex-end' - 'justify-content': 'space-evenly' - (...) -> div { :style, ... } - -sources = do - short = => "#{@id} #{@year}" - long = => @names, " (#{@year}): ", (i @title), ", #{@published}" - { - { - id: 'Milgram', - title: 'Augmented Reality: A class of displays on the reality-virtuality continuum', - published: 'in SPIE Vol. 2351', - names: 'P. Milgram, H. Takemura, A. Utsumi, F. Kishino', - year: 1994 - :long, :short, - }, - { - id: 'Marsh', - title: 'Nested Immersion: Describing and Classifying Augmented Virtual Reality', - published: 'IEEE Virtual Reality Conference 2015', - names: 'W. Marsh, F. Mérienne', - year: 2015 - :long, :short, - }, - { - id: 'Billinghurst', - title: 'The MagicBook: a transitional AR interface', - published: 'in Computer & Graphics 25', - names: 'M. Billinghurst, H. Kato, I. Poupyrev', - year: 2001, - :long, :short, - }, - { - id: 'Matrix', - title: 'The Matrix', - year: 1999, - names: 'L. Wachowski, A. Wachowski', - long: => @names, " (#{@year}): ", (i @title), " (movie)" - short: => tostring @year - }, - { - id: 'Naam', - title: 'Nexus', - published: 'Angry Robot (novel)', - names: 'R. Naam', - year: 2012, - :long, :short, - } - } - -ref = do - fmt = (id) -> - - local src - for _src in *sources - if _src.id == id - src = _src - break - - if src - a { src\short!, href: "##{src.id}" } - else - span id - - ref = (...) -> - refs = { ... } - with span "(", fmt refs[1] - for i=2, #refs - \append ", " - \append fmt refs[i] - \append ")" - -references = -> - with ol! - for src in *sources - \append li { id: src.id, src\long! } - -sect = (label) -> - with section style: 'page-break-inside': 'avoid' - \append h2 label - -append with article style: { margin: 'auto', 'max-width': '750px' } - \append div 'Sol Bekic', style: 'text-align': 'right' - - \append h1 { - style: { 'text-align': 'center', 'font-size': '2em' }, - "Reality Stacks", - div "a Taxonomy for Multi-Reality Experiences", style: 'font-size': '0.6em' - } - - \append with sect "Abstract" - \append p "With the development of mixed-reality experiences and the corresponding interface devices - multiple frameworks for classification of these experiences have been proposed. However these past - attempts have mostly been developed alongside and with the intent of capturing specific projects ", - (ref 'Marsh', 'Billinghurst'), " or are nevertheless very focused on existing methods and technologies ", - (ref 'Milgram'), ". The existing taxonomies also all assume physical reality as a fixpoint and constant and are - thereby not suited to describe many fictional mixed-reality environments and altered states of consciousness. - In this paper we describe a new model for describing such experiences and examplify it's use with currently - existing as well as idealized technologies from popular culture." - - \append with sect "Terminology" - \append p "We propose the following terms and definitions that will be used extensively for the remainder of the paper:" - for definition in *{ - { "layer of reality": "a closed system consisting of a world model and a set of rules or dynamics operating on and - constraining said model." }, - { "world model": "describes a world state containing objects, agents and/or concepts on an arbitrary abstraction level." }, - '------', - { "reality stack": "structure consisting of all layers of reality encoding an agent's interaction with his environment - in their world model at a given moment, as well as all layers supporting these respectively." }, - '------', - { "physical reality": "layer of reality defined by physical matter and the physical laws acting upon it. - While the emergent phenomena of micro- and macro physics as well as layers of social existence etc. may be seen - as separate layers, for the purpose of this paper we will group these together under the term of physical reality." }, - { "mental reality": "layer of reality perceived and processed by the brain of a human agent." }, - { "digital reality": "layer of reality created and simulated by a digital system, e.g. a virtual reality game." }, - { "phys, mind, digi": "abbreviations for physical, mental and digital reality respectively." }, - } - if 'string' == type definition - \append hr! - continue - \append with div style: { 'margin-left': '2rem' } - term = next definition - \append span term, style: { - display: 'inline-block', - 'margin-left': '-2rem', - 'font-weight': 'bold', - 'min-width': '140px' - } - \append span definition[term] - - \append with sect "Introduction" - \append p "We identify two different types of relationships between layers in multi-reality environments. - The first is layer nesting. Layer nesting describes how some layers are contained in other layers; i.e. they exist - within and can be represented fully by the parent layer's world model and the child layer's rules emerge natively from - the parent layer's dynamics. Layer nesting is visualized on the vertical axis in the following diagrams. - For each layer of reality on the bottom of the diagram the nested parent layers can be found by tracing a line upwards - to the top of the diagram. Following a materialistic point of view, physical reality therefore must completely encompass - the top of each diagram." - - \append p "The second type of relationship describes the information flow between a subject and the layers of reality - the subject is immersed in. In a multi-reality experience the subject has access to multiple layers of reality and - their corresponding world models simultaneously.", br!, - "Depending on the specific experience, different types of and directions for information exchange - can exist between these layers and the subject's internal representation of the experience. - For the sake of this paper we distinguish only between ", (i "input"), " and ", (i "output"), " data flow (from the - perspective of the subject); categorized loosely as information the subject receives from the environment - (", (i "input"), ", e.g. visual stimuli) and actions the subject can take to influence the state of the world model - (", (i "output"), ", e.g. motor actions) respectively." - - \append p "In the following diagrams, information flow is visualized horizontally, in the region below the dashed line - at the bottom of the diagram. The subject's internal mental model and layer of reality are placed on the bottom left - side of the diagram. - The layers of reality that the subject experiences directly and that mirror it's internal representations are placed - on the far right. There may be multiple layers of reality sharing this space, visualized as a vertical stack of - layers. Since the subject must necessarily have a complete internal model of the multi-reality experience around - him to feel immersed, the subject's mental layer of reality must span the full height of all the layers visible - on the right side of the diagram.", br!, - "Information flow itself is now visualized concretely using arrows that cross layer boundaries in the lower part of - the diagram as described above. Arrows pointing leftwards denote ", (i "input"), " flow, whilst arrows pointing - rightwards denote ", (i "output"), "-directed information flow. In some cases information doesn't flow directly - between the layers the subject is directly aware of and the subject's internal representation and instead - traverses ", (i "intermediate layers"), " first." - - \append p "Before we take a look at some reality stacks corresponding to current VR and AR technology, - we can take a look at waking life as a baseline stack. To illustrate the format of the diagram we will compare it - to the stack corresponding to a dreaming state:" - - \append with figures! - \append addlabel "Waking Life", Diagram => - @mind! - @inout! - @phys! - - @next! - @phys '', 2 - @finish! - - \append addlabel "Dreaming", Diagram => - @mind! - @phys! - @finish! - - \append p "In both cases, the top of the diagram is fully occupied by the physical layer of reality, colored in green. - This is due to the fact that, according to the materialistic theory of mind, human consciousness owes its existance - to the physical and chemical dynamics of neurons in our brains. Therefore our mental reality must be considered - fully embedded in the physical reality, and consequently it may only appear underneath it in the diagram." - - \append p "During waking life, we concern ourselves mostly with the physical reality surrounding us. - For this reason the physical reality is placed in the lower right corner of the diagram as the layer holding the - external world model relevant to the subject. Information flows in both directions between the physical world model - and the subject's mental model, as denoted by the two white arrows: Information about the state of the world model - enter the subjects mind via the senses (top arrow, pointing leftwards), and choices the subject makes inside of and - based on his mental model can feed back into the physical layer through movements (lower arrow, pointing rightwards)." - - \append p "In the dreaming state on the other hand, the subject is unaware of the physical layer of reality, though - the mind remains embedded inside it. When dreaming, subjects' mental models don't depend on external models, hence - the mental layer of reality must be the only layer along the bottom of the diagram." - - \append with sect "Current Technologies" - \append p "Since recent technological advancements have enabled the development of VR and AR consumer devices, - AR and VR have been established as the potential next frontier of digital entertainment.", br!, - "As the names imply, the notion of reality is at the core of both technologies. - In the following section we will take a look at the respective stacks of both experience types:" - - \append with figures! - \append addlabel "VR", Diagram => - @mind! - @phys! - @inout nil, 1 - - @next! - @phys '', 2 - @inout nil, 1 - - @next! - @digi! - @phys '' - @finish! - - - \append addlabel "AR", Diagram => - @mind! - @inout nil, 1.25 - @inn nil, 0.5 - @phys! - - @next! - @phys '', 2 - @inn nil, .5 - - @next! - @digi nil, .5 - @phys '', 1.5 - @finish! - - \append p "In both cases we find the physical layer of reality as an ", (i "intermediate layer"), " between the mental - and digital layers. Actions taken by the subject have to be acted out physically (corresponding to the - information traversing the barrier between mental and physical reality) before they can be again digitized using - the various tracking and input technologies (which in turn carry the information across the boundary of the physical - and digital spaces)." - - \append p "The difference between AR and VR lies in the fact that in AR the subject experiences a mixture of the - digital and physical world models. This can be seen in the diagram, where we find that right of the diagram origin - and the mental model, the diagram splits and terminates in both layers: while information reaches the subject both - from the digital reality through the physical one, as well as directly from the physical reality, the subject only - directly manipulates state in the physical reality." - - \append p "The data conversions necessary at layer boundaries incur at the least losses in quality and accuracy of - information for purely technical reasons. However ", (i "intermediate layers"), " come at a cost larger than just - an additional step of conversion: - For information to flow through a layer, it must be encodable within that layer’s world model. - This means that the 'weakest link' in a given reality stack determines the upper bound of information possible to - encode within said stack and thereby limits the overall expressivity of the stack.", br!, - "As a practical example we can consider creating an hypothetical VR application that allows users to traverse a - large virtual space by flying. While the human mind is perfectly capable of imagining to fly and control the motion - appropriately, it is extremely hard to devise and implement a satisfying setup and control scheme because the - physical body of the user needs to be taken into account and it, unlike the corresponding representations in the - mental and digital world models, cannot float around freely." - - \append with sect "Future Developments" - \append p "In the previous section we found that the presence of the physical layer in the information path of - VR and AR stacks limits the experience as a whole. It follows that the removal of that indirection should be - an obvious goal for future developments:" - - \append figures addlabel "holy grail of VR: 'The Matrix'", Diagram => - @mind! - @inout! - @phys! - - @next! - @digi! - @phys '' - @finish! - - \append p "In the action movie 'The Matrix' ", (ref 'Matrix'), ", users of the titular VR environment interface with it - by plugging cables into implanted sockets that connect the simulation directly to their central nervous system.", br!, - "While these cables and implanted devices are physical devices, they don't constitute the presence of the - physical layer of reality in the information path because while they do transmit information, the information - remains in either the encoding of the mental model (neural firing patterns) or the encoding of the digital model - (e.g. a numeric encoding of a player character's movement in digital space) and the conversion is made directly - between those two - the data never assumes the native encoding of the physical layer (e.g. as a physical motion)." - - \append p "While we are currently far from being able to read arbitrary high-level information from the brain - or to synthesize sensual input in human perception by bypassing the sensory organs, brain-computer interfaces (BCI) - are a very active area of research with high hopes for comparable achievements in the near future." - - \append p "Applying this same step of removing the physical layer of reality from AR, we end up with something similar - to the nano-particle drug in ", (i "Nexus"), " ", (ref 'Naam'), ". However this does not grant the user a similar - amount of control over his experience as the holy grail of VR does, since the user and the physical part of the - environment remain bound by the physical layer of reality's laws.", br!, - "Instead the holy grail of AR is reached with the creation of a god machine that can manipulate the state of the - physical world according to the user's wishes. In this way the digital and physical realities become unified and - fully 'augmented'." - - \append with figures! - \append addlabel "'Nexus'", Diagram => - @mind! - @inout nil, 0.75 - @inout nil, 1.25 - @phys! - - @next! - @digi nil, .5 - @phys '', 1.5 - @finish! - - \append addlabel "holy grail of AR: 'Deus Machina'", Diagram => - col = '#92807c' - - @mind! - @inout! - @block col, '' - - @next! - @block col, '', 2 - @svg\plain('phys + digi')\attr(o fill: 'white', 'font-size': '14px')\move 6, -2 * GRID_H - @finish! - - \append p "Despite the similarities of VR and AR, the two can be considered polar opposites, as becomes evident when - we compare their respective utopian implementations: they share the goal of allowing us to experience realities - different from the one we naturally inhabit, but while VR seeks to accomplish this by creating a new, nested reality - inside ours, thus giving us full control over it. - AR, on the other hand, is instead an attempt to retrofit our specific needs directly into the very reality we exist - in.", br!, - "This is in direct contrast with the popular notion of the 'reality-virtuality continuum' ", (ref 'Milgram'), ": - the reality-virtuality continuum places common reality and VR (virtuality) as the two extreme poles, while AR - is represented as an intermediate state between the two. Here however we propose to view instead AR and VR as the - respective poles and find instead reality at the centerpoint, where the two opposing influences 'cancel out'." - - \append with sect "Conclusion and Further Work" - \append p "In this paper we have proposed a taxonomy and visualization style for multi-reality experiences, as well - as demonstrated it's flexibility by applying them as examples. Through the application of the proposed theory, - we have also gained a new and contrasting view on preceding work such as the reality-virtuality-continuum. - We have also found that the taxonomy can be used outside the research field of media studies and its use may extend - as far as philosophy of consciousness (see Appendix below)." - - \append p "Further research could enhance the proposed theory with better and more concrete definitions. - In the future, the proposed taxonomy might be used to create a more extensive and complete classification - of reality stacks and to analyse the relationships between them." - - \append with sect 'References' - \append references! - - \append with sect "Appendix: Relation to Theories of Mind" - \append p "This paper starts from a deeply materialistic point of view that borders on microphysicalism. - However it should be noted that the diagram style introduced above lends itself also to display other - philosophical theories of mind. As an example, the following graphics show a typical VR stack as interpreted by - Materialism, Cartesian Dualism and Solipsism respectively:" - - \append with figures! - \append addlabel "VR in Materialism", Diagram => - @mind! - @inout nil, 1 - @phys! - - @next! - @phys '', 2 - @inout nil, 1 - - @next! - @digi! - @phys '' - - @finish! - - \append addlabel "VR in Solipsism", Diagram => - @mind nil, 2 - @inout nil, 1 - - @next! - @digi! - @mind '' - @finish! - - \append addlabel "VR in Cartesian Dualism", Diagram => - @mind nil, 2 - @inout nil, 1 - @next! - - @phys nil, 2 - @inout nil, 1 - @next! - - @digi! - @phys '' - @finish! - - \append p "However these philosophical theories of minds also constitute reality stacks by themselves and as such can - be compared directly:" - - \append with figures! - \append addlabel "Materialism", Diagram => - @mind! - @inout! - @phys! - - @next! - @phys '', 2 - @finish! - - \append addlabel "Solipsism", Diagram => - @mind! - @finish! - - \append addlabel "Cartesian Dualism", Diagram => - @mind! - @inout! - @next! - - @phys! - @finish! - -_content diff --git a/root/research/text$moonscript -> fn -> mmm$dom.moon b/root/research/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index aec02d9..0000000 --- a/root/research/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,10 +0,0 @@ -import div, h3, ul, li from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - div { - h3 link_to @ - ul for child in *@children - desc = child\gett 'description: mmm/dom' - li (link_to child), ': ', desc - } diff --git a/root/research/title: text$plain b/root/research/title: text$plain deleted file mode 100644 index c985e65..0000000 --- a/root/research/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -research diff --git a/root/research/watch-cad/description: text$plain b/root/research/watch-cad/description: text$plain deleted file mode 100644 index 75d7887..0000000 --- a/root/research/watch-cad/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -immediate-mode scripting for direct-manipulation of graphics diff --git a/root/research/watch-cad/link: URL b/root/research/watch-cad/link: URL deleted file mode 100644 index fdee7eb..0000000 --- a/root/research/watch-cad/link: URL +++ /dev/null @@ -1 +0,0 @@ -https://git.s-ol.nu/watch-cad/ diff --git a/root/static/$order b/root/static/$order index 1c079db..08ba4e6 100644 --- a/root/static/$order +++ b/root/static/$order @@ -1,4 +1,3 @@ highlight-pack style fengari-web -mmm diff --git a/root/text$moonscript -> fn -> mmm$dom.moon b/root/text$moonscript -> fn -> mmm$dom.moon index a77765a..262c24d 100644 --- a/root/text$moonscript -> fn -> mmm$dom.moon +++ b/root/text$moonscript -> fn -> mmm$dom.moon @@ -19,10 +19,6 @@ import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' 'You can find the source code of everything ' a { 'here', href: 'https://git.s-ol.nu/mmm' } '.' - br! - 'Most of the inner-workings of this page are documented in ' - link_to @walk 'research/mmmfs' - '.' } for child in *@children diff --git a/root/workshops/$order b/root/workshops/$order deleted file mode 100644 index d74b9f3..0000000 --- a/root/workshops/$order +++ /dev/null @@ -1,3 +0,0 @@ -xy-music -shaders -creative-coding diff --git a/root/workshops/creative-coding/description: text$plain b/root/workshops/creative-coding/description: text$plain deleted file mode 100644 index 5b53cf4..0000000 --- a/root/workshops/creative-coding/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -creative coding for web developers diff --git a/root/workshops/creative-coding/text$markdown.md b/root/workshops/creative-coding/text$markdown.md deleted file mode 100644 index 8d6bf76..0000000 --- a/root/workshops/creative-coding/text$markdown.md +++ /dev/null @@ -1,34 +0,0 @@ -# creative coding for web developers -This is a workshop i am currently preparing. -If you are interested in having this workshop be held at your institution, -please contact me! - -## topics -In this workshop I will introduce the topic of *creative coding*, present some -inspiration and examples, as well as teach the basics of the JavaScript canvas -API for creating artistic animations and other creative projects such as -the following: - -<mmm-embed nolink path="../../projects/demoloops/toroid"></mmm-embed> -<mmm-embed nolink path="../../projects/demoloops/twisted"></mmm-embed> - -* <mmm-link path="../../experiments/center_of_mass">experiment: aligning fonts by their center of mass</mmm-link> -* <mmm-link path="../../experiments/parallax_panels">experiment: parallax SVG viewer</mmm-link> - -The workshop is designed to accompany an 'industry-focused' course in web development, -and aims to deliver some wider perspective over the possibilities and creative use of -technology to participants. The following topics are covered: - -- what is creative coding? -- creative coding frameworks -- the canvas API - - drawing basic shapes - - colors - - input events -- animation - - `requestAnimationFrame` - - easing functions -- online creative coding communities - -The exact topics and structure can be adjusted based on the course runtime and -level of the participants' experience. diff --git a/root/workshops/shaders/description: text$plain b/root/workshops/shaders/description: text$plain deleted file mode 100644 index d3e92b1..0000000 --- a/root/workshops/shaders/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -(procedural) graphics with math and shaders diff --git a/root/workshops/shaders/text$markdown.md b/root/workshops/shaders/text$markdown.md deleted file mode 100644 index cea0001..0000000 --- a/root/workshops/shaders/text$markdown.md +++ /dev/null @@ -1,31 +0,0 @@ -# (procedural) graphics with math and shaders -This is a workshop i am currently preparing. -If you are interested in having this workshop be held at your institution, -please contact me! - -## topics -In this workshop I will cover the principles and tricks behind procedural -graphics and animations like the following examples: - -<mmm-embed nolink path="../../projects/demoloops/toroid"></mmm-embed> -<mmm-embed nolink path="../../projects/VJmidiKit/boxy_dnb"></mmm-embed> -<mmm-embed nolink path="../../projects/VJmidiKit/kaleidoscope"></mmm-embed> -<mmm-embed nolink path="../../projects/demoloops/twisted"></mmm-embed> - -I plan to introduce the participants to the following topics: - -- what are procedural graphics? -- what are shaders? -- drawing a circle (with math) -- transforming space - - moving, scaling, rotating - - mirroring, repeating, fractals - - bending space -- procedural animation - - tweaking motion - - easing functions -- signed distance fields and raymarching -- basic lighting - -The exact topics and structure can be adjusted based on the course runtime and -level of the participants' experience. diff --git a/root/workshops/text$moonscript -> fn -> mmm$dom.moon b/root/workshops/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 372a96f..0000000 --- a/root/workshops/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,10 +0,0 @@ -import div, h3, ul, li, p from require 'mmm.dom' -import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom' - -=> - div { - h3 link_to @ - ul for child in *@children - desc = child\gett 'description: mmm/dom' - li (link_to child, desc) - } diff --git a/root/workshops/title: text$plain b/root/workshops/title: text$plain deleted file mode 100644 index 314277d..0000000 --- a/root/workshops/title: text$plain +++ /dev/null @@ -1 +0,0 @@ -workshops and teaching diff --git a/root/workshops/xy-music/$order b/root/workshops/xy-music/$order deleted file mode 100644 index e4e7469..0000000 --- a/root/workshops/xy-music/$order +++ /dev/null @@ -1 +0,0 @@ -slides diff --git a/root/workshops/xy-music/description: text$plain b/root/workshops/xy-music/description: text$plain deleted file mode 100644 index 71ea88e..0000000 --- a/root/workshops/xy-music/description: text$plain +++ /dev/null @@ -1 +0,0 @@ -oscilloscope music and games with pure data diff --git a/root/workshops/xy-music/slides/$order b/root/workshops/xy-music/slides/$order deleted file mode 100644 index 4600622..0000000 --- a/root/workshops/xy-music/slides/$order +++ /dev/null @@ -1,10 +0,0 @@ -01 -02 -03 -05 -04 -07 -01b -06 -08 -01c diff --git a/root/workshops/xy-music/slides/01/text$html+frag.html b/root/workshops/xy-music/slides/01/text$html+frag.html deleted file mode 100644 index 2441f62..0000000 --- a/root/workshops/xy-music/slides/01/text$html+frag.html +++ /dev/null @@ -1,7 +0,0 @@ -<div style="margin-top: 4em"> - <h2>Oscilloscope Music and Games with Pure Data</h2> - <br /> - <br /> - <br /> - <p>sol bekic, 2019</p> -</div> diff --git a/root/workshops/xy-music/slides/01b/text$markdown.md b/root/workshops/xy-music/slides/01b/text$markdown.md deleted file mode 100644 index 22c1454..0000000 --- a/root/workshops/xy-music/slides/01b/text$markdown.md +++ /dev/null @@ -1,12 +0,0 @@ -who am i? -========= - -my name is sol, -i like to program, build hardware and play with technology. - -- github: @s-ol -- mastodon: @s-ol\@merveilles.town -- twitter: @S0lll0s -- links to all of those, email, and more info: - https://s-ol.nu - diff --git a/root/workshops/xy-music/slides/01c/$order b/root/workshops/xy-music/slides/01c/$order deleted file mode 100644 index 2b68b52..0000000 --- a/root/workshops/xy-music/slides/01c/$order +++ /dev/null @@ -1 +0,0 @@ -video diff --git a/root/workshops/xy-music/slides/01c/text$markdown.md b/root/workshops/xy-music/slides/01c/text$markdown.md deleted file mode 100644 index ba5718c..0000000 --- a/root/workshops/xy-music/slides/01c/text$markdown.md +++ /dev/null @@ -1,5 +0,0 @@ -what am i going to talk about? -============================== -Plonat Atek - E317 - B14 / Pavillon 6 - -<iframe width="1220" height="630" frameborder="0" src="//www.youtube.com/embed/SIQAk9_nc-s"></iframe> diff --git a/root/workshops/xy-music/slides/01c/video/URL -> youtube$video b/root/workshops/xy-music/slides/01c/video/URL -> youtube$video deleted file mode 100644 index bf07555..0000000 --- a/root/workshops/xy-music/slides/01c/video/URL -> youtube$video +++ /dev/null @@ -1 +0,0 @@ -https://www.youtube.com/watch?v=SIQAk9_nc-s diff --git a/root/workshops/xy-music/slides/02/text$markdown.md b/root/workshops/xy-music/slides/02/text$markdown.md deleted file mode 100644 index 3496b23..0000000 --- a/root/workshops/xy-music/slides/02/text$markdown.md +++ /dev/null @@ -1,12 +0,0 @@ -what am i going to talk about? -============================== - -<br /> - -- sound + scopes - - what is sound? - - what is an oscilloscope? -- pd + the audiovisual - - osc~ + output~ - - numbers boxes + sliders - - lissajous figures + sync diff --git a/root/workshops/xy-music/slides/03/text$markdown.md b/root/workshops/xy-music/slides/03/text$markdown.md deleted file mode 100644 index c90491e..0000000 --- a/root/workshops/xy-music/slides/03/text$markdown.md +++ /dev/null @@ -1,12 +0,0 @@ -what is sound? -============== -<br /> - -- *vibrations* in the air -- movement of your ear drum -- movement of a speaker membrane -- numbers in a file on your computer - -what do they all have in common? -- something is *changing over time* - - a wave! diff --git a/root/workshops/xy-music/slides/04/text$markdown.md b/root/workshops/xy-music/slides/04/text$markdown.md deleted file mode 100644 index e07fbca..0000000 --- a/root/workshops/xy-music/slides/04/text$markdown.md +++ /dev/null @@ -1,9 +0,0 @@ -what is sound? -============== - -waves are *something* changing over time: - -- in the air: pressure (in one spot) -- ear drum and speakers: distance from normal position -- audio cable: voltage over time -- sound file: number over time diff --git a/root/workshops/xy-music/slides/05/text$markdown.md b/root/workshops/xy-music/slides/05/text$markdown.md deleted file mode 100644 index 256c654..0000000 --- a/root/workshops/xy-music/slides/05/text$markdown.md +++ /dev/null @@ -1,12 +0,0 @@ -what is sound? -============== - -attributes of waves: - -| waves <div style="display: inline-block; width: 50px;"></div> | sounds <div style="display: inline-block; width: 10px;"></div> | | -|-------------|--------------------|----------------------------------| -| `amplitude` | `volume` | how far does the wave fluctuate? | -| `frequency` | `pitch` | how often does the wave repeat? | -| `shape` | `timbre` | (literally just the shape) | - -...let's look at + hear some examples! diff --git a/root/workshops/xy-music/slides/06/text$markdown.md b/root/workshops/xy-music/slides/06/text$markdown.md deleted file mode 100644 index fa5b139..0000000 --- a/root/workshops/xy-music/slides/06/text$markdown.md +++ /dev/null @@ -1,6 +0,0 @@ -on computers, sound is stored as a list of `samples`: - -- `sample rate`: how many samples per second are recorded -- `sample size` or `bit depth`: how accurate is each sample - - diff --git a/root/workshops/xy-music/slides/07/text$markdown.md b/root/workshops/xy-music/slides/07/text$markdown.md deleted file mode 100644 index 518b9fb..0000000 --- a/root/workshops/xy-music/slides/07/text$markdown.md +++ /dev/null @@ -1,6 +0,0 @@ -what is an oscilloscope? -======================== - -- machine for measuring and visualizing electronic waves (voltage) - - diff --git a/root/workshops/xy-music/slides/08/$order b/root/workshops/xy-music/slides/08/$order deleted file mode 100644 index 773b222..0000000 --- a/root/workshops/xy-music/slides/08/$order +++ /dev/null @@ -1 +0,0 @@ -image diff --git a/root/workshops/xy-music/slides/08/image/image$png.png b/root/workshops/xy-music/slides/08/image/image$png.png Binary files differdeleted file mode 100644 index ff82a9d..0000000 --- a/root/workshops/xy-music/slides/08/image/image$png.png +++ /dev/null diff --git a/root/workshops/xy-music/slides/08/text$markdown.md b/root/workshops/xy-music/slides/08/text$markdown.md deleted file mode 100644 index 1bec5c3..0000000 --- a/root/workshops/xy-music/slides/08/text$markdown.md +++ /dev/null @@ -1,4 +0,0 @@ -what is an oscilloscope? -======================== - - diff --git a/root/workshops/xy-music/slides/text$moonscript -> fn -> mmm$dom.moon b/root/workshops/xy-music/slides/text$moonscript -> fn -> mmm$dom.moon deleted file mode 100644 index 701a14c..0000000 --- a/root/workshops/xy-music/slides/text$moonscript -> fn -> mmm$dom.moon +++ /dev/null @@ -1,70 +0,0 @@ -import ReactiveVar, tohtml, fromhtml, text, elements from require 'mmm.component' -import article, button, div, span from elements - -=> - index = ReactiveVar 1 - slide = index\map (index) -> @children[index] - - local view - view = div { - style: - position: 'relative' - 'padding-top': '56.25%' - - div { - style: - position: 'absolute' - display: 'flex' - 'flex-direction': 'column' - top: 0 - left: 0 - right: 0 - bottom: 0 - padding: '1em' - background: '#eeeeee' - 'box-sizing': 'border-box' - - slide\map => @get 'mmm/dom' - } - } - - local left, right, viewNode - if MODE == 'CLIENT' - left = (_, e) -> - e\preventDefault! - index\transform (a) -> math.max 1, a - 1 - - right = (_, e) -> - e\preventDefault! - index\transform (a) -> math.min #@children, a + 1 - - viewNode = tohtml view - viewNode.tabIndex = 1 - viewNode\addEventListener 'keydown', (_, e) -> - switch e.key - when 'r' - e\preventDefault! - size = viewNode.offsetHeight / 15 - viewNode.style.fontSize = "#{size}px" - - when 'ArrowLeft' - left _, e - when 'ArrowRight' - right _, e - - tohtml with article! - \append div { - style: - display: 'flex' - - button '<', onclick: left - ' ' - span index\map (t) -> text t - ' ' - button '>', onclick: right - div style: flex: '1' - button 'fullscreen', onclick: (_, e) -> - e\preventDefault! - viewNode\requestFullscreen! - } - \append view diff --git a/root/workshops/xy-music/text$markdown.md b/root/workshops/xy-music/text$markdown.md deleted file mode 100644 index 3f4f09c..0000000 --- a/root/workshops/xy-music/text$markdown.md +++ /dev/null @@ -1,41 +0,0 @@ -# oscilloscope music and games with pure data - -<mmm-embed wrap="raw" path="../../games/plonat_atek/pictures/amaze" /></mmm-embed> - -This is a workshop I gave at [Maker Faire Rome 2019][mfr]. -For more information on my work on this topic, also see my Oscilloscope Game <mmm-link path="../../games/plonat_atek"></mmm-link>. - -## description - -> In this workshop we will learn how to view and listen to Oscilloscope Music, how it works, and how to create your own Oscilloscope Music using PureData. -> Please bring a laptop and headphones to participate. -> -> Oscilloscope Music is music produced in such a way, that when the stereo signal is applied to an Oscilloscope screen, -> the same signals that are heard create a visual animation. -> -> You can see some examples of Oscilloscope Music created by Jerobeam Fenderson here: -> -> - https://www.youtube.com/watch?v=rtR63-ecUNo -> - https://oscilloscopemusic.com/ -> -> In this workshop, we will cover the following: -> -> - What is Oscilloscope Music? -> - How do Oscilloscopes work? -> - How do Speakers and Audio Waves work? -> - Simulating an Oscilloscope on your laptop -> - Creating Oscilloscope Sounds using the PureData visual programming language -> -> No special experience is required for this workshop. -> Please bring a laptop and headphones! -> If you are using an Operating System other than Windows and Mac OS X, please install "purr-data" before the workshop. - -## slides - -focus the slide area with the mouse and hit 'r' to adjust the content scaling. -optimized for 1080p projectors. - -<mmm-embed wrap="raw" path="slides"></mmm-embed> - -[mfr]: https://2019.makerfairerome.eu/en/events-en/?ids=110 - |
