Things that live here:

  1. Work log, where I note things I feel I'll have to Google later.
  2. Journal, very similar but about non-IT topics.
  3. Blog for rare longer-form posts (last one below).
  4. Links blog, formerly my personal wiki.

Feel free to look at what you can find here and enjoy yourself.


~17% of my country is occupied by Russia, and horrible things are happening there. You can help stop this! If you can donate - I contribute to (and fully trust) Come Back Alive and Hospitallers, but there are also other ways to help.

If you're in Germany, DHL sends packets with humanitarian help for free!

Latest posts from the Work log

Day 1998 / Fish adventures in noglob, calculators and expressions

TL;DR: fish easy version below works, but needs quotes when expression has parentheses: cc 2+2 but cc 'floor(2.3)'.

I’m continuing to move my useful snippets from zsh to fish (240620-2109 Fish shell bits), and the most challenging one was the CLI python calculator I really love and depend on, since it contained arguments with parentheses (which are fish expressions as well).

Basically: cc WHATEVER runs WHATEVER inside python, can do both easy math a la 2+2 and more casual statistics-y mean([2,33,28]).

Before in zsh this was the magic function:

cc() python3 -c "from math import *; from statistics import *; print($*);"
alias cc='noglob cc'

Fish, easy version:

function cc
  command python3 -c "from math import *; from statistics import *; print($argv);"
end

Works for easy cc 2+2 bits, but as soon as functions and therefore parentheses get involved (cc floor(2.3)) it starts to error out.

[I] sh@nebra~/t $ cc mean([2,4])
fish: Unknown command: '[2,4]'
in command substitution
fish: Unknown command
cc mean([2,4])
       ^~~~~~^
[I] sh@nebra~/t $ cc mean\([2,4]\)

>>> mean([2,4])
3
[I] sh@nebra~/t $

(But I REALLY don’t want to do cc mean\([2, 3]\))

In the zsh snippet, noglob meant basically “take this literally w/o expanding anything”, and it passed everything as-is to python, and this is what fails in my fish solution.

Noglob in fish is fun:

THEN

  • command python3 -c "from math import *; from statistics import *; print($argv);"

    • cc ceil\(2\) +
    • cc ceil(2) -
  • `command python3 -c “from math import *; from statistics import *; print(’$argv’);”

    • literally prints the passed thing w/o python eval, w/ same rules
  • OK can I do a variable then?

  set pyc $argv
  echo $pyc
  command python3 -c "from math import *; from statistics import *; print($pyc);"

nope.

Bruteforcing the solution

(and learning to use fish loops mainly, of course there are better ways to do this.)


# list of simple, brackets, and parentheses + no, single, double quotes 
# no space between nums in brackets, python interpreter would add them. [2,3] — literal, [2, 3] — parsed by python
set cmds \
'2+2' \
'\'2+2\'' \
'"2+2"' \
'[2,3]' \
'\'[2,3]\'' \
'"[2,3]"' \
'floor(2.3)' \
'\'floor(2.3)\'' \
'"floor(2.3)"' 

function tcc
  set pyc $argv
  # command python3 -c "from math import *; from statistics import *; print" '(' "$pyc" ');'
  # command python3 -c "from math import *; from statistics import *; print($pyc);"
  command python3 -c "from math import *; from statistics import *; print($pyc);"
end


# loop through all test cases to see sth that works for all
for i in $cmds
  echo $i:
  echo "   $(tcc $i)"
end

At the end, no additional literal quotes + initial command didn’t error out, and we came full circle:

set cmds \
'2+2' \
'[2,3]' \
'floor(2.3)' 

# winner command!
function tcc
  command python3 -c "from math import *; from statistics import *; print($argv);"
end
[I] sh@nebra~/t $ ./test_cc.sh
2+2:
   4
[2,3]:
   [2, 3]
floor(2.3):
   2
  • Double quotes in the python command mean only $pyc gets expanded
  • $pyc in the working versions have no hard-coded quotes
  • in CLI tcc floor(2.3) still fails — because like that it’s a command, not a string. In the file it was inside single quotes, as a string. So I can do this in the CLI as well.

So simple and logical at the end.

Final solution

function cc
  echo ">>> $argv"
  command python3 -c "from math import *; from statistics import *; print($argv);"
end

When using, quotes are needed only for parentheses, and then both ' and " work.

[I] sh@nebra~/t $ cc 2+2
>>> 2+2
4

[I] sh@nebra~/t $ cc [2,3,4]
>>> [2,3,4]
[2, 3, 4]

# no quotes
[I] sh@nebra~/t $ cc mean([2,3,4])
fish: Unknown command: '[2,3,4]'
in command substitution
fish: Unknown command
cc mean([2,3,4])
       ^~~~~~~~^

# with quotes
[I] sh@nebra~/t $ cc 'mean([2,3,4])'
>>> mean([2,3,4])
3

So I literally had to follow the advice from the first link I found and used single quotes in my initial command:

If you wish to use arguments that may be expanded somehow literally, quote them. echo ‘’ and echo “” both will print the literal.

Still, I learned a lot about fish in the process and honestly am loving it.

Day 1997

Quarto --no-clean creates html.md files and errors

TL;DR –no-clean is dangerous

quarto render --no-clean ... (or an interrupted render?) created many .html.md files in the same dirs as their .qmd/.md sources:


papers/11-bank2011using/index.md               papers/23-hanig2023nlp/index.md
papers/11-hanig2011benefits/index.html.md      papers/23-tumler2023virtual/index.html.md
papers/11-hanig2011benefits/index.md           papers/23-tumler2023virtual/index.md
papers/11-hanig2011knowledge/index.html.md     papers/24-hamotskyi2024fincorpus/index.html.md
papers/

Then the custom listing for */*.md went crazy because the html.md files didn’t have the needed fields. (also .jsons/.html etc.)

Quarto has no quarto clean but one can just re-render everything without --no-clean

Fish globs

To find all these files arbitrarily many levels deep:

ls **/*.html.md

Previewing quarto websites locally

When doing a multilingual quarto website using profiles (240619-1425 Quarto multilanguage website), quarto preview/render --profile de allows previewing only one language, and the menu links (/de/xxx) break.

Solution to preview EVERYTHING, including menu links logic:

# Todo break on erorr
quarto render --profile=ua
quarto render --profile=en
quarto render --profile=de

And then serve the _site directory locally through a simple webserver, e.g. Python SimpleHTTPServer - Python HTTP Server | DigitalOcean, and see the result on http://localhost:9000:

python3 -m http.server -d _site 9000

Fish shell bits

Run and disown

In my old zsh config I had this:

function dos() {
    # run_disowned and silenced
    nohup "$@" >/dev/null 2>&1 & disown
}

Emulating my old dos command in fish:

Both together give this solution:

function dos
  echo "disowning $argv"
  command $argv  >/dev/null 2>&1 &
  disown
end

Shell notation for $(cmd)

shell - Fish equivalent of bash $(command) notation - Stack Overflow: - bash: $(command) - fish: (command)

Day 1996

Quarto multilanguage website

Config files

_quarto-profilename.yml ONLY, the rest won’t get parsed

profile:
  default: en
  # mutually exclusive group: you can do only one
  # (otherwise `--profile one,two` does multiple)
  group: 
    - [en, de, uk]

Page content

# `unless-profile` exists as well
::: {.content-visible when-profile="en"}
This content will only appear in the advanced version.
:::

Links are going to be interesting!

Currently /de is German, / is English.

Main home page is .. from DE lang, or /de from EN.

Menu items:

  • ENG as-is. (`href: whatever.qmd)
  • DEU: href: ../de/lehre.html — note the HTML bit!

But when previewing DEU, all of these pages are at / — ergo menu items don’t work, as they lead to a non-existing ../de/...

ALSO: marioangst.de shows nicely how one can link to other languages from the menu!

- icon: book
href: publications.qmd
text: Publikationen
- href: ../en/blog
text: Blog (englisch)

Site language

Website Options – Quarto tells me I can do this in each _quarto-de.yml etc. profile:

format:
  html:
    lang: de
	#lang: ua
	#lang: en

This changes the interface to follow the corresponding quarto-cli/src/resources/language/_language.yml at main · quarto-dev/quarto-cli

Unsolved

How do I change front matter (e.g. title)?

Not dealt with in any of the approaches: quarto’s native Document Language1 thing

So: - How do I do different post titles per language? - How do I change site language, so _languages.yml, conditionally?

  • Project Basics – Quarto discusses the various approaches to metadata

    • And I can conditionally include stuff
  • … I could literally do a bash script that puts a _metadata.yaml, builds with a proflie, then removes that file. Oh this would be painful

  • Skimming Website Options – Quarto doesn’t really help

    • except that I can set html format lang: de from within profiles! NICE
Do variables magic
# works
title-en: "Publications and Awards"
title: "{\{< meta title-en >}}"

If only I could do per-language attributes as shown in the docu2:

language:
  en:
    title-block-published: "Updated"
  fr:
    title-block-published: "Mis à jour"

It would be so cool if one could overwrite the other variables

language:
  de: 
    title: german post title

The above would nicely get a language from the profile _quarto-lang.yml and automatically change the things. Can I do this for titles and front-matter?

I can get the current profile from the env variable

profile: {\{< env QUARTO_PROFILE >}}

If I could just

title: vars['titles']['postname'][QUARTO_PROFILE]
Use scripts

Quarto lua filters

OK let’s do this. No choice.

Learn Lua in Y Minutes

First3 attempt to write anything in lua:

function Meta(m)
  local profiles = quarto.project.profile
  local profile = profiles[1]
  if profile then
    print("Profile: " .. profile)
    m.active_profile = profile
  end

  if profile and m.titles and m.titles[profile] then
    cleantitle = pandoc.utils.stringify(m.titles[profile])
    oldtitle = pandoc.utils.stringify(m.title)
    m.title = cleantitle
    print("Profile:" .. profile)
    print("Old title:" .. oldtitle)
    print("New title:" .. cleantitle)
  end

  return m
end

I’d need to make it more robust:

  • multiple profiles? Not now
  • No titles set in titles — use the default one

So:

  • Always require a title
  • Optionally add array of titles, indexed by language=profile name
  • If present use one of these.
function Meta(m)
  local profiles = quarto.project.profile
  if not profiles then
    -- TODO: missing YAML key? Empty YAML key?..
    -- TODO even more later: filter multiple profiles to use the language one
    return m
  end

  local profile = profiles[1]
  -- If we have a named profile, save it, otherwise return
  if profile then
    print("Profile: " .. profile)
    m.active_profile = profile
  else
    return m
  end

  if m.titles then
    local titles = m.titles
    if titles[profile] then
      newtitle = pandoc.utils.stringify(titles[profile])
      oldtitle = pandoc.utils.stringify(m.title)
      -- log both if they differ
      if newtitle ~= oldtitle then
        m.title = newtitle
        -- print("Old title:" .. oldtitle)
        -- print("New title:" .. newtitle)
        print(oldtitle .. " => " .. newtitle)
      end
    else
      print("Title for profile " .. profile .. " not found among ")
      for lang, title in pairs(titles) do -- Table iteration.
        print("    " .. lang .. ": " .. pandoc.utils.stringify(title))
      end
    end
  end

  return m
end

Main problems:

  • listing pages use the old title anyway
  • supports only title, not e.g. description (used, again, in listings)
    • and side menus!

  1. Document Language – Quarto ↩︎ ↩︎

  2. [Document Language (alternates) – Quarto](https://quarto.org/docs/authoring/language.html↩︎

  3. I think Master Thesis pandoc required lua magic and I tried some small pandoc filter bits, але це було давно і неправда. ↩︎

Quarto error title.trim() is not a function in qmd front-matter YAML

ERROR: TypeError: title.trim is not a function quarto

happens for me when in front-matter I do

---
# title: "Publications and Awards"
title: {\{< var test >}}

instead of QUOTED

---
# title: "Publications and Awards"
title: "{\{< var test >}}"

ALSO, interestingly, when I save the wrong version while previewing the error is better:

ERROR: Validation of YAML front matter failed.
ERROR: In file publications.qmd
(line 3, columns 8--24) Field "title" has value {\{< var test >}}, which must insteadbe a string
2: # title: "Publications and Awards"
3: title: {\{< var test >}}
         ~~~~~~~~~~~~~~~~~
4: css: ./posts_publications/pub_style.css
✖ The value {\{< var test >}} is of type object.
ℹ The error happened in location title.

ERROR: Render failed due to invalid YAML.

So: quarto errors are more detailed when previewing instead of when compiling from zero? Interesting. Okay.

Day 1995

Quarto publications page and adding anchors

Given: quarto website page with publications. Previously touched upon in the messy 240605-2055 Quarto website creation notes.

This works:

[UNLP paper](publications.qmd#hamotskyi2024unlp)

Anchor targets

Template

// Get anchor id somehow from paper path
<% let y= item.path.split('/'); y.pop(); let dirname = y.pop(); let citation_key = dirname.split('-').pop() %>

// Overwrite with paper front-matter if there's one
<% if (item.citation_key) { %> 
	<% citation_key = item.citation_key %>
<% } %>       

// Add to paper listing thing 
<a id="<%= citation_key %>"></a>

EJS comments

All from javascript - How can I comment the EJS code (JS node) without getting an error - Stack Overflow:



// Neat multiline comment thing
<%if(false) {%>  
  <!-- single row of inline icons for pdf. etc instead of buttons -->
<%} %>

// hard to grep for and no syntax highlight, so maybea adding COMMENT works as my bad idea
<%if(false) {%>  
  <!-- COMMENT 
	single row of inline icons for pdf. etc instead of buttons 
  -->

// Documentation says: 
<%# comment %> 


// Not documentation, multiline comment:
<%/* comment */%> 

I had issues putting HTML code w/ EJS snippets in the latter one, so iffalse it is. For nested things, SO suggests these (both bad imo):

<!--label for="<%#= user.id %>" style="background-color: <%#= user.color %>;"-->
<!--label for= <%#=`${user.id}` %> style= <%#=`background-color: ${user.color};`%> -->

Day 1985 / Arch linux xlock before suspend service

Old way with systemd

/etc/systemd/system/user-suspend@.service:

[Unit]
Description=Lock the screen
Before=sleep.target

[Service]
User=%I
Type=forking
Environment=DISPLAY=:0
ExecStart=/usr/bin/xlock -usefirst -echokeys -description -modelist swarm,starfish,mandelbrot,polyominoes,fadeplot,matrix,lisa,life3d,life1d,kumppa,grav,flow


[Install]
WantedBy=sleep.target 

To enable1: sudo systemctl enable user-suspend@myusername.service

Arch wiki (Session lock - ArchWiki) omits @myusername which leads to this error:

Failed to enable unit: Destination unit sleep.target is a non-template unit.

Also: xlock (xlockmore) is neat, here’s a list of modes: XlockMore modes

(Also: XScreenSaver versus XLock)

Offtopic but cool: Cool, but obscure X11 tools

New way with xss-lock

Added this to qtile autostart:

xss-lock -- xlock -usefirst -echokeys -modelist qix,lisa & 

Also

Auto-lock after 300 seconds:

xset s on xset s 300

Day 1984

Screenshots in qtile with maim

maim is supposed to be the “better scrot”1

# screenshot and put into clipboard
 maim -s | xclip -selection clipboard -t image/png -i

In qtile you can’t do that, because | is a shell construct2.

Solution: do it in a shell:

CommandSet(commands={
	#...
	"S/clipboard": "bash -c \"maim -s | xclip -selection clipboard -t image/png -i\"",

DDG feeling lucky custom search engine in qutebrowser

Added ddg’s backslash-feeling-lucky to qb search engines. Encoded the backslash as URI, it worked!

https://duckduckgo.com/?q=%5C{}

Full list:

c.url.searchengines = {
        'DEFAULT': 'https://search.brave.com/search?q={}',
        'b': 'https://search.brave.com/search?q={}',
        'g': 'https://google.com/search?q={}', 
        's': 'https://scholar.google.de/scholar?hl=de&as_sdt=0%2C5&q={}&btnG=', 
        'ddg': 'https://duckduckgo.com/?q={}', 
        'l': 'https://duckduckgo.com/?q=%5C{}', 
        'c': 'http://dict.cc/?s={}', 
        'y': 'https://youtube.com/results?search_query={}',
        'd': 'https://en.wiktionary.org/wiki/Special:Search?search={}',
        'w': 'https://en.wikipedia.org/wiki/Special:Search?search={}',
        'wa': 'http://wolframalpha.com/input?i={}', 
}

Day 1982

Quarto website creation notes

quarto create project 

Listing pages

---
title: "Blog"
listing:
- id: test-l1
  contents: "blog_posts/*"
  sort: "date desc"
  type: table
  categories: true
- id: test-l2
  contents: "blog_posts/*"
  sort: "date desc"
  type: default
  categories: true
- id: test-l3
  contents: "blog_posts/*"
  sort: "date desc"
  type: grid
  categories: true
---

This will be a test listing page.


## Table listing
::: {#test-l1}
:::


## Default listing
::: {#test-l2}
:::


## Grid listing
::: {#test-l3}
:::
  • Configs
    • each directory can have it’s own _metadata.yml with configs that will be applied to all files in that directory

Publications

To get something like Drew Dimmery - Research or our old wowchemy thingy some magic will be needed.

Doing

---
title: "Publications and Awards"
bibliography: "./publications/papers.bib"
nocite: |
  @*
---

results in a list in a certain CSL format, which is limited — no ways to link videos/slides/… etc.

So likely it’ll be yet another listings view, or how Drew Dimmery - Quarto for an Academic Website did it — papers to YAML with ALL the metadata, then python script (inside quarto qmds, first nice case I see for this!) to convert it into the on-screen form.

And if code — then maybe it’s a conveter package from wowchemy yaml thingy?

OK, then:

  • Concatenate all wowchemy publication files into one large yaml (one-time python thing?)
  • do EJS template for it

(Alternatively — just use the dirs as-is and do no yaml)

Onwards

Creating a publications view


	<% for (let i = 0; i < item['authors'].length; i++) { %>
<%= item['authors'][i] %>,
    <% } %>

Changes in the paper mds

  • Remove markdown from all existing paper md, HTML-only
  • Remove “image” key
  • date is publishing date of the paper, not of its page — publishDate doesn’t exist
  • publicationType: maybe at some point change the int representation into str, as per latest hugo blocks behaviour
  • doi: no URI
  • publication: no In *journal*, just journal

This and only this will be supported:

title: 'Title'
authors:
  - TODO
  - TODO
date: '2010-10-20T00:00:00Z'
doi: 

# Publication name and optional abbreviated publication name.
publication: 'Proceedings of the World Congress on Engineering and Computer Science. Vol. 1'
publication_short: 'WCeCS 2010'

abstract: 'Long abstract'
links:
  - name: TODO Anthology
    url: https://aclanthology.org/L14-1240

url_pdf:
slides:
video:

tags:
  - paper-tag

EDIT: more fields here: hugo-blox-builder/modules/blox-bootstrap/archetypes/publication/index.md at main · HugoBlox/hugo-blox-builder

url_pdf:
url_code:
url_dataset:
url_poster:
url_source:
url_project:
url_slides:
url_video:

Process

Parsing date year

Datetime formatting / customization in ejs - Stack Overflow describes ways to do things with dates in EJS/JS

<%= new Date().getFullYear();%>

OK so I can use JS?

// Works
<%= new Date(item.date).getFullYear() %>

Iconify Icons

I can’t seem to use shortcodes inside html EJS (same as markdown problem I guess?)

But I can use the CSS (and ofc just download the PNG files)

Accessing file path to find its Bibtex

.. in a file inside same dir as paper markdown.

Most horrible thing I’ve ever written but seems to work:

<%= item.path %><br>              
<% let x= item.path.split('/') %> 
<% x.pop() %>                     
<%- x.join('/') %>                
<%- x.join('/') %>/cite.bib       

// ---

<% let x= item.path.split('/'); x.pop(); let biburi =  x.join('/')+'/cite.bib' %>
<a href="<%- biburi %>">
	<%= biburi %>
</a>

(I should just do a lua filter or something at this point)

Anchors

Idea: link from elsewhere directly to the paper in papers

Final system: described in 240618-1448 Quarto publications page and adding anchors

Quarto multilingual website options

And back to exporting obsidian to hugo

Obyde needs 3.8 and fails otherwise, new OS maybe time for new ways to convert. There are many actually. Some active mantained and expandable.

For later:

So

obsidian-to-hugo doesn’t support assets/images :( Leaving only ukautz/obsidian-meets-hugo: Command line tool to export Obsidian Vault into Hugo published website for me.

  • preserves Obsidian directory structure — nice
  • not recursive by default
  • doesn’t create _index.md files, and converts existing ones in Obsidian to -index.md
  • doesn’t support folders, but one can filter by tags — good that I used both since the beginning!
    • for multiple tags a “list” is possible — and apparently that’s -i tag1 -i tag2 -i tag31

Current CLI:

go run cmds/omh/main.go --obsidian-root=../public_obs/ -R --hugo-root=../dtb/ --sub-path= -i=uni -i=zc/it -i=zc/rl

Onwards

  • 3 refs not found
  • cyrillic names now unsupported?
    • 220407-2246 Чебуреки etc.
    • damn.
    • It’s the same
      var insane = regexp.MustCompile(`[^a-zA-Z0-9\-]`)
      func Sanitize(in string) string {
      	return insane.ReplaceAllString(in, "")
      }
      
    • w/ chatGPT, changed regex to [^a-zA-Z0-9\-\p{Cyrillic}] — now it does upper+lowercase cyrillics — so now it’s 220407-2246-Чебуреки.md in the md filename, but the URI has it lowercased.
    • Relevant: disablePathToLower in config2 — not changing because cool URIs don’t change and this was the default for years on this website
  • Images are broken
    • ![2024-05-13-182935_1304x442_scrot.png](//assets/2024-05-13-182935-1304-x-442-scrot.png)
    • //assets alrighty…
    • Docu: Static files | Hugo
      • By default, the static/ directory in the site project is used for all static files (e.g. stylesheets, JavaScript, images). The static files are served on the site root path (eg. if you have the file static/image.png you can access it using http://{server-url}/image.png, to include it in a document you can use ![Example image](/image.png)).

      • you can have multiple such directories
    • Ah — maybe it’ll work when uploaded to my website, where /xxx will refer to the website and not my local install
    • If I manually fix //assets/.. to /assets (one slash) then it shows up nicely locally
    • In omh.go this happens: return fmt.Sprintf("[%s](/%s/%s)", title, c.SubPath, target)
    • AH it’s because of my empty subpath directory argument — if I pass something then everything works. Oh GodDAMN it.
    • OK this fixes it. And I hope creates no more problems.
      if c.SubPath == "" {
          return fmt.Sprintf("[%s](%s/%s)", title, c.SubPath, target)
        } else {
      return fmt.Sprintf("[%s](/%s/%s)", title, c.SubPath, target)
      
    } ```
  • Debugging a notes called _index I realize that it takes Hugo frontmatter title from note title, which in turn is the filename, NOT the obsidian file frontmatter title :(
    • problem because my layouts rely on a magic constant in some directories…
    • I hope it’s my last fix.
  // Keep title in Obsidian front-matter as note title if it's there (a la obyde), 
  // otherwise use Obsidian filename for this (standard behaviour). 
  oldTitle := hugo["title"]
  if oldTitle==nil {
    log.Warn("No title in front-matter, using filename in ", note.Title)
    // must have title
    hugo["title"] = note.Title
  } else {
    log.Warn("Using frontmatter title for ", oldTitle)
  }

Day 1981 / New Linux install notes

Wanted to do Manjaro, after googling found out it has a very bad reputation (arindas/manjarno: Reasons for which I don’t use Manjaro anymore) — I’ll go with EndeavourOS. OpenSUSE Tumbleweed will be my next choice if this fails.

Strategy:

  • /opt will have executable programs
    • TG, hugo(?), pycharm, kitty?..
    • qtile, qutebrowser
  • home encrypted, but separate swap+etc. partitions of size of ram
    • or not, since encrypted home/swap/… and hibernation are hard — so only encryption
  • FS: BTRFS
    • …because snappshotting for if one randomly rms /etc12.
    • F2FS is the fastest for SSDs but can lose data if battery dies
  • Dotfiles
    • radically simplify everything, no need to source global ones and /home/me etc. — I’ll just use the same user for everything

OK, EndeavourOS+btfrs it is.

Day 1959

NII files

https://www.kaggle.com/code/datark1/what-are-dcm-and-nii-files-and-how-to-read-them

Inkscape bullet points


Latest post from Blog

'The Hacker Manifesto', переклад українською

Оригінал: .:: Phrack Magazine ::.
Контекст: Маніфест хакера — Вікіпедія / Hacker Manifesto - Wikipedia
Існуючий дуже класний переклад, не відкривав, поки не закінчив свій: Маніфест хакера | Hacker’s Manifesto | webKnjaZ: be a LifeHacker

                               ==Phrack Inc.==

                    Том I, випуск 7, Ph-айл[0] 3 з 10

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Наступне було написано невдовзі після мого арешту...

	                        \/\Совість хакера/\/

	                               автор:

	                          +++The Mentor+++

	                           8 січня 1986р.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

	Сьогодні ще одного спіймали, пишуть у всіх газетах. "Кібер-скандал:
підлітку повідомили про підозру", "Кіберзлочинця затримали після
проникнення в систему банку".
	Тупа школота[1], вони всі однакові.

	Та чи ви, з вашою трафаретною ментальністю[2] та знаннями 
інформатики зразка першої половини пʼятидесятих[3], коли-небудь дивилися 
в душу хакера?[4] Чи вас колись цікавило, що є причиною його поведінки[5], 
які сили на нього впливали, що його сформувало?
	Я хакер, ласкаво прошу у мій світ...
	Мій світ почався ще зі школи... Я розумніший за більшість інших
дітей, і дурниці, які нам викладають, мені набридають.
	Тупий відстаючий[6], вони всі однакові.

	Восьмий, девʼятий, десятий, одинадцятий клас[7]. В пʼятнадцятий
раз слухаю, як вчителька пояснює, як скорочувати дроби. Мені все ясно. "Ні, 
Вікторія Миколаївна[8], я не написав проміжні кроки, я розвʼязав все усно..."
	Тупий підліток. Мабуть списав. Всі вони такі.

	Сьогодні я зробив відкриття. Я знайшов компʼютер. Ха, почекай-но,
це круто. Він робить те, що я від нього хочу. І якщо він помиляється,
це тому, що помилився я. А не тому що він мене не любить...
                         Або відчуває від мене загрозу...
                         Або думає що я тіпа самий умний[9]...
                         Або не любить викладати[10] і йому тут не місце...
	Тупий підліток. Він постійно тільки грає в свої ігри. Всі вони такі...

	Потім це відбулось... відчинились двері в світ... несучись телефонною 
лінією як героїн венами наркомана, надсилається електронний пульс,
шукається спасіння від невігластва навколо...[11] Знаходиться борд.[12]
	"Це воно... це те, до чого я належу..."
	Я з усіма тут знайомий... попри те, що я з ними ніколи не 
зустрічався, не розмовляв, і колись можливо більше нічого не чутиму про 
них... Я їх всіх знаю...
	Тупий підліток. Знову займає телефонну лінію... Вони всі однакові.

	Та можете не сумніватись,[13] що ми всі однакові... Нас годували
дитячими сумішами з ложки, коли ми хотіли стейк... а ті куски мʼяса, які 
до нас все ж потрапляли, були вже пережовані і без смаку. Над нами
панували садисти, або нас ігнорували байдужі. Для тих, хто хотіли чомусь 
нас навчити, ми були вдячними учнями, але їх було як краплин дощу в
пустелі.

	Цей світ зараз наш... світ електрона і комутатора, світ краси
бода[14]. Ми користуємося існуючою послугою не платячи за те, що могло б 
бути дуже дешевим, якби ним не завідували ненажерливі бариги[15], і ви 
називаєте нас злочинцями. Ми досліджуємо... і ви називаєте нас 
злочинцями. Ми шукаємо знання... і ви називаєте нас злочинцями. Ми 
існуємо без кольору шкіри, без національності і без релігійної 
нетерпимості... і ви називаєте нас злочинцями. Ви будуєте атомні бомби, 
ви ведете війни, ви вбиваєте, обманюєте, і брешете нам, намагаючись 
заставити нас повірити, що ви це робите для нашого блага, і попри все - 
це ми тут злочинці.

	Так, я злочинець. Мій злочин - моя допитливість. Мій злочин - 
оцінювати людей по тому, що вони кажуть і думають, а не по тому, як 
вони виглядають. Мій злочин в тому, що я вас перехитрив, і ви мене 
ніколи не пробачите за це.

	Я хакер, і це мій маніфест. Можливо ви зупините мене як особу, але ви 
ніколи не зупините нас всіх... зрештою, ми всі однакові.
	

Замітки:

  1. Ph-айл: worst of both worlds between phile and файл
  2. Damn kids: тупі/кляті/грьобані діти/школота1/малолітки2? Дякую цьому твіту Букви, який дає мені моральне право використовувати слово “школота”, бо нічого інше не клеїлося (“Окаяні дітлахи!")
  3. three-piece-psychology: інтерпретую як невисоку оцінку розвитку внутрішнього світу. Тому: пересічним/шаблонним/банальним/трафаретним3/примітивним/нехитрим/безхитрим; psychology: ‘інтелект’ але не зовсім, мені подобається ‘ментальність’
  4. and 1950’s technobrain: Німецький переклад, який сподобався англіцизмами та дав ідею перекласти technobrain в значенні “знання про компʼютери”, а не слово в слово: Berühmte Manifeste 2 – openPunk
  5. хакер/гакер: Вікіпедія вважає обидва допустимими; сам Авраменко ссилаючись на ті самі правила українського правопису теж вважає обидва допустимими, але все ж любить “г” більше (Хакер чи гакер - експрес-урок - YouTube). А я не можу і не буду. Хакер. I will die on this hill.
  6. what makes him tick: TODO, нічого не подобається. Що його рухає/надихає, що у нього в середині, …
  7. underachiever: хай буде “відстаючий”. Хоча пригадую з ЗНО, що суфікси уч/юч обмежені у вживанні, правильніше ВІДСТАЛИЙ мені не подобається.
  8. junior high or high school: тут додаю драми замість дослівності, тому що все ближче до оригіналу, що я можу придумати, занадто канцеляристично: “я закінчую базову чи повну загальну середню освіту”..?
  9. Ms. Smith:
  10. I’m a smart ass
  11. doesn’t like teaching: оплакую невикористаний варіант від душі “ненавидить себе, дітей, і педагогіку”. Дуже оплакую.
  12. a refuge from the day-to-day incompetencies is sought
  13. a board is found: мається на увазі електронна дошка оголошень (BBS — Вікіпедія), дід форумів і прадід іміджбордів. Найцікавіше слово для перекладу. Якщо буде “борд” то збережеться драматизм оригіналу, але є шанси, що хтось спутає з іміджбордами. Коли вони були популярні, нормальні люди в Україні їх не називали ніяк, російською були варіанти “доска”, “бибиэска”4. “BBS” був би найпростішим виходом; “електронна дошка оголошень” знову ж таки канцеляризм. По контексту далі очевидно, що мова йде про якесь спілкування, тому хай буде “борд”, принесу в жертву однозначність і зрозумілість милозвучності.
  14. you bet your ass we’re all alike: як же складно підбирати такі речі. Умовні embeddings з ML тут були б в тему. “Дай мені щось на кшталт ‘авжеж’ тільки більш emphatical”. Попередня версія “Авжеж ми всі однакові!”
    1. You bet – phrases: базара нет, по любому, я вас умоляю
    2. Будьте певні5
    3. ЩЕ Б ПАК — СИНОНІМІЯ | Горох — українські словники
      1. Авжеж?6
  15. the beauty of the baud: Бод — Вікіпедія Нехай мій (і єдиний можливий) переклад буде всім настільки ж зрозумілим, наскільки мені був зрозумілий оригінал, коли я його читав вперше.
  16. profitteering gluttons

Hat tip to:

Random: